load_map_from_string has always accepted a base path argument to drive the interpretation of relative paths in the stylesheet when loaded in memory- this really should be a full map property so that it can be known on the map object after parsing and changed if the map is saved to a new location

This commit is contained in:
Dane Springmeyer 2011-05-25 23:48:07 +00:00
parent 0d0c3cdb09
commit 7a17c7e597
5 changed files with 72 additions and 13 deletions

View file

@ -69,17 +69,17 @@ struct map_pickle_suite : boost::python::pickle_suite
s.append(style_pair);
}
return boost::python::make_tuple(m.get_current_extent(),m.background(),l,s);
return boost::python::make_tuple(m.get_current_extent(),m.background(),l,s,m.base_path());
}
static void
setstate (Map& m, boost::python::tuple state)
{
using namespace boost::python;
if (len(state) != 4)
if (len(state) != 5)
{
PyErr_SetObject(PyExc_ValueError,
("expected 4-item tuple in call to __setstate__; got %s"
("expected 5-item tuple in call to __setstate__; got %s"
% state).ptr()
);
throw_error_already_set();
@ -107,6 +107,12 @@ struct map_pickle_suite : boost::python::pickle_suite
mapnik::feature_type_style style = extract<mapnik::feature_type_style>(style_pair[1]);
m.insert_style(name, style);
}
if (state[4])
{
std::string base_path = extract<std::string>(state[4]);
m.set_base_path(base_path);
}
}
};
@ -464,6 +470,16 @@ void export_map()
"Usage:\n"
">>> m.background = Color('steelblue')\n"
)
.add_property("base",
make_function(&Map::base_path,return_value_policy<copy_const_reference>()),
&Map::set_base_path,
"The base path of the map where any files using relative \n"
"paths will be interpreted as relative to.\n"
"\n"
"Usage:\n"
">>> m.base_path = '.'\n"
)
.add_property("buffer_size",
&Map::buffer_size,

View file

@ -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, std::string const& base_url="");
MAPNIK_DECL void load_map_string(Map & map, std::string const& str, bool strict = false, std::string const& base_path="");
}
#endif // LOAD_MAP_HPP

View file

@ -83,6 +83,7 @@ private:
aspect_fix_mode aspectFixMode_;
box2d<double> current_extent_;
boost::optional<box2d<double> > maximum_extent_;
std::string base_path_;
parameters extra_attr_;
public:
@ -341,6 +342,15 @@ public:
*/
boost::optional<box2d<double> > const& maximum_extent() const;
/*! \brief Get the map base path where paths should be relative to.
*/
std::string const& base_path() const;
/*! \brief Set the map base path where paths should be releative to.
* @param srs Map base_path.
*/
void set_base_path(std::string const& base);
/*! \brief Zoom the map at the current position.
* @param factor The factor how much the map is zoomed in or out.
*/

View file

@ -83,7 +83,7 @@ public:
relative_to_xml_(true),
font_manager_(font_engine_) {}
void parse_map(Map & map, ptree const & sty);
void parse_map(Map & map, ptree const & sty, std::string const& base_path="");
private:
void parse_map_include( Map & map, ptree const & include);
void parse_style(Map & map, ptree const & sty);
@ -146,15 +146,19 @@ void load_map(Map & map, std::string const& filename, bool strict)
parser.parse_map(map, pt);
}
void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_url)
void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_path)
{
ptree pt;
#ifdef HAVE_LIBXML2
read_xml2_string(str, pt, base_url);
if (!base_path.empty())
read_xml2_string(str, pt, base_path); // accept base_path passed into function
else
read_xml2_string(str, pt, map.base_path()); // default to map base_path
#else
try
{
std::istringstream s(str);
// TODO - support base_path?
read_xml(s,pt);
}
catch (const boost::property_tree::xml_parser_error & ex)
@ -163,11 +167,11 @@ void load_map_string(Map & map, std::string const& str, bool strict, std::string
}
#endif
map_parser parser( strict, base_url);
parser.parse_map(map, pt);
map_parser parser( strict, base_path);
parser.parse_map(map, pt, base_path);
}
void map_parser::parse_map( Map & map, ptree const & pt )
void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base_path )
{
try
{
@ -181,7 +185,8 @@ void map_parser::parse_map( Map & map, ptree const & pt )
<< "paths-from-xml,"
<< "minimum-version,"
<< "font-directory,"
<< "maximum-extent";
<< "maximum-extent,"
<< "base";
ensure_attrs(map_node, "Map", s.str());
try
@ -196,6 +201,28 @@ void map_parser::parse_map( Map & map, ptree const & pt )
relative_to_xml_ = *paths_from_xml;
}
optional<std::string> base_path_from_xml = get_opt_attr<std::string>(map_node, "base");
if (!base_path.empty())
{
map.set_base_path( base_path );
}
else if (base_path_from_xml)
{
map.set_base_path( *base_path_from_xml );
}
else
{
boost::filesystem::path xml_path(filename_);
// TODO - should we make this absolute?
#if (BOOST_FILESYSTEM_VERSION == 3)
std::string const& base = xml_path.parent_path().string();
#else // v2
std::string const& base = xml_path.branch_path().string();
#endif
map.set_base_path( base );
}
optional<color> bgcolor = get_opt_attr<color>(map_node, "background-color");
if (bgcolor)
{
@ -2093,7 +2120,8 @@ std::string map_parser::ensure_relative_to_xml( boost::optional<std::string> opt
if ( !rel_path.has_root_path() )
{
#if (BOOST_FILESYSTEM_VERSION == 3)
boost::filesystem::path full = boost::filesystem::absolute(xml_path.branch_path()/rel_path).normalize();
// TODO - normalize is now deprecated, use make_preferred?
boost::filesystem::path full = boost::filesystem::absolute(xml_path.parent_path()/rel_path);
#else // v2
boost::filesystem::path full = boost::filesystem::complete(xml_path.branch_path()/rel_path).normalize();
#endif

View file

@ -834,13 +834,18 @@ void serialize_map(ptree & pt, Map const & map, bool explicit_defaults)
set_attr( map_node, "background-image", *image_filename );
}
unsigned buffer_size = map.buffer_size();
if ( buffer_size || explicit_defaults)
{
set_attr( map_node, "buffer-size", buffer_size );
}
std::string const& base_path = map.base_path();
if ( !base_path.empty() || explicit_defaults)
{
set_attr( map_node, "base", base_path );
}
optional<box2d<double> > const& maximum_extent = map.maximum_extent();
if ( maximum_extent)
{