Merge branch 'master' into geometry_cleanup

This commit is contained in:
Artem Pavlenko 2011-12-14 14:04:30 +00:00
commit 726cea7ba4
16 changed files with 123 additions and 70 deletions

View file

@ -41,8 +41,10 @@ def is_py3():
prefix = env['PREFIX']
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik')
target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
libraries = ['mapnik','png']
libraries = ['mapnik']
libraries.append('png')
if env['JPEG']:
libraries.append('jpeg')
@ -121,22 +123,24 @@ else:
paths = '''
"""Configuration paths of Mapnik fonts and input plugins (auto-generated by SCons)."""
import os
from os.path import normpath,join,dirname
mapniklibpath = '%s'
mapniklibpath = normpath(join(dirname(__file__),mapniklibpath))
'''
paths += "inputpluginspath = os.path.normpath(mapniklibpath + '/input')\n"
paths += "inputpluginspath = join(mapniklibpath,'input')\n"
if env['SYSTEM_FONTS']:
paths += "fontscollectionpath = os.path.normpath('%s')" % env['SYSTEM_FONTS']
paths += "fontscollectionpath = normpath('%s')\n" % env['SYSTEM_FONTS']
else:
paths += "fontscollectionpath = os.path.normpath(mapniklibpath + '/fonts')"
paths += "fontscollectionpath = join(mapniklibpath,'fonts')\n"
paths += "__all__ = [mapniklibpath,inputpluginspath,fontscollectionpath]\n"
if not os.path.exists('mapnik'):
os.mkdir('mapnik')
file('mapnik/paths.py','w').write(paths % (env['MAPNIK_LIB_DIR']))
file('mapnik/paths.py','w').write(paths % (os.path.relpath(env['MAPNIK_LIB_DIR'],target_path)))
# force open perms temporarily so that `sudo scons install`
# does not later break simple non-install non-sudo rebuild
@ -152,8 +156,7 @@ if 'install' in COMMAND_LINE_TARGETS:
init_module = env.Install(target_path, init_files)
env.Alias(target='install', source=init_module)
# install mapnik2 module which redirects to mapnik and issues DeprecatedWarning
path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
init_mapnik2 = env.Install(path, 'mapnik2/__init__.py')
init_mapnik2 = env.Install(target_path_deprecated, 'mapnik2/__init__.py')
env.Alias(target='install', source=init_mapnik2)
# fix perms and install the custom generated 'paths.py'
@ -204,4 +207,5 @@ if 'uninstall' not in COMMAND_LINE_TARGETS:
env['create_uninstall_target'](env, target_path)
env['create_uninstall_target'](env, target_path_deprecated)

View file

@ -1,3 +0,0 @@
mapniklibpath = '@PACKAGE_LIB_DIR@'
inputpluginspath = mapniklibpath + '/input'
fontscollectionpath = '@SYSTEM_FONTS_DIR@/truetype/ttf-dejavu'

View file

@ -213,6 +213,12 @@ struct symbolizer_attributes : public boost::static_visitor<>
void operator () (building_symbolizer const& sym)
{
expression_ptr const& height_expr = sym.height();
if (height_expr)
{
expression_attributes f_attr(names_);
boost::apply_visitor(f_attr,*height_expr);
}
collect_metawriter(sym);
}
// TODO - support remaining syms

View file

@ -26,6 +26,7 @@
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/filter_factory.hpp>
namespace mapnik
{
@ -79,11 +80,10 @@ struct MAPNIK_DECL building_symbolizer : public symbolizer_base
explicit building_symbolizer()
: symbolizer_base(),
fill_(color(128,128,128)),
height_(0.0),
opacity_(1.0)
{}
building_symbolizer(color const& fill,double height)
building_symbolizer(color const& fill, expression_ptr height)
: symbolizer_base(),
fill_(fill),
height_(height),
@ -97,11 +97,11 @@ struct MAPNIK_DECL building_symbolizer : public symbolizer_base
{
fill_ = fill;
}
double height() const
expression_ptr height() const
{
return height_;
}
void set_height(double height)
void set_height(expression_ptr height)
{
height_=height;
}
@ -115,7 +115,7 @@ struct MAPNIK_DECL building_symbolizer : public symbolizer_base
}
private:
color fill_;
double height_;
expression_ptr height_;
double opacity_;
};
}

View file

