From c38598e9ad41c8a31c444671b11d8dfb22973f0f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 26 Jun 2012 18:25:56 -0700 Subject: [PATCH 1/6] allow the ogr shapefile reading test to pass with latest gdal --- tests/python_tests/ogr_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/python_tests/ogr_test.py b/tests/python_tests/ogr_test.py index c8d1df242..8ac695806 100644 --- a/tests/python_tests/ogr_test.py +++ b/tests/python_tests/ogr_test.py @@ -26,7 +26,9 @@ if 'ogr' in mapnik.DatasourceCache.instance().plugin_names(): # Shapefile properties def test_shapefile_properties(): - ds = mapnik.Ogr(file='../../demo/data/boundaries.shp',layer_by_index=0,encoding='latin1') + # NOTE: encoding is latin1 but gdal >= 1.9 should now expose utf8 encoded features + # See SHAPE_ENCODING for overriding: http://gdal.org/ogr/drv_shapefile.html + ds = mapnik.Ogr(file='../../demo/data/boundaries.shp',layer_by_index=0) f = ds.features_at_point(ds.envelope().center()).features[0] eq_(ds.geometry_type(),mapnik.DataGeometryType.Polygon) From 9e8f815b075e24a33c6ab2a6392e29a7d319a290 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 26 Jun 2012 18:55:58 -0700 Subject: [PATCH 2/6] add a few more filter tests - all should pass cleanly --- tests/python_tests/filter_test.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/python_tests/filter_test.py b/tests/python_tests/filter_test.py index 7568af250..f28153abd 100644 --- a/tests/python_tests/filter_test.py +++ b/tests/python_tests/filter_test.py @@ -124,5 +124,27 @@ def test_unicode_regex_replace(): expr = mapnik.Expression("[name].replace('(\B)|( )','$1 ')") eq_(expr.evaluate(f), u'Q u é b e c') +def test_float_precision(): + context = mapnik.Context() + context.push('num') + f = mapnik.Feature(context,0) + f["num"] = 1.0000 + eq_(f["num"],1.0000) + expr = mapnik.Expression("[num] = 1.0000") + eq_(expr.evaluate(f),True) + expr = mapnik.Expression("[num].match('.*0$')") + eq_(expr.evaluate(f),True) + expr = mapnik.Expression("[num].match('.*0$')") + eq_(expr.evaluate(f),True) + +def test_string_matching_on_precision(): + context = mapnik.Context() + context.push('num') + f = mapnik.Feature(context,0) + f["num"] = "1.0000" + eq_(f["num"],"1.0000") + expr = mapnik.Expression("[num].match('.*(^0|00)$')") + eq_(expr.evaluate(f),True) + if __name__ == "__main__": [eval(run)() for run in dir() if 'test_' in run] From 0caebc52aeeca3f0d93669dd0a388aa678c15a2c Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Thu, 28 Jun 2012 20:49:41 +0200 Subject: [PATCH 3/6] Add tests for international text. --- tests/visual_tests/styles/harfbuzz.xml | 46 ++++++++++++++++++++++++++ tests/visual_tests/test.py | 9 +++-- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 tests/visual_tests/styles/harfbuzz.xml diff --git a/tests/visual_tests/styles/harfbuzz.xml b/tests/visual_tests/styles/harfbuzz.xml new file mode 100644 index 000000000..af0891bfd --- /dev/null +++ b/tests/visual_tests/styles/harfbuzz.xml @@ -0,0 +1,46 @@ + + + + + My Style + + shape + ../data/points.shp + + + + + + diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 86e03122f..57de9ac81 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -44,7 +44,8 @@ files = [ {'name': "rtl-point", 'sizes': [(200, 200)]}, {'name': "jalign-auto", 'sizes': [(200, 200)]}, {'name': "line-offset", 'sizes':[(900, 250)], - 'bbox': mapnik.Box2d(-5.192, 50.189, -5.174, 50.195)} + 'bbox': mapnik.Box2d(-5.192, 50.189, -5.174, 50.195)}, + {'name': "harfbuzz"}, ] def render(filename, width, height, bbox, quiet=False): @@ -78,9 +79,11 @@ if __name__ == "__main__": quiet = False if len(sys.argv) == 2: - files = [(sys.argv[1], (500, 500))] + files = [{"name": sys.argv[1], "sizes": sizes_few_square}] elif len(sys.argv) > 2: - files = [sys.argv[1:]] + files = [] + for name in argv[1:]: + files.append({"name": name}) for f in files: config = dict(defaults) From d9afce16c2c7d69f5504640cf08c9a1201683ee1 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Fri, 29 Jun 2012 00:58:28 +0200 Subject: [PATCH 4/6] Revert "Add tests for international text." This reverts commit 0caebc52aeeca3f0d93669dd0a388aa678c15a2c. --- tests/visual_tests/styles/harfbuzz.xml | 46 -------------------------- tests/visual_tests/test.py | 9 ++--- 2 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 tests/visual_tests/styles/harfbuzz.xml diff --git a/tests/visual_tests/styles/harfbuzz.xml b/tests/visual_tests/styles/harfbuzz.xml deleted file mode 100644 index af0891bfd..000000000 --- a/tests/visual_tests/styles/harfbuzz.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - My Style - - shape - ../data/points.shp - - - - - - diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 57de9ac81..86e03122f 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -44,8 +44,7 @@ files = [ {'name': "rtl-point", 'sizes': [(200, 200)]}, {'name': "jalign-auto", 'sizes': [(200, 200)]}, {'name': "line-offset", 'sizes':[(900, 250)], - 'bbox': mapnik.Box2d(-5.192, 50.189, -5.174, 50.195)}, - {'name': "harfbuzz"}, + 'bbox': mapnik.Box2d(-5.192, 50.189, -5.174, 50.195)} ] def render(filename, width, height, bbox, quiet=False): @@ -79,11 +78,9 @@ if __name__ == "__main__": quiet = False if len(sys.argv) == 2: - files = [{"name": sys.argv[1], "sizes": sizes_few_square}] + files = [(sys.argv[1], (500, 500))] elif len(sys.argv) > 2: - files = [] - for name in argv[1:]: - files.append({"name": name}) + files = [sys.argv[1:]] for f in files: config = dict(defaults) From 67e9b0d616e9469d8ef9fa8f6c1f2cb8b5793d42 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 28 Jun 2012 19:54:25 -0700 Subject: [PATCH 5/6] move marker width/height to expressions - closes #1102 and replaces #1255 --- include/mapnik/attribute_collector.hpp | 10 ++++++++++ include/mapnik/markers_symbolizer.hpp | 13 +++++++------ src/agg/process_markers_symbolizer.cpp | 5 +++-- src/cairo_renderer.cpp | 4 ++-- src/grid/process_markers_symbolizer.cpp | 12 ++++++------ src/load_map.cpp | 5 +++-- src/markers_symbolizer.cpp | 19 +++++++++++-------- src/save_map.cpp | 4 ++-- tests/python_tests/object_test.py | 12 ++++++++++++ tests/python_tests/render_grid_test.py | 4 ++-- tests/python_tests/render_test.py | 4 ++-- 11 files changed, 60 insertions(+), 32 deletions(-) diff --git a/include/mapnik/attribute_collector.hpp b/include/mapnik/attribute_collector.hpp index 970dc9413..4cba3a09b 100644 --- a/include/mapnik/attribute_collector.hpp +++ b/include/mapnik/attribute_collector.hpp @@ -171,6 +171,16 @@ struct symbolizer_attributes : public boost::static_visitor<> void operator () (markers_symbolizer const& sym) { + expression_ptr const& height_expr = sym.get_height(); + if (height_expr) + { + boost::apply_visitor(f_attr,*height_expr); + } + expression_ptr const& width_expr = sym.get_width(); + if (width_expr) + { + boost::apply_visitor(f_attr,*width_expr); + } collect_metawriter(sym); collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); diff --git a/include/mapnik/markers_symbolizer.hpp b/include/mapnik/markers_symbolizer.hpp index f5a79cab8..065251df7 100644 --- a/include/mapnik/markers_symbolizer.hpp +++ b/include/mapnik/markers_symbolizer.hpp @@ -29,6 +29,7 @@ #include #include #include +#include namespace mapnik { @@ -66,10 +67,10 @@ public: double get_max_error() const; void set_fill(color fill); color const& get_fill() const; - void set_width(double width); - double get_width() const; - void set_height(double height); - double get_height() const; + void set_width(expression_ptr width); + expression_ptr get_width() const; + void set_height(expression_ptr height); + expression_ptr get_height() const; stroke const& get_stroke() const; void set_stroke(stroke const& stroke); void set_marker_placement(marker_placement_e marker_p); @@ -83,8 +84,8 @@ private: color fill_; double spacing_; double max_error_; - double width_; - double height_; + expression_ptr width_; + expression_ptr height_; stroke stroke_; marker_placement_e marker_p_; marker_type_e marker_type_; diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 1c9cd4d54..5cadd294f 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -196,8 +196,9 @@ void agg_renderer::process(markers_symbolizer const& sym, unsigned s_g=col.green(); unsigned s_b=col.blue(); unsigned s_a=col.alpha(); - double w = sym.get_width(); - double h = sym.get_height(); + double w = (boost::apply_visitor(evaluate(feature), *(sym.get_width()))).to_double() * scale_factor_; + double h = (boost::apply_visitor(evaluate(feature), *(sym.get_height()))).to_double() * scale_factor_; + double rx = w/2.0; double ry = h/2.0; diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index ef6a209db..ac61eb747 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -1480,8 +1480,8 @@ void cairo_renderer_base::start_map_processing(Map const& map) stroke const& stroke_ = sym.get_stroke(); color const& col = stroke_.get_color(); double strk_width = stroke_.get_width(); - double w = sym.get_width(); - double h = sym.get_height(); + double w = (boost::apply_visitor(evaluate(feature), *(sym.get_width()))).to_double() * scale_factor_; + double h = (boost::apply_visitor(evaluate(feature), *(sym.get_height()))).to_double() * scale_factor_; double rx = w/2.0; double ry = h/2.0; diff --git a/src/grid/process_markers_symbolizer.cpp b/src/grid/process_markers_symbolizer.cpp index 01d5b95e5..068a2e1e8 100644 --- a/src/grid/process_markers_symbolizer.cpp +++ b/src/grid/process_markers_symbolizer.cpp @@ -152,16 +152,16 @@ void grid_renderer::process(markers_symbolizer const& sym, else { - double w; - double h; + double w = (boost::apply_visitor(evaluate(feature), *(sym.get_width()))).to_double() * scale_factor_; + double h = (boost::apply_visitor(evaluate(feature), *(sym.get_height()))).to_double() * scale_factor_; // clamp to at least 4 px otherwise interactive pixels can be too small if (res == 1) { - w = std::max(sym.get_width(),4.0); - h = std::max(sym.get_height(),4.0); + w = std::max(w,4.0); + h = std::max(h,4.0); } else { double min = static_cast(4.0/res); - w = std::max(sym.get_width()/res,min); - h = std::max(sym.get_height()/res,min); + w = std::max(w/res,min); + h = std::max(h/res,min); } double rx = w/2.0; diff --git a/src/load_map.cpp b/src/load_map.cpp index a73bb3853..2ac531718 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1045,8 +1045,9 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) if (allow_overlap) symbol.set_allow_overlap(*allow_overlap); if (ignore_placement) symbol.set_ignore_placement(*ignore_placement); - optional w = sym.get_opt_attr("width"); - optional h = sym.get_opt_attr("height"); + optional w = sym.get_opt_attr("width"); + optional h = sym.get_opt_attr("height"); + if (w && h) { symbol.set_width(*w); diff --git a/src/markers_symbolizer.cpp b/src/markers_symbolizer.cpp index 6c8201a1b..3e16b790c 100644 --- a/src/markers_symbolizer.cpp +++ b/src/markers_symbolizer.cpp @@ -23,6 +23,9 @@ // mapnik #include +// boost +#include + namespace mapnik { static const char * marker_placement_strings[] = { @@ -50,8 +53,8 @@ markers_symbolizer::markers_symbolizer() fill_(color(0,0,255)), spacing_(100.0), max_error_(0.2), - width_(10.0), - height_(10.0), + width_(boost::make_shared(10.0)), + height_(boost::make_shared(10.0)), stroke_(), marker_p_(MARKER_LINE_PLACEMENT), marker_type_(MARKER_ARROW) {} @@ -64,8 +67,8 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr filename) fill_(color(0,0,255)), spacing_(100.0), max_error_(0.2), - width_(10.0), - height_(10.0), + width_(boost::make_shared(10.0)), + height_(boost::make_shared(10.0)), stroke_(), marker_p_(MARKER_LINE_PLACEMENT), marker_type_(MARKER_ARROW) {} @@ -134,22 +137,22 @@ color const& markers_symbolizer::get_fill() const return fill_; } -void markers_symbolizer::set_width(double width) +void markers_symbolizer::set_width(expression_ptr width) { width_ = width; } -double markers_symbolizer::get_width() const +expression_ptr markers_symbolizer::get_width() const { return width_; } -void markers_symbolizer::set_height(double height) +void markers_symbolizer::set_height(expression_ptr height) { height_ = height; } -double markers_symbolizer::get_height() const +expression_ptr markers_symbolizer::get_height() const { return height_; } diff --git a/src/save_map.cpp b/src/save_map.cpp index ff0219ce5..c91bac6e3 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -288,11 +288,11 @@ public: } if (sym.get_width() != dfl.get_width() || explicit_defaults_) { - set_attr( sym_node, "width", sym.get_width() ); + set_attr( sym_node, "width", to_expression_string(*sym.get_width()) ); } if (sym.get_height() != dfl.get_height() || explicit_defaults_) { - set_attr( sym_node, "height", sym.get_height() ); + set_attr( sym_node, "height", to_expression_string(*sym.get_height()) ); } if (sym.get_marker_type() != dfl.get_marker_type() || explicit_defaults_) { diff --git a/tests/python_tests/object_test.py b/tests/python_tests/object_test.py index e4d7eede5..44517286f 100644 --- a/tests/python_tests/object_test.py +++ b/tests/python_tests/object_test.py @@ -134,6 +134,18 @@ def test_markersymbolizer_init(): eq_(p.ignore_placement,False) eq_(p.spacing,100) eq_(p.max_error,0.2) + eq_(str(p.width),'10.0') + eq_(str(p.height),'10.0') + + p.width = mapnik.Expression('12') + p.height = mapnik.Expression('12') + eq_(str(p.width),'12') + eq_(str(p.height),'12') + + p.width = mapnik.Expression('[field] + 2') + p.height = mapnik.Expression('[field] + 2') + eq_(str(p.width),'([field]+2)') + eq_(str(p.height),'([field]+2)') stroke = mapnik.Stroke() stroke.color = mapnik.Color('black') diff --git a/tests/python_tests/render_grid_test.py b/tests/python_tests/render_grid_test.py index ebffa27c6..3b77ccf3d 100644 --- a/tests/python_tests/render_grid_test.py +++ b/tests/python_tests/render_grid_test.py @@ -57,8 +57,8 @@ def create_grid_map(width,height): s = mapnik.Style() r = mapnik.Rule() symb = mapnik.MarkersSymbolizer() - symb.width = 10 - symb.height = 10 + symb.width = mapnik.Expression('10') + symb.height = mapnik.Expression('10') symb.allow_overlap = True r.symbols.append(symb) diff --git a/tests/python_tests/render_test.py b/tests/python_tests/render_test.py index cb1f19be7..c0808a1a0 100644 --- a/tests/python_tests/render_test.py +++ b/tests/python_tests/render_test.py @@ -146,8 +146,8 @@ def test_render_grid(): s = mapnik.Style() r = mapnik.Rule() symb = mapnik.MarkersSymbolizer() - symb.width = 10 - symb.height = 10 + symb.width = mapnik.Expression('10') + symb.height = mapnik.Expression('10') symb.allow_overlap = True r.symbols.append(symb) s.rules.append(r) From 523a57441ca4795ced959f41cba641805159e88f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 28 Jun 2012 19:58:40 -0700 Subject: [PATCH 6/6] update changelog re: #1102 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25c7cc37e..e8753967a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ For a complete change history, see the git log. Not yet released +- MarkersSymbolizer width and height moved to expressions (#1102) + - Added style-level 'opacity' (#314) - PostGIS: Added 'simplify_geometries' option - will trigger ST_Simplify on geometries before returning to Mapnik (#1179)