diff --git a/CHANGELOG.md b/CHANGELOG.md index f0d6bfd47..a5b716508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ For a complete change history, see the git log. ## Future +- Added support for DBF `Logical` type: #1614 + - Added serialization of `line-offset` to save_map (#1562) - Enabled default input plugin directory and fonts path to be set inherited from environment settings in diff --git a/include/mapnik/grid/grid_marker_helpers.hpp b/include/mapnik/grid/grid_marker_helpers.hpp index a77bd7510..f5e3629a7 100644 --- a/include/mapnik/grid/grid_marker_helpers.hpp +++ b/include/mapnik/grid/grid_marker_helpers.hpp @@ -78,11 +78,17 @@ struct raster_markers_rasterizer_dispatch_grid { marker_placement_e placement_method = sym_.get_marker_placement(); box2d bbox_(0,0, src_.width(),src_.height()); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; @@ -209,11 +215,17 @@ struct vector_markers_rasterizer_dispatch_grid void add_path(T & path) { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index 594617702..7d9861528 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.hpp @@ -87,7 +87,8 @@ struct vector_markers_rasterizer_dispatch { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; @@ -188,7 +189,8 @@ struct raster_markers_rasterizer_dispatch marker_placement_e placement_method = sym_.get_marker_placement(); box2d bbox_(0,0, src_.width(),src_.height()); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; diff --git a/plugins/input/shape/dbfile.cpp b/plugins/input/shape/dbfile.cpp index 7ed0da535..d2583200c 100644 --- a/plugins/input/shape/dbfile.cpp +++ b/plugins/input/shape/dbfile.cpp @@ -134,8 +134,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature & f) switch (fields_[col].type_) { case 'C': - case 'D'://todo handle date? - case 'M': + case 'D': { // FIXME - avoid constructing std::string on stack std::string str(record_+fields_[col].offset_,fields_[col].length_); @@ -152,6 +151,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature & f) } else { + // NOTE: null logical fields use '?' f.put(name,false); } break; diff --git a/plugins/input/shape/shape_datasource.cpp b/plugins/input/shape/shape_datasource.cpp index 366ea46f5..736f7e913 100644 --- a/plugins/input/shape/shape_datasource.cpp +++ b/plugins/input/shape/shape_datasource.cpp @@ -50,6 +50,7 @@ DATASOURCE_PLUGIN(shape_datasource) using mapnik::String; using mapnik::Double; using mapnik::Integer; +using mapnik::Boolean; using mapnik::datasource_exception; using mapnik::filter_in_box; using mapnik::filter_at_point; @@ -121,10 +122,12 @@ void shape_datasource::bind() const case 'C': // character case 'D': // Date case 'M': // Memo, a string - case 'L': // logical case '@': // timestamp desc_.add_descriptor(attribute_descriptor(fld_name, String)); break; + case 'L': // logical + desc_.add_descriptor(attribute_descriptor(fld_name, Boolean)); + break; case 'N': case 'O': // double case 'F': // float @@ -153,7 +156,7 @@ void shape_datasource::bind() const } } - catch (const datasource_exception& ex) + catch (datasource_exception const& ex) { MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes, " << ex.what(); throw; diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index b7642a7b3..651f33e32 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -272,8 +272,11 @@ void agg_renderer::end_style_processing(feature_type_style const& st) } template -void agg_renderer::render_marker(pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, - double opacity, composite_mode_e comp_op) +void agg_renderer::render_marker(pixel_position const& pos, + marker const& marker, + agg::trans_affine const& tr, + double opacity, + composite_mode_e comp_op) { typedef agg::rgba8 color_type; typedef agg::order_rgba order_type; diff --git a/src/build.py b/src/build.py index 0513d5433..674ae2498 100644 --- a/src/build.py +++ b/src/build.py @@ -399,5 +399,13 @@ else: env['create_uninstall_target'](env, target1) env['create_uninstall_target'](env, target) + # to enable local testing + lib_major_minor = "%s.%d.%d" % (os.path.basename(env.subst(env['MAPNIK_LIB_NAME'])), int(major), int(minor)) + local_lib = os.path.basename(env.subst(env['MAPNIK_LIB_NAME'])) + if os.path.islink(lib_major_minor) or os.path.exists(lib_major_minor): + os.remove(lib_major_minor) + os.symlink(local_lib,lib_major_minor) + Clean(mapnik,lib_major_minor); + if not env['RUNTIME_LINK'] == 'static': Depends(mapnik, env.subst('../deps/agg/libagg.a')) diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 55e0f9f63..7a5d36234 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -53,6 +53,7 @@ // boost #include #include +#include // agg #include "agg_conv_clip_polyline.h" @@ -1197,7 +1198,13 @@ void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& else if (marker.is_bitmap()) { agg::trans_affine matrix = tr; - matrix *= agg::trans_affine_translation(pos.x, pos.y); + double width = (*marker.get_bitmap_data())->width(); + double height = (*marker.get_bitmap_data())->height(); + double cx = 0.5 * width; + double cy = 0.5 * height; + matrix *= agg::trans_affine_translation( + boost::math::iround(pos.x - cx), + boost::math::iround(pos.y - cy)); context.add_image(matrix, **marker.get_bitmap_data(), opacity); } } @@ -1279,8 +1286,7 @@ void cairo_renderer_base::process(shield_symbolizer const& sym, { if (glyphs->marker()) { - // Position is handled differently by cairo renderer - pixel_position pos = glyphs->marker_pos() - 0.5 * + pixel_position pos = glyphs->marker_pos() + 0.5 * pixel_position(glyphs->marker()->marker->width(), glyphs->marker()->marker->height()); @@ -1538,11 +1544,17 @@ struct markers_dispatch { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; @@ -1621,11 +1633,17 @@ struct markers_dispatch_2 { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; diff --git a/tests/data/csv/long_lat.vrt b/tests/data/csv/long_lat.vrt index 45513c909..2fa0a9f41 100644 --- a/tests/data/csv/long_lat.vrt +++ b/tests/data/csv/long_lat.vrt @@ -1,6 +1,6 @@ - long_lat.csv + long_lat.csv wkbPoint WGS84 diff --git a/tests/data/shp/long_lat.dbf b/tests/data/shp/long_lat.dbf new file mode 100644 index 000000000..d3716daf8 Binary files /dev/null and b/tests/data/shp/long_lat.dbf differ diff --git a/tests/data/shp/long_lat.dbt b/tests/data/shp/long_lat.dbt new file mode 100644 index 000000000..608c35740 Binary files /dev/null and b/tests/data/shp/long_lat.dbt differ diff --git a/tests/data/shp/long_lat.prj b/tests/data/shp/long_lat.prj new file mode 100644 index 000000000..a30c00a55 --- /dev/null +++ b/tests/data/shp/long_lat.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file diff --git a/tests/data/shp/long_lat.shp b/tests/data/shp/long_lat.shp new file mode 100644 index 000000000..0112cd743 Binary files /dev/null and b/tests/data/shp/long_lat.shp differ diff --git a/tests/data/shp/long_lat.shx b/tests/data/shp/long_lat.shx new file mode 100644 index 000000000..cc0b42ae7 Binary files /dev/null and b/tests/data/shp/long_lat.shx differ diff --git a/tests/python_tests/shapefile_test.py b/tests/python_tests/shapefile_test.py index 1a706eed3..c447f1e04 100644 --- a/tests/python_tests/shapefile_test.py +++ b/tests/python_tests/shapefile_test.py @@ -52,6 +52,23 @@ if 'shape' in mapnik.DatasourceCache.plugin_names(): query.add_property_name('bogus') fs = ds.features(query) + def test_dbf_logical_field_is_boolean(): + ds = mapnik.Shapefile(file='../data/shp/long_lat') + eq_(len(ds.fields()),7) + eq_(ds.fields(),['LONG', 'LAT', 'LOGICAL_TR', 'LOGICAL_FA', 'CHARACTER', 'NUMERIC', 'DATE']) + eq_(ds.field_types(),['str', 'str', 'bool', 'bool', 'str', 'float', 'str']) + query = mapnik.Query(ds.envelope()) + for fld in ds.fields(): + query.add_property_name(fld) + feat = ds.all_features()[0] + eq_(feat.id(),1) + eq_(feat['LONG'],'0') + eq_(feat['LAT'],'0') + eq_(feat['LOGICAL_TR'],True) + eq_(feat['LOGICAL_FA'],False) + eq_(feat['CHARACTER'],'254') + eq_(feat['NUMERIC'],32) + eq_(feat['DATE'],'20121202') if __name__ == "__main__": setup() diff --git a/tests/visual_tests/compare.py b/tests/visual_tests/compare.py index 92bea4ad8..3530688c5 100644 --- a/tests/visual_tests/compare.py +++ b/tests/visual_tests/compare.py @@ -85,7 +85,7 @@ def summary(generate=False): global passed if len(errors) != 0: - msg = "Visual text rendering: %s failures" % len(errors) + msg = "Visual text rendering: %s failed / %s passed" % (len(errors),passed) print "-"*len(msg) print msg print "-"*len(msg) diff --git a/tests/visual_tests/grids/marker_line_placement_on_points-500-reference.json b/tests/visual_tests/grids/marker_line_placement_on_points-500-reference.json new file mode 100644 index 000000000..eb5e8d76b --- /dev/null +++ b/tests/visual_tests/grids/marker_line_placement_on_points-500-reference.json @@ -0,0 +1,40 @@ +{ + "keys": [ + "", + "4", + "3", + "6", + "5", + "7", + "1", + "2" + ], + "data": {}, + "grid": [ + " !!!!!! ###### ", + " !!!!! ##### ", + " !! ## ", + " ", + " ", + " ", + " ", + " ", + " $$$$ ", + " $$$$$$ ", + " $$$$$$$ ", + " $$$$$$ ", + " %%%$$%% ", + " %%&&&&% ", + " &&&&&& ", + " &&&&&&& ", + " &&&&&& ", + " && ", + " ", + " ", + " ", + " ", + " ", + " ''' ((( ", + " ''''' ((((( " + ] +} \ No newline at end of file diff --git a/tests/visual_tests/images/marker_line_placement_on_points-500-reference.png b/tests/visual_tests/images/marker_line_placement_on_points-500-reference.png new file mode 100644 index 000000000..71b1fb1f1 Binary files /dev/null and b/tests/visual_tests/images/marker_line_placement_on_points-500-reference.png differ diff --git a/tests/visual_tests/styles/marker_line_placement_on_points.xml b/tests/visual_tests/styles/marker_line_placement_on_points.xml new file mode 100644 index 000000000..db11328c6 --- /dev/null +++ b/tests/visual_tests/styles/marker_line_placement_on_points.xml @@ -0,0 +1,36 @@ + + + + + + 1 + + csv + + x,y,id + 0,0,1 + 5,0,1 + 5,5,1 + 0,5,1 + 2.5,2.5,2 + 2.5,3,3 + 2.5,2,3 + 3,2.5,3 + 2,2.5,3 + + + + \ No newline at end of file diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 07c3b9288..a1814ad9a 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -41,6 +41,7 @@ files = [ {'name': "lines-6", 'sizes': sizes_few_square}, {'name': "lines-shield", 'sizes': sizes_few_square,'bbox':default_text_box}, {'name': "marker-multi-policy", 'sizes':[(600,400)]}, + {'name': "marker_line_placement_on_points"}, {'name': "whole-centroid", 'sizes':[(600,400)], 'bbox': mapnik.Box2d(736908, 4390316, 2060771, 5942346)}, {'name': "simple-E", 'bbox':mapnik.Box2d(-0.05, -0.01, 0.95, 0.01)},