add support for arbitrary, custom parameters to be attached to the map during load and serialized when saved - refs #977

This commit is contained in:
Dane Springmeyer 2011-12-02 17:48:09 -08:00
parent dcae156e92
commit b03ce6e607
5 changed files with 136 additions and 6 deletions

View file

@ -84,6 +84,7 @@ private:
boost::optional<box2d<double> > maximum_extent_;
std::string base_path_;
parameters extra_attr_;
parameters extra_params_;
public:
@ -444,14 +445,34 @@ public:
std::string get_metawriter_property(std::string name) const;
/*!
* @brief Get extra properties that can be carried on the Map
* @brief Get extra valid attributes of the Map that are not true members
*/
parameters const& get_extra_attributes() const;
/*!
* @brief Set extra properties that can be carried on the Map
* @brief Get non-const extra valid attributes of the Map that are not true members
*/
void set_extra_attributes(parameters& params);
parameters& get_extra_attributes();
/*!
* @brief Set extra attributes of the Map
*/
void set_extra_attributes(parameters& attr);
/*!
* @brief Get extra, arbitrary Parameters attached to the Map
*/
parameters const& get_extra_parameters() const;
/*!
* @brief Get non-const extra, arbitrary Parameters attached to the Map
*/
parameters& get_extra_parameters();
/*!
* @brief Set extra, arbitary Parameters of the Map
*/
void set_extra_parameters(parameters& params);
private:
void fixAspectRatio();

View file

@ -390,6 +390,32 @@ void map_parser::parse_map_include( Map & map, ptree const & include )
}
datasource_templates_[name] = params;
}
else if (v.first == "Parameters")
{
std::string name = get_attr(v.second, "name", std::string("Unnamed"));
parameters & params = map.get_extra_parameters();
ptree::const_iterator paramIter = v.second.begin();
ptree::const_iterator endParam = v.second.end();
for (; paramIter != endParam; ++paramIter)
{
ptree const& param = paramIter->second;
if (paramIter->first == "Parameter")
{
std::string name = get_attr<std::string>(param, "name");
std::string value = get_value<std::string>( param,
"parameter");
params[name] = value;
}
else if( paramIter->first != "<xmlattr>" &&
paramIter->first != "<xmlcomment>" )
{
throw config_error(std::string("Unknown child node in ") +
"'Parameters'. Expected 'Parameter' but got '" +
paramIter->first + "'");
}
}
}
else if (v.first != "<xmlcomment>" &&
v.first != "<xmlattr>")
{

View file

@ -92,7 +92,8 @@ Map::Map(const Map& rhs)
current_extent_(rhs.current_extent_),
maximum_extent_(rhs.maximum_extent_),
base_path_(rhs.base_path_),
extra_attr_(rhs.extra_attr_) {}
extra_attr_(rhs.extra_attr_),
extra_params_(rhs.extra_params_) {}
Map& Map::operator=(const Map& rhs)
{
@ -110,6 +111,7 @@ Map& Map::operator=(const Map& rhs)
maximum_extent_=rhs.maximum_extent_;
base_path_=rhs.base_path_;
extra_attr_=rhs.extra_attr_;
extra_params_=rhs.extra_params_;
return *this;
}
@ -677,9 +679,29 @@ parameters const& Map::get_extra_attributes() const
return extra_attr_;
}
void Map::set_extra_attributes(parameters& params)
parameters& Map::get_extra_attributes()
{
extra_attr_ = params;
return extra_attr_;
}
void Map::set_extra_attributes(parameters& attr)
{
extra_attr_ = attr;
}
parameters const& Map::get_extra_parameters() const
{
return extra_params_;
}
parameters& Map::get_extra_parameters()
{
return extra_params_;
}
void Map::set_extra_parameters(parameters& params)
{
extra_params_ = params;
}
}

View file

@ -761,6 +761,24 @@ void serialize_datasource( ptree & layer_node, datasource_ptr datasource)
}
}
void serialize_parameters( ptree & map_node, mapnik::parameters const& params)
{
ptree & params_node = map_node.push_back(
ptree::value_type("Parameters", ptree()))->second;
parameters::const_iterator it = params.begin();
parameters::const_iterator end = params.end();
for (; it != end; ++it)
{
boost::property_tree::ptree & param_node = params_node.push_back(
boost::property_tree::ptree::value_type("Parameter",
boost::property_tree::ptree()))->second;
param_node.put("<xmlattr>.name", it->first );
param_node.put_value( it->second );
}
}
void serialize_layer( ptree & map_node, const layer & layer, bool explicit_defaults )
{
ptree & layer_node = map_node.push_back(
@ -900,6 +918,8 @@ void serialize_map(ptree & pt, Map const & map, bool explicit_defaults)
{
set_attr( map_node, p_it->first, p_it->second );
}
serialize_parameters( map_node, map.get_extra_parameters());
Map::const_style_iterator it = map.styles().begin();
Map::const_style_iterator end = map.styles().end();

View file

@ -0,0 +1,41 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from nose.tools import *
from utilities import execution_path
from Queue import Queue
import threading
import os, mapnik
import sqlite3
def setup():
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def test_non_member_known_attributes():
m = mapnik.Map(256,256)
mapnik.load_map(m,'../data/good_maps/extra_known_map_attributes.xml')
attr = m.extra_attributes
eq_(len(attr),2)
eq_(attr['font-directory'],'.')
eq_(attr['minimum-version'],'0.0.0')
def test_arbitrary_parameters_attached_to_map():
m = mapnik.Map(256,256)
mapnik.load_map(m,'../data/good_maps/extra_arbitary_map_parameters.xml')
attr = m.extra_attributes
eq_(len(attr),0)
params = m.extra_parameters
eq_(len(params),3)
eq_(params['key'],'value2')
eq_(params['key3'],'value3')
eq_(params['unicode'],u'iván')
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]