diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index 833c7dc62..59712e781 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -263,7 +263,7 @@ bool has_pycairo() BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_overloads, load_map, 2, 3); -BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 3); +BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 4); BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3); BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_string_overloads, save_map_string, 1, 2); diff --git a/include/mapnik/libxml2_loader.hpp b/include/mapnik/libxml2_loader.hpp index 7ec9b7a06..9e0551c97 100644 --- a/include/mapnik/libxml2_loader.hpp +++ b/include/mapnik/libxml2_loader.hpp @@ -30,7 +30,7 @@ namespace mapnik { void read_xml2( std::string const & filename, boost::property_tree::ptree & pt); - void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt); + void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path=""); } #endif // LIBXML2_LOADER_INCLUDED diff --git a/include/mapnik/load_map.hpp b/include/mapnik/load_map.hpp index 2589d6ce9..5bc93cd05 100644 --- a/include/mapnik/load_map.hpp +++ b/include/mapnik/load_map.hpp @@ -34,7 +34,7 @@ namespace mapnik { MAPNIK_DECL void load_map(Map & map, std::string const& filename, bool strict = false); - MAPNIK_DECL void load_map_string(Map & map, std::string const& str, bool strict = false); + MAPNIK_DECL void load_map_string(Map & map, std::string const& str, bool strict = false, std::string const& base_url=""); } #endif // LOAD_MAP_HPP diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index 7973a109a..a453e7a8f 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -37,6 +37,7 @@ using boost::property_tree::ptree; using namespace std; +//#define DEFAULT_OPTIONS (XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA) #define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA) namespace mapnik @@ -69,7 +70,7 @@ namespace mapnik void load( const std::string & filename, ptree & pt ) { boost::filesystem::path path(filename); - if ( ! boost::filesystem::exists( path ) ) { + if ( !boost::filesystem::exists( path ) ) { throw config_error(string("Could not load map file '") + filename + "': File does not exist"); } @@ -114,9 +115,19 @@ namespace mapnik load(doc, pt); } - void load_string( const std::string & buffer, ptree & pt ) + void load_string( const std::string & buffer, ptree & pt, std::string const & base_url ) { - xmlDocPtr doc = xmlCtxtReadMemory(ctx_, buffer.data(), buffer.length(), url_, encoding_, options_); + if (!base_url.empty()) + { + boost::filesystem::path path(base_url); + if ( ! boost::filesystem::exists( path ) ) { + throw config_error(string("Could not locate base_url '") + + base_url + "': file or directory does not exist"); + } + } + + xmlDocPtr doc = xmlCtxtReadMemory(ctx_, buffer.data(), buffer.length(), base_url.c_str(), encoding_, options_); + load(doc, pt); } @@ -203,10 +214,10 @@ namespace mapnik libxml2_loader loader; loader.load( filename, pt ); } - void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt) + void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_url) { libxml2_loader loader; - loader.load_string( str, pt ); + loader.load_string( str, pt, base_url ); } } // end of namespace mapnik diff --git a/src/load_map.cpp b/src/load_map.cpp index aed6a7484..e0476449b 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -122,11 +122,11 @@ namespace mapnik parser.parse_map(map, pt); } - void load_map_string(Map & map, std::string const& str, bool strict) + void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_url) { ptree pt; #ifdef HAVE_LIBXML2 - read_xml2_string(str, pt); + read_xml2_string(str, pt, base_url); #else try { @@ -139,7 +139,7 @@ namespace mapnik } #endif - map_parser parser( strict ); + map_parser parser( strict, base_url); parser.parse_map(map, pt); } diff --git a/tests/data/good_maps/entities.xml b/tests/data/good_maps/entities.xml new file mode 100644 index 000000000..11aa3d932 --- /dev/null +++ b/tests/data/good_maps/entities.xml @@ -0,0 +1,22 @@ + + +%entities; +]> + + &fontset-settings; + + + turning_circle + + \ No newline at end of file diff --git a/tests/data/inc/entities.xml.inc b/tests/data/inc/entities.xml.inc new file mode 100644 index 000000000..a9b2dd399 --- /dev/null +++ b/tests/data/inc/entities.xml.inc @@ -0,0 +1,7 @@ + + + + + + +%scales; \ No newline at end of file diff --git a/tests/data/inc/expected.xml b/tests/data/inc/expected.xml new file mode 100644 index 000000000..e69de29bb diff --git a/tests/data/inc/fontset-settings.xml.inc b/tests/data/inc/fontset-settings.xml.inc new file mode 100644 index 000000000..51094cc2d --- /dev/null +++ b/tests/data/inc/fontset-settings.xml.inc @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/data/inc/scales.xml.inc b/tests/data/inc/scales.xml.inc new file mode 100644 index 000000000..f5f5a2556 --- /dev/null +++ b/tests/data/inc/scales.xml.inc @@ -0,0 +1,37 @@ +250000000000"> +500000000"> +200000000"> +200000000"> +100000000"> +100000000"> +50000000"> +50000000"> +25000000"> +25000000"> +12500000"> +12500000"> +6500000"> +6500000"> +3000000"> +3000000"> +1500000"> +1500000"> +750000"> +750000"> +400000"> +400000"> +200000"> +200000"> +100000"> +100000"> +50000"> +50000"> +25000"> +25000"> +12500"> +12500"> +5000"> +5000"> +2500"> +2500"> +1000"> \ No newline at end of file diff --git a/tests/python_tests/load_map_test.py b/tests/python_tests/load_map_test.py index e00bbd205..602071f83 100644 --- a/tests/python_tests/load_map_test.py +++ b/tests/python_tests/load_map_test.py @@ -17,6 +17,12 @@ def assert_loads_successfully(file): strict = True mapnik.load_map(m, file, strict) + + # libxml2 is not smart about paths, and clips the last directory off + # of a path if it does not end in a trailing slash + base_path = os.path.dirname(file) + '/' + mapnik.load_map_from_string(m,open(file,'rb').read(),strict,base_path) + # We expect these files to raise a UserWarning # and fail if there isn't one (or a different type diff --git a/tests/python_tests/object_test.py b/tests/python_tests/object_test.py index 02d5e2389..8fa9f5122 100644 --- a/tests/python_tests/object_test.py +++ b/tests/python_tests/object_test.py @@ -262,7 +262,8 @@ def test_map_init_from_string(): m = mapnik.Map(600, 300) mapnik.load_map_from_string(m, map_string) - mapnik.load_map_from_string(m, map_string, True) + mapnik.load_map_from_string(m, map_string, False, "") + mapnik.load_map_from_string(m, map_string, True, "") raise(Todo("Need to write more map property tests in 'object_test.py'...")) # Map pickling