add support for relative paths for entities when using libxml2 and loading xml from string - thanks dodobas for the initial patch

This commit is contained in:
Dane Springmeyer 2009-12-06 22:18:45 +00:00
parent c1ed612b2d
commit d0b4db9ba3
12 changed files with 108 additions and 12 deletions

View file

@ -263,7 +263,7 @@ bool has_pycairo()
BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_overloads, load_map, 2, 3); 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_overloads, save_map, 2, 3);
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_string_overloads, save_map_string, 1, 2); BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_string_overloads, save_map_string, 1, 2);

View file

@ -30,7 +30,7 @@
namespace mapnik namespace mapnik
{ {
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt); 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 #endif // LIBXML2_LOADER_INCLUDED

View file

@ -34,7 +34,7 @@
namespace mapnik namespace mapnik
{ {
MAPNIK_DECL void load_map(Map & map, std::string const& filename, bool strict = false); 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 #endif // LOAD_MAP_HPP

View file

@ -37,6 +37,7 @@
using boost::property_tree::ptree; using boost::property_tree::ptree;
using namespace std; 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) #define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA)
namespace mapnik namespace mapnik
@ -69,7 +70,7 @@ namespace mapnik
void load( const std::string & filename, ptree & pt ) void load( const std::string & filename, ptree & pt )
{ {
boost::filesystem::path path(filename); boost::filesystem::path path(filename);
if ( ! boost::filesystem::exists( path ) ) { if ( !boost::filesystem::exists( path ) ) {
throw config_error(string("Could not load map file '") + throw config_error(string("Could not load map file '") +
filename + "': File does not exist"); filename + "': File does not exist");
} }
@ -114,9 +115,19 @@ namespace mapnik
load(doc, pt); 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); load(doc, pt);
} }
@ -203,10 +214,10 @@ namespace mapnik
libxml2_loader loader; libxml2_loader loader;
loader.load( filename, pt ); 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; libxml2_loader loader;
loader.load_string( str, pt ); loader.load_string( str, pt, base_url );
} }
} // end of namespace mapnik } // end of namespace mapnik

View file

@ -122,11 +122,11 @@ namespace mapnik
parser.parse_map(map, pt); 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; ptree pt;
#ifdef HAVE_LIBXML2 #ifdef HAVE_LIBXML2
read_xml2_string(str, pt); read_xml2_string(str, pt, base_url);
#else #else
try try
{ {
@ -139,7 +139,7 @@ namespace mapnik
} }
#endif #endif
map_parser parser( strict ); map_parser parser( strict, base_url);
parser.parse_map(map, pt); parser.parse_map(map, pt);
} }

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map [
<!ENTITY % entities SYSTEM "../inc/entities.xml.inc">
%entities;
]>
<Map bgcolor="#b5d0d0" srs="&srs900913;">
&fontset-settings;
<Style name="turning_circle">
<Rule>
&maxscale_zoom15;
&minscale_zoom16;
<PointSymbolizer file="&symbols;/dummy.png" type="png" width="15" height="15" />
</Rule>
<Rule>
&maxscale_zoom17;
<PointSymbolizer file="&symbols;/dummy.png" type="png" width="19" height="19" />
</Rule>
</Style>
<Layer name="area-text" status="on" srs="&srs900913;">
<StyleName>turning_circle</StyleName>
</Layer>
</Map>

View file

@ -0,0 +1,7 @@
<!ENTITY fontset-settings SYSTEM "fontset-settings.xml.inc">
<!ENTITY srs900913 "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over">
<!ENTITY srsmercator "+proj=merc +datum=WGS84 +over">
<!ENTITY srs4326 "+init=epsg:4326">
<!ENTITY symbols "../images">
<!ENTITY % scales SYSTEM "scales.xml.inc">
%scales;

View file

View file

@ -0,0 +1,12 @@
<FontSet name="book-fonts">
<Font face_name="DejaVu Sans Book" />
<!--Font face_name="unifont Medium" /-->
</FontSet>
<FontSet name="bold-fonts">
<Font face_name="DejaVu Sans Bold" />
<!--Font face_name="unifont Medium" /-->
</FontSet>
<FontSet name="oblique-fonts">
<Font face_name="DejaVu Sans Oblique" />
<!--Font face_name="unifont Medium" /-->
</FontSet>

View file