@ -489,10 +489,12 @@ void csv_datasource::parse_csv(T& stream,
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,
(
qi::lit("POINT") >> '(' >> double_[ref(x) = _1] >> double_[ref(y) = _1] >> ')'
),
ascii::space);
(
qi::lit("POINT") >> '('
>> double_[ref(x) = _1]
>> double_[ref(y) = _1] >> ')'
),
ascii::space);
if (r && (str_beg == str_end))
{
@ -615,28 +617,27 @@ void csv_datasource::parse_csv(T& stream,
}
}
// add all values as attributes
// here we detect numbers and treat everything else as pure strings
// this is intentional since boolean and null types are not common in csv editors
if (value.empty())
{
UnicodeString ustr = tr.transcode(value.c_str());
boost::put(*feature,fld_name,ustr);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
}
}
// only true strings are this long
else if (value_length > 20)
{
UnicodeString ustr = tr.transcode(value.c_str());
boost::put(*feature,fld_name,ustr);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
}
// now, add all values as attributes
/* First we detect likely strings, then try parsing likely numbers,
finally falling back to string type
* We intentionally do not try to detect boolean or null types
since they are not common in csv
* Likely strings are either empty values, very long values
or value with leading zeros like 001 (which are not safe
to assume are numbers)
*/
bool has_dot = value.find(".") != std::string::npos;
if (value.empty() ||
(value_length > 20) ||
(value_length > 1 && !has_dot && value[0] == '0'))
{
UnicodeString ustr = tr.transcode(value.c_str());
boost::put(*feature,fld_name,ustr);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
}
}
else if ((value[0] >= '0' && value[0] <= '9') || value[0] == '-')
{
@ -646,12 +647,14 @@ void csv_datasource::parse_csv(T& stream,
bool r = qi::phrase_parse(str_beg,str_end,qi::double_,ascii::space,float_val);
if (r && (str_beg == str_end))
{
if (value.find(".") != std::string::npos)
if (has_dot)
{
boost::put(*feature,fld_name,float_val);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Double));
desc_.add_descriptor(
mapnik::attribute_descriptor(
fld_name,mapnik::Double));
}
}
else
@ -660,7 +663,9 @@ void csv_datasource::parse_csv(T& stream,
boost::put(*feature,fld_name,val);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Integer));
desc_.add_descriptor(
mapnik::attribute_descriptor(
fld_name,mapnik::Integer));
}
}
}
@ -671,7 +676,9 @@ void csv_datasource::parse_csv(T& stream,
boost::put(*feature,fld_name,ustr);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
desc_.add_descriptor(
mapnik::attribute_descriptor(
fld_name,mapnik::String));
}
}
}
@ -682,7 +689,9 @@ void csv_datasource::parse_csv(T& stream,
boost::put(*feature,fld_name,ustr);
if (feature_count == 1)
{
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
desc_.add_descriptor(
mapnik::attribute_descriptor(
fld_name,mapnik::String));
}
}
}

View file

