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;
+]>
+
\ 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