add ability to have typed arbitrary parameters in xml - refs #977

This commit is contained in:
Dane Springmeyer 2011-12-05 14:46:38 -08:00
parent cb504ea4c9
commit b78b8e735b
4 changed files with 77 additions and 9 deletions

View file

@ -403,9 +403,30 @@ void map_parser::parse_map_include( Map & map, ptree const & include )
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;
bool is_string = true;
boost::optional<std::string> type = get_opt_attr<std::string>(param, "type");
if (type)
{
if (*type == "int")
{
is_string = false;
int value = get_value<int>( param,"parameter");
params[name] = value;
}
else if (*type == "float")
{
is_string = false;
double value = get_value<double>( param,"parameter");
params[name] = value;
}
}
if (is_string)
{
std::string value = get_value<std::string>( param,
"parameter");
params[name] = value;
}
}
else if( paramIter->first != "<xmlattr>" &&
paramIter->first != "<xmlcomment>" )

View file

@ -761,6 +761,36 @@ void serialize_datasource( ptree & layer_node, datasource_ptr datasource)
}
}
class serialize_type : public boost::static_visitor<>
{
public:
serialize_type( boost::property_tree::ptree & node):
node_(node) {}
void operator () ( int val ) const
{
node_.put("<xmlattr>.type", "int" );
}
void operator () ( double val ) const
{
node_.put("<xmlattr>.type", "float" );
}
void operator () ( std::string const& val ) const
{
node_.put("<xmlattr>.type", "string" );
}
void operator () ( mapnik::value_null val ) const
{
node_.put("<xmlattr>.type", "string" );
}
private:
boost::property_tree::ptree & node_;
};
void serialize_parameters( ptree & map_node, mapnik::parameters const& params)
{
ptree & params_node = map_node.push_back(
@ -775,7 +805,7 @@ void serialize_parameters( ptree & map_node, mapnik::parameters const& params)
boost::property_tree::ptree()))->second;
param_node.put("<xmlattr>.name", it->first );
param_node.put_value( it->second );
boost::apply_visitor(serialize_type(param_node),it->second);
}
}

View file

@ -10,11 +10,15 @@
-->
<Parameters>
<Parameter name="key"><![CDATA[value]]></Parameter>
<Parameter name="key" type="string"><![CDATA[value]]></Parameter>
<!-- this one will override previous key with same name -->
<Parameter name="key"><![CDATA[value2]]></Parameter>
<Parameter name="key3"><![CDATA[value3]]></Parameter>
<Parameter name="unicode"><![CDATA[iván]]></Parameter>
<Parameter name="key" type="string"><![CDATA[value2]]></Parameter>
<Parameter name="key3" type="string"><![CDATA[value3]]></Parameter>
<Parameter name="unicode" type="string"><![CDATA[iván]]></Parameter>
<Parameter name="integer" type="int"><![CDATA[10]]></Parameter>
<Parameter name="decimal" type="float"><![CDATA[.999]]></Parameter>
<!-- without a type attribute numbers are treated as strings -->
<Parameter name="number-as-string"><![CDATA[.9998]]></Parameter>
</Parameters>
</Map>

View file

@ -28,12 +28,25 @@ def test_arbitrary_parameters_attached_to_map():
attr = m.extra_attributes
eq_(len(attr),0)
eq_(len(m.params),3)
eq_(len(m.params),6)
eq_(m.params['key'],'value2')
eq_(m.params['key3'],'value3')
eq_(m.params['unicode'],u'iván')
eq_(m.params['integer'],10)
eq_(m.params['decimal'],.999)
eq_(m.params['number-as-string'],u'.9998')
def test_serializing_arbitrary_parameters():
m = mapnik.Map(256,256)
m.params.append(mapnik.Parameter('width',m.width))
m.params.append(mapnik.Parameter('height',m.height))
m2 = mapnik.Map(1,1)
mapnik.load_map_from_string(m2,mapnik.save_map_to_string(m))
eq_(m2.params['width'],m.width)
eq_(m2.params['height'],m.height)
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]