@ -25,6 +25,7 @@
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/segment.hpp>
#include <mapnik/expression_evaluator.hpp>
// boost
#include <boost/scoped_ptr.hpp>
@ -66,7 +67,13 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
ras_ptr->reset();
ras_ptr->gamma(agg::gamma_linear());
double height = sym.height() * scale_factor_;
double height = 0.0;
expression_ptr height_expr = sym.height();
if (height_expr)
{
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr);
height = result.to_double() * scale_factor_;
}
for (unsigned i=0;i<feature.num_geometries();++i)
{

View file

@ -62,7 +62,7 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
renderer ren(renb);
ras_ptr->reset();
ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma()));
ras_ptr->gamma(agg::gamma_power(sym.get_gamma()));
metawriter_with_properties writer = sym.get_metawriter();
for (unsigned i=0;i<feature.num_geometries();++i)
{

View file

@ -779,7 +779,13 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
cairo_context context(context_);
color const& fill = sym.get_fill();
double height = 0.7071 * sym.height(); // height in meters
double height = 0.0;
expression_ptr height_expr = sym.height();
if (height_expr)
{
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr);
height = 0.7071 * result.to_double();
}
for (unsigned i = 0; i < feature.num_geometries(); ++i)
{

View file

@ -28,6 +28,7 @@
#include <mapnik/grid/grid_pixel.hpp>
#include <mapnik/grid/grid.hpp>
#include <mapnik/segment.hpp>
#include <mapnik/expression_evaluator.hpp>
// boost
#include <boost/scoped_ptr.hpp>
@ -59,7 +60,13 @@ void grid_renderer<T>::process(building_symbolizer const& sym,
ras_ptr->reset();
double height = sym.height() * scale_factor_;
double height = 0.0;
expression_ptr height_expr = sym.height();
if (height_expr)
{
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr);
height = result.to_double() * scale_factor_;
}
for (unsigned i=0;i<feature.num_geometries();++i)
{

View file

@ -1906,9 +1906,8 @@ void map_parser::parse_building_symbolizer( rule & rule, ptree const & sym )
optional<double> opacity = get_opt_attr<double>(sym, "fill-opacity");
if (opacity) building_sym.set_opacity(*opacity);
// height
// TODO - expression
optional<double> height = get_opt_attr<double>(sym, "height");
if (height) building_sym.set_height(*height);
optional<std::string> height = get_opt_attr<std::string>(sym, "height");
if (height) building_sym.set_height(parse_expression(*height, "utf8"));
parse_metawriter_in_symbolizer(building_sym, sym);
rule.append(building_sym);

View file

@ -241,10 +241,9 @@ public:
{
set_attr( sym_node, "fill-opacity", sym.get_opacity() );
}
if ( sym.height() != dfl.height() || explicit_defaults_ )
{
set_attr( sym_node, "height", sym.height() );
}
set_attr( sym_node, "height", to_expression_string(*sym.height()) );
add_metawriter_attributes(sym_node, sym);
}

View file

@ -0,0 +1,4 @@
x,y,fips
0,0,001
0,0,003
0,0,005
1 x y fips
2 0 0 001
3 0 0 003
4 0 0 005

View file

@ -7,25 +7,15 @@
</Rule>
</Style>
<!-- layer created by ogr like: ogr2ogr -t_srs EPSG:4326 -f SQLite ../sqlite/world.sqlite world_merc.shp -->
<!-- here we read with the ogr plugin -->
<Layer name="world_borders1" srs="+init=epsg:4326">
<StyleName>world_borders_style1</StyleName>
<Datasource>
<Parameter name="type">ogr</Parameter>
<Parameter name="file">../sqlite/world.sqlite</Parameter>
<Parameter name="layer">world_merc</Parameter>
</Datasource>
</Layer>
<Style name="world_borders_style2">
<Rule>
<PolygonSymbolizer fill="yellow" gamma="0.5"/>
</Rule>
</Style>
<!-- here we read with native sqlite plugin -->
<!-- layer created by ogr like: ogr2ogr -t_srs EPSG:4326 -f SQLite ../sqlite/world.sqlite world_merc.shp -->
<Layer name="world_borders2" srs="+init=epsg:4326">
<StyleName>world_borders_style1</StyleName>
<StyleName>world_borders_style2</StyleName>
<Datasource>
<Parameter name="type">sqlite</Parameter>

6
tests/data/svg/README.md Normal file
View file

@ -0,0 +1,6 @@
Other good sources of svg for tests include:
* http://intertwingly.net/svg/
* http://www.w3.org/Graphics/SVG/Test/20110816/
* http://croczilla.com/bits_and_pieces/svg/samples/
* http://www.w3schools.com/svg/svg_examples.asp

View file

@ -227,6 +227,25 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
query.add_property_name('bogus')
fs = ds.features(query)
def test_that_leading_zeros_mean_strings(**kwargs):
ds = get_csv_ds('leading_zeros.csv')
eq_(len(ds.fields()),3)
eq_(ds.fields(),['x','y','fips'])
eq_(ds.field_types(),['int','int','str'])
fs = ds.featureset()
feat = fs.next()
eq_(feat['x'],0)
eq_(feat['y'],0)
eq_(feat['fips'],'001')
feat = fs.next()
eq_(feat['x'],0)
eq_(feat['y'],0)
eq_(feat['fips'],'003')
feat = fs.next()
eq_(feat['x'],0)
eq_(feat['y'],0)
eq_(feat['fips'],'005')
if __name__ == "__main__":
setup()
[eval(run)(visual=True) for run in dir() if 'test_' in run]

View file

@ -12,7 +12,7 @@ def usage():
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "hvqp:", ["help", "prefix="])
except getopt.GetoptError as err:
except getopt.GetoptError,err:
print(str(err))
usage()
sys.exit(2)