@ -0,0 +1,37 @@
<!ENTITY maxscale_zoom0 "<MaxScaleDenominator>250000000000</MaxScaleDenominator>">
<!ENTITY maxscale_zoom1 "<MaxScaleDenominator>500000000</MaxScaleDenominator>">
<!ENTITY minscale_zoom1 "<MinScaleDenominator>200000000</MinScaleDenominator>">
<!ENTITY maxscale_zoom2 "<MaxScaleDenominator>200000000</MaxScaleDenominator>">
<!ENTITY minscale_zoom2 "<MinScaleDenominator>100000000</MinScaleDenominator>">
<!ENTITY maxscale_zoom3 "<MaxScaleDenominator>100000000</MaxScaleDenominator>">
<!ENTITY minscale_zoom3 "<MinScaleDenominator>50000000</MinScaleDenominator>">
<!ENTITY maxscale_zoom4 "<MaxScaleDenominator>50000000</MaxScaleDenominator>">
<!ENTITY minscale_zoom4 "<MinScaleDenominator>25000000</MinScaleDenominator>">
<!ENTITY maxscale_zoom5 "<MaxScaleDenominator>25000000</MaxScaleDenominator>">
<!ENTITY minscale_zoom5 "<MinScaleDenominator>12500000</MinScaleDenominator>">
<!ENTITY maxscale_zoom6 "<MaxScaleDenominator>12500000</MaxScaleDenominator>">
<!ENTITY minscale_zoom6 "<MinScaleDenominator>6500000</MinScaleDenominator>">
<!ENTITY maxscale_zoom7 "<MaxScaleDenominator>6500000</MaxScaleDenominator>">
<!ENTITY minscale_zoom7 "<MinScaleDenominator>3000000</MinScaleDenominator>">
<!ENTITY maxscale_zoom8 "<MaxScaleDenominator>3000000</MaxScaleDenominator>">
<!ENTITY minscale_zoom8 "<MinScaleDenominator>1500000</MinScaleDenominator>">
<!ENTITY maxscale_zoom9 "<MaxScaleDenominator>1500000</MaxScaleDenominator>">
<!ENTITY minscale_zoom9 "<MinScaleDenominator>750000</MinScaleDenominator>">
<!ENTITY maxscale_zoom10 "<MaxScaleDenominator>750000</MaxScaleDenominator>">
<!ENTITY minscale_zoom10 "<MinScaleDenominator>400000</MinScaleDenominator>">
<!ENTITY maxscale_zoom11 "<MaxScaleDenominator>400000</MaxScaleDenominator>">
<!ENTITY minscale_zoom11 "<MinScaleDenominator>200000</MinScaleDenominator>">
<!ENTITY maxscale_zoom12 "<MaxScaleDenominator>200000</MaxScaleDenominator>">
<!ENTITY minscale_zoom12 "<MinScaleDenominator>100000</MinScaleDenominator>">
<!ENTITY maxscale_zoom13 "<MaxScaleDenominator>100000</MaxScaleDenominator>">
<!ENTITY minscale_zoom13 "<MinScaleDenominator>50000</MinScaleDenominator>">
<!ENTITY maxscale_zoom14 "<MaxScaleDenominator>50000</MaxScaleDenominator>">
<!ENTITY minscale_zoom14 "<MinScaleDenominator>25000</MinScaleDenominator>">
<!ENTITY maxscale_zoom15 "<MaxScaleDenominator>25000</MaxScaleDenominator>">
<!ENTITY minscale_zoom15 "<MinScaleDenominator>12500</MinScaleDenominator>">
<!ENTITY maxscale_zoom16 "<MaxScaleDenominator>12500</MaxScaleDenominator>">
<!ENTITY minscale_zoom16 "<MinScaleDenominator>5000</MinScaleDenominator>">
<!ENTITY maxscale_zoom17 "<MaxScaleDenominator>5000</MaxScaleDenominator>">
<!ENTITY minscale_zoom17 "<MinScaleDenominator>2500</MinScaleDenominator>">
<!ENTITY maxscale_zoom18 "<MaxScaleDenominator>2500</MaxScaleDenominator>">
<!ENTITY minscale_zoom18 "<MinScaleDenominator>1000</MinScaleDenominator>">

View file

@ -17,6 +17,12 @@ def assert_loads_successfully(file):
strict = True strict = True
mapnik.load_map(m, file, strict) 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 # We expect these files to raise a UserWarning
# and fail if there isn't one (or a different type # and fail if there isn't one (or a different type

View file

@ -262,7 +262,8 @@ def test_map_init_from_string():
m = mapnik.Map(600, 300) m = mapnik.Map(600, 300)
mapnik.load_map_from_string(m, map_string) 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'...")) raise(Todo("Need to write more map property tests in 'object_test.py'..."))
# Map pickling # Map pickling