From 064b99168b89aedc48a6472eff79e7aca6906859 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 27 Mar 2017 16:14:51 +0100 Subject: [PATCH] geometry.hpp --- .gitmodules | 5 +- .travis.yml | 48 +- Makefile | 10 +- README.md | 2 +- SConstruct | 39 +- benchmark/bench_framework.hpp | 2 +- benchmark/run | 2 +- benchmark/test_expression_parse.cpp | 2 +- benchmark/test_polygon_clipping.cpp | 8 +- benchmark/test_proj_transform1.cpp | 2 +- bootstrap.sh | 63 +- circle.yml | 12 +- demo/c++/rundemo.cpp | 2 +- demo/python/README.txt | 20 - demo/python/rundemo.py | 379 ------ demo/viewer/about_dialog.cpp | 2 +- demo/viewer/about_dialog.hpp | 2 +- demo/viewer/info_dialog.cpp | 2 +- demo/viewer/info_dialog.hpp | 2 +- demo/viewer/layer_info_dialog.cpp | 2 +- demo/viewer/layer_info_dialog.hpp | 2 +- demo/viewer/layerdelegate.cpp | 2 +- demo/viewer/layerdelegate.hpp | 2 +- demo/viewer/layerlistmodel.cpp | 2 +- demo/viewer/layerlistmodel.hpp | 2 +- demo/viewer/layerwidget.cpp | 2 +- demo/viewer/layerwidget.hpp | 2 +- demo/viewer/main.cpp | 2 +- demo/viewer/mainwindow.cpp | 2 +- demo/viewer/mainwindow.hpp | 2 +- demo/viewer/mapwidget.cpp | 2 +- demo/viewer/mapwidget.hpp | 2 +- demo/viewer/styles_model.cpp | 2 +- demo/viewer/styles_model.hpp | 2 +- demo/viewer/viewer.pro | 1 - deps/agg/include/agg_vpgen_clip_polygon.h | 10 +- deps/agg/include/agg_vpgen_clip_polyline.h | 10 +- deps/mapbox/geometry | 2 +- deps/mapbox/variant | 2 +- include/build.py | 5 +- include/mapnik/agg_helpers.hpp | 2 +- include/mapnik/agg_pattern_source.hpp | 2 +- include/mapnik/agg_rasterizer.hpp | 2 +- include/mapnik/agg_render_marker.hpp | 9 +- include/mapnik/agg_renderer.hpp | 62 +- include/mapnik/attribute.hpp | 4 +- include/mapnik/attribute_collector.hpp | 4 +- include/mapnik/attribute_descriptor.hpp | 2 +- include/mapnik/boolean.hpp | 2 +- include/mapnik/cairo/cairo_context.hpp | 2 +- include/mapnik/cairo/cairo_image_util.hpp | 2 +- include/mapnik/cairo/cairo_render_vector.hpp | 2 +- include/mapnik/cairo/cairo_renderer.hpp | 2 +- include/mapnik/cairo_io.hpp | 2 +- include/mapnik/color.hpp | 9 +- include/mapnik/color_factory.hpp | 2 +- include/mapnik/config.hpp | 2 +- include/mapnik/config_error.hpp | 8 +- include/mapnik/coord.hpp | 3 +- include/mapnik/css_color_grammar.hpp | 67 -- .../mapnik/css_color_grammar_x3.hpp | 42 +- ..._impl.hpp => css_color_grammar_x3_def.hpp} | 399 ++++--- include/mapnik/csv/csv_grammar.hpp | 79 -- include/mapnik/csv/csv_grammar_x3.hpp | 67 ++ include/mapnik/csv/csv_grammar_x3_def.hpp | 120 ++ include/mapnik/csv/csv_types.hpp | 2 +- include/mapnik/cxx11_support.hpp | 43 + include/mapnik/datasource.hpp | 15 +- include/mapnik/datasource_cache.hpp | 2 +- include/mapnik/datasource_geometry_type.hpp | 2 +- include/mapnik/debug.hpp | 2 +- include/mapnik/ellipsoid.hpp | 2 +- include/mapnik/enumeration.hpp | 13 +- include/mapnik/evaluate_global_attributes.hpp | 42 +- include/mapnik/expression.hpp | 2 +- include/mapnik/expression_evaluator.hpp | 4 +- include/mapnik/expression_grammar.hpp | 103 -- include/mapnik/expression_grammar_impl.hpp | 280 ----- include/mapnik/expression_grammar_x3.hpp | 51 + .../mapnik/expression_grammar_x3_config.hpp | 43 + include/mapnik/expression_grammar_x3_def.hpp | 456 ++++++++ include/mapnik/expression_node.hpp | 86 +- include/mapnik/expression_node_types.hpp | 4 +- include/mapnik/expression_string.hpp | 2 +- include/mapnik/extend_converter.hpp | 232 ++++ include/mapnik/factory.hpp | 2 +- include/mapnik/feature.hpp | 15 +- include/mapnik/feature_factory.hpp | 4 +- include/mapnik/feature_kv_iterator.hpp | 2 +- include/mapnik/feature_layer_desc.hpp | 2 +- include/mapnik/feature_style_processor.hpp | 12 +- .../feature_style_processor_context.hpp | 2 +- .../mapnik/feature_style_processor_impl.hpp | 105 +- include/mapnik/feature_type_style.hpp | 2 +- include/mapnik/featureset.hpp | 2 +- include/mapnik/filter_factory.hpp | 8 - include/mapnik/filter_featureset.hpp | 2 +- include/mapnik/font_engine_freetype.hpp | 2 +- include/mapnik/font_set.hpp | 2 +- include/mapnik/function_call.hpp | 6 +- include/mapnik/geom_util.hpp | 6 +- include/mapnik/geometry.hpp | 10 +- .../boost_adapters.hpp} | 127 ++- .../geometry/boost_spirit_karma_adapter.hpp | 121 ++ include/mapnik/{ => geometry}/box2d.hpp | 5 +- include/mapnik/{ => geometry}/box2d_impl.hpp | 53 +- .../centroid.hpp} | 10 +- .../correct.hpp} | 4 +- .../envelope.hpp} | 4 +- .../envelope_impl.hpp} | 8 +- .../fusion_adapted.hpp} | 2 +- .../mapnik/{ => geometry}/geometry_type.hpp | 6 +- .../mapnik/{ => geometry}/geometry_types.hpp | 2 +- include/mapnik/geometry/is_empty.hpp | 173 +++ .../is_simple.hpp} | 27 +- .../is_valid.hpp} | 53 +- include/mapnik/geometry/polygon.hpp | 75 +- .../remove_empty.hpp} | 4 +- .../reprojection.hpp} | 2 +- .../reprojection_impl.hpp} | 18 +- .../strategy.hpp} | 32 +- .../to_path.hpp} | 4 +- .../transform.hpp} | 9 +- include/mapnik/geometry_is_empty.hpp | 184 --- include/mapnik/global.hpp | 2 +- include/mapnik/gradient.hpp | 4 +- include/mapnik/grid/grid.hpp | 4 +- include/mapnik/grid/grid_pixel.hpp | 2 +- include/mapnik/grid/grid_pixfmt.hpp | 2 +- include/mapnik/grid/grid_rasterizer.hpp | 2 +- include/mapnik/grid/grid_render_marker.hpp | 2 +- include/mapnik/grid/grid_renderer.hpp | 8 +- include/mapnik/grid/grid_renderer_base.hpp | 2 +- include/mapnik/grid/grid_rendering_buffer.hpp | 2 +- include/mapnik/grid/grid_view.hpp | 8 +- include/mapnik/group/group_layout.hpp | 2 +- include/mapnik/group/group_layout_manager.hpp | 4 +- include/mapnik/group/group_rule.hpp | 2 +- .../mapnik/group/group_symbolizer_helper.hpp | 14 +- .../group/group_symbolizer_properties.hpp | 2 +- include/mapnik/hextree.hpp | 2 +- include/mapnik/hit_test_filter.hpp | 4 +- include/mapnik/image.hpp | 2 +- include/mapnik/image_any.hpp | 2 +- include/mapnik/image_compositing.hpp | 2 +- include/mapnik/image_copy.hpp | 2 +- include/mapnik/image_filter.hpp | 12 +- include/mapnik/image_filter_grammar.hpp | 87 -- include/mapnik/image_filter_grammar_impl.hpp | 141 --- include/mapnik/image_filter_grammar_x3.hpp | 55 + .../mapnik/image_filter_grammar_x3_def.hpp | 261 +++++ include/mapnik/image_filter_types.hpp | 43 +- include/mapnik/image_impl.hpp | 2 +- include/mapnik/image_null.hpp | 2 +- include/mapnik/image_options.hpp | 6 +- include/mapnik/image_reader.hpp | 8 +- include/mapnik/image_scaling.hpp | 2 +- include/mapnik/image_scaling_traits.hpp | 2 +- include/mapnik/image_util.hpp | 6 +- include/mapnik/image_util_jpeg.hpp | 2 +- include/mapnik/image_util_png.hpp | 2 +- include/mapnik/image_util_tiff.hpp | 2 +- include/mapnik/image_util_webp.hpp | 2 +- include/mapnik/image_view.hpp | 2 +- include/mapnik/image_view_any.hpp | 2 +- include/mapnik/image_view_impl.hpp | 2 +- include/mapnik/image_view_null.hpp | 2 +- include/mapnik/jpeg_io.hpp | 2 +- .../mapnik/json/attribute_value_visitor.hpp | 1 - include/mapnik/json/create_feature.hpp | 242 ++++ ...{geometry_util.hpp => create_geometry.hpp} | 140 +-- include/mapnik/json/error_handler.hpp | 73 -- .../json/extract_bounding_box_grammar.hpp | 64 -- .../extract_bounding_box_grammar_impl.hpp | 157 --- .../mapnik/json/extract_bounding_boxes_x3.hpp | 35 + .../json/extract_bounding_boxes_x3_config.hpp | 117 ++ .../json/feature_collection_grammar.hpp | 103 -- .../json/feature_collection_grammar_impl.hpp | 122 -- .../mapnik/json/feature_generator_grammar.hpp | 23 +- .../json/feature_generator_grammar_impl.hpp | 9 +- include/mapnik/json/feature_grammar.hpp | 91 -- include/mapnik/json/feature_grammar_impl.hpp | 87 -- include/mapnik/json/feature_grammar_x3.hpp | 50 + .../mapnik/json/feature_grammar_x3_def.hpp | 318 ++++++ include/mapnik/json/feature_parser.hpp | 21 +- include/mapnik/json/generic_json.hpp | 196 ---- .../generic_json_grammar_x3.hpp} | 44 +- .../json/generic_json_grammar_x3_def.hpp | 133 +++ include/mapnik/json/geojson_grammar_x3.hpp | 83 ++ .../mapnik/json/geojson_grammar_x3_def.hpp | 183 +++ .../json/geometry_generator_grammar.hpp | 58 +- .../json/geometry_generator_grammar_impl.hpp | 85 +- include/mapnik/json/geometry_grammar.hpp | 63 - include/mapnik/json/geometry_grammar_impl.hpp | 94 -- .../geometry_grammar_x3.hpp} | 37 +- .../mapnik/json/geometry_grammar_x3_def.hpp | 161 +++ include/mapnik/json/geometry_parser.hpp | 2 +- include/mapnik/json/json_grammar_config.hpp | 118 ++ include/mapnik/json/json_value.hpp | 65 ++ .../mapnik/json/parse_feature.hpp | 26 +- include/mapnik/json/positions_grammar.hpp | 55 - .../mapnik/json/positions_grammar_impl.hpp | 97 -- include/mapnik/json/positions_grammar_x3.hpp | 50 + .../mapnik/json/positions_grammar_x3_def.hpp | 67 ++ .../json/{positions.hpp => positions_x3.hpp} | 11 +- .../json/properties_generator_grammar.hpp | 4 +- .../properties_generator_grammar_impl.hpp | 20 +- include/mapnik/json/stringifier.hpp | 2 +- include/mapnik/json/topojson_grammar.hpp | 206 ---- include/mapnik/json/topojson_grammar_impl.hpp | 206 ---- include/mapnik/json/topojson_grammar_x3.hpp | 48 + .../mapnik/json/topojson_grammar_x3_def.hpp | 445 ++++++++ include/mapnik/json/topojson_utils.hpp | 6 +- include/mapnik/json/topology.hpp | 4 +- .../mapnik/json/unicode_string_grammar_x3.hpp | 46 + .../json/unicode_string_grammar_x3_def.hpp | 159 +++ include/mapnik/json/value_converters.hpp | 2 +- include/mapnik/label_collision_detector.hpp | 4 +- include/mapnik/layer.hpp | 26 +- include/mapnik/load_map.hpp | 2 +- include/mapnik/make_unique.hpp | 6 +- include/mapnik/map.hpp | 4 +- include/mapnik/mapped_memory_cache.hpp | 2 +- include/mapnik/marker.hpp | 2 +- include/mapnik/marker_cache.hpp | 2 +- include/mapnik/marker_helpers.hpp | 10 +- include/mapnik/markers_placement.hpp | 2 +- include/mapnik/markers_placements/basic.hpp | 2 +- .../mapnik/markers_placements/interior.hpp | 4 +- include/mapnik/markers_placements/line.hpp | 4 +- include/mapnik/markers_placements/point.hpp | 4 +- .../markers_placements/vertext_first.hpp | 2 +- .../markers_placements/vertext_last.hpp | 2 +- include/mapnik/memory_datasource.hpp | 2 +- include/mapnik/memory_featureset.hpp | 6 +- include/mapnik/octree.hpp | 2 +- include/mapnik/offset_converter.hpp | 34 +- include/mapnik/palette.hpp | 2 +- include/mapnik/params.hpp | 4 +- include/mapnik/params_impl.hpp | 4 +- include/mapnik/parse_path.hpp | 2 +- include/mapnik/path.hpp | 8 +- include/mapnik/path_expression.hpp | 2 +- include/mapnik/path_expression_grammar_x3.hpp | 48 + .../mapnik/path_expression_grammar_x3_def.hpp | 63 + include/mapnik/pixel_position.hpp | 2 +- include/mapnik/pixel_types.hpp | 2 +- include/mapnik/plugin.hpp | 2 +- include/mapnik/png_io.hpp | 61 +- include/mapnik/pool.hpp | 2 +- include/mapnik/proj_strategy.hpp | 2 +- include/mapnik/proj_transform.hpp | 2 +- include/mapnik/projection.hpp | 2 +- include/mapnik/ptree_helpers.hpp | 2 +- include/mapnik/quad_tree.hpp | 32 +- include/mapnik/query.hpp | 20 +- include/mapnik/raster.hpp | 8 +- include/mapnik/raster_colorizer.hpp | 2 +- include/mapnik/renderer_common.hpp | 4 +- .../apply_vertex_converter.hpp | 2 +- .../renderer_common/clipping_extent.hpp | 4 +- .../renderer_common/pattern_alignment.hpp | 2 +- .../process_building_symbolizer.hpp | 2 +- .../process_point_symbolizer.hpp | 8 +- .../process_polygon_symbolizer.hpp | 2 +- .../process_raster_symbolizer.hpp | 2 +- .../render_group_symbolizer.hpp | 4 +- .../mapnik/renderer_common/render_pattern.hpp | 2 +- .../mapnik/renderer_common/render_thunk.hpp | 3 +- include/mapnik/request.hpp | 4 +- include/mapnik/rule.hpp | 2 +- include/mapnik/rule_cache.hpp | 2 +- include/mapnik/safe_cast.hpp | 2 +- include/mapnik/save_map.hpp | 2 +- include/mapnik/scale_denominator.hpp | 2 +- include/mapnik/segment.hpp | 2 +- include/mapnik/simplify_converter.hpp | 12 +- include/mapnik/span_image_filter.hpp | 6 +- include/mapnik/sql_utils.hpp | 136 ++- include/mapnik/sse.hpp | 2 +- include/mapnik/stringify_macro.hpp | 7 +- include/mapnik/svg/geometry_svg_generator.hpp | 2 +- .../svg/geometry_svg_generator_impl.hpp | 4 +- include/mapnik/svg/output/svg_generator.hpp | 4 +- .../svg/output/svg_output_attributes.hpp | 12 +- .../mapnik/svg/output/svg_output_grammars.hpp | 2 +- .../svg/output/svg_output_grammars_impl.hpp | 2 +- .../mapnik/svg/output/svg_path_iterator.hpp | 2 +- include/mapnik/svg/output/svg_renderer.hpp | 8 +- include/mapnik/svg/svg_converter.hpp | 2 +- .../svg_grammar_config_x3.hpp} | 53 +- include/mapnik/svg/svg_parser.hpp | 2 +- include/mapnik/svg/svg_parser_exception.hpp | 6 +- include/mapnik/svg/svg_path_adapter.hpp | 4 +- include/mapnik/svg/svg_path_attributes.hpp | 2 +- include/mapnik/svg/svg_path_commands.hpp | 2 +- include/mapnik/svg/svg_path_grammar.hpp | 61 - include/mapnik/svg/svg_path_grammar_impl.hpp | 112 -- include/mapnik/svg/svg_path_grammar_x3.hpp | 46 + .../mapnik/svg/svg_path_grammar_x3_def.hpp | 203 ++++ include/mapnik/svg/svg_path_parser.hpp | 7 +- .../mapnik/svg/svg_points_grammar_impl.hpp | 61 - include/mapnik/svg/svg_renderer_agg.hpp | 6 +- include/mapnik/svg/svg_storage.hpp | 4 +- include/mapnik/svg/svg_transform_grammar.hpp | 56 - .../mapnik/svg/svg_transform_grammar_impl.hpp | 172 --- .../mapnik/svg/svg_transform_grammar_x3.hpp | 43 + .../svg/svg_transform_grammar_x3_def.hpp | 163 +++ include/mapnik/symbolizer.hpp | 6 +- include/mapnik/symbolizer_base.hpp | 17 +- include/mapnik/symbolizer_default_values.hpp | 11 +- include/mapnik/symbolizer_dispatch.hpp | 2 +- include/mapnik/symbolizer_enumerations.hpp | 2 +- include/mapnik/symbolizer_hash.hpp | 2 +- include/mapnik/symbolizer_keys.hpp | 3 +- include/mapnik/symbolizer_utils.hpp | 6 +- .../text/evaluated_format_properties_ptr.hpp | 2 +- include/mapnik/text/face.hpp | 5 +- include/mapnik/text/font_feature_settings.hpp | 2 +- include/mapnik/text/font_library.hpp | 2 +- include/mapnik/text/formatting/base.hpp | 2 +- include/mapnik/text/formatting/format.hpp | 2 +- include/mapnik/text/formatting/layout.hpp | 2 +- include/mapnik/text/formatting/list.hpp | 2 +- include/mapnik/text/formatting/registry.hpp | 2 +- include/mapnik/text/formatting/text.hpp | 2 +- include/mapnik/text/glyph_info.hpp | 2 +- include/mapnik/text/glyph_positions.hpp | 4 +- include/mapnik/text/harfbuzz_shaper.hpp | 142 ++- include/mapnik/text/icu_shaper.hpp | 2 +- include/mapnik/text/itemizer.hpp | 4 +- include/mapnik/text/placement_finder.hpp | 6 +- include/mapnik/text/placement_finder_impl.hpp | 5 +- include/mapnik/text/placements/base.hpp | 2 +- include/mapnik/text/placements/dummy.hpp | 2 +- include/mapnik/text/placements/list.hpp | 6 +- include/mapnik/text/placements/registry.hpp | 2 +- include/mapnik/text/placements/simple.hpp | 2 +- include/mapnik/text/properties_util.hpp | 2 +- include/mapnik/text/renderer.hpp | 12 +- include/mapnik/text/symbolizer_helpers.hpp | 4 +- include/mapnik/text/text_layout.hpp | 12 +- include/mapnik/text/text_line.hpp | 2 +- include/mapnik/text/text_properties.hpp | 5 +- include/mapnik/tiff_io.hpp | 2 +- include/mapnik/timer.hpp | 2 +- include/mapnik/tolerance_iterator.hpp | 2 +- .../{ => transform}/parse_transform.hpp | 2 +- .../{ => transform}/transform_expression.hpp | 26 +- .../transform_expression_grammar_x3.hpp | 51 + .../transform_expression_grammar_x3_def.hpp | 223 ++++ .../{ => transform}/transform_processor.hpp | 4 +- .../mapnik/transform_expression_grammar.hpp | 66 -- .../transform_expression_grammar_impl.hpp | 128 --- include/mapnik/transform_path_adapter.hpp | 2 +- include/mapnik/unicode.hpp | 4 +- .../mapnik/util/const_rendering_buffer.hpp | 4 +- include/mapnik/util/container_adapter.hpp | 2 +- include/mapnik/util/conversions.hpp | 4 +- include/mapnik/util/dasharray_parser.hpp | 2 +- include/mapnik/util/feature_to_geojson.hpp | 21 +- include/mapnik/util/featureset_buffer.hpp | 2 +- include/mapnik/util/file_io.hpp | 5 +- include/mapnik/util/fs.hpp | 2 +- include/mapnik/util/geometry_to_ds_type.hpp | 4 +- include/mapnik/util/geometry_to_geojson.hpp | 2 +- include/mapnik/util/geometry_to_svg.hpp | 2 +- include/mapnik/util/geometry_to_wkb.hpp | 6 +- include/mapnik/util/geometry_to_wkt.hpp | 26 +- include/mapnik/util/hsl.hpp | 2 +- include/mapnik/util/is_clockwise.hpp | 2 +- include/mapnik/util/math.hpp | 2 +- include/mapnik/util/noncopyable.hpp | 2 +- include/mapnik/util/path_iterator.hpp | 2 +- include/mapnik/util/rounding_cast.hpp | 2 +- include/mapnik/util/singleton.hpp | 2 +- include/mapnik/util/spatial_index.hpp | 4 +- .../util/spirit_transform_attribute.hpp | 2 +- include/mapnik/util/timer.hpp | 2 +- include/mapnik/util/trim.hpp | 2 +- include/mapnik/util/utf_conv_win.hpp | 2 +- include/mapnik/util/variant.hpp | 12 +- include/mapnik/util/variant_io.hpp | 4 +- include/mapnik/value.hpp | 40 +- .../{value_error.hpp => value/error.hpp} | 10 +- .../mapnik/{value_hash.hpp => value/hash.hpp} | 23 +- .../{value_types.hpp => value/types.hpp} | 101 +- include/mapnik/version.hpp | 6 +- include/mapnik/vertex.hpp | 2 +- include/mapnik/vertex_adapters.hpp | 4 +- include/mapnik/vertex_cache.hpp | 2 +- include/mapnik/vertex_converters.hpp | 23 +- include/mapnik/vertex_processor.hpp | 6 +- include/mapnik/vertex_vector.hpp | 2 +- include/mapnik/view_strategy.hpp | 2 +- include/mapnik/view_transform.hpp | 4 +- include/mapnik/warning_ignore.hpp | 2 +- include/mapnik/warning_ignore_agg.hpp | 2 +- include/mapnik/warp.hpp | 4 +- include/mapnik/webp_io.hpp | 2 +- include/mapnik/well_known_srs.hpp | 23 +- include/mapnik/wkb.hpp | 2 +- include/mapnik/wkt/wkt_factory.hpp | 16 +- include/mapnik/wkt/wkt_generator_grammar.hpp | 55 +- .../mapnik/wkt/wkt_generator_grammar_impl.hpp | 95 +- include/mapnik/wkt/wkt_grammar.hpp | 108 -- include/mapnik/wkt/wkt_grammar_impl.hpp | 161 --- include/mapnik/wkt/wkt_grammar_x3.hpp | 49 + include/mapnik/wkt/wkt_grammar_x3_def.hpp | 138 +++ include/mapnik/xml_attribute_cast.hpp | 4 +- include/mapnik/xml_loader.hpp | 2 +- include/mapnik/xml_node.hpp | 20 +- include/mapnik/xml_tree.hpp | 8 +- mason_latest.sh | 67 -- plugins/input/csv/csv_datasource.cpp | 6 +- plugins/input/csv/csv_datasource.hpp | 6 +- plugins/input/csv/csv_featureset.cpp | 9 +- plugins/input/csv/csv_featureset.hpp | 2 +- plugins/input/csv/csv_getline.hpp | 2 +- plugins/input/csv/csv_index_featureset.cpp | 9 +- plugins/input/csv/csv_index_featureset.hpp | 2 +- plugins/input/csv/csv_inline_featureset.cpp | 4 +- plugins/input/csv/csv_inline_featureset.hpp | 2 +- plugins/input/csv/csv_utils.cpp | 27 +- plugins/input/csv/csv_utils.hpp | 6 +- plugins/input/gdal/gdal_datasource.cpp | 4 +- plugins/input/gdal/gdal_datasource.hpp | 4 +- plugins/input/gdal/gdal_featureset.cpp | 2 +- plugins/input/gdal/gdal_featureset.hpp | 2 +- plugins/input/geojson/geojson_datasource.cpp | 219 ++-- plugins/input/geojson/geojson_datasource.hpp | 4 +- plugins/input/geojson/geojson_featureset.cpp | 2 +- plugins/input/geojson/geojson_featureset.hpp | 2 +- .../geojson/geojson_index_featureset.cpp | 21 +- .../geojson/geojson_index_featureset.hpp | 2 +- .../geojson_memory_index_featureset.cpp | 23 +- .../geojson_memory_index_featureset.hpp | 2 +- plugins/input/ogr/ogr_converter.cpp | 2 +- plugins/input/ogr/ogr_converter.hpp | 2 +- plugins/input/ogr/ogr_datasource.cpp | 2 +- plugins/input/ogr/ogr_datasource.hpp | 4 +- plugins/input/ogr/ogr_featureset.cpp | 10 +- plugins/input/ogr/ogr_featureset.hpp | 2 +- plugins/input/ogr/ogr_index.hpp | 10 +- plugins/input/ogr/ogr_index_featureset.cpp | 8 +- plugins/input/ogr/ogr_index_featureset.hpp | 2 +- plugins/input/ogr/ogr_layer_ptr.hpp | 2 +- .../input/pgraster/pgraster_datasource.cpp | 1012 ++++++++--------- .../input/pgraster/pgraster_datasource.hpp | 26 +- .../input/pgraster/pgraster_featureset.cpp | 4 +- .../input/pgraster/pgraster_featureset.hpp | 4 +- .../input/pgraster/pgraster_wkb_reader.cpp | 4 +- .../input/pgraster/pgraster_wkb_reader.hpp | 4 +- plugins/input/postgis/asyncresultset.hpp | 2 +- plugins/input/postgis/build.py | 1 - plugins/input/postgis/connection.hpp | 2 +- plugins/input/postgis/connection_manager.hpp | 2 +- plugins/input/postgis/cursorresultset.hpp | 2 +- plugins/input/postgis/numeric2string.hpp | 2 +- plugins/input/postgis/postgis_datasource.cpp | 368 +++--- plugins/input/postgis/postgis_datasource.hpp | 24 +- plugins/input/postgis/postgis_featureset.cpp | 4 +- plugins/input/postgis/postgis_featureset.hpp | 4 +- plugins/input/postgis/resultset.hpp | 2 +- plugins/input/raster/raster_datasource.cpp | 2 +- plugins/input/raster/raster_datasource.hpp | 4 +- plugins/input/raster/raster_featureset.cpp | 2 +- plugins/input/raster/raster_featureset.hpp | 2 +- plugins/input/raster/raster_info.cpp | 4 +- plugins/input/raster/raster_info.hpp | 2 +- plugins/input/shape/dbf_test.cpp | 2 +- plugins/input/shape/dbfile.cpp | 20 +- plugins/input/shape/dbfile.hpp | 4 +- plugins/input/shape/shape_datasource.cpp | 4 +- plugins/input/shape/shape_datasource.hpp | 6 +- plugins/input/shape/shape_featureset.cpp | 2 +- plugins/input/shape/shape_featureset.hpp | 4 +- .../input/shape/shape_index_featureset.cpp | 2 +- .../input/shape/shape_index_featureset.hpp | 4 +- plugins/input/shape/shape_io.cpp | 4 +- plugins/input/shape/shape_io.hpp | 4 +- plugins/input/shape/shape_utils.cpp | 2 +- plugins/input/shape/shape_utils.hpp | 2 +- plugins/input/shape/shapefile.hpp | 4 +- plugins/input/sqlite/sqlite_connection.hpp | 2 +- plugins/input/sqlite/sqlite_datasource.cpp | 4 +- plugins/input/sqlite/sqlite_datasource.hpp | 6 +- plugins/input/sqlite/sqlite_featureset.cpp | 10 +- plugins/input/sqlite/sqlite_featureset.hpp | 2 +- plugins/input/sqlite/sqlite_prepared.hpp | 4 +- plugins/input/sqlite/sqlite_resultset.hpp | 2 +- plugins/input/sqlite/sqlite_utils.hpp | 6 +- .../input/topojson/topojson_datasource.cpp | 32 +- .../input/topojson/topojson_datasource.hpp | 4 +- .../input/topojson/topojson_featureset.cpp | 2 +- .../input/topojson/topojson_featureset.hpp | 2 +- scripts/travis-common.sh | 21 +- src/agg/agg_renderer.cpp | 173 +-- src/agg/process_building_symbolizer.cpp | 6 +- src/agg/process_debug_symbolizer.cpp | 8 +- src/agg/process_dot_symbolizer.cpp | 5 +- src/agg/process_group_symbolizer.cpp | 15 +- src/agg/process_line_pattern_symbolizer.cpp | 100 +- src/agg/process_line_symbolizer.cpp | 9 +- src/agg/process_markers_symbolizer.cpp | 11 +- src/agg/process_point_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 152 +-- src/agg/process_polygon_symbolizer.cpp | 7 +- src/agg/process_raster_symbolizer.cpp | 6 +- src/agg/process_shield_symbolizer.cpp | 4 +- src/agg/process_text_symbolizer.cpp | 4 +- src/build.py | 22 +- src/cairo/cairo_context.cpp | 2 +- src/cairo/cairo_render_vector.cpp | 8 +- src/cairo/cairo_renderer.cpp | 21 +- src/cairo/process_building_symbolizer.cpp | 3 +- src/cairo/process_debug_symbolizer.cpp | 2 +- src/cairo/process_group_symbolizer.cpp | 4 +- src/cairo/process_line_pattern_symbolizer.cpp | 4 +- src/cairo/process_line_symbolizer.cpp | 4 +- src/cairo/process_markers_symbolizer.cpp | 6 +- src/cairo/process_point_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 2 +- src/cairo/process_polygon_symbolizer.cpp | 2 +- src/cairo/process_raster_symbolizer.cpp | 4 +- src/cairo/process_text_symbolizer.cpp | 2 +- src/cairo_io.cpp | 2 +- src/color.cpp | 2 +- src/color_factory.cpp | 13 +- src/config_error.cpp | 2 +- src/conversions.cpp | 264 ----- src/conversions_numeric.cpp | 146 +++ src/conversions_string.cpp | 162 +++ src/css_color_grammar_x3.cpp | 33 + src/dasharray_parser.cpp | 27 +- src/datasource_cache.cpp | 2 +- src/datasource_cache_static.cpp | 2 +- src/debug.cpp | 2 +- src/expression.cpp | 25 +- ..._grammar.cpp => expression_grammar_x3.cpp} | 11 +- src/expression_node.cpp | 4 +- src/expression_string.cpp | 4 +- src/feature_kv_iterator.cpp | 2 +- src/feature_style_processor.cpp | 2 +- src/feature_type_style.cpp | 6 +- src/font_engine_freetype.cpp | 3 +- src/font_set.cpp | 2 +- src/fs.cpp | 2 +- src/function_call.cpp | 2 +- ...r_types.cpp => generate_image_filters.cpp} | 18 +- src/{ => geometry}/box2d.cpp | 4 +- .../envelope.cpp} | 7 +- .../reprojection.cpp} | 14 +- src/gradient.cpp | 4 +- src/grid/grid.cpp | 2 +- src/grid/grid_renderer.cpp | 2 +- src/grid/process_building_symbolizer.cpp | 3 +- src/grid/process_group_symbolizer.cpp | 3 +- src/grid/process_line_pattern_symbolizer.cpp | 2 +- src/grid/process_line_symbolizer.cpp | 4 +- src/grid/process_markers_symbolizer.cpp | 7 +- src/grid/process_point_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 2 +- src/grid/process_polygon_symbolizer.cpp | 2 +- src/grid/process_raster_symbolizer.cpp | 2 +- src/grid/process_shield_symbolizer.cpp | 2 +- src/grid/process_text_symbolizer.cpp | 2 +- src/group/group_layout_manager.cpp | 50 +- src/group/group_rule.cpp | 2 +- src/group/group_symbolizer_helper.cpp | 5 +- src/image.cpp | 3 +- src/image_any.cpp | 2 +- src/image_compositing.cpp | 2 +- src/image_copy.cpp | 2 +- src/image_filter_grammar_x3.cpp | 33 + src/image_options.cpp | 115 +- src/image_reader.cpp | 2 +- src/image_scaling.cpp | 2 +- src/image_util.cpp | 4 +- src/image_util_jpeg.cpp | 4 +- src/image_util_png.cpp | 22 +- src/image_util_tiff.cpp | 2 +- src/image_util_webp.cpp | 4 +- src/image_view.cpp | 4 +- src/image_view_any.cpp | 2 +- src/jpeg_reader.cpp | 2 +- src/json/extract_bounding_boxes_x3.cpp | 203 ++++ ...ry_parser.cpp => feature_from_geojson.cpp} | 26 +- src/json/feature_grammar_x3.cpp | 34 + src/json/generic_json.cpp | 63 - src/json/generic_json_grammar_x3.cpp | 37 + .../json/geojson_grammar_x3.cpp | 50 +- src/json/geometry_from_geojson.cpp | 50 + .../json/mapnik_feature_to_geojson.cpp | 13 +- src/json/mapnik_geometry_to_geojson.cpp | 2 +- src/json/mapnik_json_generator_grammar.cpp | 7 +- src/json/mapnik_topojson_grammar.cpp | 28 - src/json/parse_feature.cpp | 59 + src/json/positions_grammar_x3.cpp | 44 + ...re_grammar.cpp => topojson_grammar_x3.cpp} | 14 +- src/json/unicode_string_grammar_x3.cpp | 46 + src/layer.cpp | 87 +- src/libxml2_loader.cpp | 2 +- src/load_map.cpp | 75 +- src/map.cpp | 48 +- src/mapped_memory_cache.cpp | 2 +- src/marker_cache.cpp | 2 +- src/marker_helpers.cpp | 2 +- src/math.cpp | 2 +- src/memory_datasource.cpp | 16 +- src/palette.cpp | 2 +- src/params.cpp | 4 +- src/parse_image_filters.cpp | 53 + src/parse_path.cpp | 12 +- src/parse_transform.cpp | 33 +- src/path_expression_grammar_x3.cpp | 32 + src/plugin.cpp | 10 +- src/png_reader.cpp | 2 +- src/proj_transform.cpp | 4 +- src/projection.cpp | 2 +- src/rapidxml_loader.cpp | 2 +- src/raster_colorizer.cpp | 28 +- src/renderer_common.cpp | 2 +- .../render_group_symbolizer.cpp | 8 +- .../render_markers_symbolizer.cpp | 8 +- src/renderer_common/render_pattern.cpp | 4 +- .../render_thunk_extractor.cpp | 10 +- src/request.cpp | 2 +- src/rule.cpp | 2 +- src/save_map.cpp | 24 +- src/scale_denominator.cpp | 2 +- src/svg/output/process_line_symbolizer.cpp | 2 +- src/svg/output/process_polygon_symbolizer.cpp | 2 +- src/svg/output/process_symbolizers.cpp | 6 +- src/svg/output/svg_generator.cpp | 2 +- src/svg/output/svg_output_attributes.cpp | 2 +- src/svg/output/svg_output_grammars.cpp | 2 +- src/svg/output/svg_renderer.cpp | 2 +- src/svg/svg_parser.cpp | 149 +-- .../svg_path_grammar_x3.cpp} | 20 +- src/svg/svg_path_parser.cpp | 30 +- src/svg/svg_points_parser.cpp | 29 +- src/svg/svg_transform_parser.cpp | 33 +- src/symbolizer.cpp | 4 +- src/symbolizer_enumerations.cpp | 2 +- src/symbolizer_keys.cpp | 3 +- src/text/face.cpp | 29 +- src/text/font_feature_settings.cpp | 26 +- src/text/font_library.cpp | 2 +- src/text/formatting/base.cpp | 2 +- src/text/formatting/format.cpp | 2 +- src/text/formatting/layout.cpp | 2 +- src/text/formatting/list.cpp | 14 +- src/text/formatting/registry.cpp | 2 +- src/text/formatting/text.cpp | 2 +- src/text/glyph_positions.cpp | 2 +- src/text/itemizer.cpp | 2 +- src/text/placement_finder.cpp | 3 +- src/text/placements/base.cpp | 2 +- src/text/placements/dummy.cpp | 2 +- src/text/placements/list.cpp | 2 +- src/text/placements/registry.cpp | 2 +- src/text/placements/simple.cpp | 49 +- src/text/properties_util.cpp | 2 +- src/text/renderer.cpp | 107 +- src/text/scrptrun.cpp | 6 +- src/text/symbolizer_helpers.cpp | 52 +- src/text/text_layout.cpp | 14 +- src/text/text_line.cpp | 4 +- src/text/text_properties.cpp | 4 +- src/tiff_reader.cpp | 2 +- src/transform_expression.cpp | 4 +- src/transform_expression_grammar.cpp | 26 - ...pp => transform_expression_grammar_x3.cpp} | 13 +- src/twkb.cpp | 4 +- src/unicode.cpp | 4 +- src/util/utf_conv_win.cpp | 2 +- src/value.cpp | 2 +- src/vertex_adapters.cpp | 2 +- src/vertex_cache.cpp | 2 +- src/warp.cpp | 4 +- src/webp_reader.cpp | 3 +- src/well_known_srs.cpp | 2 +- src/wkb.cpp | 8 +- src/wkt/geometry_to_wkt.cpp | 47 + src/wkt/mapnik_wkt_generator_grammar.cpp | 7 +- src/wkt/wkt_factory.cpp | 47 + .../wkt_grammar_x3.cpp} | 16 +- src/xml_tree.cpp | 27 +- test/build.py | 1 + test/data | 2 +- test/data-visual | 2 +- test/standalone/font_registration_test.cpp | 2 +- test/unit/color/css_color.cpp | 160 ++- test/unit/core/box2d_test.cpp | 3 +- test/unit/core/comparison_test.cpp | 3 +- test/unit/core/conversions_test.cpp | 18 +- test/unit/core/expressions_test.cpp | 17 +- test/unit/core/params_test.cpp | 3 +- test/unit/core/transform_expressions_test.cpp | 60 + test/unit/core/value_test.cpp | 3 +- test/unit/datasource/csv.cpp | 4 +- test/unit/datasource/ds_test_util.hpp | 6 +- test/unit/datasource/geojson.cpp | 50 +- test/unit/datasource/postgis.cpp | 70 +- test/unit/datasource/topojson.cpp | 26 +- test/unit/font/fontset_runtime_test.cpp | 5 +- test/unit/geometry/centroid.cpp | 4 +- test/unit/geometry/geometry_envelope_test.cpp | 4 +- test/unit/geometry/geometry_equal.hpp | 2 +- test/unit/geometry/geometry_hit_test.cpp | 2 +- test/unit/geometry/geometry_is_simple.cpp | 5 +- test/unit/geometry/geometry_is_valid.cpp | 4 +- test/unit/geometry/geometry_reprojection.cpp | 26 +- test/unit/geometry/geometry_strategy_test.cpp | 6 +- test/unit/geometry/geometry_test_helper.cpp | 4 +- test/unit/geometry/has_empty.cpp | 6 +- test/unit/geometry/is_empty.cpp | 6 +- test/unit/geometry/remove_empty.cpp | 2 +- test/unit/projection/proj_transform.cpp | 3 +- test/unit/serialization/parse_hex.hpp | 12 +- test/unit/serialization/wkb_formats_test.cpp | 10 +- test/unit/serialization/wkb_test.cpp | 27 +- test/unit/text/shaping.cpp | 104 +- test/unit/vertex_adapter/extend_converter.cpp | 128 +++ test/unit/vertex_adapter/fake_path.hpp | 93 ++ test/unit/vertex_adapter/line_offset_test.cpp | 48 +- test/unit/vertex_adapter/offset_converter.cpp | 53 +- test/unit/vertex_adapter/vertex_adapter.cpp | 2 +- ..._sizes_grammar.hpp => parse_map_sizes.cpp} | 48 +- .../visual/parse_map_sizes.hpp | 19 +- test/visual/runner.cpp | 16 +- test/visual/runner.hpp | 7 +- utils/mapnik-index/build.py | 4 +- utils/mapnik-index/mapnik-index.cpp | 15 +- utils/mapnik-index/process_csv_file.cpp | 2 +- utils/mapnik-index/process_csv_file.hpp | 2 +- utils/mapnik-index/process_geojson_file.cpp | 146 --- .../mapnik-index/process_geojson_file_x3.cpp | 330 ++++++ ...n_file.hpp => process_geojson_file_x3.hpp} | 10 +- utils/ogrindex/ogrindex.cpp | 2 +- utils/pgsql2sqlite/pgsql2sqlite.hpp | 4 +- utils/shapeindex/shapeindex.cpp | 6 +- 743 files changed, 11298 insertions(+), 8765 deletions(-) delete mode 100644 demo/python/README.txt delete mode 100755 demo/python/rundemo.py delete mode 100644 include/mapnik/css_color_grammar.hpp rename src/css_color_grammar.cpp => include/mapnik/css_color_grammar_x3.hpp (61%) rename include/mapnik/{css_color_grammar_impl.hpp => css_color_grammar_x3_def.hpp} (54%) delete mode 100644 include/mapnik/csv/csv_grammar.hpp create mode 100644 include/mapnik/csv/csv_grammar_x3.hpp create mode 100644 include/mapnik/csv/csv_grammar_x3_def.hpp create mode 100644 include/mapnik/cxx11_support.hpp delete mode 100644 include/mapnik/expression_grammar.hpp delete mode 100644 include/mapnik/expression_grammar_impl.hpp create mode 100644 include/mapnik/expression_grammar_x3.hpp create mode 100644 include/mapnik/expression_grammar_x3_config.hpp create mode 100644 include/mapnik/expression_grammar_x3_def.hpp create mode 100644 include/mapnik/extend_converter.hpp delete mode 100644 include/mapnik/filter_factory.hpp rename include/mapnik/{geometry_adapters.hpp => geometry/boost_adapters.hpp} (66%) create mode 100644 include/mapnik/geometry/boost_spirit_karma_adapter.hpp rename include/mapnik/{ => geometry}/box2d.hpp (98%) rename include/mapnik/{ => geometry}/box2d_impl.hpp (89%) rename include/mapnik/{geometry_centroid.hpp => geometry/centroid.hpp} (94%) rename include/mapnik/{geometry_correct.hpp => geometry/correct.hpp} (96%) rename include/mapnik/{geometry_envelope.hpp => geometry/envelope.hpp} (94%) rename include/mapnik/{geometry_envelope_impl.hpp => geometry/envelope_impl.hpp} (94%) rename include/mapnik/{geometry_fusion_adapted.hpp => geometry/fusion_adapted.hpp} (98%) rename include/mapnik/{ => geometry}/geometry_type.hpp (94%) rename include/mapnik/{ => geometry}/geometry_types.hpp (97%) create mode 100644 include/mapnik/geometry/is_empty.hpp rename include/mapnik/{geometry_is_simple.hpp => geometry/is_simple.hpp} (88%) rename include/mapnik/{geometry_is_valid.hpp => geometry/is_valid.hpp} (82%) rename include/mapnik/{geometry_remove_empty.hpp => geometry/remove_empty.hpp} (96%) rename include/mapnik/{geometry_reprojection.hpp => geometry/reprojection.hpp} (98%) rename include/mapnik/{geometry_reprojection_impl.hpp => geometry/reprojection_impl.hpp} (95%) rename include/mapnik/{geometry_strategy.hpp => geometry/strategy.hpp} (96%) rename include/mapnik/{geometry_to_path.hpp => geometry/to_path.hpp} (97%) rename include/mapnik/{geometry_transform.hpp => geometry/transform.hpp} (97%) delete mode 100644 include/mapnik/geometry_is_empty.hpp delete mode 100644 include/mapnik/image_filter_grammar.hpp delete mode 100644 include/mapnik/image_filter_grammar_impl.hpp create mode 100644 include/mapnik/image_filter_grammar_x3.hpp create mode 100644 include/mapnik/image_filter_grammar_x3_def.hpp create mode 100644 include/mapnik/json/create_feature.hpp rename include/mapnik/json/{geometry_util.hpp => create_geometry.hpp} (61%) delete mode 100644 include/mapnik/json/error_handler.hpp delete mode 100644 include/mapnik/json/extract_bounding_box_grammar.hpp delete mode 100644 include/mapnik/json/extract_bounding_box_grammar_impl.hpp create mode 100644 include/mapnik/json/extract_bounding_boxes_x3.hpp create mode 100644 include/mapnik/json/extract_bounding_boxes_x3_config.hpp delete mode 100644 include/mapnik/json/feature_collection_grammar.hpp delete mode 100644 include/mapnik/json/feature_collection_grammar_impl.hpp delete mode 100644 include/mapnik/json/feature_grammar.hpp delete mode 100644 include/mapnik/json/feature_grammar_impl.hpp create mode 100644 include/mapnik/json/feature_grammar_x3.hpp create mode 100644 include/mapnik/json/feature_grammar_x3_def.hpp delete mode 100644 include/mapnik/json/generic_json.hpp rename include/mapnik/{path_expression_grammar.hpp => json/generic_json_grammar_x3.hpp} (56%) create mode 100644 include/mapnik/json/generic_json_grammar_x3_def.hpp create mode 100644 include/mapnik/json/geojson_grammar_x3.hpp create mode 100644 include/mapnik/json/geojson_grammar_x3_def.hpp delete mode 100644 include/mapnik/json/geometry_grammar.hpp delete mode 100644 include/mapnik/json/geometry_grammar_impl.hpp rename include/mapnik/{svg/svg_points_grammar.hpp => json/geometry_grammar_x3.hpp} (62%) create mode 100644 include/mapnik/json/geometry_grammar_x3_def.hpp create mode 100644 include/mapnik/json/json_grammar_config.hpp create mode 100644 include/mapnik/json/json_value.hpp rename src/json/mapnik_json_feature_collection_grammar.cpp => include/mapnik/json/parse_feature.hpp (66%) delete mode 100644 include/mapnik/json/positions_grammar.hpp delete mode 100644 include/mapnik/json/positions_grammar_impl.hpp create mode 100644 include/mapnik/json/positions_grammar_x3.hpp create mode 100644 include/mapnik/json/positions_grammar_x3_def.hpp rename include/mapnik/json/{positions.hpp => positions_x3.hpp} (82%) delete mode 100644 include/mapnik/json/topojson_grammar.hpp delete mode 100644 include/mapnik/json/topojson_grammar_impl.hpp create mode 100644 include/mapnik/json/topojson_grammar_x3.hpp create mode 100644 include/mapnik/json/topojson_grammar_x3_def.hpp create mode 100644 include/mapnik/json/unicode_string_grammar_x3.hpp create mode 100644 include/mapnik/json/unicode_string_grammar_x3_def.hpp create mode 100644 include/mapnik/path_expression_grammar_x3.hpp create mode 100644 include/mapnik/path_expression_grammar_x3_def.hpp rename include/mapnik/{path_expression_grammar_impl.hpp => svg/svg_grammar_config_x3.hpp} (52%) delete mode 100644 include/mapnik/svg/svg_path_grammar.hpp delete mode 100644 include/mapnik/svg/svg_path_grammar_impl.hpp create mode 100644 include/mapnik/svg/svg_path_grammar_x3.hpp create mode 100644 include/mapnik/svg/svg_path_grammar_x3_def.hpp delete mode 100644 include/mapnik/svg/svg_points_grammar_impl.hpp delete mode 100644 include/mapnik/svg/svg_transform_grammar.hpp delete mode 100644 include/mapnik/svg/svg_transform_grammar_impl.hpp create mode 100644 include/mapnik/svg/svg_transform_grammar_x3.hpp create mode 100644 include/mapnik/svg/svg_transform_grammar_x3_def.hpp rename include/mapnik/{ => transform}/parse_transform.hpp (97%) rename include/mapnik/{ => transform}/transform_expression.hpp (92%) create mode 100644 include/mapnik/transform/transform_expression_grammar_x3.hpp create mode 100644 include/mapnik/transform/transform_expression_grammar_x3_def.hpp rename include/mapnik/{ => transform}/transform_processor.hpp (98%) delete mode 100644 include/mapnik/transform_expression_grammar.hpp delete mode 100644 include/mapnik/transform_expression_grammar_impl.hpp rename include/mapnik/{value_error.hpp => value/error.hpp} (91%) rename include/mapnik/{value_hash.hpp => value/hash.hpp} (75%) rename include/mapnik/{value_types.hpp => value/types.hpp} (61%) delete mode 100644 include/mapnik/wkt/wkt_grammar.hpp delete mode 100644 include/mapnik/wkt/wkt_grammar_impl.hpp create mode 100644 include/mapnik/wkt/wkt_grammar_x3.hpp create mode 100644 include/mapnik/wkt/wkt_grammar_x3_def.hpp delete mode 100755 mason_latest.sh delete mode 100644 src/conversions.cpp create mode 100644 src/conversions_numeric.cpp create mode 100644 src/conversions_string.cpp create mode 100644 src/css_color_grammar_x3.cpp rename src/{wkt/mapnik_wkt_grammar.cpp => expression_grammar_x3.cpp} (79%) rename src/{image_filter_types.cpp => generate_image_filters.cpp} (66%) rename src/{ => geometry}/box2d.cpp (93%) rename src/{geometry_envelope.cpp => geometry/envelope.cpp} (91%) rename src/{geometry_reprojection.cpp => geometry/reprojection.cpp} (89%) create mode 100644 src/image_filter_grammar_x3.cpp create mode 100644 src/json/extract_bounding_boxes_x3.cpp rename src/json/{mapnik_json_geometry_parser.cpp => feature_from_geojson.cpp} (69%) create mode 100644 src/json/feature_grammar_x3.cpp delete mode 100644 src/json/generic_json.cpp create mode 100644 src/json/generic_json_grammar_x3.cpp rename include/mapnik/csv/csv_grammar_impl.hpp => src/json/geojson_grammar_x3.cpp (50%) create mode 100644 src/json/geometry_from_geojson.cpp rename include/mapnik/json/feature_generator.hpp => src/json/mapnik_feature_to_geojson.cpp (81%) delete mode 100644 src/json/mapnik_topojson_grammar.cpp create mode 100644 src/json/parse_feature.cpp create mode 100644 src/json/positions_grammar_x3.cpp rename src/json/{mapnik_json_feature_grammar.cpp => topojson_grammar_x3.cpp} (76%) create mode 100644 src/json/unicode_string_grammar_x3.cpp create mode 100644 src/parse_image_filters.cpp create mode 100644 src/path_expression_grammar_x3.cpp rename src/{json/mapnik_json_positions_grammar.cpp => svg/svg_path_grammar_x3.cpp} (58%) delete mode 100644 src/transform_expression_grammar.cpp rename src/{json/mapnik_json_geometry_grammar.cpp => transform_expression_grammar_x3.cpp} (76%) create mode 100644 src/wkt/geometry_to_wkt.cpp create mode 100644 src/wkt/wkt_factory.cpp rename src/{expression_grammar.cpp => wkt/wkt_grammar_x3.cpp} (72%) create mode 100644 test/unit/core/transform_expressions_test.cpp create mode 100644 test/unit/vertex_adapter/extend_converter.cpp create mode 100644 test/unit/vertex_adapter/fake_path.hpp rename test/visual/{map_sizes_grammar.hpp => parse_map_sizes.cpp} (55%) rename src/image_filter_grammar.cpp => test/visual/parse_map_sizes.hpp (80%) delete mode 100644 utils/mapnik-index/process_geojson_file.cpp create mode 100644 utils/mapnik-index/process_geojson_file_x3.cpp rename utils/mapnik-index/{process_geojson_file.hpp => process_geojson_file_x3.hpp} (81%) diff --git a/.gitmodules b/.gitmodules index 7846a4f6c..345b8a2aa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,10 +5,13 @@ [submodule "test/data-visual"] path = test/data-visual url = https://github.com/mapnik/test-data-visual.git - branch = master + branch = harfbuzz-shaper [submodule "deps/mapbox/variant"] path = deps/mapbox/variant url = https://github.com/mapbox/variant.git + branch = master [submodule "deps/mapbox/geometry"] path = deps/mapbox/geometry url = https://github.com/mapbox/geometry.hpp.git + branch = master + diff --git a/.travis.yml b/.travis.yml index bc4d5462f..174406b30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,6 @@ env: - CCACHE_COMPRESS=1 - HEAVY_JOBS="2" - PREFIX=/tmp/mapnik - - secure: "N3a5nzzsgpuu45k8qWdYsHNxrSnqeAGLTOYpfYoAH7B94vuf7pa7XV1tQjXbxrnx2D6ryTdtUtyRKwy7zXbwXxGt4DpczWEo8f6DUd6+obAp3kdnXABg2Sj4oA7KMs0F0CmoADy0jdUZD5YyOJHu64LCIIgzEQ9q49PFMNbU3IE=" - - secure: "iQYPNpMtejcgYeUkWZGIWz1msIco5qydJrhZTSCQOYahAQerdT7q5WZEpEo3G6IWOGgO1eo7GFuY8DvqQjw1+jC9b9mhkRNdo3LhGTKS9Gsbl5Q27k0rjlaFZmmQHrfPlQJwhfAIp+KLugHtQw5bCoLh+95E3j0F0DayF1tuJ3s=" - secure: "F6ivqDNMBQQnrDGA9+7IX+GDswuIqQQd7YPJdQqa2Ked9jddAQDeJClb05ig3JlwfOlYLGZOd43ZX0pKuMtI2Gbkwz211agGP9S3YunwlRg8iWtJlO5kYFUdKCmJNhjg4icfkGELCgwXn+zuEWFSLpkPcjqAFKFlQrIJeAJJgKM=" addons: postgresql: "9.4" @@ -25,24 +23,32 @@ matrix: - os: linux sudo: false compiler: ": clang" - env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8" TRIGGER=true + env: JOBS=4 CXX="ccache g++-6" CC="gcc-6" addons: apt: sources: [ 'ubuntu-toolchain-r-test'] - packages: [ 'libstdc++-5-dev', 'xutils-dev'] + packages: [ 'libstdc++-6-dev', 'g++-6', 'xutils-dev'] + - os: linux + sudo: false + compiler: ": clang" + env: JOBS=8 CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" TRIGGER=true + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test'] + packages: [ 'libstdc++-4.9-dev', 'xutils-dev'] - os: linux sudo: false compiler: ": clang-coverage" - env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8" + env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" addons: apt: sources: [ 'ubuntu-toolchain-r-test'] - packages: ['libstdc++-5-dev', 'xutils-dev' ] + packages: ['libstdc++-4.9-dev', 'xutils-dev' ] - os: osx compiler: ": clang-osx" # https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions osx_image: xcode7.3 # upgrades clang from 6 -> 7 - env: JOBS=4 MASON_PUBLISH=true CXX="ccache clang++ -Qunused-arguments" + env: JOBS=4 CXX="ccache clang++ -Qunused-arguments" before_install: # workaround travis rvm bug @@ -52,8 +58,7 @@ before_install: rvm get head || true fi - source scripts/travis-common.sh - - export PYTHONUSERBASE=$(pwd)/mason_packages/.link - - export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PYTHONUSERBASE}/bin:${PATH} + - export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PATH} - export COVERAGE=${COVERAGE:-false} - export MASON_PUBLISH=${MASON_PUBLISH:-false} - export BENCH=${BENCH:-false} @@ -62,8 +67,6 @@ before_install: - git_submodule_update --init --depth=10 install: - - on 'linux' export PYTHONPATH=${PYTHONUSERBASE}/lib/python2.7/site-packages - - on 'osx' export PYTHONPATH=${PYTHONUSERBASE}/lib/python/site-packages - on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres - on 'osx' rm -rf ${DATA_PATH} - on 'osx' initdb ${DATA_PATH} -E utf8 @@ -72,16 +75,19 @@ install: - on 'osx' createuser -s postgres - psql -c 'create database template_postgis;' -U postgres - psql -c 'create extension postgis;' -d template_postgis -U postgres - - enabled ${COVERAGE} pip install --user cpp-coveralls + - enabled ${COVERAGE} curl -S -f https://codecov.io/bash -o codecov + - enabled ${COVERAGE} chmod +x codecov before_script: - source bootstrap.sh - | if [[ $(uname -s) == 'Linux' ]]; then - mason install clang 3.8.0 - export PATH=$(mason prefix clang 3.8.0)/bin:${PATH} - which clang++ - export LLVM_COV="$(mason prefix clang 3.8.0)/bin/llvm-cov" + mason install clang++ 3.9.1 + export PATH=$(mason prefix clang++ 3.9.1)/bin:${PATH} + mason install llvm-cov 3.9.1 + export PATH=$(mason prefix llvm-cov 3.9.1)/bin:${PATH} + which llvm-cov + export LLVM_COV="$(mason prefix llvm-cov 3.9.1)/bin/llvm-cov" fi - ccache --version - ccache -p || true @@ -98,14 +104,12 @@ script: # (and might work) for the next build - DURATION=2400 - scripts/travis-command-wrapper.py -s "date" -i 120 --deadline=$(( $(date +%s) + ${DURATION} )) make - - make test + - RESULT=0 + - make test || RESULT=$? + # we allow visual failures with g++ for now: https://github.com/mapnik/mapnik/issues/3567 + - if [[ ${RESULT} != 0 ]] && [[ ${CXX} =~ 'clang++' ]]; then false; fi; - enabled ${COVERAGE} coverage - enabled ${BENCH} make bench after_success: - enabled ${TRIGGER} trigger_downstream - - if enabled ${MASON_PUBLISH}; then - source ./.mason/mason.sh && - ./mason_latest.sh build && - ./mason_latest.sh publish; - fi diff --git a/Makefile b/Makefile index 752791b1e..090be8d5d 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - OS := $(shell uname -s) PYTHON = python @@ -36,15 +35,14 @@ src/json/libmapnik-json.a: src/renderer_common/render_thunk_extractor.os \ src/json/libmapnik-json.a \ src/wkt/libmapnik-wkt.a \ - src/css_color_grammar.os \ - src/expression_grammar.os \ - src/transform_expression_grammar.os \ - src/image_filter_grammar.os \ + src/css_color_grammar_x3.os \ + src/expression_grammar_x3.os \ + src/transform_expression_grammar_x3.os \ + src/image_filter_grammar_x3.os \ src/marker_helpers.os \ src/svg/svg_transform_parser.os \ src/agg/process_line_symbolizer.os \ plugins/input/geojson/geojson_datasource.os \ - utils/mapnik-index/process_geojson_file.o \ src/svg/svg_path_parser.os \ src/svg/svg_parser.os \ src/svg/svg_points_parser.os \ diff --git a/README.md b/README.md index b58be712a..300aac3e9 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/ [![Build Status Linux](https://api.travis-ci.org/mapnik/mapnik.svg?branch=master)](http://travis-ci.org/mapnik/mapnik) [![Build Status Windows](https://ci.appveyor.com/api/projects/status/hc9l7okdjtucfqqn?branch=master&svg=true)](https://ci.appveyor.com/project/Mapbox/mapnik) -[![Coverage Status](https://coveralls.io/repos/mapnik/mapnik/badge.svg?branch=master&service=github)](https://coveralls.io/github/mapnik/mapnik?branch=master) +[![codecov](https://codecov.io/gh/mapnik/mapnik/branch/master/graph/badge.svg)](https://codecov.io/gh/mapnik/mapnik) Mapnik is an open source toolkit for developing mapping applications. At the core is a C++ shared library providing algorithms and patterns for spatial data access and visualization. diff --git a/SConstruct b/SConstruct index 85713c694..d640afe15 100644 --- a/SConstruct +++ b/SConstruct @@ -41,8 +41,8 @@ ICU_LIBS_DEFAULT='/usr/' DEFAULT_CC = "cc" DEFAULT_CXX = "c++" -DEFAULT_CXX11_CXXFLAGS = " -std=c++11" -DEFAULT_CXX11_LINKFLAGS = "" +DEFAULT_CXX14_CXXFLAGS = " -std=c++14" +DEFAULT_CXX14_LINKFLAGS = "" if sys.platform == 'darwin': # homebrew default ICU_INCLUDES_DEFAULT='/usr/local/opt/icu4c/include/' @@ -61,7 +61,7 @@ SCONS_CONFIGURE_CACHE = 'config.cache' SCONF_TEMP_DIR = '.sconf_temp' # auto-search directories for boost libs/headers BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',] -BOOST_MIN_VERSION = '1.47' +BOOST_MIN_VERSION = '1.61' #CAIRO_MIN_VERSION = '1.8.0' HARFBUZZ_MIN_VERSION = (0, 9, 34) @@ -1037,12 +1037,12 @@ int main() return True return False -def supports_cxx11(context,silent=False): +def supports_cxx14(context,silent=False): ret = context.TryRun(""" int main() { -#if __cplusplus >= 201103 +#if __cplusplus >= 201402L return 0; #else return -1; @@ -1051,7 +1051,7 @@ int main() """, '.cpp') if not silent: - context.Message('Checking if compiler (%s) supports -std=c++11 flag... ' % context.env.get('CXX','CXX')) + context.Message('Checking if compiler (%s) supports -std=c++14 flag... ' % context.env.get('CXX','CXX')) if silent: context.did_show_result=1 context.Result(ret[0]) @@ -1080,7 +1080,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths, 'harfbuzz_with_freetype_support': harfbuzz_with_freetype_support, 'boost_regex_has_icu' : boost_regex_has_icu, 'sqlite_has_rtree' : sqlite_has_rtree, - 'supports_cxx11' : supports_cxx11, + 'supports_cxx14' : supports_cxx14, 'CheckBoostScopedEnum' : CheckBoostScopedEnum, } @@ -1129,6 +1129,7 @@ if not preconfigured: else: color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...') + conf = Configure(env, custom_tests = conf_tests) if env['DEBUG']: @@ -1142,6 +1143,9 @@ if not preconfigured: env['PLATFORM'] = platform.uname()[0] color_print(4,"Configuring on %s in *%s*..." % (env['PLATFORM'],mode)) + cxx_version = call("%s --version" % env["CXX"] ,silent=True) + color_print(5, "CXX %s" % cxx_version) + env['MISSING_DEPS'] = [] env['SKIPPED_DEPS'] = [] env['HAS_CAIRO'] = False @@ -1213,13 +1217,13 @@ if not preconfigured: # set any custom cxxflags and ldflags to come first if sys.platform == 'darwin' and not env['HOST']: - DEFAULT_CXX11_CXXFLAGS += ' -stdlib=libc++' - DEFAULT_CXX11_LINKFLAGS = ' -stdlib=libc++' + DEFAULT_CXX14_CXXFLAGS += ' -stdlib=libc++' + DEFAULT_CXX14_LINKFLAGS = ' -stdlib=libc++' env.Append(CPPDEFINES = env['CUSTOM_DEFINES']) - env.Append(CXXFLAGS = DEFAULT_CXX11_CXXFLAGS) + env.Append(CXXFLAGS = DEFAULT_CXX14_CXXFLAGS) env.Append(CXXFLAGS = env['CUSTOM_CXXFLAGS']) env.Append(CFLAGS = env['CUSTOM_CFLAGS']) - env.Append(LINKFLAGS = DEFAULT_CXX11_LINKFLAGS) + env.Append(LINKFLAGS = DEFAULT_CXX14_LINKFLAGS) env.Append(LINKFLAGS = env['CUSTOM_LDFLAGS']) ### platform specific bits @@ -1353,9 +1357,9 @@ if not preconfigured: if env['PRIORITIZE_LINKING']: conf.prioritize_paths(silent=True) - # test for C++11 support, which is required - if not env['HOST'] and not conf.supports_cxx11(): - color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler") + # test for C++14 support, which is required + if not env['HOST'] and not conf.supports_cxx14(): + color_print(1,"C++ compiler does not support C++14 standard (-std=c++14), which is required. Please upgrade your compiler") Exit(1) if not env['HOST']: @@ -1784,11 +1788,10 @@ if not preconfigured: # Common flags for g++/clang++ CXX compiler. # TODO: clean up code more to make -Wextra -Wsign-compare -Wsign-conversion -Wconversion viable # -Wfloat-equal -Wold-style-cast -Wexit-time-destructors -Wglobal-constructors -Wreserved-id-macro -Wheader-hygiene -Wmissing-noreturn - common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread) + common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare ' % (env['WARNING_CXXFLAGS'], pthread) if 'clang++' in env['CXX']: - common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene ' - + common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene -Wc++14-extensions ' if env['DEBUG']: env.Append(CXXFLAGS = common_cxx_flags + '-O0') else: @@ -1797,7 +1800,7 @@ if not preconfigured: env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv') if env['DEBUG_SANITIZE']: - env.Append(CXXFLAGS = ['-fsanitize=address']) + env.Append(CXXFLAGS = ['-fsanitize=address','-fno-omit-frame-pointer']) env.Append(LINKFLAGS = ['-fsanitize=address']) diff --git a/benchmark/bench_framework.hpp b/benchmark/bench_framework.hpp index a3de4fdd9..4cc9390e8 100644 --- a/benchmark/bench_framework.hpp +++ b/benchmark/bench_framework.hpp @@ -4,7 +4,7 @@ // mapnik #include #include -#include +#include #include #include "../test/cleanup.hpp" diff --git a/benchmark/run b/benchmark/run index 6a8fdd938..36cda4e92 100755 --- a/benchmark/run +++ b/benchmark/run @@ -24,7 +24,7 @@ run test_getline 30 10000000 #run test_polygon_clipping 10 1000 #run test_polygon_clipping_rendering 10 100 run test_proj_transform1 10 100 -run test_expression_parse 10 1000 +run test_expression_parse 10 10000 run test_face_ptr_creation 10 1000 run test_font_registration 10 100 run test_offset_converter 10 1000 diff --git a/benchmark/test_expression_parse.cpp b/benchmark/test_expression_parse.cpp index 7e399223c..f39fb8e84 100644 --- a/benchmark/test_expression_parse.cpp +++ b/benchmark/test_expression_parse.cpp @@ -1,8 +1,8 @@ #include "bench_framework.hpp" #include +#include #include #include -#include class test : public benchmark::test_case { diff --git a/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp index d10911a42..aed74fe33 100644 --- a/benchmark/test_polygon_clipping.cpp +++ b/benchmark/test_polygon_clipping.cpp @@ -10,10 +10,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include // boost geometry diff --git a/benchmark/test_proj_transform1.cpp b/benchmark/test_proj_transform1.cpp index 37f4b0c4c..fa050da12 100644 --- a/benchmark/test_proj_transform1.cpp +++ b/benchmark/test_proj_transform1.cpp @@ -1,5 +1,5 @@ #include "bench_framework.hpp" -#include +#include #include #include diff --git a/bootstrap.sh b/bootstrap.sh index e926c26bc..b2b171f49 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -11,7 +11,7 @@ todo - shrink icu data ' -MASON_VERSION="new-pkgs" +MASON_VERSION="3c6df04" function setup_mason() { if [[ ! -d ./.mason ]]; then @@ -19,7 +19,7 @@ function setup_mason() { (cd ./.mason && git checkout ${MASON_VERSION}) else echo "Updating to latest mason" - (cd ./.mason && git fetch && git checkout ${MASON_VERSION} && git pull) + (cd ./.mason && git fetch && git checkout ${MASON_VERSION} && git pull origin ${MASON_VERSION}) fi export PATH=$(pwd)/.mason:$PATH export CXX=${CXX:-clang++} @@ -44,45 +44,37 @@ function install() { mason link $1 $2 } -ICU_VERSION="55.1" +ICU_VERSION="57.1" function install_mason_deps() { - FAIL=0 - install ccache 3.3.0 & - install zlib system & - install jpeg_turbo 1.5.0 libjpeg & - install libpng 1.6.24 libpng & - install libtiff 4.0.6 libtiff & - install libpq 9.5.2 & - install sqlite 3.14.1 libsqlite3 & - install expat 2.2.0 libexpat & - install icu ${ICU_VERSION} & - install proj 4.9.2 libproj & - install pixman 0.34.0 libpixman-1 & - install cairo 1.14.6 libcairo & - install protobuf 2.6.1 & + install ccache 3.3.1 + install zlib 1.2.8 + install jpeg_turbo 1.5.1 libjpeg + install libpng 1.6.28 libpng + install libtiff 4.0.7 libtiff + install libpq 9.6.2 + install sqlite 3.17.0 libsqlite3 + install expat 2.2.0 libexpat + install icu ${ICU_VERSION} + install proj 4.9.3 libproj + install pixman 0.34.0 libpixman-1 + install cairo 1.14.8 libcairo + install protobuf 3.2.0 # technically protobuf is not a mapnik core dep, but installing # here by default helps make mapnik-vector-tile builds easier - install webp 0.5.1 libwebp & - install gdal 2.1.1 libgdal & - install boost 1.61.0 & - install boost_libsystem 1.61.0 & - install boost_libfilesystem 1.61.0 & - install boost_libprogram_options 1.61.0 & - install boost_libregex_icu 1.61.0 & + install webp 0.6.0 libwebp + install libgdal 2.1.3 libgdal + install boost 1.63.0 + install boost_libsystem 1.63.0 + install boost_libfilesystem 1.63.0 + install boost_libprogram_options 1.63.0 + install boost_libregex_icu57 1.63.0 # technically boost thread and python are not a core dep, but installing # here by default helps make python-mapnik builds easier - install boost_libthread 1.61.0 & - install boost_libpython 1.61.0 & - install freetype 2.6.5 libfreetype & - install harfbuzz 1.3.0 libharfbuzz & - for job in $(jobs -p) - do - wait $job || let "FAIL+=1" - done - if [[ "$FAIL" != "0" ]]; then - exit ${FAIL} - fi + install boost_libthread 1.63.0 + install boost_libpython 1.63.0 + install freetype 2.7.1 libfreetype + install harfbuzz 1.4.4-ft libharfbuzz } MASON_LINKED_ABS=$(pwd)/mason_packages/.link @@ -95,6 +87,7 @@ function make_config() { echo " CXX = '$CXX' CC = '$CC' +CUSTOM_CXXFLAGS = '-D_GLIBCXX_USE_CXX11_ABI=0' RUNTIME_LINK = 'static' INPUT_PLUGINS = 'all' PATH = '${MASON_LINKED_REL}/bin' diff --git a/circle.yml b/circle.yml index d9d4bad81..5624c66ae 100644 --- a/circle.yml +++ b/circle.yml @@ -7,11 +7,7 @@ machine: JOBS: 8 CCACHE_TEMPDIR: /tmp/.ccache-temp CCACHE_COMPRESS: 1 - LLVM_VERSION: 3.8 - pre: - - echo "here" - post: - - echo "there" + LLVM_VERSION: 3.9.1 checkout: post: @@ -32,9 +28,9 @@ dependencies: database: pre: - ./bootstrap.sh - - ./.mason/mason install clang ${LLVM_VERSION}.0 - - ./.mason/mason link clang ${LLVM_VERSION}.0 - - ./configure CC="$(pwd)/mason_packages/.link/bin/clang-${LLVM_VERSION}" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++-${LLVM_VERSION} -Qunused-arguments" + - ./.mason/mason install clang++ ${LLVM_VERSION} + - ./.mason/mason link clang++ ${LLVM_VERSION} + - ./configure CC="$(pwd)/mason_packages/.link/bin/clang" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++ -Qunused-arguments" - make override: - psql -c 'create database template_postgis;' diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp index ff7907d2e..46e2cb2c0 100644 --- a/demo/c++/rundemo.cpp +++ b/demo/c++/rundemo.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/demo/python/README.txt b/demo/python/README.txt deleted file mode 100644 index 4a13579cb..000000000 --- a/demo/python/README.txt +++ /dev/null @@ -1,20 +0,0 @@ -This directory contains a sample python script implementing the Mapnik API. - -The script is thoroughly commented and also acts as a mini tutorial. Reading -it should get you on your way, and you can use it as a base for your work. - -You must compile and install mapnik and the python bindings FIRST. - -Once this is done, run it: - -/path/to/python rundemo.py - -If all goes well, it should render 2 map images: - -demo.jpg -demo.png - -Have a look! - -Cheers, -J.F. diff --git a/demo/python/rundemo.py b/demo/python/rundemo.py deleted file mode 100755 index 910d846a5..000000000 --- a/demo/python/rundemo.py +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# -# -# This file is part of Mapnik (c++ mapping toolkit) -# Copyright (C) 2005 Jean-Francois Doyon -# -# Mapnik is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -from __future__ import print_function -import sys -from os import path -import mapnik - -# Instanciate a map, giving it a width and height. Remember: the word "map" is -# reserved in Python! :) - -root = path.dirname(__file__) -m = mapnik.Map(800,600,"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs") - -# Set its background colour. More on colours later ... - -m.background = mapnik.Color('white') - -# Now we can start adding layers, in stacking order (i.e. bottom layer first) - -# Canadian Provinces (Polygons) - -# Instanciate a layer. The parameters depend on the type of data: -# shape: -# type='shape' -# file='/path/to/shape' -# raster: -# type='raster' -# file='/path/to/raster' -# postgis: -# type='postgis' -# host='127.0.0.1' -# dbname='mydatabase' -# user='myusername' -# password='mypassword' -# table= TODO - -provpoly_lyr = mapnik.Layer('Provinces') -provpoly_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -provpoly_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/boundaries'), encoding='latin1') - -# We then define a style for the layer. A layer can have one or many styles. -# Styles are named, so they can be shared across different layers. -# Multiple styles per layer behaves functionally like multiple layers. The -# data is completely re-scanned for each style within one layer, and a style -# will be drawn entirely "above" the previous one. Performance wise using -# multiple styles in one layer is the same has having multiple layers. -# The paradigm is useful mostly as a convenience. - -provpoly_style = mapnik.Style() - -# A Style needs one or more rules. A rule will normally consist of a filter -# for feature selection, and one or more symbolizers. - -provpoly_rule_on = mapnik.Rule() - -# A Expression() allows the selection of features to which the symbology will -# be applied. More on Mapnik expressions can be found in Tutorial #2. -# A given feature can only match one filter per rule per style. - -provpoly_rule_on.filter = mapnik.Expression("[NAME_EN] = 'Ontario'") - -# Here a symbolizer is defined. Available are: -# - LineSymbolizer(Color(),) -# - LineSymbolizer(Stroke()) -# - PolygonSymbolizer(Color()) -# - PointSymbolizer(,,,) - -# Some of them can accept a Color() instance, which can be created with: -# - Color(, , ) -# - Color(, , , ) -# - Color() where will be something like '#00FF00' -# or '#0f0' or 'green' - -sym = mapnik.PolygonSymbolizer() -sym.fill = mapnik.Color(250, 190, 183); -provpoly_rule_on.symbols.append(sym) -provpoly_style.rules.append(provpoly_rule_on) - -provpoly_rule_qc = mapnik.Rule() -provpoly_rule_qc.filter = mapnik.Expression("[NOM_FR] = 'Québec'") -sym = mapnik.PolygonSymbolizer() -sym.fill = mapnik.Color(217, 235, 203) -provpoly_rule_qc.symbols.append(sym) -provpoly_style.rules.append(provpoly_rule_qc) - -# Add the style to the map, giving it a name. This is the name that will be -# used to refer to it from here on. Having named styles allows them to be -# re-used throughout the map. - -m.append_style('provinces', provpoly_style) - -# Then associate the style to the layer itself. - -provpoly_lyr.styles.append('provinces') - -# Then add the layer to the map. In reality, it's the order in which you -# append them to the map that will determine the drawing order, though by -# convention it is recommended to define them in drawing order as well. - -m.layers.append(provpoly_lyr) - -# Drainage - -# A simple example ... - -qcdrain_lyr = mapnik.Layer('Quebec Hydrography') -qcdrain_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -qcdrain_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/qcdrainage')) - -qcdrain_style = mapnik.Style() -qcdrain_rule = mapnik.Rule() -qcdrain_rule.filter = mapnik.Expression('[HYC] = 8') -sym = mapnik.PolygonSymbolizer() -sym.fill = mapnik.Color(153, 204, 255) -sym.smooth = 1.0 # very smooth -qcdrain_rule.symbols.append(sym) -qcdrain_style.rules.append(qcdrain_rule) - -m.append_style('drainage', qcdrain_style) -qcdrain_lyr.styles.append('drainage') -m.layers.append(qcdrain_lyr) - -# In this case, we have 2 data sets with similar schemas (same filtering -# attributes, and same desired style), so we're going to -# re-use the style defined in the above layer for the next one. - -ondrain_lyr = mapnik.Layer('Ontario Hydrography') -ondrain_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -ondrain_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/ontdrainage')) - -ondrain_lyr.styles.append('drainage') -m.layers.append(ondrain_lyr) - -# Provincial boundaries - -provlines_lyr = mapnik.Layer('Provincial borders') -provlines_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -provlines_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/boundaries_l')) - -# Here we define a "dash dot dot dash" pattern for the provincial boundaries. - -provlines_style = mapnik.Style() -provlines_rule = mapnik.Rule() -sym = mapnik.LineSymbolizer() -# FIXME - currently adding dash arrays is broken -# https://github.com/mapnik/mapnik/issues/2324 -sym.stroke = mapnik.Color('black') -sym.stroke_width = 1.0 -provlines_rule.symbols.append(sym) -provlines_style.rules.append(provlines_rule) - -m.append_style('provlines', provlines_style) -provlines_lyr.styles.append('provlines') -m.layers.append(provlines_lyr) - -# Roads 3 and 4 (The "grey" roads) - -roads34_lyr = mapnik.Layer('Roads') -roads34_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -# create roads datasource (we're going to re-use it later) - -roads34_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/roads')) - -roads34_style = mapnik.Style() -roads34_rule = mapnik.Rule() -roads34_rule.filter = mapnik.Expression('([CLASS] = 3) or ([CLASS] = 4)') - -# With lines of a certain width, you can control how the ends -# are closed off using line_cap as below. - -# Available options are: -# line_cap: BUTT_CAP, SQUARE_CAP, ROUND_CAP -# line_join: MITER_JOIN, MITER_REVERT_JOIN, ROUND_JOIN, BEVEL_JOIN - -# And one last Stroke() attribute not used here is "opacity", which -# can be set to a numerical value. - -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(171,158,137) -sym.stroke_width = 2.0 -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP - -roads34_rule.symbols.append(sym) -roads34_style.rules.append(roads34_rule) - -m.append_style('smallroads', roads34_style) -roads34_lyr.styles.append('smallroads') -m.layers.append(roads34_lyr) - -# Roads 2 (The thin yellow ones) - -roads2_lyr = mapnik.Layer('Roads') -roads2_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -# Just get a copy from roads34_lyr -roads2_lyr.datasource = roads34_lyr.datasource - -roads2_style_1 = mapnik.Style() -roads2_rule_1 = mapnik.Rule() -roads2_rule_1.filter = mapnik.Expression('[CLASS] = 2') - -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(171,158,137) -sym.stroke_width = 4.0 -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -roads2_rule_1.symbols.append(sym) -roads2_style_1.rules.append(roads2_rule_1) - -m.append_style('road-border', roads2_style_1) - -roads2_style_2 = mapnik.Style() -roads2_rule_2 = mapnik.Rule() -roads2_rule_2.filter = mapnik.Expression('[CLASS] = 2') -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(255,250,115) -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -sym.stroke_width = 2.0 -roads2_rule_2.symbols.append(sym) -roads2_style_2.rules.append(roads2_rule_2) - -m.append_style('road-fill', roads2_style_2) - -roads2_lyr.styles.append('road-border') -roads2_lyr.styles.append('road-fill') - -m.layers.append(roads2_lyr) - -# Roads 1 (The big orange ones, the highways) - -roads1_lyr = mapnik.Layer('Roads') -roads1_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -roads1_lyr.datasource = roads34_lyr.datasource - -roads1_style_1 = mapnik.Style() -roads1_rule_1 = mapnik.Rule() -roads1_rule_1.filter = mapnik.Expression('[CLASS] = 1') -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(188,149,28) -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -sym.stroke_width = 7.0 -roads1_rule_1.symbols.append(sym) -roads1_style_1.rules.append(roads1_rule_1) -m.append_style('highway-border', roads1_style_1) - -roads1_style_2 = mapnik.Style() -roads1_rule_2 = mapnik.Rule() -roads1_rule_2.filter = mapnik.Expression('[CLASS] = 1') -sym.stroke = mapnik.Color(242,191,36) -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -sym.stroke_width = 5.0 -roads1_rule_2.symbols.append(sym) -roads1_style_2.rules.append(roads1_rule_2) - -m.append_style('highway-fill', roads1_style_2) - -roads1_lyr.styles.append('highway-border') -roads1_lyr.styles.append('highway-fill') - -m.layers.append(roads1_lyr) - -# Populated Places - -popplaces_lyr = mapnik.Layer('Populated Places') -popplaces_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -popplaces_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/popplaces'),encoding='latin1') - -popplaces_style = mapnik.Style() -popplaces_rule = mapnik.Rule() - -# And here we have a TextSymbolizer, used for labeling. -# The first parameter is the name of the attribute to use as the source of the -# text to label with. Then there is font size in points (I think?), and colour. - -# TODO - currently broken: https://github.com/mapnik/mapnik/issues/2324 -#popplaces_text_symbolizer = mapnik.TextSymbolizer(mapnik.Expression("[GEONAME]"), -# 'DejaVu Sans Book', -# 10, mapnik.Color('black')) - -# We set a "halo" around the text, which looks like an outline if thin enough, -# or an outright background if large enough. -#popplaces_text_symbolizer.label_placement= mapnik.label_placement.POINT_PLACEMENT -#popplaces_text_symbolizer.halo_fill = mapnik.Color(255,255,200) -#popplaces_text_symbolizer.halo_radius = 1 -#popplaces_text_symbolizer.avoid_edges = True -#popplaces_text_symbolizer.minimum_padding = 30 -#popplaces_rule.symbols.append(popplaces_text_symbolizer) - -popplaces_style.rules.append(popplaces_rule) - -m.append_style('popplaces', popplaces_style) -popplaces_lyr.styles.append('popplaces') -m.layers.append(popplaces_lyr) - -# Draw map - -# Set the initial extent of the map in 'master' spherical Mercator projection -m.zoom_to_box(mapnik.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855)) - -# Render map -im = mapnik.Image(m.width,m.height) -mapnik.render(m, im) - -# Save image to files -images_ = [] -if mapnik.has_png(): - im.save('demo.png', 'png') # true-colour RGBA - images_.append('demo.png') - - # old behavior, now can do 'png8:c=256' - im.save('demo256.png', 'png256') # save to palette based (max 256 colours) png - images_.append('demo256.png') - - im.save('demo64_binary_transparency.png', 'png8:c=64:t=1') - images_.append('demo64_binary_transparency.png') - - im.save('demo128_colors_hextree_no_alpha.png', 'png8:c=100:m=h:t=0') - images_.append('demo128_colors_hextree_no_alpha.png') - -if mapnik.has_jpeg(): - im.save('demo_high.jpg', 'jpeg100') - images_.append('demo_high.jpg') - - im.save('demo_low.jpg', 'jpeg50') - images_.append('demo_low.jpg') - -if mapnik.has_tiff(): - im.save('demo.tif', 'tiff') - images_.append('demo.tif') - -if mapnik.has_webp(): - im.save('demo.webp', 'webp') # default quality is 90 - images_.append('demo.webp') - - im.save('demo_highest.webp', 'webp:quality=100') - images_.append('demo_med.webp') - - im.save('demo_low.webp', 'webp:quality=50') - images_.append('demo_low.webp') - - -# Render cairo examples -if mapnik.has_cairo(): - mapnik.render_to_file(m,'demo.pdf') - images_.append('demo.pdf') - mapnik.render_to_file(m,'demo.ps') - images_.append('demo.ps') - mapnik.render_to_file(m,'demo.svg') - images_.append('demo.svg') - mapnik.render_to_file(m,'demo_cairo_rgb24.png','RGB24') - images_.append('demo_cairo_rgb.png') - mapnik.render_to_file(m,'demo_cairo_argb32.png','ARGB32') - images_.append('demo_cairo_argb.png') - -print ("\n\n", len(images_), "maps have been rendered in the current directory:") - -for im_ in images_: - print ("-", im_) - -print ("\n\nHave a look!\n\n") - -mapnik.save_map(m,"map.xml") diff --git a/demo/viewer/about_dialog.cpp b/demo/viewer/about_dialog.cpp index 2a37349ee..b6aa9fa33 100644 --- a/demo/viewer/about_dialog.cpp +++ b/demo/viewer/about_dialog.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/about_dialog.hpp b/demo/viewer/about_dialog.hpp index 160dcc857..0edc78dfa 100644 --- a/demo/viewer/about_dialog.hpp +++ b/demo/viewer/about_dialog.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/info_dialog.cpp b/demo/viewer/info_dialog.cpp index b25002025..a65951082 100644 --- a/demo/viewer/info_dialog.cpp +++ b/demo/viewer/info_dialog.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/info_dialog.hpp b/demo/viewer/info_dialog.hpp index c4b887f18..4dfded270 100644 --- a/demo/viewer/info_dialog.hpp +++ b/demo/viewer/info_dialog.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layer_info_dialog.cpp b/demo/viewer/layer_info_dialog.cpp index f7e983d35..65dddd392 100644 --- a/demo/viewer/layer_info_dialog.cpp +++ b/demo/viewer/layer_info_dialog.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layer_info_dialog.hpp b/demo/viewer/layer_info_dialog.hpp index 370551e01..3ac825dbc 100644 --- a/demo/viewer/layer_info_dialog.hpp +++ b/demo/viewer/layer_info_dialog.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerdelegate.cpp b/demo/viewer/layerdelegate.cpp index 5e4331793..a43214a9b 100644 --- a/demo/viewer/layerdelegate.cpp +++ b/demo/viewer/layerdelegate.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerdelegate.hpp b/demo/viewer/layerdelegate.hpp index 92a57a75e..479e0838d 100644 --- a/demo/viewer/layerdelegate.hpp +++ b/demo/viewer/layerdelegate.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerlistmodel.cpp b/demo/viewer/layerlistmodel.cpp index f2ad085ef..e1e46e075 100644 --- a/demo/viewer/layerlistmodel.cpp +++ b/demo/viewer/layerlistmodel.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerlistmodel.hpp b/demo/viewer/layerlistmodel.hpp index d69133315..4fec7a712 100644 --- a/demo/viewer/layerlistmodel.hpp +++ b/demo/viewer/layerlistmodel.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerwidget.cpp b/demo/viewer/layerwidget.cpp index d392150fb..f066a3d1b 100644 --- a/demo/viewer/layerwidget.cpp +++ b/demo/viewer/layerwidget.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerwidget.hpp b/demo/viewer/layerwidget.hpp index e75ee7db2..09763fc45 100644 --- a/demo/viewer/layerwidget.hpp +++ b/demo/viewer/layerwidget.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/main.cpp b/demo/viewer/main.cpp index d8f06d25a..f7ab2e432 100644 --- a/demo/viewer/main.cpp +++ b/demo/viewer/main.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mainwindow.cpp b/demo/viewer/mainwindow.cpp index 939028ab5..27f71d4c0 100644 --- a/demo/viewer/mainwindow.cpp +++ b/demo/viewer/mainwindow.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mainwindow.hpp b/demo/viewer/mainwindow.hpp index ebfc2c59a..b816617ad 100644 --- a/demo/viewer/mainwindow.hpp +++ b/demo/viewer/mainwindow.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mapwidget.cpp b/demo/viewer/mapwidget.cpp index 9b2c5278d..fd3c3d1f7 100644 --- a/demo/viewer/mapwidget.cpp +++ b/demo/viewer/mapwidget.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mapwidget.hpp b/demo/viewer/mapwidget.hpp index e65908fcf..d0f538e6e 100644 --- a/demo/viewer/mapwidget.hpp +++ b/demo/viewer/mapwidget.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/styles_model.cpp b/demo/viewer/styles_model.cpp index d7b68ba0e..332200b21 100644 --- a/demo/viewer/styles_model.cpp +++ b/demo/viewer/styles_model.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/styles_model.hpp b/demo/viewer/styles_model.hpp index a21885915..ce7879469 100644 --- a/demo/viewer/styles_model.hpp +++ b/demo/viewer/styles_model.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/viewer.pro b/demo/viewer/viewer.pro index 8a9747752..aad00b424 100644 --- a/demo/viewer/viewer.pro +++ b/demo/viewer/viewer.pro @@ -1,7 +1,6 @@ ###################################################################### # Mapnik viewer - Copyright (C) 2007 Artem Pavlenko ###################################################################### -QMAKE_MAC_SDK = macosx10.11 TEMPLATE = app QT += core gui widgets QMAKE_CXX = $$system(mapnik-config --cxx) diff --git a/deps/agg/include/agg_vpgen_clip_polygon.h b/deps/agg/include/agg_vpgen_clip_polygon.h index 4972a390b..7f98538e3 100644 --- a/deps/agg/include/agg_vpgen_clip_polygon.h +++ b/deps/agg/include/agg_vpgen_clip_polygon.h @@ -43,12 +43,12 @@ namespace agg { } - void clip_box(double x1, double y1, double x2, double y2) + void clip_box(double _x1, double _y1, double _x2, double _y2) { - m_clip_box.x1 = x1; - m_clip_box.y1 = y1; - m_clip_box.x2 = x2; - m_clip_box.y2 = y2; + m_clip_box.x1 = _x1; + m_clip_box.y1 = _y1; + m_clip_box.x2 = _x2; + m_clip_box.y2 = _y2; m_clip_box.normalize(); } diff --git a/deps/agg/include/agg_vpgen_clip_polyline.h b/deps/agg/include/agg_vpgen_clip_polyline.h index a2e60fa7b..c7b18c98a 100644 --- a/deps/agg/include/agg_vpgen_clip_polyline.h +++ b/deps/agg/include/agg_vpgen_clip_polyline.h @@ -41,12 +41,12 @@ namespace agg { } - void clip_box(double x1, double y1, double x2, double y2) + void clip_box(double _x1, double _y1, double _x2, double _y2) { - m_clip_box.x1 = x1; - m_clip_box.y1 = y1; - m_clip_box.x2 = x2; - m_clip_box.y2 = y2; + m_clip_box.x1 = _x1; + m_clip_box.y1 = _y1; + m_clip_box.x2 = _x2; + m_clip_box.y2 = _y2; m_clip_box.normalize(); } diff --git a/deps/mapbox/geometry b/deps/mapbox/geometry index 03778c6af..b0d64e6e8 160000 --- a/deps/mapbox/geometry +++ b/deps/mapbox/geometry @@ -1 +1 @@ -Subproject commit 03778c6af7f1f116fc5722596a31334315451a53 +Subproject commit b0d64e6e8d55026781325df1068e8043ff880aff diff --git a/deps/mapbox/variant b/deps/mapbox/variant index a5a79a594..916139a2e 160000 --- a/deps/mapbox/variant +++ b/deps/mapbox/variant @@ -1 +1 @@ -Subproject commit a5a79a594f39d705a7ef969f54a0743516f0bc6d +Subproject commit 916139a2e51e125816efce6e19d428385601273f diff --git a/include/build.py b/include/build.py index ec705419a..aa122d9a5 100644 --- a/include/build.py +++ b/include/build.py @@ -39,7 +39,10 @@ subdirs = [ 'text', 'text/placements', 'text/formatting', - 'markers_placements' + 'transform', + 'markers_placements', + 'geometry', + 'value' ] if env['SVG_RENDERER']: diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp index ff87ce0ef..51319d52b 100644 --- a/include/mapnik/agg_helpers.hpp +++ b/include/mapnik/agg_helpers.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/agg_pattern_source.hpp b/include/mapnik/agg_pattern_source.hpp index 42dd7f36f..7ca93e1df 100644 --- a/include/mapnik/agg_pattern_source.hpp +++ b/include/mapnik/agg_pattern_source.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/agg_rasterizer.hpp b/include/mapnik/agg_rasterizer.hpp index 66da59fd6..b25160b04 100644 --- a/include/mapnik/agg_rasterizer.hpp +++ b/include/mapnik/agg_rasterizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/agg_render_marker.hpp b/include/mapnik/agg_render_marker.hpp index 283807a93..d11789df4 100644 --- a/include/mapnik/agg_render_marker.hpp +++ b/include/mapnik/agg_render_marker.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,13 +20,16 @@ * *****************************************************************************/ +#ifndef MAPNIK_AGG_RENDER_MARKER_HPP +#define MAPNIK_AGG_RENDER_MARKER_HPP + #include #include #include #include #include #include -#include +#include #include #include @@ -148,3 +151,5 @@ void render_raster_marker(RendererType renb, RasterizerType & ras, image_rgba8 c } } + +#endif // MAPNIK_AGG_RENDER_MARKER_HPP diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 776632d68..27a22b74a 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,15 +28,17 @@ #include #include // for noncopyable #include // for rule, symbolizers -#include // for box2d +#include // for box2d #include // for view_transform #include // for composite_mode_e #include #include #include #include +#include // stl #include +#include // fwd declaration to avoid dependence on agg headers namespace agg { struct trans_affine; } @@ -58,6 +60,53 @@ namespace mapnik { namespace mapnik { +template +class buffer_stack +{ +public: + buffer_stack(std::size_t width, std::size_t height) + : width_(width), + height_(height), + buffers_(), + position_(buffers_.begin()) + { + } + + T & push() + { + if (position_ == buffers_.begin()) + { + buffers_.emplace_front(width_, height_); + position_ = buffers_.begin(); + } + else + { + position_--; + mapnik::fill(*position_, 0); // fill with transparent colour + } + return *position_; + } + + void pop() + { + if (position_ != buffers_.end()) + { + position_++; + } + } + + T & top() const + { + return *position_; + } + +private: + const std::size_t width_; + const std::size_t height_; + std::deque buffers_; + typename std::deque::iterator position_; +}; + template class MAPNIK_DECL agg_renderer : public feature_style_processor >, private util::noncopyable @@ -160,15 +209,14 @@ protected: void draw_geo_extent(box2d const& extent,mapnik::color const& color); private: - buffer_type & pixmap_; - std::shared_ptr internal_buffer_; - mutable buffer_type * current_buffer_; - mutable bool style_level_compositing_; + std::stack> buffers_; + buffer_stack internal_buffers_; + std::unique_ptr inflated_buffer_; const std::unique_ptr ras_ptr; gamma_method_enum gamma_method_; double gamma_; renderer_common common_; - void setup(Map const& m); + void setup(Map const & m, buffer_type & pixmap); }; extern template class MAPNIK_DECL agg_renderer>; diff --git a/include/mapnik/attribute.hpp b/include/mapnik/attribute.hpp index edfaebefc..3e82f8f2f 100644 --- a/include/mapnik/attribute.hpp +++ b/include/mapnik/attribute.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_ATTRIBUTE_HPP // mapnik -#include +#include #include #include // stl diff --git a/include/mapnik/attribute_collector.hpp b/include/mapnik/attribute_collector.hpp index cfd29cc6b..83fec1171 100644 --- a/include/mapnik/attribute_collector.hpp +++ b/include/mapnik/attribute_collector.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_ATTRIBUTE_COLLECTOR_HPP // mapnik -#include +#include #include #include #include diff --git a/include/mapnik/attribute_descriptor.hpp b/include/mapnik/attribute_descriptor.hpp index a5245ea55..a80d7e0d5 100644 --- a/include/mapnik/attribute_descriptor.hpp +++ b/include/mapnik/attribute_descriptor.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/boolean.hpp b/include/mapnik/boolean.hpp index 92751b7fe..9d2b97bf6 100644 --- a/include/mapnik/boolean.hpp +++ b/include/mapnik/boolean.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/cairo/cairo_context.hpp b/include/mapnik/cairo/cairo_context.hpp index c15f87cd7..1e775d6a0 100644 --- a/include/mapnik/cairo/cairo_context.hpp +++ b/include/mapnik/cairo/cairo_context.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/cairo/cairo_image_util.hpp b/include/mapnik/cairo/cairo_image_util.hpp index 9f039d605..2c7c269a4 100644 --- a/include/mapnik/cairo/cairo_image_util.hpp +++ b/include/mapnik/cairo/cairo_image_util.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/cairo/cairo_render_vector.hpp b/include/mapnik/cairo/cairo_render_vector.hpp index 37bd44925..ead3798e9 100644 --- a/include/mapnik/cairo/cairo_render_vector.hpp +++ b/include/mapnik/cairo/cairo_render_vector.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/cairo/cairo_renderer.hpp b/include/mapnik/cairo/cairo_renderer.hpp index 0563149a6..9e7a91477 100644 --- a/include/mapnik/cairo/cairo_renderer.hpp +++ b/include/mapnik/cairo/cairo_renderer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/cairo_io.hpp b/include/mapnik/cairo_io.hpp index 55b107286..45c4353d2 100644 --- a/include/mapnik/cairo_io.hpp +++ b/include/mapnik/cairo_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp index 434a9cf21..7f8ee7c03 100644 --- a/include/mapnik/color.hpp +++ b/include/mapnik/color.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,16 +38,15 @@ namespace mapnik { -class MAPNIK_DECL color - : boost::equality_comparable +class MAPNIK_DECL color : boost::equality_comparable { -private: +public: std::uint8_t red_; std::uint8_t green_; std::uint8_t blue_; std::uint8_t alpha_; bool premultiplied_; -public: + // default ctor color() : red_(0xff), diff --git a/include/mapnik/color_factory.hpp b/include/mapnik/color_factory.hpp index 6fdb5663c..594cb40b0 100644 --- a/include/mapnik/color_factory.hpp +++ b/include/mapnik/color_factory.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/config.hpp b/include/mapnik/config.hpp index a9168e59f..25df5371f 100644 --- a/include/mapnik/config.hpp +++ b/include/mapnik/config.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/config_error.hpp b/include/mapnik/config_error.hpp index b8bd31f67..0d1d4c1dc 100644 --- a/include/mapnik/config_error.hpp +++ b/include/mapnik/config_error.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,10 +41,8 @@ public: config_error(std::string const& what, unsigned line_number, std::string const& filename); - virtual ~config_error() throw() {} - - virtual const char * what() const throw(); - + virtual ~config_error() {} + virtual const char * what() const noexcept; void append_context(std::string const& ctx) const; void append_context(std::string const& ctx, xml_node const& node) const; void append_context(xml_node const& node) const; diff --git a/include/mapnik/coord.hpp b/include/mapnik/coord.hpp index f8ea3f161..c20c755bc 100644 --- a/include/mapnik/coord.hpp +++ b/include/mapnik/coord.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -181,6 +181,7 @@ private: }; using coord2d = coord; +using coord2f = coord; using coord2i = coord; } diff --git a/include/mapnik/css_color_grammar.hpp b/include/mapnik/css_color_grammar.hpp deleted file mode 100644 index 8fbdeaa6f..000000000 --- a/include/mapnik/css_color_grammar.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_CSS_COLOR_GRAMMAR_HPP -#define MAPNIK_CSS_COLOR_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -// boost -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik -{ - -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; - -using ascii_space_type = boost::spirit::ascii::space_type; - -template -struct css_color_grammar : qi::grammar -{ - // ctor - css_color_grammar(); - // rules - qi::uint_parser< unsigned, 16, 2, 2 > hex2 ; - qi::uint_parser< unsigned, 16, 1, 1 > hex1 ; - qi::uint_parser< unsigned, 10, 1, 3 > dec3 ; - qi::rule rgba_color; - qi::rule rgba_percent_color; - qi::rule,color(), ascii_space_type> hsl_percent_color; - qi::rule hex_color; - qi::rule hex_color_small; - qi::rule css_color; -}; - -} - -#endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP diff --git a/src/css_color_grammar.cpp b/include/mapnik/css_color_grammar_x3.hpp similarity index 61% rename from src/css_color_grammar.cpp rename to include/mapnik/css_color_grammar_x3.hpp index 2e9f60c92..54e022528 100644 --- a/src/css_color_grammar.cpp +++ b/include/mapnik/css_color_grammar_x3.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,12 +20,36 @@ * *****************************************************************************/ -// NOTE: we define this here in a cpp because def is needed twice: -// once by src/color_factory.cpp and once by include/mapnik/image_filter_grammar.hpp -// otherwise it would make sense to simply do `#include ` -// in a single file -#include -#include -#include +#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP +#define MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP -template struct mapnik::css_color_grammar; +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik +{ + +namespace x3 = boost::spirit::x3; + +namespace css_color_grammar +{ + +struct css_color_class; +using css_color_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(css_color_grammar_type); + +}} + + +namespace mapnik +{ +css_color_grammar::css_color_grammar_type const& color_grammar(); +} + + +#endif // MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP diff --git a/include/mapnik/css_color_grammar_impl.hpp b/include/mapnik/css_color_grammar_x3_def.hpp similarity index 54% rename from include/mapnik/css_color_grammar_impl.hpp rename to include/mapnik/css_color_grammar_x3_def.hpp index 22fa74472..457f0d999 100644 --- a/include/mapnik/css_color_grammar_impl.hpp +++ b/include/mapnik/css_color_grammar_x3_def.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,84 +20,49 @@ * *****************************************************************************/ -// NOTE: This is an implementation header file and is only meant to be included -// from implementation files. It therefore doesn't have an include guard. -// mapnik -#include -// boost +// REF: http://www.w3.org/TR/css3-color/ + +#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP +#define MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + #pragma GCC diagnostic push -#include -#include -#include -#include +#include +#include +#include +#include #pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_ADT( +BOOST_FUSION_ADAPT_STRUCT ( mapnik::color, - (unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast(val))) + (std::uint8_t, red_) + (std::uint8_t, green_) + (std::uint8_t, blue_) + (std::uint8_t, alpha_) ) -namespace mapnik +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace css_color_grammar { + +using x3::lit; +using x3::uint_parser; +using x3::hex; +using x3::symbols; +using x3::omit; +using x3::attr; +using x3::double_; +using x3::no_case; +using x3::no_skip; + +struct named_colors_ : x3::symbols { -namespace phoenix = boost::phoenix; - -struct percent_conv_impl -{ - using result_type = unsigned; - unsigned operator() (double val) const - { - return safe_cast(std::lround((255.0 * val)/100.0)); - } -}; - -struct alpha_conv_impl -{ - using result_type = unsigned; - unsigned operator() (double val) const - { - return safe_cast(std::lround((255.0 * val))); - } -}; - -struct hsl_conv_impl -{ - using result_type = void; - template - void operator() (T0 & c, T1 h, T2 s, T3 l) const - { - double m1,m2; - // normalize values - h /= 360.0; - s /= 100.0; - l /= 100.0; - - if (l <= 0.5) - { - m2 = l * (s + 1.0); - } - else - { - m2 = l + s - l*s; - } - m1 = l * 2 - m2; - - double r = hue_to_rgb(m1, m2, h + 1.0/3.0); - double g = hue_to_rgb(m1, m2, h); - double b = hue_to_rgb(m1, m2, h - 1.0/3.0); - - c.set_red(safe_cast(std::lround(255.0 * r))); - c.set_green(safe_cast(std::lround(255.0 * g))); - c.set_blue(safe_cast(std::lround(255.0 * b))); - } -}; - -struct named_colors : qi::symbols -{ - named_colors() + named_colors_() { add ("aliceblue", color(240, 248, 255)) @@ -249,77 +214,241 @@ struct named_colors : qi::symbols ("transparent", color(0, 0, 0, 0)) ; } +} named_colors; + +x3::uint_parser hex2; +x3::uint_parser hex1; +x3::uint_parser dec3; + +// starting rule +css_color_grammar_type const css_color("css_color"); +// rules +x3::rule const hex2_color("hex2_color"); +x3::rule const hex1_color("hex1_color"); +x3::rule const rgb_color("rgb_color"); +x3::rule const rgba_color("rgba_color"); +x3::rule const rgb_color_percent("rgb_color_percent"); +x3::rule const rgba_color_percent("rgba_color_percent"); + +struct clip_opacity +{ + static double call(double val) + { + if (val > 1.0) return 1.0; + if (val < 0.0) return 0.0; + return val; + } }; -template -css_color_grammar::css_color_grammar() - : css_color_grammar::base_type(css_color) - +struct percent_converter { - qi::lit_type lit; - qi::_val_type _val; - qi::double_type double_; - qi::_1_type _1; - qi::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::lexeme_type lexeme; - ascii::no_case_type no_case; - using phoenix::at_c; - // symbols - named_colors named; - // functions - phoenix::function percent_converter; - phoenix::function alpha_converter; - phoenix::function hsl_converter; + static std::uint8_t call(double val) + { + return safe_cast(std::lround((255.0 * val)/100.0)); + } +}; - css_color %= rgba_color - | rgba_percent_color - | hsl_percent_color - | hex_color - | hex_color_small - | no_case[named]; +auto dec_red = [](auto& ctx) +{ + _val(ctx).red_ = _attr(ctx); +}; - hex_color = lexeme[ lit('#') - >> hex2 [ at_c<0>(_val) = _1 ] - >> hex2 [ at_c<1>(_val) = _1 ] - >> hex2 [ at_c<2>(_val) = _1 ] - >>-hex2 [ at_c<3>(_val) = _1 ] ] - ; +auto dec_green = [](auto& ctx) +{ + _val(ctx).green_ = _attr(ctx); +}; - hex_color_small = lexeme[ lit('#') - >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] - >>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] ] - ; +auto dec_blue = [](auto& ctx) +{ + _val(ctx).blue_ = _attr(ctx); +}; - rgba_color = lit("rgb") >> -lit('a') - >> lit('(') - >> dec3 [at_c<0>(_val) = _1] >> ',' - >> dec3 [at_c<1>(_val) = _1] >> ',' - >> dec3 [at_c<2>(_val) = _1] - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; +auto opacity = [](auto& ctx) +{ + _val(ctx).alpha_ = uint8_t((255.0 * clip_opacity::call(_attr(ctx))) + 0.5); +}; - rgba_percent_color = lit("rgb") >> -lit('a') - >> lit('(') - >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; +auto percent_red = [] (auto & ctx) +{ + _val(ctx).red_ = percent_converter::call(_attr(ctx)); +}; - hsl_percent_color = lit("hsl") >> -lit('a') - >> lit('(') - >> double_ [ _a = _1] >> ',' // hue 0..360 - >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% - >> double_ [ _c = _1] >> '%' // lightness 0..100% - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 - >> lit (')') [ hsl_converter(_val,_a,_b,_c)] - ; +auto percent_green = [] (auto & ctx) +{ + _val(ctx).green_ = percent_converter::call(_attr(ctx)); +}; + +auto percent_blue = [] (auto & ctx) +{ + _val(ctx).blue_ = percent_converter::call(_attr(ctx)); +}; + +auto hex1_red = [](auto& ctx) +{ + _val(ctx).red_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex1_green = [](auto& ctx) +{ + _val(ctx).green_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex1_blue = [](auto& ctx) +{ + _val(ctx).blue_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex1_opacity = [](auto& ctx) +{ + _val(ctx).alpha_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex2_red = [](auto& ctx) +{ + _val(ctx).red_ = _attr(ctx); +}; + +auto hex2_green = [](auto& ctx) +{ + _val(ctx).green_ = _attr(ctx); +}; + +auto hex2_blue = [](auto& ctx) +{ + _val(ctx).blue_ = _attr(ctx); +}; + +auto hex2_opacity = [](auto& ctx) +{ + _val(ctx).alpha_ = _attr(ctx); +}; + +auto hsl_to_rgba = [] (auto& ctx) +{ + double h = std::get<0>(_attr(ctx)); + double s = std::get<1>(_attr(ctx)); + double l = std::get<2>(_attr(ctx)); + double m1; + double m2; + // normalise values + h /= 360.0; + s /= 100.0; + l /= 100.0; + if (l <= 0.5) + { + m2 = l * (s + 1.0); + } + else + { + m2 = l + s - l*s; + } + m1 = l * 2 - m2; + + double r = hue_to_rgb(m1, m2, h + 1.0/3.0); + double g = hue_to_rgb(m1, m2, h); + double b = hue_to_rgb(m1, m2, h - 1.0/3.0); + uint8_t alpha = uint8_t((255.0 * clip_opacity::call(std::get<3>(_attr(ctx)))) + 0.5); + _val(ctx) = color(safe_cast(std::lround(255.0 * r)), + safe_cast(std::lround(255.0 * g)), + safe_cast(std::lround(255.0 * b)), + alpha); +}; + +auto const hex2_color_def = no_skip[lit('#') + >> hex2[hex2_red] + >> hex2[hex2_green] + >> hex2[hex2_blue] + >> (hex2[hex2_opacity] | attr(255)[hex2_opacity])]; + +auto const hex1_color_def = no_skip[lit('#') + >> hex1[hex1_red] + >> hex1[hex1_green] + >> hex1[hex1_blue] + >> (hex1[hex1_opacity] | attr(15)[hex1_opacity])]; + +auto const rgb_color_def = lit("rgb") + >> lit('(') >> dec3[dec_red] + >> lit(',') >> dec3[dec_green] + >> lit(',') >> dec3[dec_blue] + >> attr(255) >> lit(')'); + +auto const rgb_color_percent_def = lit("rgb") + >> lit('(') >> dec3[percent_red] >> lit('%') + >> lit(',') >> dec3[percent_green] >> lit('%') + >> lit(',') >> dec3[percent_blue] >> lit('%') + >> attr(255) >> lit(')'); + +auto const rgba_color_def = lit("rgba") + >> lit('(') >> dec3[dec_red] + >> lit(',') >> dec3[dec_green] + >> lit(',') >> dec3[dec_blue] + >> lit(',') >> double_[opacity] >> lit(')'); + +auto const rgba_color_percent_def = lit("rgba") + >> lit('(') >> dec3[percent_red] >> lit('%') + >> lit(',') >> dec3[percent_green] >> lit('%') + >> lit(',') >> dec3[percent_blue] >> lit('%') + >> lit(',') >> double_[opacity] >> lit(')'); + +auto const hsl_values = x3::rule> {} = + lit("hsl") + >> lit('(') >> dec3 + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> dec3 >> lit('%') + >> attr(1.0) >> lit(')') + ; + +auto const hsla_values = x3::rule> {} = + lit("hsla") + >> lit('(') >> dec3 + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> double_ >> lit(')') + ; + +auto const hsl_color = x3::rule {} = hsl_values[hsl_to_rgba]; +auto const hsla_color = x3::rule {} = hsla_values[hsl_to_rgba]; + +auto const css_color_def = + no_case[named_colors] + | + hex2_color + | + hex1_color + | + rgb_color + | + rgba_color + | + rgb_color_percent + | + rgba_color_percent + | + hsl_color + | + hsla_color + ; + +#pragma GCC diagnostic push +#include +BOOST_SPIRIT_DEFINE( + css_color, + hex2_color, + hex1_color, + rgb_color, + rgba_color, + rgb_color_percent, + rgba_color_percent + ); +#pragma GCC diagnostic pop + +} // ns + +css_color_grammar::css_color_grammar_type const& color_grammar() +{ + return css_color_grammar::css_color; } -} +} //ns mapnik + +#endif //MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/csv/csv_grammar.hpp b/include/mapnik/csv/csv_grammar.hpp deleted file mode 100644 index 240f11ce1..000000000 --- a/include/mapnik/csv/csv_grammar.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_CSV_GRAMMAR_HPP -#define MAPNIK_CSV_GRAMMAR_HPP - -#include -#include - -namespace mapnik { - -namespace qi = boost::spirit::qi; - -struct csv_white_space_skipper : qi::primitive_parser -{ - template - struct attribute - { - typedef qi::unused_type type; - }; - - template - bool parse(Iterator& first, Iterator const& last - , Context& /*context*/, Skipper const& skipper - , Attribute& /*attr*/) const - { - qi::skip_over(first, last, skipper); - if (first != last && *first == ' ') - { - while (++first != last && *first == ' ') - ; - return true; - } - return false; - } - - template - qi::info what(Context& /*context*/) const - { - return qi::info("csv_white_space_skipper"); - } -}; - - -template -struct csv_line_grammar : qi::grammar -{ - csv_line_grammar(); -private: - qi::rule line; - qi::rule column; // no-skip - qi::rule text; // no-skip - qi::rule quoted; // no-skip - qi::symbols unesc_char; -}; - -} - -#endif // MAPNIK_CSV_GRAMMAR_HPP diff --git a/include/mapnik/csv/csv_grammar_x3.hpp b/include/mapnik/csv/csv_grammar_x3.hpp new file mode 100644 index 000000000..26abba97f --- /dev/null +++ b/include/mapnik/csv/csv_grammar_x3.hpp @@ -0,0 +1,67 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_CSV_GRAMMAR_X3_HPP +#define MAPNIK_CSV_GRAMMAR_X3_HPP + +#include +#include +#include +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +struct csv_white_space_skipper : x3::parser +{ + using attribute_type = x3::unused_type; + static bool const has_attribute = false; + + template + bool parse(Iterator& first, Iterator const& last, + Context const& context, x3::unused_type, Attribute& ) const + { + x3::skip_over(first, last, context); + if (first != last && *first == ' ') + { + while (++first != last && *first == ' ') + ; + return true; + } + return false; + } +}; + +auto static const csv_white_space = csv_white_space_skipper{}; + +namespace grammar { + +struct separator_tag; +struct quote_tag; + +struct csv_line_class; +using csv_line_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(csv_line_grammar_type); + +}} + +#endif // MAPNIK_CSV_GRAMMAR_X3_HPP diff --git a/include/mapnik/csv/csv_grammar_x3_def.hpp b/include/mapnik/csv/csv_grammar_x3_def.hpp new file mode 100644 index 000000000..d284cbbce --- /dev/null +++ b/include/mapnik/csv/csv_grammar_x3_def.hpp @@ -0,0 +1,120 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_CSV_GRAMMAR_X3_DEF_HPP +#define MAPNIK_CSV_GRAMMAR_X3_DEF_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +namespace ascii = boost::spirit::x3::ascii; + +using x3::lit; +using x3::lexeme; +using ascii::char_; + +struct unesc_char_ : x3::symbols +{ + unesc_char_() + { + add("\\a", '\a') + ("\\b", '\b') + ("\\f", '\f') + ("\\n", '\n') + ("\\r", '\r') + ("\\t", '\t') + ("\\v", '\v') + ("\\\\",'\\') + ("\\\'", '\'') + ("\\\"", '\"') + ("\"\"", '\"') // double quote + ; + } +} unesc_char; + +template +struct literal : x3::parser> +{ + using attribute_type = x3::unused_type; + using context_tag = T; + static bool const has_attribute = false; + + template + bool parse(Iterator& first, Iterator const& last, + Context const& context, x3::unused_type, Attribute& ) const + { + x3::skip_over(first, last, context); + if (first != last && *first == x3::get(context)) + { + ++first; + return true; + } + return false; + } +}; + +auto static const separator = literal{}; +auto static const quote = literal{}; + +// starting rule +csv_line_grammar_type const line("csv-line"); +// rules +x3::rule column("csv-column"); +x3::rule text("csv-text"); +x3::rule quoted_text("csv-quoted-text"); + +auto const line_def = -lit('\r') > -lit('\n') > lexeme[column] % separator + ; + +auto const column_def = quoted_text | *(char_ - separator) + ; + +auto const quoted_text_def = quote > text > quote // support unmatched quotes or not (??) + ; + +auto const text_def = *(unesc_char | (char_ - quote)) + ; + +BOOST_SPIRIT_DEFINE ( + line, + column, + quoted_text, + text + ); + +} // grammar + +grammar::csv_line_grammar_type const& csv_line_grammar() +{ + return grammar::line; +} + +} // namespace mapnik + + +#endif // MAPNIK_CSV_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/csv/csv_types.hpp b/include/mapnik/csv/csv_types.hpp index 5359c3dd6..042f68968 100644 --- a/include/mapnik/csv/csv_types.hpp +++ b/include/mapnik/csv/csv_types.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/cxx11_support.hpp b/include/mapnik/cxx11_support.hpp new file mode 100644 index 000000000..dafd721dd --- /dev/null +++ b/include/mapnik/cxx11_support.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_CXX11_SUPPORT_HPP +#define MAPNIK_CXX11_SUPPORT_HPP + +#include + +namespace mapnik { +namespace detail { + +template +using conditional_t = typename std::conditional::type; + +template +using decay_t = typename std::decay::type; + +template +using enable_if_t = typename std::enable_if::type; + +} // namespace detail +} // namespace mapnik + +#endif // MAPNIK_CXX11_SUPPORT_HPP diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index ec14a621c..2917ab976 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -46,14 +46,11 @@ class MAPNIK_DECL datasource_exception : public std::exception public: datasource_exception(std::string const& message) : message_(message) - { - } + {} - ~datasource_exception() throw() - { - } + ~datasource_exception() {} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } @@ -69,8 +66,8 @@ public: Raster }; - datasource (parameters const& params) - : params_(params) {} + datasource (parameters const& _params) + : params_(_params) {} /*! * @brief Get the configuration parameters of the data source. diff --git a/include/mapnik/datasource_cache.hpp b/include/mapnik/datasource_cache.hpp index 4f90f8907..bd5b3310d 100644 --- a/include/mapnik/datasource_cache.hpp +++ b/include/mapnik/datasource_cache.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/datasource_geometry_type.hpp b/include/mapnik/datasource_geometry_type.hpp index 00e4b2af7..4d824b841 100644 --- a/include/mapnik/datasource_geometry_type.hpp +++ b/include/mapnik/datasource_geometry_type.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp index 84290958b..b841d81d5 100644 --- a/include/mapnik/debug.hpp +++ b/include/mapnik/debug.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/ellipsoid.hpp b/include/mapnik/ellipsoid.hpp index 6f872d4d4..b43a6dad9 100644 --- a/include/mapnik/ellipsoid.hpp +++ b/include/mapnik/ellipsoid.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/enumeration.hpp b/include/mapnik/enumeration.hpp index d57955b9f..c4b736025 100644 --- a/include/mapnik/enumeration.hpp +++ b/include/mapnik/enumeration.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,6 @@ #include // stl -#include #include #include #include @@ -45,9 +44,9 @@ public: what_( _what ) { } - virtual ~illegal_enum_value() throw() {} + virtual ~illegal_enum_value() {} - virtual const char * what() const throw() + virtual const char * what() const noexcept { return what_.c_str(); } @@ -190,6 +189,8 @@ public: for (unsigned i = 0; i < THE_MAX; ++i) { #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc +#pragma GCC diagnostic ignored "-Wpragmas" // gcc #pragma GCC diagnostic ignored "-Wundefined-var-template" if (str_copy == our_strings_[i]) #pragma GCC diagnostic pop @@ -203,6 +204,8 @@ public: } } #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc +#pragma GCC diagnostic ignored "-Wpragmas" // gcc #pragma GCC diagnostic ignored "-Wundefined-var-template" throw illegal_enum_value(std::string("Illegal enumeration value '") + str + "' for enum " + our_name_); @@ -213,6 +216,8 @@ public: std::string as_string() const { #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc +#pragma GCC diagnostic ignored "-Wpragmas" // gcc #pragma GCC diagnostic ignored "-Wundefined-var-template" return our_strings_[value_]; #pragma GCC diagnostic pop diff --git a/include/mapnik/evaluate_global_attributes.hpp b/include/mapnik/evaluate_global_attributes.hpp index 3e3d63cbd..a73ac1262 100644 --- a/include/mapnik/evaluate_global_attributes.hpp +++ b/include/mapnik/evaluate_global_attributes.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,8 +43,8 @@ struct evaluate_expression { using value_type = T; - explicit evaluate_expression(Attributes const& attributes) - : attributes_(attributes) {} + explicit evaluate_expression(Attributes const& attrs) + : attrs_(attrs) {} value_type operator() (attribute const&) const { @@ -53,8 +53,8 @@ struct evaluate_expression value_type operator() (global_attribute const& attr) const { - auto itr = attributes_.find(attr.name); - if (itr != attributes_.end()) + auto itr = attrs_.find(attr.name); + if (itr != attrs_.end()) { return itr->second; } @@ -129,7 +129,7 @@ struct evaluate_expression return value_type(val); } - Attributes const& attributes_; + Attributes const& attrs_; }; template @@ -221,7 +221,7 @@ struct evaluate_expression struct assign_value { template - static void apply(symbolizer_base::value_type & val, expression_ptr const& expr, Attributes const& attributes, property_types target ) + static void apply(symbolizer_base::value_type & val, expression_ptr const& expr, Attributes const& attrs, property_types target ) { switch (target) @@ -230,24 +230,24 @@ struct assign_value { // evaluate expression as a string then parse as css color std::string str = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_string(); + Attributes>(attrs),*expr).to_string(); try { val = parse_color(str); } catch (...) { val = color(0,0,0);} break; } case property_types::target_double: { - val = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_double(); + val = util::apply_visitor(mapnik::evaluate_expression(attrs),*expr).to_double(); break; } case property_types::target_integer: { - val = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_int(); + val = util::apply_visitor(mapnik::evaluate_expression(attrs),*expr).to_int(); break; } case property_types::target_bool: { - val = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_bool(); + val = util::apply_visitor(mapnik::evaluate_expression(attrs),*expr).to_bool(); break; } default: // no-op @@ -276,14 +276,14 @@ struct evaluate_global_attributes : util::noncopyable template struct evaluator { - evaluator(symbolizer_base::cont_type::value_type & prop, Attributes const& attributes) + evaluator(symbolizer_base::cont_type::value_type & prop, Attributes const& attrs) : prop_(prop), - attributes_(attributes) {} + attrs_(attrs) {} void operator() (expression_ptr const& expr) const { auto const& meta = get_meta(prop_.first); - assign_value::apply(prop_.second, expr, attributes_, std::get<2>(meta)); + assign_value::apply(prop_.second, expr, attrs_, std::get<2>(meta)); } template @@ -292,28 +292,28 @@ struct evaluate_global_attributes : util::noncopyable // no-op } symbolizer_base::cont_type::value_type & prop_; - Attributes const& attributes_; + Attributes const& attrs_; }; template struct extract_symbolizer { - extract_symbolizer(Attributes const& attributes) - : attributes_(attributes) {} + extract_symbolizer(Attributes const& attrs) + : attrs_(attrs) {} template void operator() (Symbolizer & sym) const { for (auto & prop : sym.properties) { - util::apply_visitor(evaluator(prop, attributes_), prop.second); + util::apply_visitor(evaluator(prop, attrs_), prop.second); } } - Attributes const& attributes_; + Attributes const& attrs_; }; template - static void apply(Map & m, Attributes const& attributes) + static void apply(Map & m, Attributes const& attrs) { for ( auto & val : m.styles() ) { @@ -321,7 +321,7 @@ struct evaluate_global_attributes : util::noncopyable { for (auto & sym : rule) { - util::apply_visitor(extract_symbolizer(attributes), sym); + util::apply_visitor(extract_symbolizer(attrs), sym); } } } diff --git a/include/mapnik/expression.hpp b/include/mapnik/expression.hpp index 7b9ca59e7..7b8f0c4f8 100644 --- a/include/mapnik/expression.hpp +++ b/include/mapnik/expression.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/expression_evaluator.hpp b/include/mapnik/expression_evaluator.hpp index 58b34486e..8b87a64e1 100644 --- a/include/mapnik/expression_evaluator.hpp +++ b/include/mapnik/expression_evaluator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #include #include diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp deleted file mode 100644 index ad35589bb..000000000 --- a/include/mapnik/expression_grammar.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_HPP -#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP - -// mapnik -#include -#include -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik -{ -namespace qi = boost::spirit::qi; -namespace standard_wide = boost::spirit::standard_wide; -using standard_wide::space_type; - -template -struct integer_parser -{ - using type = qi::int_parser; -}; - -struct unary_function_types : qi::symbols -{ - unary_function_types(); -}; - -struct binary_function_types : qi::symbols -{ - binary_function_types(); -}; - - -#ifdef __GNUC__ -template -struct MAPNIK_DECL expression_grammar : qi::grammar -#else -template -struct expression_grammar : qi::grammar -#endif -{ - using rule_type = qi::rule; - - explicit expression_grammar(std::string const& encoding = "utf-8"); - - qi::real_parser > strict_double; - typename integer_parser::type int__; - mapnik::transcoder tr_; - - rule_type expr; - rule_type equality_expr; - rule_type cond_expr; - rule_type relational_expr; - rule_type logical_expr; - rule_type additive_expr; - rule_type multiplicative_expr; - rule_type unary_expr; - rule_type not_expr; - rule_type primary_expr; - qi::rule unary_function_expr; - qi::rule binary_function_expr; - qi::rule regex_match_expr; - qi::rule, space_type> regex_replace_expr; - qi::rule attr; - qi::rule global_attr; - qi::rule > quoted_ustring; - qi::rule unquoted_ustring; - qi::rule ustring; - - qi::symbols unesc_char; - qi::rule quote_char; - qi::symbols constant; - unary_function_types unary_func_type; - binary_function_types binary_func_type; - -}; - -} // namespace - -#endif // MAPNIK_EXPRESSIONS_GRAMMAR_HPP diff --git a/include/mapnik/expression_grammar_impl.hpp b/include/mapnik/expression_grammar_impl.hpp deleted file mode 100644 index ad28f0135..000000000 --- a/include/mapnik/expression_grammar_impl.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// NOTE: This is an implementation header file and is only meant to be included -// from implementation files. It therefore doesn't have an include guard. - -// mapnik -#include -#include -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call, - (mapnik::unary_function_impl, fun) - (mapnik::unary_function_call::argument_type, arg)) - -BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call, - (mapnik::binary_function_impl, fun) - (mapnik::binary_function_call::argument_type, arg1) - (mapnik::binary_function_call::argument_type, arg2)) - -// fwd declare -namespace mapnik { - struct attribute; - struct geometry_type_attribute; -} - -namespace mapnik -{ - -struct unicode_impl -{ - using result_type = mapnik::value_unicode_string; - explicit unicode_impl(mapnik::transcoder const& tr) - : tr_(tr) {} - - mapnik::value_unicode_string operator()(std::string const& str) const - { - return tr_.transcode(str.c_str()); - } - - mapnik::transcoder const& tr_; -}; - -struct regex_match_impl -{ - using result_type = expr_node; - explicit regex_match_impl(mapnik::transcoder const& tr) - : tr_(tr) {} - - template - expr_node operator() (T0 & node, T1 const& pattern) const; - - mapnik::transcoder const& tr_; -}; - -struct regex_replace_impl -{ - using result_type = expr_node; - explicit regex_replace_impl(mapnik::transcoder const& tr) - : tr_(tr) {} - - template - expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const; - - mapnik::transcoder const& tr_; -}; - -unary_function_types::unary_function_types() -{ - add - ("sin", sin_impl()) - ("cos", cos_impl()) - ("tan", tan_impl()) - ("atan", atan_impl()) - ("exp", exp_impl()) - ("log", log_impl()) - ("abs", abs_impl()) - ("length",length_impl()) - ; -} - -binary_function_types::binary_function_types() -{ - add - ("min", binary_function_impl(min_impl)) - ("max", binary_function_impl(max_impl)) - ("pow", binary_function_impl(pow_impl)) - ; -} - -template -expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const -{ - return regex_match_node(tr_,node,pattern); -} - -template -expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const -{ - return regex_replace_node(tr_,node,pattern,format); -} - -template -expression_grammar::expression_grammar(std::string const& encoding) - : expression_grammar::base_type(expr), - tr_(encoding) -{ - qi::_1_type _1; - qi::_a_type _a; - qi::_b_type _b; - qi::_r1_type _r1; - qi::no_skip_type no_skip; - qi::_val_type _val; - qi::lit_type lit; - qi::double_type double_; - qi::hex_type hex; - qi::omit_type omit; - qi::alpha_type alpha; - qi::alnum_type alnum; - standard_wide::char_type char_; - standard_wide::no_case_type no_case; - using boost::phoenix::construct; - using boost::phoenix::if_else; - - boost::phoenix::function unicode = unicode_impl(tr_); - boost::phoenix::function regex_match = regex_match_impl(tr_); - boost::phoenix::function regex_replace = regex_replace_impl(tr_); - - constant.add - ("null", mapnik::value_null()) - ("false", mapnik::value_bool(false)) - ("true", mapnik::value_bool(true)) - ("point", mapnik::value_integer(1)) - ("linestring", mapnik::value_integer(2)) - ("polygon", mapnik::value_integer(3)) - ("collection", mapnik::value_integer(4)) - ("pi", mapnik::value_double(3.1415926535897932384626433832795)) - ("deg_to_rad", mapnik::value_double(0.017453292519943295769236907684886)) - ("rad_to_deg", mapnik::value_double(57.295779513082320876798154814105)) - ; - - expr = logical_expr [_val = _1] - //| ustring [_val = unicode(_1)] - ; - - logical_expr = not_expr [_val = _1] - >> - *( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] ) - | (( lit("or") | lit("||")) >> not_expr [_val || _1]) - ) - ; - - not_expr = - cond_expr [_val = _1 ] - | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ]) - ; - - cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1] - ; - - equality_expr = - relational_expr [_val = _1] - >> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1]) - | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1]) - ) - ; - - regex_match_expr = lit(".match") - >> lit('(') - >> quoted_ustring [_val = _1] - >> lit(')') - ; - - regex_replace_expr = - lit(".replace") - >> lit('(') - >> quoted_ustring [_a = _1] - >> lit(',') - >> quoted_ustring [_b = _1] - >> lit(')') [_val = regex_replace(_r1,_a,_b)] - ; - - relational_expr = additive_expr[_val = _1] - >> - *( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ]) - | ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ]) - | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ]) - | ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ]) - ) - ; - - additive_expr = multiplicative_expr [_val = _1] - >> * ( '+' >> multiplicative_expr[_val += _1] - | '-' >> multiplicative_expr[_val -= _1] - ) - ; - - multiplicative_expr = unary_expr [_val = _1] - >> *( '*' >> unary_expr [_val *= _1] - | '/' >> unary_expr [_val /= _1] - | '%' >> unary_expr [_val %= construct(_1)] //needed by clang++ with -std=c++11 - | regex_match_expr[_val = regex_match(_val, _1)] - | regex_replace_expr(_val) [_val = _1] - ) - ; - - unary_function_expr = unary_func_type >> '(' > logical_expr > ')' - ; - - binary_function_expr = binary_func_type >> '(' > logical_expr > ',' - > logical_expr > ')' - ; - - unary_expr = primary_expr [_val = _1] - | '+' >> primary_expr [_val = _1] - | '-' >> primary_expr [_val = -_1] - ; - - primary_expr = strict_double [_val = _1] - | int__[_val = _1] - | no_case[constant] [_val = _1] - | quoted_ustring [_val = unicode(_1)] - | attr [if_else(_1 == "mapnik::geometry_type", - _val = construct(), - _val = construct(_1))] - | global_attr [_val = construct( _1 )] - | unary_function_expr [_val = _1] - | binary_function_expr [_val = _1] - | '(' > logical_expr [_val = _1 ] > ')' - // TODO: this is a backward compatibility hack to allow unquoted strings - | unquoted_ustring [_val = unicode(_1)] - // ^ https://github.com/mapnik/mapnik/pull/3389 - ; - - unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n') - ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\') - ("\\\'", '\'')("\\\"", '\"') - ; - - ustring %= no_skip[alpha >> *alnum]; - quote_char %= char_('\'') | char_('"'); - quoted_ustring %= omit[quote_char[_a = _1]] - >> *(unesc_char | "\\x" >> hex | (char_ - lit(_a))) - >> lit(_a); - unquoted_ustring %= no_skip[alpha >> *alnum] - lit("not"); - attr %= '[' >> no_skip[+~char_(']')] >> ']'; - global_attr %= '@' >> no_skip[alpha >> * (alnum | char_('-'))]; - -} - -} diff --git a/include/mapnik/expression_grammar_x3.hpp b/include/mapnik/expression_grammar_x3.hpp new file mode 100644 index 000000000..ae3660c4f --- /dev/null +++ b/include/mapnik/expression_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct transcoder_tag; +struct expression_class; // top-most ID +using expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(expression_grammar_type); + +}} + + +namespace mapnik +{ +grammar::expression_grammar_type const& expression_grammar(); +} + + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/expression_grammar_x3_config.hpp b/include/mapnik/expression_grammar_x3_config.hpp new file mode 100644 index 000000000..6d79b3b82 --- /dev/null +++ b/include/mapnik/expression_grammar_x3_config.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP + +#include +#include +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using phrase_context_type = x3::phrase_parse_context::type; + +// define combined context +using context_type = x3::with_context const, + phrase_context_type>::type; + +}} + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP diff --git a/include/mapnik/expression_grammar_x3_def.hpp b/include/mapnik/expression_grammar_x3_def.hpp new file mode 100644 index 000000000..a7efe6173 --- /dev/null +++ b/include/mapnik/expression_grammar_x3_def.hpp @@ -0,0 +1,456 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call, + (mapnik::unary_function_impl, fun) + (mapnik::unary_function_call::argument_type, arg)) + +BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call, + (mapnik::binary_function_impl, fun) + (mapnik::binary_function_call::argument_type, arg1) + (mapnik::binary_function_call::argument_type, arg2)) + + +namespace mapnik { namespace grammar { + + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + using ascii::char_; + using ascii::string; + using x3::lit; + using x3::double_; + using x3::int_; + using x3::bool_; + using x3::_attr; + using x3::_val; + using x3::no_skip; + using x3::lexeme; + using x3::no_case; + using x3::alpha; + using x3::alnum; + x3::uint_parser const hex2 {}; + + namespace { + auto const& escaped_unicode = json::grammar::escaped_unicode; + } + + auto append = [](auto const& ctx) + { + _val(ctx) += _attr(ctx); + }; + + auto do_assign = [] (auto const& ctx) + { + _val(ctx) = std::move(_attr(ctx)); + }; + + auto do_negate = [] (auto const& ctx) + { + _val(ctx) = std::move(unary_node(_attr(ctx))); + }; + + auto do_attribute = [] (auto const& ctx) + { + auto & attr = _attr(ctx); + if (attr == "mapnik::geometry_type") + { + _val(ctx) = std::move(geometry_type_attribute()); + } + else + { + _val(ctx) = std::move(attribute(attr)); + } + }; + + auto do_global_attribute = [] (auto const& ctx) + { + _val(ctx) = std::move(global_attribute(_attr(ctx))); + }; + + auto do_add = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_subt = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_mult = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_div = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_mod = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_unicode = [] (auto const& ctx) + { + auto & tr = x3::get(ctx).get(); + _val(ctx) = std::move(tr.transcode(_attr(ctx).c_str())); + }; + + auto do_null = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::value_null()); + }; + + auto do_not = [] (auto const& ctx) + { + mapnik::unary_node node(_attr(ctx)); + _val(ctx) = std::move(node); + }; + + auto do_and = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_or = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_not_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_less = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_less_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_greater = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_greater_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + +// regex + auto do_regex_match = [] (auto const& ctx) + { + auto const& tr = x3::get(ctx).get(); + _val(ctx) = std::move(mapnik::regex_match_node(tr, std::move(_val(ctx)) , std::move(_attr(ctx)))); + }; + + auto do_regex_replace = [] (auto const& ctx) + { + auto const& tr = x3::get(ctx).get(); + auto const& pair = _attr(ctx); + auto const& pattern = std::get<0>(pair); + auto const& format = std::get<1>(pair); + _val(ctx) = mapnik::regex_replace_node(tr, _val(ctx) , pattern, format); + }; + +// mapnik::value_integer + auto const mapnik_int = x3::int_parser(); +// mapnik::value_double + auto const mapnik_double = x3::real_parser>(); +// mapnik::value_bool + struct boolean_ : x3::symbols + { + boolean_() + { + add + ("true", true) + ("false", false) + ; + } + } boolean; + + struct floating_point_constants : x3::symbols + { + floating_point_constants() + { + add + ("pi", 3.1415926535897932384626433832795) + ("deg_to_rad",0.017453292519943295769236907684886) + ("rad_to_deg",57.295779513082320876798154814105) + ; + } + } float_const; + +// unary functions + struct unary_function_types_ : x3::symbols + { + unary_function_types_() + { + add + ("sin", sin_impl()) + ("cos", cos_impl()) + ("tan", tan_impl()) + ("atan", atan_impl()) + ("exp", exp_impl()) + ("log", log_impl()) + ("abs", abs_impl()) + ("length",length_impl()) + ; + } + } unary_func_types ; + + +// binary functions + + struct binary_function_types_ : x3::symbols + { + binary_function_types_() + { + add + ("min", binary_function_impl(min_impl)) + ("max", binary_function_impl(max_impl)) + ("pow", binary_function_impl(pow_impl)) + ; + } + } binary_func_types; + +// geometry types + struct geometry_types_ : x3::symbols + { + geometry_types_() + { + add + ("point", 1) + ("linestring", 2) + ("polygon",3) + ("collection",4) + ; + } + } geometry_type; + + struct unesc_chars_ : x3::symbols + { + unesc_chars_() + { + add + ("\\a", '\a') + ("\\b", '\b') + ("\\f", '\f') + ("\\n", '\n') + ("\\r", '\r') + ("\\t", '\t') + ("\\v", '\v') + ("\\\\", '\\') + ("\\\'", '\'') + ("\\\"", '\"') + ; + } + } unesc_char; + // starting rule + expression_grammar_type const expression("expression"); + // rules + x3::rule const logical_expression("logical expression"); + x3::rule const not_expression("not expression"); + x3::rule const conditional_expression("conditional expression"); + x3::rule const equality_expression("equality expression"); + x3::rule const relational_expression("relational expression"); + x3::rule const additive_expression("additive expression"); + x3::rule const multiplicative_expression("multiplicative expression"); + x3::rule const unary_func_expression("unary function expression"); + x3::rule const binary_func_expression("binary function expression"); + x3::rule const unary_expression("unary expression"); + x3::rule const primary_expression("primary expression"); + x3::rule const regex_match_expression("regex match expression"); + x3::rule > const regex_replace_expression("regex replace expression"); + + // strings + auto const single_quoted_string = x3::rule {} = lit('\'') + >> no_skip[*(unesc_char[append] + | + //(lit('\\') > escaped_unicode[append]) // FIXME (!) + //| + (~char_('\''))[append])] > lit('\''); + + auto const double_quoted_string = x3::rule {} = lit('"') + >> no_skip[*(unesc_char[append] + | + (lit('\\') > escaped_unicode[append]) + | + (~char_('"'))[append])] > lit('"'); + + auto const quoted_string = x3::rule {} = single_quoted_string | double_quoted_string; + + auto const unquoted_ustring = x3::rule {} = no_skip[alpha > *alnum] - lit("not"); + + // start + auto const expression_def = logical_expression [do_assign] + ; + + auto const logical_expression_def = not_expression[do_assign] > + *(((lit("and") | lit("&&")) > not_expression[do_and]) + | + ((lit("or") | lit("||")) > not_expression[do_or])); + + auto const not_expression_def = conditional_expression[do_assign] + | + ((lit("not") | lit('!')) > conditional_expression[do_not]) + ; + + auto const conditional_expression_def = equality_expression[do_assign] + | + additive_expression[do_assign] + ; + + auto const equality_expression_def = relational_expression[do_assign] > + *( ( ( lit("=") | lit("eq") | lit("is")) > relational_expression [do_equal]) + | (( lit( "!=") | lit("<>") | lit("neq") ) > relational_expression [do_not_equal]) + ); + + auto const relational_expression_def = additive_expression[do_assign] > + *( ( (lit("<=") | lit("le")) > additive_expression [do_less_equal]) + | + ( (lit("<") | lit("lt")) >> additive_expression[do_less]) // allow backtracking to be able to handle '<' and '<>' correctly + | + ( (lit(">=") | lit("ge")) > additive_expression [do_greater_equal]) + | + ( (lit(">") | lit("gt")) > additive_expression [do_greater])); + + + auto const additive_expression_def = multiplicative_expression[do_assign] + > *( ('+' > multiplicative_expression[do_add]) + | + ('-' > multiplicative_expression[do_subt])); + + auto const feature_attr = lexeme['[' > +~char_(']') > ']']; + auto const global_attr = x3::rule {} = lexeme[lit('@') > char_("a-zA-Z_") > *char_("a-zA-Z0-9_")]; + + auto const regex_match_expression_def = lit(".match") > '(' > quoted_string > ')'; + auto const regex_replace_expression_def = lit(".replace") > '(' > quoted_string > ',' > quoted_string > ')'; + auto const multiplicative_expression_def = unary_expression [do_assign] + > *( ('*' > unary_expression [do_mult]) + | + ('/' > unary_expression [do_div]) + | + ('%' > unary_expression [do_mod]) + | + regex_match_expression[do_regex_match] + | + regex_replace_expression[do_regex_replace] + ); + + auto const unary_func_expression_def = unary_func_types > '(' > expression > ')'; + auto const binary_func_expression_def = binary_func_types > '(' > expression > ',' > expression > ')'; + + auto const unary_expression_def = + primary_expression[do_assign] + | + ('+' > primary_expression[do_assign]) + | + ('-' > primary_expression[do_negate]) + ; + + auto const primary_expression_def = + mapnik_double[do_assign] + | + mapnik_int[do_assign] + | + no_case[boolean][do_assign] + | + no_case["null"][do_null] + | + no_case[geometry_type][do_assign] + | + float_const[do_assign] + | + quoted_string[do_unicode] + | + feature_attr[do_attribute] + | + global_attr[do_global_attribute] + | + unary_func_expression[do_assign] + | + binary_func_expression[do_assign] + | + ('(' > logical_expression[do_assign] > ')') + | + unquoted_ustring[do_unicode] + // ^ https://github.com/mapnik/mapnik/pull/3389 + ; + + BOOST_SPIRIT_DEFINE ( + expression, + logical_expression, + not_expression, + conditional_expression, + equality_expression, + relational_expression, + additive_expression, + regex_match_expression, + regex_replace_expression, + multiplicative_expression, + unary_func_expression, + binary_func_expression, + unary_expression, + primary_expression + ); + + }} + +namespace mapnik +{ +grammar::expression_grammar_type const& expression_grammar() +{ + return grammar::expression; +} +} + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/expression_node.hpp b/include/mapnik/expression_node.hpp index 6fdad8f5f..9823fd05e 100644 --- a/include/mapnik/expression_node.hpp +++ b/include/mapnik/expression_node.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_EXPRESSION_NODE_HPP // mapnik -#include +#include #include #include #include @@ -59,6 +59,9 @@ template <> struct make_op { using type = std::logica template struct unary_node { + unary_node (expr_node && a) + : expr(std::move(a)) {} + unary_node (expr_node const& a) : expr(a) {} @@ -73,6 +76,10 @@ struct unary_node template struct binary_node { + binary_node(expr_node && a, expr_node && b) + : left(std::move(a)), + right(std::move(b)) {} + binary_node(expr_node const& a, expr_node const& b) : left(a), right(b) {} @@ -130,81 +137,6 @@ struct MAPNIK_DECL regex_replace_node std::shared_ptr<_regex_replace_impl> impl_; }; -inline expr_node & operator- (expr_node& expr) -{ - return expr = unary_node(expr); -} - -inline expr_node & operator += ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator -= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator *= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator /= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator %= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator < ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator <= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator > ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator >= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator == ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator != ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator ! (expr_node & expr) -{ - return expr = unary_node(expr); -} - -inline expr_node & operator && ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator || ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - } diff --git a/include/mapnik/expression_node_types.hpp b/include/mapnik/expression_node_types.hpp index 371274a4e..2db430486 100644 --- a/include/mapnik/expression_node_types.hpp +++ b/include/mapnik/expression_node_types.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include namespace mapnik diff --git a/include/mapnik/expression_string.hpp b/include/mapnik/expression_string.hpp index 6efc07e81..0a8a171da 100644 --- a/include/mapnik/expression_string.hpp +++ b/include/mapnik/expression_string.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/extend_converter.hpp b/include/mapnik/extend_converter.hpp new file mode 100644 index 000000000..a7ac187eb --- /dev/null +++ b/include/mapnik/extend_converter.hpp @@ -0,0 +1,232 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2015 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_EXTEND_CONVERTER_HPP +#define MAPNIK_EXTEND_CONVERTER_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +// stl +#include + +namespace mapnik +{ + +namespace detail +{ + +namespace msm = boost::msm; +namespace mpl = boost::mpl; +using namespace msm::front; + +template +T extend(T const & v1, T const & v2, double length) +{ + double dx = v2.x - v1.x; + double dy = v2.y - v1.y; + double l12 = std::sqrt(dx * dx + dy * dy); + double coef = 1.0 + length / l12; + return vertex2d(v1.x + dx * coef, + v1.y + dy * coef, v2.cmd); +} + +namespace events +{ + struct vertex_event + { + vertex_event(vertex2d const & vertex) : vertex(vertex) { } + vertex2d const & vertex; + }; + + struct move_to : vertex_event { using vertex_event::vertex_event; }; + struct line_to : vertex_event { using vertex_event::vertex_event; }; + struct close : vertex_event { using vertex_event::vertex_event; }; + struct end : vertex_event { using vertex_event::vertex_event; }; +} + +namespace actions +{ + struct store + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.v2 = m.v1; + m.v1 = e.vertex; + m.output = boost::none; + } + }; + + struct output + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.output = e.vertex; + } + }; + + struct store_and_output + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.v2 = m.v1; + m.v1 = e.vertex; + m.output = m.v2; + } + }; + + struct output_begin + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.v2 = m.v1; + m.v1 = e.vertex; + m.output = extend(m.v1, m.v2, m.extend_length); + } + }; + + struct output_end + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.output = extend(m.v2, m.v1, m.extend_length); + m.v1 = e.vertex; + } + }; +} + +struct extender_def : public msm::front::state_machine_def +{ + using no_exception_thrown = int; + using no_message_queue = int; + + struct initial : public msm::front::state<> { }; + struct vertex_one : public msm::front::state<> { }; + struct vertex_two : public msm::front::state<> { }; + struct end : public msm::front::state<> { }; + + using initial_state = initial; + + struct transition_table : mpl::vector< + // Start Event Next Action Guard + // +------------+-----------------+------------+--------------------+------+ + Row < initial , events::move_to , vertex_one , actions::store >, + Row < initial , events::line_to , vertex_one , actions::store >, + Row < initial , events::close , initial >, + Row < initial , events::end , end , actions::output >, + Row < vertex_one , events::move_to , vertex_one , actions::store_and_output >, + Row < vertex_one , events::line_to , vertex_two , actions::output_begin >, + Row < vertex_one , events::close , initial , actions::store_and_output >, + Row < vertex_one , events::end , end , actions::store_and_output >, + Row < vertex_two , events::move_to , vertex_one , actions::output_end >, + Row < vertex_two , events::line_to , vertex_two , actions::store_and_output >, + Row < vertex_two , events::close , initial , actions::output_end >, + Row < vertex_two , events::end , end , actions::output_end >, + Row < end , events::end , end , actions::output > + > {}; + + extender_def(double extend_length) + : extend_length(extend_length) + { + } + + boost::optional output; + vertex2d v1, v2; + double extend_length; +}; + +using extender = msm::back::state_machine; + +} + +template +struct extend_converter +{ + extend_converter(Geometry & geom) + : extend_converter(geom, 0) + {} + + extend_converter(Geometry & geom, double extend) + : geom_(geom), extender_(extend) + {} + + void set_extend(double extend) + { + extender_.extend_length = extend; + } + + unsigned vertex(double * x, double * y) + { + using namespace detail; + vertex2d v; + do + { + v.cmd = geom_.vertex(&v.x, &v.y); + switch (v.cmd) + { + case SEG_MOVETO: + extender_.process_event(events::move_to(v)); + break; + case SEG_LINETO: + extender_.process_event(events::line_to(v)); + break; + case SEG_CLOSE: + extender_.process_event(events::close(v)); + break; + case SEG_END: + extender_.process_event(events::end(v)); + break; + } + } while(!extender_.output); + + vertex2d const & output = *extender_.output; + *x = output.x; + *y = output.y; + return output.cmd; + } + + void rewind(unsigned) + { + geom_.rewind(0); + extender_.start(); + } + +private: + Geometry & geom_; + detail::extender extender_; +}; + +} + +#endif // MAPNIK_EXTEND_CONVERTER_HPP diff --git a/include/mapnik/factory.hpp b/include/mapnik/factory.hpp index 81f261320..69f62b8bf 100644 --- a/include/mapnik/factory.hpp +++ b/include/mapnik/factory.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp index 2812d0b3d..657cc906f 100644 --- a/include/mapnik/feature.hpp +++ b/include/mapnik/feature.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,11 +25,11 @@ // mapnik #include -#include +#include #include -#include +#include #include -#include +#include // #include #include @@ -105,7 +105,7 @@ public: : id_(_id), ctx_(ctx), data_(ctx_->mapping_.size()), - geom_(geometry::geometry_empty()), + geom_(geometry::geometry_empty()), raster_() {} inline mapnik::value_integer id() const { return id_;} @@ -208,6 +208,11 @@ public: return geom_; } + inline geometry::geometry & get_geometry() + { + return geom_; + } + inline box2d envelope() const { return mapnik::geometry::envelope(geom_); diff --git a/include/mapnik/feature_factory.hpp b/include/mapnik/feature_factory.hpp index c4a4d560e..4388ac1e7 100644 --- a/include/mapnik/feature_factory.hpp +++ b/include/mapnik/feature_factory.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include // boost //#include diff --git a/include/mapnik/feature_kv_iterator.hpp b/include/mapnik/feature_kv_iterator.hpp index 1def2e7c2..eb3402b37 100644 --- a/include/mapnik/feature_kv_iterator.hpp +++ b/include/mapnik/feature_kv_iterator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/feature_layer_desc.hpp b/include/mapnik/feature_layer_desc.hpp index cd69d831f..d8fcc4990 100644 --- a/include/mapnik/feature_layer_desc.hpp +++ b/include/mapnik/feature_layer_desc.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/feature_style_processor.hpp b/include/mapnik/feature_style_processor.hpp index c0ba4f383..4ae4fa9c0 100644 --- a/include/mapnik/feature_style_processor.hpp +++ b/include/mapnik/feature_style_processor.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,12 +24,13 @@ #define MAPNIK_FEATURE_STYLE_PROCESSOR_HPP // mapnik -#include +#include #include #include #include // stl +#include #include #include @@ -93,6 +94,12 @@ private: featureset_ptr features, proj_transform const& prj_trans); + void prepare_layers(layer_rendering_material & parent_mat, + std::vector const & layers, + feature_style_context_map & ctx_map, + Processor & p, + double scale_denom); + /*! * \brief prepare features for rendering asynchronously. */ @@ -111,6 +118,7 @@ private: * \brief render features list queued when they are available. */ void render_material(layer_rendering_material const & mat, Processor & p ); + void render_submaterials(layer_rendering_material const & mat, Processor & p); Map const& m_; }; diff --git a/include/mapnik/feature_style_processor_context.hpp b/include/mapnik/feature_style_processor_context.hpp index aca0c8f72..c1f1d7112 100644 --- a/include/mapnik/feature_style_processor_context.hpp +++ b/include/mapnik/feature_style_processor_context.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/feature_style_processor_impl.hpp b/include/mapnik/feature_style_processor_impl.hpp index 2fea9d8b3..981595147 100644 --- a/include/mapnik/feature_style_processor_impl.hpp +++ b/include/mapnik/feature_style_processor_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -63,6 +63,7 @@ struct layer_rendering_material std::vector active_styles_; std::vector featureset_ptr_list_; std::vector rule_caches_; + std::vector materials_; layer_rendering_material(layer const& lay, projection const& dest) : @@ -84,6 +85,41 @@ feature_style_processor::feature_style_processor(Map const& m, double } } +template +void feature_style_processor::prepare_layers(layer_rendering_material & parent_mat, + std::vector const & layers, + feature_style_context_map & ctx_map, + Processor & p, + double scale_denom) +{ + for (layer const& lyr : layers) + { + if (lyr.visible(scale_denom)) + { + std::set names; + layer_rendering_material mat(lyr, parent_mat.proj0_); + + prepare_layer(mat, + ctx_map, + p, + m_.scale(), + scale_denom, + m_.width(), + m_.height(), + m_.get_current_extent(), + m_.buffer_size(), + names); + + // Store active material + if (!mat.active_styles_.empty()) + { + prepare_layers(mat, lyr.layers(), ctx_map, p, scale_denom); + parent_mat.materials_.emplace_back(std::move(mat)); + } + } + } +} + template void feature_style_processor::apply(double scale_denom) { @@ -101,44 +137,16 @@ void feature_style_processor::apply(double scale_denom) // in a second time, we fetch the results and // do the actual rendering - std::vector mat_list; - // Define processing context map used by datasources // implementing asynchronous queries feature_style_context_map ctx_map; - for ( layer const& lyr : m_.layers() ) + if (!m_.layers().empty()) { - if (lyr.visible(scale_denom)) - { - std::set names; - layer_rendering_material mat(lyr, proj); + layer_rendering_material root_mat(m_.layers().front(), proj); + prepare_layers(root_mat, m_.layers(), ctx_map, p, scale_denom); - prepare_layer(mat, - ctx_map, - p, - m_.scale(), - scale_denom, - m_.width(), - m_.height(), - m_.get_current_extent(), - m_.buffer_size(), - names); - - // Store active material - if (!mat.active_styles_.empty()) - { - mat_list.emplace_back(std::move(mat)); - } - } - } - - for ( layer_rendering_material const & mat : mat_list ) - { - if (!mat.active_styles_.empty()) - { - render_material(mat, p); - } + render_submaterials(root_mat, p); } p.end_map_processing(m_); @@ -201,9 +209,12 @@ void feature_style_processor::apply_to_layer(layer const& lay, buffer_size, names); + prepare_layers(mat, lay.layers(), ctx_map, p, scale_denom); + if (!mat.active_styles_.empty()) { render_material(mat,p); + render_submaterials(mat, p); } } @@ -368,10 +379,10 @@ void feature_style_processor::prepare_layer(layer_rendering_material continue; } - std::vector const& rules = style->get_rules(); + std::vector const& style_rules = style->get_rules(); bool active_rules = false; rule_cache rc; - for(rule const& r : rules) + for(rule const& r : style_rules) { if (r.active(scale_denom)) { @@ -441,10 +452,27 @@ void feature_style_processor::prepare_layer(layer_rendering_material } } +template +void feature_style_processor::render_submaterials(layer_rendering_material const & parent_mat, + Processor & p) +{ + for (layer_rendering_material const & mat : parent_mat.materials_) + { + if (!mat.active_styles_.empty()) + { + p.start_layer_processing(mat.lay_, mat.layer_ext2_); + + render_material(mat, p); + render_submaterials(mat, p); + + p.end_layer_processing(mat.lay_); + } + } +} template void feature_style_processor::render_material(layer_rendering_material const & mat, - Processor & p ) + Processor & p) { std::vector const & active_styles = mat.active_styles_; std::vector const & featureset_ptr_list = mat.featureset_ptr_list_; @@ -460,8 +488,6 @@ void feature_style_processor::render_material(layer_rendering_materia return; } - p.start_layer_processing(mat.lay_, mat.layer_ext2_); - layer const& lay = mat.lay_; std::vector const & rule_caches = mat.rule_caches_; @@ -555,7 +581,6 @@ void feature_style_processor::render_material(layer_rendering_materia ++i; } } - p.end_layer_processing(mat.lay_); } template diff --git a/include/mapnik/feature_type_style.hpp b/include/mapnik/feature_type_style.hpp index 9f9f1aec9..5341b2fdb 100644 --- a/include/mapnik/feature_type_style.hpp +++ b/include/mapnik/feature_type_style.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/featureset.hpp b/include/mapnik/featureset.hpp index a6ad4e85d..579bf6ffe 100644 --- a/include/mapnik/featureset.hpp +++ b/include/mapnik/featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/filter_factory.hpp b/include/mapnik/filter_factory.hpp deleted file mode 100644 index 68d729a6c..000000000 --- a/include/mapnik/filter_factory.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// TODO - remove this file at mapnik 3.x -#ifdef _MSC_VER -#pragma NOTE("filter_factory.hpp" is now called "expression.hpp") -#else -#warning "filter_factory.hpp" is now called "expression.hpp" -#endif - -#include diff --git a/include/mapnik/filter_featureset.hpp b/include/mapnik/filter_featureset.hpp index ee3fa4087..a4bf5d299 100644 --- a/include/mapnik/filter_featureset.hpp +++ b/include/mapnik/filter_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 73227cdbf..a4ca09642 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/font_set.hpp b/include/mapnik/font_set.hpp index 5df8e35df..6e1366559 100644 --- a/include/mapnik/font_set.hpp +++ b/include/mapnik/font_set.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/function_call.hpp b/include/mapnik/function_call.hpp index f50829bd6..68f102129 100644 --- a/include/mapnik/function_call.hpp +++ b/include/mapnik/function_call.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -47,7 +47,6 @@ struct exp_impl { return std::exp(val.to_double()); } - }; // log @@ -58,7 +57,6 @@ struct log_impl { return std::log(val.to_double()); } - }; // sin @@ -102,7 +100,7 @@ struct abs_impl { value_type operator() (value_type const& val) const { - return std::fabs(val.to_double()); + return std::abs(val.to_double()); } }; diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index 7dbe51ff4..da2b0f4e1 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,10 +24,10 @@ #define MAPNIK_GEOM_UTIL_HPP // mapnik -#include +#include #include #include -#include +#include // stl #include #include diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 3f5d2aabd..eb0505a82 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,14 +43,10 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct geometry_collection; -template -struct geometry_empty -{ - using coordinate_type = T; -}; +struct geometry_empty {}; template -using geometry_base = mapnik::util::variant, +using geometry_base = mapnik::util::variant, line_string, polygon, diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry/boost_adapters.hpp similarity index 66% rename from include/mapnik/geometry_adapters.hpp rename to include/mapnik/geometry/boost_adapters.hpp index 770cb630c..63f135aea 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry/boost_adapters.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2017 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,9 @@ * *****************************************************************************/ -#ifndef MAPNIK_GEOMETRY_ADAPTERS_HPP -#define MAPNIK_GEOMETRY_ADAPTERS_HPP + +#ifndef MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP +#define MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP #include @@ -29,63 +30,77 @@ #pragma GCC diagnostic push #include #undef B0 -#include +#include #include #include -// NOTE: ideally we would not include all of boost/geometry here to save on compile time -// however we need to pull in for things to work -// and once we do that the compile time is == to just including boost/geometry.hpp -#include +#include #pragma GCC diagnostic pop -#include +// mapnik #include #include -#include -#include +#include -// register point -BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, double, boost::geometry::cs::cartesian, x, y) -BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, std::int64_t, boost::geometry::cs::cartesian, x, y) -// ring +BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::geometry::point, double, boost::geometry::cs::cartesian, x, y) +BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(mapnik::geometry::line_string) BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring) -// needed by box2d +// needed by box2d BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y) -namespace boost { +namespace mapnik { template -struct range_iterator > +struct interior_rings { - using type = typename mapnik::geometry::line_string::iterator; + using polygon_type = mapnik::geometry::polygon; + using iterator = typename polygon_type::iterator; + using const_iterator = typename polygon_type::const_iterator; + using value_type = typename polygon_type::value_type; + + interior_rings(polygon_type & poly) + : poly_(poly) {} + + iterator begin() + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + + iterator end() { return poly_.end();} + const_iterator begin() const + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + + const_iterator end() const { return poly_.end();} + + void clear() + { + poly_.resize(1); + } + + void resize(std::size_t size) + { + poly_.resize(size + 1); + } + + std::size_t size() const + { + return poly_.empty() ? 0 : poly_.size() - 1; + } + + void push_back(value_type const& val) { poly_.push_back(val); } + value_type& back() { return poly_.back(); } + value_type const& back() const { return poly_.back(); } + polygon_type & poly_; }; -template -struct range_const_iterator > -{ - using type = typename mapnik::geometry::line_string::const_iterator; -}; +} // ns mapnik -template -inline typename mapnik::geometry::line_string::iterator -range_begin(mapnik::geometry::line_string & line) {return line.begin();} +namespace boost { namespace geometry { namespace traits { -template -inline typename mapnik::geometry::line_string::iterator -range_end(mapnik::geometry::line_string & line) {return line.end();} - -template -inline typename mapnik::geometry::line_string::const_iterator -range_begin(mapnik::geometry::line_string const& line) {return line.begin();} - -template -inline typename mapnik::geometry::line_string::const_iterator -range_end(mapnik::geometry::line_string const& line) {return line.end();} - -namespace geometry { - -namespace traits { - -// register mapnik::box2d template<> struct tag > { using type = box_tag; }; template<> struct point_type > { using type = mapnik::coord2d; }; @@ -121,14 +136,6 @@ struct indexed_access, max_corner, 1> static inline void set(mapnik::box2d &b , ct const& value) { b.set_maxy(value); } }; -// mapnik::geometry::line_string -template -struct tag > -{ - using type = linestring_tag; -}; - -// mapnik::geometry::polygon template struct tag > { @@ -176,16 +183,15 @@ struct ring_mutable_type > template struct interior_const_type > { - using type = typename mapnik::geometry::polygon::interior_rings const&; + using type = typename mapnik::interior_rings const; }; template struct interior_mutable_type > { - using type = typename mapnik::geometry::polygon::interior_rings& ; + using type = typename mapnik::interior_rings ; }; -// exterior template struct exterior_ring > { @@ -193,13 +199,13 @@ struct exterior_ring > using ring_mutable_type = typename ring_mutable_type >::type; static ring_mutable_type get(mapnik::geometry::polygon & p) { - if (p.empty()) throw std::runtime_error("ring must be initialized 1"); + if (p.empty()) p.resize(1); return p[0]; } static ring_const_type get(mapnik::geometry::polygon const& p) { - if (p.empty()) throw std::runtime_error("ring must be initialized 2"); + if (p.empty()) throw std::runtime_error("Exterior ring must be initialized!"); return p[0]; } }; @@ -212,16 +218,15 @@ struct interior_rings > static interior_const_type get(mapnik::geometry::polygon const& p) { - return p.interior(); + return mapnik::interior_rings(const_cast&>(p)); } static interior_mutable_type get(mapnik::geometry::polygon& p) { - return p.interior(); + return mapnik::interior_rings(p); } }; }}} - -#endif //MAPNIK_GEOMETRY_ADAPTERS_HPP +#endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP diff --git a/include/mapnik/geometry/boost_spirit_karma_adapter.hpp b/include/mapnik/geometry/boost_spirit_karma_adapter.hpp new file mode 100644 index 000000000..8182e6e57 --- /dev/null +++ b/include/mapnik/geometry/boost_spirit_karma_adapter.hpp @@ -0,0 +1,121 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + + +#ifndef MAPNIK_BOOST_SPIRIT_KARMA_ADAPTER_HPP +#define MAPNIK_BOOST_SPIRIT_KARMA_ADAPTER_HPP + +#include + +namespace boost { using mapbox::util::get; } + +#include +#include + +namespace boost { namespace spirit { namespace traits +{ +template <> +struct not_is_variant, karma::domain> + : mpl::false_ +{}; + +template <> +struct not_is_variant, karma::domain> + : mpl::false_ +{}; + +template <> +struct variant_which< mapnik::geometry::geometry > +{ + static int call(mapnik::geometry::geometry const& v) + { + return v.which(); + } +}; + +template <> +struct variant_which< mapnik::geometry::geometry > +{ + static int call(mapnik::geometry::geometry const& v) + { + return v.which(); + } +}; + +namespace detail { + +template +struct has_type; + +template +struct has_type> : std::false_type {}; + +template +struct has_type> : has_type> {}; + +template +struct has_type> : std::true_type {}; + +template +struct index; + +template +struct index> +{ + static const std::size_t value = 0; +}; + +template +struct index> +{ + static const std::size_t value = 1 + index>::value; +}; + +} + +template +struct compute_compatible_component_variant, Expected> + : detail::has_type::types> +{ + using compatible_type = Expected; + static bool is_compatible(int index) + { + return (index == detail::index::types>::value); + } +}; + +template +struct compute_compatible_component_variant, Expected> + : detail::has_type::types> +{ + using compatible_type = Expected; + static bool is_compatible(int index) + { + return (index == detail::index::types>::value); + } +}; + +}}} + + + +#endif //MAPNIK_BOOST_SPIRIT_KARMA_ADAPTER_HPP diff --git a/include/mapnik/box2d.hpp b/include/mapnik/geometry/box2d.hpp similarity index 98% rename from include/mapnik/box2d.hpp rename to include/mapnik/geometry/box2d.hpp index 267120111..f9f59ba28 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/geometry/box2d.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,11 +51,11 @@ template class MAPNIK_DECL box2d public: using value_type = T; using box2d_type = box2d; -private: T minx_; T miny_; T maxx_; T maxy_; +private: friend inline void swap(box2d_type & lhs, box2d_type & rhs) { using std::swap; @@ -116,6 +116,7 @@ public: bool valid() const; void move(T x, T y); std::string to_string() const; + T area() const; // define some operators box2d_type& operator+=(box2d_type const& other); diff --git a/include/mapnik/box2d_impl.hpp b/include/mapnik/geometry/box2d_impl.hpp similarity index 89% rename from include/mapnik/box2d_impl.hpp rename to include/mapnik/geometry/box2d_impl.hpp index 7f3e9d1e7..dccc8d270 100644 --- a/include/mapnik/box2d_impl.hpp +++ b/include/mapnik/geometry/box2d_impl.hpp @@ -21,7 +21,7 @@ *****************************************************************************/ // mapnik -#include +#include #include // stl @@ -33,24 +33,35 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include +#include #pragma GCC diagnostic pop // agg #include "agg_trans_affine.h" -BOOST_FUSION_ADAPT_TPL_ADT( +BOOST_FUSION_ADAPT_TPL_STRUCT( (T), (mapnik::box2d)(T), - (T, T, obj.minx(), obj.set_minx(mapnik::safe_cast(val))) - (T, T, obj.miny(), obj.set_miny(mapnik::safe_cast(val))) - (T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast(val))) - (T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast(val)))) + (T, minx_), + (T, miny_), + (T, maxx_), + (T, maxy_)) -namespace mapnik +namespace mapnik { namespace detail { namespace { + +template +struct assign { + template + void operator() (Context & ctx) const + { + _val(ctx) = safe_cast(_attr(ctx)); + } +}; +} // anonymous +} // detail + template box2d::box2d() :minx_( std::numeric_limits::max()), @@ -61,13 +72,13 @@ box2d::box2d() template box2d::box2d(T minx,T miny,T maxx,T maxy) { - init(minx,miny,maxx,maxy); + init(minx, miny, maxx, maxy); } template box2d::box2d(coord const& c0, coord const& c1) { - init(c0.x,c0.y,c1.x,c1.y); + init(c0.x, c0.y, c1.x, c1.y); } template @@ -350,12 +361,15 @@ void box2d::pad(T padding) template bool box2d::from_string(std::string const& str) { - boost::spirit::qi::lit_type lit; - boost::spirit::qi::double_type double_; - boost::spirit::ascii::space_type space; - bool r = boost::spirit::qi::phrase_parse(str.begin(), + using boost::spirit::x3::lit; + boost::spirit::x3::double_type double_; + boost::spirit::x3::ascii::space_type space; + bool r = boost::spirit::x3::phrase_parse(str.begin(), str.end(), - double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_, + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()], space, *this); return r; @@ -393,6 +407,11 @@ std::string box2d::to_string() const return s.str(); } +template +T box2d::area() const +{ + return width() * height(); +} template box2d& box2d::operator+=(box2d const& other) diff --git a/include/mapnik/geometry_centroid.hpp b/include/mapnik/geometry/centroid.hpp similarity index 94% rename from include/mapnik/geometry_centroid.hpp rename to include/mapnik/geometry/centroid.hpp index c88588fba..3608d95ce 100644 --- a/include/mapnik/geometry_centroid.hpp +++ b/include/mapnik/geometry/centroid.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,10 +24,10 @@ #define MAPNIK_GEOMETRY_CENTROID_HPP #include -#include +#include #include -#include -#include +#include +#include namespace mapnik { namespace geometry { @@ -47,7 +47,7 @@ struct geometry_centroid return util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const&) const + result_type operator() (geometry_empty const&) const { return false; } diff --git a/include/mapnik/geometry_correct.hpp b/include/mapnik/geometry/correct.hpp similarity index 96% rename from include/mapnik/geometry_correct.hpp rename to include/mapnik/geometry/correct.hpp index 673250c0c..42bdf1826 100644 --- a/include/mapnik/geometry_correct.hpp +++ b/include/mapnik/geometry/correct.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_CORRECT_HPP #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/geometry_envelope.hpp b/include/mapnik/geometry/envelope.hpp similarity index 94% rename from include/mapnik/geometry_envelope.hpp rename to include/mapnik/geometry/envelope.hpp index 1621fd22f..d42d517a7 100644 --- a/include/mapnik/geometry_envelope.hpp +++ b/include/mapnik/geometry/envelope.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_ENVELOPE_HPP #include -#include +#include namespace mapnik { namespace geometry { diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry/envelope_impl.hpp similarity index 94% rename from include/mapnik/geometry_envelope_impl.hpp rename to include/mapnik/geometry/envelope_impl.hpp index 692481131..b6cf47403 100644 --- a/include/mapnik/geometry_envelope_impl.hpp +++ b/include/mapnik/geometry/envelope_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,9 @@ * *****************************************************************************/ -#include +#include #include -#include +#include namespace mapnik { namespace geometry { @@ -44,7 +44,7 @@ struct geometry_envelope return mapnik::util::apply_visitor(*this, geom); } - void operator() (mapnik::geometry::geometry_empty const&) const {} + void operator() (mapnik::geometry::geometry_empty const&) const {} void operator() (mapnik::geometry::point const& pt) const { diff --git a/include/mapnik/geometry_fusion_adapted.hpp b/include/mapnik/geometry/fusion_adapted.hpp similarity index 98% rename from include/mapnik/geometry_fusion_adapted.hpp rename to include/mapnik/geometry/fusion_adapted.hpp index 8430d4f48..3abdb478c 100644 --- a/include/mapnik/geometry_fusion_adapted.hpp +++ b/include/mapnik/geometry/fusion_adapted.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/geometry_type.hpp b/include/mapnik/geometry/geometry_type.hpp similarity index 94% rename from include/mapnik/geometry_type.hpp rename to include/mapnik/geometry/geometry_type.hpp index c0055c5b4..a5a4658a5 100644 --- a/include/mapnik/geometry_type.hpp +++ b/include/mapnik/geometry/geometry_type.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include namespace mapnik { namespace geometry { namespace detail { @@ -37,7 +37,7 @@ struct geometry_type return mapnik::util::apply_visitor(*this, geom); } - mapnik::geometry::geometry_types operator() (geometry_empty const& ) const + mapnik::geometry::geometry_types operator() (geometry_empty const& ) const { return mapnik::geometry::geometry_types::Unknown; } diff --git a/include/mapnik/geometry_types.hpp b/include/mapnik/geometry/geometry_types.hpp similarity index 97% rename from include/mapnik/geometry_types.hpp rename to include/mapnik/geometry/geometry_types.hpp index 8c4d67722..a4f00c287 100644 --- a/include/mapnik/geometry_types.hpp +++ b/include/mapnik/geometry/geometry_types.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/geometry/is_empty.hpp b/include/mapnik/geometry/is_empty.hpp new file mode 100644 index 000000000..206fb185c --- /dev/null +++ b/include/mapnik/geometry/is_empty.hpp @@ -0,0 +1,173 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_IS_EMPTY_HPP +#define MAPNIK_GEOMETRY_IS_EMPTY_HPP + +#include + +namespace mapnik { namespace geometry { + +namespace detail { + +struct geometry_is_empty +{ + bool operator() (mapnik::geometry::geometry const& geom) const + { + return mapnik::util::apply_visitor(*this, geom); + } + + bool operator() (mapnik::geometry::point const&) const + { + return false; + } + + bool operator() (mapnik::geometry::line_string const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::polygon const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::multi_point const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::multi_line_string const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::multi_polygon const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::geometry_collection const& geom) const + { + return geom.empty(); + } + + template + bool operator() (T const&) const + { + return true; + } + +}; + +struct geometry_has_empty +{ + bool operator() (mapnik::geometry::geometry const& geom) const + { + return mapnik::util::apply_visitor(*this, geom); + } + + bool operator() (mapnik::geometry::geometry_empty const&) const + { + return false; + } + + bool operator() (mapnik::geometry::point const&) const + { + return false; + } + + bool operator() (mapnik::geometry::line_string const&) const + { + return false; + } + + bool operator() (mapnik::geometry::polygon const&) const + { + return false; + } + + bool operator() (mapnik::geometry::multi_point const&) const + { + return false; + } + + bool operator() (mapnik::geometry::multi_line_string const& geom) const + { + return test_multigeometry(geom); + } + + bool operator() (mapnik::geometry::multi_polygon const& geom) const + { + return test_multigeometry(geom); + } + + bool operator() (mapnik::geometry::geometry_collection const& geom) const + { + for (auto const & item : geom) + { + if (geometry_is_empty()(item) || (*this)(item)) + { + return true; + } + } + return false; + } + + template + bool operator() (T const&) const + { + return true; + } + +private: + template + bool test_multigeometry(T const & geom) const + { + for (auto const & item : geom) + { + if (item.empty()) + { + return true; + } + } + return false; + } +}; + +} + +template +inline bool is_empty(GeomType const& geom) +{ + return detail::geometry_is_empty()(geom); +} + +template +inline bool has_empty(GeomType const& geom) +{ + return detail::geometry_has_empty()(geom); +} + +}} + +#endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP diff --git a/include/mapnik/geometry_is_simple.hpp b/include/mapnik/geometry/is_simple.hpp similarity index 88% rename from include/mapnik/geometry_is_simple.hpp rename to include/mapnik/geometry/is_simple.hpp index 68953ca1f..c8df58e2d 100644 --- a/include/mapnik/geometry_is_simple.hpp +++ b/include/mapnik/geometry/is_simple.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,30 +29,31 @@ #if BOOST_VERSION >= 105600 #include -#include +#include #include namespace mapnik { namespace geometry { namespace detail { -template struct geometry_is_simple { using result_type = bool; + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { // An empty geometry has no anomalous geometric points, such as self intersection or self tangency. // Therefore, we will return true return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -62,11 +63,12 @@ struct geometry_is_simple return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_simple(pt); } - + template result_type operator() (line_string const& line) const { if (line.empty()) @@ -78,12 +80,12 @@ struct geometry_is_simple } return boost::geometry::is_simple(line); } - + template result_type operator() (polygon const& poly) const { - return poly.empty() ? true : boost::geometry::is_simple(poly); + return boost::geometry::is_simple(poly); } - + template result_type operator() (multi_point const& multi_pt) const { if (multi_pt.empty()) @@ -94,7 +96,7 @@ struct geometry_is_simple } return boost::geometry::is_simple(multi_pt); } - + template result_type operator() (multi_line_string const& multi_line) const { if (multi_line.empty()) @@ -109,7 +111,7 @@ struct geometry_is_simple } return true; } - + template result_type operator() (multi_polygon const& multi_poly) const { if (multi_poly.empty()) @@ -132,14 +134,13 @@ struct geometry_is_simple template inline bool is_simple(T const& geom) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_simple() (geom); + return detail::geometry_is_simple() (geom); } template inline bool is_simple(mapnik::geometry::geometry const& geom) { - return util::apply_visitor(detail::geometry_is_simple(), geom); + return util::apply_visitor(detail::geometry_is_simple(), geom); } }} diff --git a/include/mapnik/geometry_is_valid.hpp b/include/mapnik/geometry/is_valid.hpp similarity index 82% rename from include/mapnik/geometry_is_valid.hpp rename to include/mapnik/geometry/is_valid.hpp index fbaef63c4..9fb17b192 100644 --- a/include/mapnik/geometry_is_valid.hpp +++ b/include/mapnik/geometry/is_valid.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +29,7 @@ #if BOOST_VERSION >= 105800 #include -#include +#include #include #include @@ -37,21 +37,22 @@ namespace mapnik { namespace geometry { namespace detail { -template struct geometry_is_valid { using result_type = bool; + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -61,38 +62,43 @@ struct geometry_is_valid return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt); } + template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line); } + template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly); } + template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt); } + template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line); } + template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly); } }; -template struct geometry_is_valid_reason { using result_type = bool; @@ -102,17 +108,19 @@ struct geometry_is_valid_reason geometry_is_valid_reason(boost::geometry::validity_failure_type & failure): failure_(failure) {} + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { failure_ = boost::geometry::no_failure; return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -122,38 +130,43 @@ struct geometry_is_valid_reason return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt, failure_); } + template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line, failure_); } + template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly, failure_); } + template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt, failure_); } + template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line, failure_); } + template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly, failure_); } }; -template struct geometry_is_valid_string { using result_type = bool; @@ -163,17 +176,19 @@ struct geometry_is_valid_string geometry_is_valid_string(std::string & message): message_(message) {} + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { message_ = "Geometry is valid"; return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -183,78 +198,82 @@ struct geometry_is_valid_string return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt, message_); } + template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line, message_); } + template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly, message_); } + template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt, message_); } + template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line, message_); } + template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly, message_); } }; + } template inline bool is_valid(T const& geom) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_valid() (geom); + return detail::geometry_is_valid() (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom) { - return util::apply_visitor(detail::geometry_is_valid(), geom); + return util::apply_visitor(detail::geometry_is_valid(), geom); } template inline bool is_valid(T const& geom, boost::geometry::validity_failure_type & failure) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_valid_reason(failure) (geom); + return detail::geometry_is_valid_reason(failure) (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom, boost::geometry::validity_failure_type & failure) { - return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom); + return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom); } template inline bool is_valid(T const& geom, std::string & message) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_valid_string(message) (geom); + return detail::geometry_is_valid_string(message) (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom, std::string & message) { - return util::apply_visitor(detail::geometry_is_valid_string(message), geom); + return util::apply_visitor(detail::geometry_is_valid_string(message), geom); } }} diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index 0840fd000..efb65e60f 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -32,80 +32,7 @@ template using linear_ring = mapbox::geometry::linear_ring; template -struct polygon : mapbox::geometry::polygon -{ - using coordinate_type = T; - using base_type = mapbox::geometry::polygon; - using linear_ring_type = linear_ring; - struct interior_rings - { - using iterator = typename base_type::iterator; - using const_iterator = typename base_type::const_iterator; - using value_type = typename base_type::value_type; - interior_rings(polygon & poly) - : poly_(poly) {} - iterator begin() - { - auto itr = poly_.begin(); - std::advance(itr, 1); - return itr; - } - - iterator end() { return poly_.end();} - const_iterator begin() const - { - auto itr = poly_.begin(); - std::advance(itr, 1); - return itr; - } - const_iterator end() const { return poly_.end();} - - void clear() - { - poly_.resize(1); - } - - void resize(std::size_t size) - { - poly_.resize(size + 1); - } - - std::size_t size() const - { - return poly_.empty() ? 0 : poly_.size() - 1; - } - - void push_back(value_type const& val) { poly_.push_back(val); } - value_type& back() { return poly_.back(); } - value_type const& back() const { return poly_.back(); } - polygon & poly_; - }; - - polygon() - : base_type(), - interior_(*this) - { - //this->resize(1); // explicit exterior ring ? - } - - polygon(polygon && other) - : base_type(std::move(other)), - interior_(*this) {} - - polygon(polygon const& other) - : base_type(other), - interior_(*this) {} - - interior_rings const& interior() const - { - return interior_; - } - interior_rings & interior() - { - return interior_; - } - interior_rings interior_; -}; +using polygon = mapbox::geometry::polygon; }} diff --git a/include/mapnik/geometry_remove_empty.hpp b/include/mapnik/geometry/remove_empty.hpp similarity index 96% rename from include/mapnik/geometry_remove_empty.hpp rename to include/mapnik/geometry/remove_empty.hpp index de60d9869..7ae365235 100644 --- a/include/mapnik/geometry_remove_empty.hpp +++ b/include/mapnik/geometry/remove_empty.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_REMOVE_EMPTY_HPP #include -#include +#include namespace mapnik { namespace geometry { diff --git a/include/mapnik/geometry_reprojection.hpp b/include/mapnik/geometry/reprojection.hpp similarity index 98% rename from include/mapnik/geometry_reprojection.hpp rename to include/mapnik/geometry/reprojection.hpp index 22a334e61..a8b82860b 100644 --- a/include/mapnik/geometry_reprojection.hpp +++ b/include/mapnik/geometry/reprojection.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/geometry_reprojection_impl.hpp b/include/mapnik/geometry/reprojection_impl.hpp similarity index 95% rename from include/mapnik/geometry_reprojection_impl.hpp rename to include/mapnik/geometry/reprojection_impl.hpp index d76e84081..f4903613e 100644 --- a/include/mapnik/geometry_reprojection_impl.hpp +++ b/include/mapnik/geometry/reprojection_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2017 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,10 +29,10 @@ namespace geometry { namespace detail { -template -geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) +//template +geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) { - return geometry_empty(); + return geometry_empty(); } template @@ -153,7 +153,7 @@ geometry_collection reproject_internal(geometry_collection const & c, proj { geometry new_g = reproject_copy(g, proj_trans, n_err); - if (!new_g.template is>()) + if (!new_g.template is()) { new_c.emplace_back(std::move(new_g)); } @@ -169,9 +169,9 @@ struct geom_reproj_copy_visitor : proj_trans_(proj_trans), n_err_(n_err) {} - geometry operator() (geometry_empty) const + geometry operator() (geometry_empty) const { - return geometry_empty(); + return geometry_empty(); } geometry operator() (point const& p) const @@ -280,8 +280,8 @@ struct geom_reproj_visitor { return mapnik::util::apply_visitor((*this), geom); } - template - bool operator() (geometry_empty &) const { return true; } + //template + bool operator() (geometry_empty &) const { return true; } template bool operator() (point & p) const diff --git a/include/mapnik/geometry_strategy.hpp b/include/mapnik/geometry/strategy.hpp similarity index 96% rename from include/mapnik/geometry_strategy.hpp rename to include/mapnik/geometry/strategy.hpp index cc4121e60..d71479072 100644 --- a/include/mapnik/geometry_strategy.hpp +++ b/include/mapnik/geometry/strategy.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,20 +23,20 @@ #ifndef MAPNIK_GEOMETRY_STRATEGY_HPP #define MAPNIK_GEOMETRY_STRATEGY_HPP -#include +#include #include -namespace mapnik { +namespace mapnik { namespace geometry { namespace helper { template struct index {}; - + template struct gen_seq : gen_seq {}; - + template struct gen_seq<0, Ts...> : index {}; } @@ -70,7 +70,7 @@ struct strategy_group template inline P2 execute(P1 const& p, bool & status, T const& strat, Args const& ... args) const - { + { return execute(strat.template execute(p, status), status, args...); } @@ -79,7 +79,7 @@ struct strategy_group { return strat.template execute(p, status); } - + private: std::tuple ops_; @@ -87,7 +87,7 @@ private: // The difference between this strategy group and the previous is that the conversion from P1 to P2 happens -// in the first strategy rather then the last strategy. +// in the first strategy rather then the last strategy. template struct strategy_group_first { @@ -116,13 +116,13 @@ struct strategy_group_first template inline P2 execute_first(P1 const& p, bool & status, T const& strat, Args const& ... args) const - { + { return execute(strat.template execute(p, status), status, args...); } template inline P2 execute(P2 const& p, bool & status, T const& strat, Args const& ... args) const - { + { return execute(strat.template execute(p, status), status, args...); } @@ -131,13 +131,13 @@ struct strategy_group_first { return strat.template execute(p, status); } - + template inline P2 execute(P2 const& p, bool & status) const { return p; } - + private: std::tuple ops_; @@ -151,7 +151,7 @@ struct scale_strategy template inline bool apply(P1 const & p1, P2 & p2) const { - + using p2_type = typename boost::geometry::coordinate_type::type; double x = (boost::geometry::get<0>(p1) * scale_) + offset_; double y = (boost::geometry::get<1>(p1) * scale_) + offset_; @@ -159,7 +159,7 @@ struct scale_strategy boost::geometry::set<1>(p2, static_cast(y)); return true; } - + template inline P2 execute(P1 const& p1, bool & status) const { @@ -181,7 +181,7 @@ struct scale_rounding_strategy template inline bool apply(P1 const & p1, P2 & p2) const { - + using p2_type = typename boost::geometry::coordinate_type::type; double x = (boost::geometry::get<0>(p1) * scale_) + offset_; double y = (boost::geometry::get<1>(p1) * scale_) + offset_; @@ -189,7 +189,7 @@ struct scale_rounding_strategy boost::geometry::set<1>(p2, static_cast(std::round(y))); return true; } - + template inline P2 execute(P1 const& p1, bool & status) const { diff --git a/include/mapnik/geometry_to_path.hpp b/include/mapnik/geometry/to_path.hpp similarity index 97% rename from include/mapnik/geometry_to_path.hpp rename to include/mapnik/geometry/to_path.hpp index 2aadbc200..afa432246 100644 --- a/include/mapnik/geometry_to_path.hpp +++ b/include/mapnik/geometry/to_path.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,7 +39,7 @@ struct geometry_to_path mapnik::util::apply_visitor(*this, geom); } - void operator() (geometry_empty const&) const + void operator() (geometry_empty const&) const { // no-op } diff --git a/include/mapnik/geometry_transform.hpp b/include/mapnik/geometry/transform.hpp similarity index 97% rename from include/mapnik/geometry_transform.hpp rename to include/mapnik/geometry/transform.hpp index 4004d6083..11848e019 100644 --- a/include/mapnik/geometry_transform.hpp +++ b/include/mapnik/geometry/transform.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_TRANSFORM_HPP #include -#include +#include #include namespace mapnik { namespace geometry { namespace detail { @@ -103,10 +103,9 @@ struct geometry_transform using result_type = geometry; - template - geometry operator() (geometry_empty const& empty) const + geometry operator() (geometry_empty const& empty) const { - return geometry_empty(); + return geometry_empty(); } template diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp deleted file mode 100644 index ccc85a41e..000000000 --- a/include/mapnik/geometry_is_empty.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_GEOMETRY_IS_EMPTY_HPP -#define MAPNIK_GEOMETRY_IS_EMPTY_HPP - -#include - -namespace mapnik { namespace geometry { - -namespace detail { - -template -struct geometry_is_empty -{ - bool operator() (mapnik::geometry::geometry const& geom) const - { - return mapnik::util::apply_visitor(*this, geom); - } - - bool operator() (mapnik::geometry::point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::line_string const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::linear_ring const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::polygon const& geom) const - { - return geom.empty() || geom.front().empty(); - } - - bool operator() (mapnik::geometry::multi_point const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::multi_line_string const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::multi_polygon const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::geometry_collection const& geom) const - { - return geom.empty(); - } - - template - bool operator() (U const&) const - { - return true; - } - -}; - -template -struct geometry_has_empty -{ - bool operator() (mapnik::geometry::geometry const& geom) const - { - return mapnik::util::apply_visitor(*this, geom); - } - - bool operator() (mapnik::geometry::geometry_empty const&) const - { - return false; - } - - bool operator() (mapnik::geometry::point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::line_string const&) const - { - return false; - } - - bool operator() (mapnik::geometry::linear_ring const&) const - { - return false; - } - - bool operator() (mapnik::geometry::polygon const&) const - { - return false; - } - - bool operator() (mapnik::geometry::multi_point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::multi_line_string const& multi_line) const - { - for (auto const& line : multi_line) - { - if (line.empty()) return true; - } - return false; - } - - bool operator() (mapnik::geometry::multi_polygon const& multi_poly) const - { - for (auto const& poly : multi_poly) - { - if (poly.empty() || poly.front().empty()) // no-rings OR exterioir is empty - { - return true; - } - } - return false; - } - - bool operator() (mapnik::geometry::geometry_collection const& geom) const - { - for (auto const & item : geom) - { - if (geometry_is_empty()(item) || (*this)(item)) - { - return true; - } - } - return false; - } - - template - bool operator() (U const&) const - { - return true; - } -}; - -} - -template -inline bool is_empty(G const& geom) -{ - using coordinate_type = typename G::coordinate_type; - return detail::geometry_is_empty()(geom); -} - -template -inline bool has_empty(G const& geom) -{ - using coordinate_type = typename G::coordinate_type; - return detail::geometry_has_empty()(geom); -} - -}} - -#endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP diff --git a/include/mapnik/global.hpp b/include/mapnik/global.hpp index 39a8c5ff7..0ef336d6b 100644 --- a/include/mapnik/global.hpp +++ b/include/mapnik/global.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/gradient.hpp b/include/mapnik/gradient.hpp index ae9acb5a3..cad7dd3ea 100644 --- a/include/mapnik/gradient.hpp +++ b/include/mapnik/gradient.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -96,7 +96,7 @@ public: void get_control_points(double &x1, double &y1, double &x2, double &y2) const; private: - void swap(gradient& other) throw(); + void swap(gradient& other) noexcept; }; } diff --git a/include/mapnik/grid/grid.hpp b/include/mapnik/grid/grid.hpp index ab79cdd2a..39a32bcef 100644 --- a/include/mapnik/grid/grid.hpp +++ b/include/mapnik/grid/grid.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include #include diff --git a/include/mapnik/grid/grid_pixel.hpp b/include/mapnik/grid/grid_pixel.hpp index fda65779a..16a917a2b 100644 --- a/include/mapnik/grid/grid_pixel.hpp +++ b/include/mapnik/grid/grid_pixel.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/grid/grid_pixfmt.hpp b/include/mapnik/grid/grid_pixfmt.hpp index dda24121f..7d5623850 100644 --- a/include/mapnik/grid/grid_pixfmt.hpp +++ b/include/mapnik/grid/grid_pixfmt.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/grid/grid_rasterizer.hpp b/include/mapnik/grid/grid_rasterizer.hpp index 612944799..c79dec555 100644 --- a/include/mapnik/grid/grid_rasterizer.hpp +++ b/include/mapnik/grid/grid_rasterizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/grid/grid_render_marker.hpp b/include/mapnik/grid/grid_render_marker.hpp index 5ad5fea13..68b09c3a3 100644 --- a/include/mapnik/grid/grid_render_marker.hpp +++ b/include/mapnik/grid/grid_render_marker.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/grid/grid_renderer.hpp b/include/mapnik/grid/grid_renderer.hpp index cc689e308..9c2e4dbf8 100644 --- a/include/mapnik/grid/grid_renderer.hpp +++ b/include/mapnik/grid/grid_renderer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +29,7 @@ #include #include #include // for rule, symbolizers -#include // for box2d +#include // for box2d #include // for color #include // for view_transform #include // for composite_mode_e @@ -124,9 +124,9 @@ public: return pixmap_.painted(); } - void painted(bool painted) + void painted(bool _painted) { - pixmap_.painted(painted); + pixmap_.painted(_painted); } inline eAttributeCollectionPolicy attribute_collection_policy() const diff --git a/include/mapnik/grid/grid_renderer_base.hpp b/include/mapnik/grid/grid_renderer_base.hpp index bcc2e18c1..439b585a5 100644 --- a/include/mapnik/grid/grid_renderer_base.hpp +++ b/include/mapnik/grid/grid_renderer_base.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/grid/grid_rendering_buffer.hpp b/include/mapnik/grid/grid_rendering_buffer.hpp index 8ab12cfc0..dc38d3d83 100644 --- a/include/mapnik/grid/grid_rendering_buffer.hpp +++ b/include/mapnik/grid/grid_rendering_buffer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/grid/grid_view.hpp b/include/mapnik/grid/grid_view.hpp index 80c539f53..bd5575d56 100644 --- a/include/mapnik/grid/grid_view.hpp +++ b/include/mapnik/grid/grid_view.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_GRID_VIEW_HPP #include -#include +#include #include #include #include @@ -52,7 +52,7 @@ public: hit_grid_view(unsigned x, unsigned y, unsigned width, unsigned height, - T const& data, + T const& _data, std::string const& key, std::string const& id_name, std::set const& names, @@ -63,7 +63,7 @@ public: y_(y), width_(width), height_(height), - data_(data), + data_(_data), key_(key), id_name_(id_name), names_(names), diff --git a/include/mapnik/group/group_layout.hpp b/include/mapnik/group/group_layout.hpp index 23811e800..4b4e6d4a3 100644 --- a/include/mapnik/group/group_layout.hpp +++ b/include/mapnik/group/group_layout.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/group/group_layout_manager.hpp b/include/mapnik/group/group_layout_manager.hpp index 548e37bb6..6037718a3 100644 --- a/include/mapnik/group/group_layout_manager.hpp +++ b/include/mapnik/group/group_layout_manager.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_GROUP_LAYOUT_MANAGER_HPP // mapnik -#include +#include #include #include diff --git a/include/mapnik/group/group_rule.hpp b/include/mapnik/group/group_rule.hpp index 58f8505b4..486e85bca 100644 --- a/include/mapnik/group/group_rule.hpp +++ b/include/mapnik/group/group_rule.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/group/group_symbolizer_helper.hpp b/include/mapnik/group/group_symbolizer_helper.hpp index 93c7d4f3f..b3ff666bf 100644 --- a/include/mapnik/group/group_symbolizer_helper.hpp +++ b/include/mapnik/group/group_symbolizer_helper.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ //mapnik #include #include -#include +#include #include namespace mapnik { @@ -68,16 +68,6 @@ public: box_elements_.push_back(box_element(box, repeat_key)); } - inline void clear_box_elements() - { - box_elements_.clear(); - } - - inline text_symbolizer_properties const& get_properties() const - { - return info_ptr_->properties; - } - pixel_position_list const& get(); // Iterate over the given path, placing line-following labels or point labels with respect to label_spacing. diff --git a/include/mapnik/group/group_symbolizer_properties.hpp b/include/mapnik/group/group_symbolizer_properties.hpp index f5967b8be..6837b5ef2 100644 --- a/include/mapnik/group/group_symbolizer_properties.hpp +++ b/include/mapnik/group/group_symbolizer_properties.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/hextree.hpp b/include/mapnik/hextree.hpp index 5d8adc1da..33654703f 100644 --- a/include/mapnik/hextree.hpp +++ b/include/mapnik/hextree.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/hit_test_filter.hpp b/include/mapnik/hit_test_filter.hpp index fd9fb443c..11fcb1504 100644 --- a/include/mapnik/hit_test_filter.hpp +++ b/include/mapnik/hit_test_filter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -49,7 +49,7 @@ struct hit_test_visitor y_(y), tol_(tol) {} - bool operator() (geometry::geometry_empty const& ) const + bool operator() (geometry::geometry_empty const& ) const { return false; } diff --git a/include/mapnik/image.hpp b/include/mapnik/image.hpp index da2f7738e..96b65e00e 100644 --- a/include/mapnik/image.hpp +++ b/include/mapnik/image.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_any.hpp b/include/mapnik/image_any.hpp index 8aedf302a..9ee056c81 100644 --- a/include/mapnik/image_any.hpp +++ b/include/mapnik/image_any.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp index 82b89a398..0cb6b1339 100644 --- a/include/mapnik/image_compositing.hpp +++ b/include/mapnik/image_compositing.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_copy.hpp b/include/mapnik/image_copy.hpp index 8f40ef40a..84481c692 100644 --- a/include/mapnik/image_copy.hpp +++ b/include/mapnik/image_copy.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp index 0532b6a5b..8c29fe19b 100644 --- a/include/mapnik/image_filter.hpp +++ b/include/mapnik/image_filter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -681,7 +681,7 @@ void apply_filter(Src & src, scale_hsla const& transform, double /*scale_factor* } template -void color_blind_filter(Src & src, ColorBlindFilter const& op) +void apply_color_blind_filter(Src & src, ColorBlindFilter const& op) { using namespace boost::gil; rgba8_view_t src_view = rgba8_view(src); @@ -804,19 +804,19 @@ void color_blind_filter(Src & src, ColorBlindFilter const& op) template void apply_filter(Src & src, color_blind_protanope const& op, double /*scale_factor*/) { - color_blind_filter(src, op); + apply_color_blind_filter(src, op); } template void apply_filter(Src & src, color_blind_deuteranope const& op, double /*scale_factor*/) { - color_blind_filter(src, op); + apply_color_blind_filter(src, op); } template void apply_filter(Src & src, color_blind_tritanope const& op, double /*scale_factor*/) { - color_blind_filter(src, op); + apply_color_blind_filter(src, op); } template @@ -916,7 +916,7 @@ void apply_filter(Src & src, invert const& /*op*/, double /*scale_factor*/) template struct filter_visitor { - filter_visitor(Src & src, double scale_factor) + filter_visitor(Src & src, double scale_factor=1.0) : src_(src), scale_factor_(scale_factor) {} diff --git a/include/mapnik/image_filter_grammar.hpp b/include/mapnik/image_filter_grammar.hpp deleted file mode 100644 index ca96116eb..000000000 --- a/include/mapnik/image_filter_grammar.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_HPP -#define MAPNIK_IMAGE_FILTER_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik { - -namespace filter { -struct color_stop; -struct colorize_alpha; -} - -namespace qi = boost::spirit::qi; - -struct percent_offset_impl -{ - using result_type = double; - double operator() (double val) const - { - double result = std::abs(val/100.0); - if (result > 1.0) result = 1.0; - return result; - } -}; - - -template -struct image_filter_grammar : - qi::grammar -{ - using alternative_type = qi::rule; - - image_filter_grammar(); - - qi::rule start; - qi::rule> filter; - qi::rule no_args; - qi::symbols alternatives; - qi::uint_parser< unsigned, 10, 1, 3 > radius_; - css_color_grammar css_color_; - qi::rule color_stop_; - qi::rule color_stop_offset; - -private: - alternative_type & add(std::string const& symbol); - static constexpr unsigned max_alternatives = 16; - unsigned num_alternatives = 0; - alternative_type alternative_storage[max_alternatives]; -}; - -} // namespace mapnik - -#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_HPP diff --git a/include/mapnik/image_filter_grammar_impl.hpp b/include/mapnik/image_filter_grammar_impl.hpp deleted file mode 100644 index bf1770083..000000000 --- a/include/mapnik/image_filter_grammar_impl.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace { // internal - - BOOST_PHOENIX_ADAPT_FUNCTION( - typename std::remove_reference::type, ovo, // = optional_value_or - boost::get_optional_value_or, 2) - -} // namespace internal - -namespace mapnik { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; - -template -image_filter_grammar::image_filter_grammar() - : image_filter_grammar::base_type(start) -{ - qi::lit_type lit; - qi::_val_type _val; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_5_type _5; - qi::_6_type _6; - qi::_7_type _7; - qi::_8_type _8; - qi::_a_type _a; - qi::attr_type attr; - qi::double_type double_; - qi::hold_type hold; - qi::omit_type omit; - using phoenix::push_back; - using phoenix::construct; - - // functions - phoenix::function percent_offset; - - start = -(filter % *lit(',')) - ; - - filter = omit[alternatives[_a = _1]] >> qi::lazy(*_a) - ; - - add("emboss") = no_args >> attr(construct()); - add("blur") = no_args >> attr(construct()); - add("gray") = no_args >> attr(construct()); - add("edge-detect") = no_args >> attr(construct()); - add("sobel") = no_args >> attr(construct()); - add("sharpen") = no_args >> attr(construct()); - add("x-gradient") = no_args >> attr(construct()); - add("y-gradient") = no_args >> attr(construct()); - add("invert") = no_args >> attr(construct()); - add("color-blind-protanope") = no_args >> attr(construct()); - add("color-blind-deuteranope") = no_args >> attr(construct()); - add("color-blind-tritanope") = no_args >> attr(construct()); - - add("agg-stack-blur") = - (lit('(') >> radius_ >> -( lit(',') >> radius_ ) >> lit(')')) - [push_back(_val, construct(_1, ovo(_2, _1)))] - | - no_args - [push_back(_val, construct(1, 1))] - ; - - add("scale-hsla") = - (lit('(') - >> double_ >> lit(',') >> double_ >> lit(',') - >> double_ >> lit(',') >> double_ >> lit(',') - >> double_ >> lit(',') >> double_ >> lit(',') - >> double_ >> lit(',') >> double_ >> lit(')')) - [push_back(_val, construct(_1,_2,_3,_4,_5,_6,_7,_8))] - ; - - add("colorize-alpha") = qi::as() - [lit('(') >> color_stop_ % lit(',') >> lit(')')] - [push_back(_val, _1)] - ; - - color_stop_ = (css_color_ >> -color_stop_offset) - [_val = construct(_1, ovo(_2, 0.0))] - ; - - color_stop_offset = double_[_val = _1] - >> -lit('%')[_val = percent_offset(_val)] - ; - - add("color-to-alpha") = - hold[lit('(') >> css_color_ >> lit(')')] - [push_back(_val, construct(_1))] - ; - - no_args = -(lit('(') >> lit(')')); -} - -template -auto image_filter_grammar::add(std::string const& symbol) - -> alternative_type & -{ - if (num_alternatives >= max_alternatives) - { - throw std::length_error("too many alternatives in image_filter_grammar"); - } - - alternative_storage[num_alternatives].name(symbol); - alternatives.add(symbol, &alternative_storage[num_alternatives]); - return alternative_storage[num_alternatives++]; -} - -} // namespace mapnik diff --git a/include/mapnik/image_filter_grammar_x3.hpp b/include/mapnik/image_filter_grammar_x3.hpp new file mode 100644 index 000000000..cddc2d0dd --- /dev/null +++ b/include/mapnik/image_filter_grammar_x3.hpp @@ -0,0 +1,55 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP +#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik +{ + +namespace x3 = boost::spirit::x3; + +namespace image_filter +{ + +struct image_filter_class; +using image_filter_grammar_type = x3::rule >; + +BOOST_SPIRIT_DECLARE(image_filter_grammar_type); + + +}} + +namespace mapnik { + +image_filter::image_filter_grammar_type const& image_filter_grammar(); + +} + +#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP diff --git a/include/mapnik/image_filter_grammar_x3_def.hpp b/include/mapnik/image_filter_grammar_x3_def.hpp new file mode 100644 index 000000000..b40bfc8f9 --- /dev/null +++ b/include/mapnik/image_filter_grammar_x3_def.hpp @@ -0,0 +1,261 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP +#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP + + +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include // spirit support +#pragma GCC diagnostic pop + + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::filter::scale_hsla, + (double, h0) + (double, h1) + (double, s0) + (double, s1) + (double, l0) + (double, l1) + (double, a0) + (double, a1) +) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::filter::color_stop, + (mapnik::color, color ) + (double, offset) +) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::filter::color_to_alpha, + (mapnik::color, color) +) + +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace image_filter { + +using x3::lit; +using x3::uint_parser; +using x3::hex; +using x3::symbols; +using x3::omit; +using x3::attr; +using x3::double_; +using x3::no_case; +using x3::no_skip; +using x3::char_; + +auto push_back = [](auto& ctx) +{ + _val(ctx).push_back(_attr(ctx)); + +}; + +auto set_rx_ry = [](auto & ctx) +{ + _val(ctx).rx = _val(ctx).ry = _attr(ctx); +}; + +auto set_ry = [](auto & ctx) +{ + _val(ctx).ry = _attr(ctx); +}; + +auto offset_value = [](auto & ctx) +{ + _val(ctx) = _attr(ctx); +}; + +auto percent = [](auto & ctx) +{ + double val = std::abs(_val(ctx)/100.0); + if (val > 1.0) val = 1.0; + _val(ctx) = val; +}; + +x3::uint_parser radius; + +// Import the expression rule +namespace { auto const& css_color = color_grammar(); } + +// starting rule +image_filter_grammar_type const start("start"); +// rules +x3::rule const filter("filter"); + +x3::rule const emboss_filter("emboss"); +x3::rule const blur_filter("blur"); +x3::rule const gray_filter("gray"); +x3::rule const edge_detect_filter("edge-detect"); +x3::rule const sobel_filter("sobel"); +x3::rule const sharpen_filter("sharpen"); +x3::rule const x_gradient_filter("x-gradient"); +x3::rule const y_gradient_filter("y-gradient"); +x3::rule const invert_filter("invert"); +x3::rule const color_blind_protanope_filter("color-blind-protanope"); +x3::rule const color_blind_deuteranope_filter("color-blind-deuteranope"); +x3::rule const color_blind_tritanope_filter("color-blind-tritanope"); + +x3::rule const agg_blur_filter("agg blur filter"); +x3::rule const scale_hsla_filter("scale-hsla"); +x3::rule const colorize_alpha_filter("colorize-alpha"); +x3::rule const color_stop("color-stop"); +x3::rule const offset("color-stop-offset"); +x3::rule const color_to_alpha_filter("color-to-alpha"); + +auto const no_args = -(lit('(') > lit(')')); + +auto const start_def = -(filter[push_back] % *lit(',')); + +auto const filter_def = (emboss_filter + | + blur_filter + | + gray_filter + | + edge_detect_filter + | + sobel_filter + | + sharpen_filter + | + x_gradient_filter + | + y_gradient_filter + | + invert_filter + | + color_blind_protanope_filter + | + color_blind_deuteranope_filter + | + color_blind_tritanope_filter + | + agg_blur_filter + | + scale_hsla_filter + | + colorize_alpha_filter + | + color_to_alpha_filter + ) + ; + +auto const emboss_filter_def = lit("emboss") > no_args; + +auto const blur_filter_def = lit("blur") > no_args; + +auto const gray_filter_def = lit("gray") > no_args; + +auto const edge_detect_filter_def = lit("edge-detect") > no_args; + +auto const sobel_filter_def = lit("sobel") > no_args; + +auto const sharpen_filter_def = lit("sharpen") > no_args; + +auto const x_gradient_filter_def = lit("x-gradient") > no_args; + +auto const y_gradient_filter_def = lit("y-gradient") > no_args; + +auto const invert_filter_def = lit("invert") > no_args; + +auto const color_blind_protanope_filter_def = lit("color-blind-protanope") > no_args; + +auto const color_blind_deuteranope_filter_def = lit("color-blind-deuteranope") > no_args; + +auto const color_blind_tritanope_filter_def = lit("color-blind-tritanope") > no_args; + +auto const agg_blur_filter_def = lit("agg-stack-blur") + > -(lit('(') > -(radius[set_rx_ry] > -(lit(',') > radius[set_ry])) > lit(')')); + +auto const scale_hsla_filter_def = lit("scale-hsla") > lit('(') + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ')' ; + + +auto const offset_def = double_[offset_value] > -lit('%')[percent]; +auto const color_stop_def = css_color > -offset; + +auto const colorize_alpha_filter_def = lit("colorize-alpha") + > lit('(') + > color_stop > *(lit(',') > color_stop) + > lit(')') ; + +auto const color_to_alpha_filter_def = lit("color-to-alpha") > lit('(') + > -css_color > lit(')'); + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + start, + filter, + emboss_filter, + blur_filter, + gray_filter, + edge_detect_filter, + sobel_filter, + sharpen_filter, + x_gradient_filter, + y_gradient_filter, + invert_filter, + agg_blur_filter, + color_blind_protanope_filter, + color_blind_deuteranope_filter, + color_blind_tritanope_filter, + scale_hsla_filter, + colorize_alpha_filter, + color_stop, + offset, + color_to_alpha_filter + ); +#pragma GCC diagnostic pop + +} // image_filter + +image_filter::image_filter_grammar_type const& image_filter_grammar() +{ + return image_filter::start; +} + +} //ns mapnik + +#endif //MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp index 7e04df87a..1b7fd0498 100644 --- a/include/mapnik/image_filter_types.hpp +++ b/include/mapnik/image_filter_types.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -56,32 +56,41 @@ struct y_gradient : image_filter_base {}; struct invert : image_filter_base {}; // http://vision.psychol.cam.ac.uk/jdmollon/papers/colourmaps.pdf -struct color_blind_protanope : image_filter_base +struct color_blind_filter : image_filter_base { - const double x = 0.7465; - const double y = 0.2535; - const double m = 1.273463; - const double yint = -0.073894; + color_blind_filter(double x_, double y_, double m_, double yint_) + : x(x_), y(y_), m(m_), yint(yint_) {} + double x; + double y; + double m; + double yint; }; -struct color_blind_deuteranope : image_filter_base +struct color_blind_protanope : color_blind_filter { - const double x = 1.4; - const double y = -0.4; - const double m = 0.968437; - const double yint = 0.003331; + color_blind_protanope() + : color_blind_filter(0.7465, 0.2535, 1.273463, -0.073894) {} }; -struct color_blind_tritanope : image_filter_base +struct color_blind_deuteranope : color_blind_filter { - const double x = 0.1748; - const double y = 0.0; - const double m = 0.062921; - const double yint = 0.292119; + color_blind_deuteranope() + : color_blind_filter(1.4, -0.4, 0.968437, 0.003331) {} }; +struct color_blind_tritanope : color_blind_filter +{ + color_blind_tritanope() + : color_blind_filter(0.1748, 0.0, 0.062921, 0.292119) {} +}; + + struct agg_stack_blur : image_filter_base { + agg_stack_blur() + : rx(1), ry(1) {} + agg_stack_blur(unsigned r) + : rx(r), ry(r) {} agg_stack_blur(unsigned rx_, unsigned ry_) : rx(rx_),ry(ry_) {} inline bool operator==(agg_stack_blur const& rhs) const @@ -94,6 +103,7 @@ struct agg_stack_blur : image_filter_base struct color_to_alpha : image_filter_base { + color_to_alpha() {} color_to_alpha(mapnik::color const& c) : color(c) {} inline bool operator==(color_to_alpha const& rhs) const @@ -105,6 +115,7 @@ struct color_to_alpha : image_filter_base struct scale_hsla : image_filter_base { + scale_hsla() {} scale_hsla(double _h0, double _h1, double _s0, double _s1, double _l0, double _l1, diff --git a/include/mapnik/image_impl.hpp b/include/mapnik/image_impl.hpp index f340d9a4b..5e9a50948 100644 --- a/include/mapnik/image_impl.hpp +++ b/include/mapnik/image_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_null.hpp b/include/mapnik/image_null.hpp index 5a698bbc9..7fb2a5da8 100644 --- a/include/mapnik/image_null.hpp +++ b/include/mapnik/image_null.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_options.hpp b/include/mapnik/image_options.hpp index d44b2bf35..17b279ce1 100644 --- a/include/mapnik/image_options.hpp +++ b/include/mapnik/image_options.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +38,10 @@ using image_options_map = std::map >; inline std::string to_string(boost::optional const& val) { return val ? *val : "";} image_options_map parse_image_options(std::string const& options); +#if defined(HAVE_PNG) +int parse_png_filters(std::string const& str); +#endif + } #endif // MAPNIK_IMAGE_OPTIONS_HPP diff --git a/include/mapnik/image_reader.hpp b/include/mapnik/image_reader.hpp index 6c1c2329c..77cc1073b 100644 --- a/include/mapnik/image_reader.hpp +++ b/include/mapnik/image_reader.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include @@ -50,9 +50,9 @@ public: image_reader_exception(std::string const& message) : message_(message) {} - ~image_reader_exception() throw() {} + ~image_reader_exception() {} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } diff --git a/include/mapnik/image_scaling.hpp b/include/mapnik/image_scaling.hpp index 461e99f27..f2ac1c10c 100644 --- a/include/mapnik/image_scaling.hpp +++ b/include/mapnik/image_scaling.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_scaling_traits.hpp b/include/mapnik/image_scaling_traits.hpp index b8daff152..a1c329e31 100644 --- a/include/mapnik/image_scaling_traits.hpp +++ b/include/mapnik/image_scaling_traits.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_util.hpp b/include/mapnik/image_util.hpp index 0db5a3752..b36ba75d6 100644 --- a/include/mapnik/image_util.hpp +++ b/include/mapnik/image_util.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -56,9 +56,9 @@ public: image_writer_exception(std::string const& message) : message_(message) {} - ~image_writer_exception() throw() {} + ~image_writer_exception(){} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } diff --git a/include/mapnik/image_util_jpeg.hpp b/include/mapnik/image_util_jpeg.hpp index feb810533..d684b9a22 100644 --- a/include/mapnik/image_util_jpeg.hpp +++ b/include/mapnik/image_util_jpeg.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_util_png.hpp b/include/mapnik/image_util_png.hpp index 8592c4fd4..c6ef08a24 100644 --- a/include/mapnik/image_util_png.hpp +++ b/include/mapnik/image_util_png.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_util_tiff.hpp b/include/mapnik/image_util_tiff.hpp index 39b524d88..87791e4e2 100644 --- a/include/mapnik/image_util_tiff.hpp +++ b/include/mapnik/image_util_tiff.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_util_webp.hpp b/include/mapnik/image_util_webp.hpp index 6d28138de..3c654dec8 100644 --- a/include/mapnik/image_util_webp.hpp +++ b/include/mapnik/image_util_webp.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_view.hpp b/include/mapnik/image_view.hpp index 846da6691..3b2270b27 100644 --- a/include/mapnik/image_view.hpp +++ b/include/mapnik/image_view.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_view_any.hpp b/include/mapnik/image_view_any.hpp index a5452df0b..fde9b723e 100644 --- a/include/mapnik/image_view_any.hpp +++ b/include/mapnik/image_view_any.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_view_impl.hpp b/include/mapnik/image_view_impl.hpp index 14032042a..9609913d6 100644 --- a/include/mapnik/image_view_impl.hpp +++ b/include/mapnik/image_view_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/image_view_null.hpp b/include/mapnik/image_view_null.hpp index 76ebc5f49..214e8f0a3 100644 --- a/include/mapnik/image_view_null.hpp +++ b/include/mapnik/image_view_null.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/jpeg_io.hpp b/include/mapnik/jpeg_io.hpp index cc64dac75..02b8b94a2 100644 --- a/include/mapnik/jpeg_io.hpp +++ b/include/mapnik/jpeg_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/json/attribute_value_visitor.hpp b/include/mapnik/json/attribute_value_visitor.hpp index 206530cae..3e5e74219 100644 --- a/include/mapnik/json/attribute_value_visitor.hpp +++ b/include/mapnik/json/attribute_value_visitor.hpp @@ -27,7 +27,6 @@ #include #include #include -#include namespace mapnik { namespace json { diff --git a/include/mapnik/json/create_feature.hpp b/include/mapnik/json/create_feature.hpp new file mode 100644 index 000000000..bada4ab69 --- /dev/null +++ b/include/mapnik/json/create_feature.hpp @@ -0,0 +1,242 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_CREATE_FEATURE_HPP +#define MAPNIK_JSON_CREATE_FEATURE_HPP + +#include +#include +#include +#include + +#include +#include +#include + +namespace mapnik { namespace json { + +struct stringifier +{ + stringifier(keys_map const& keys) + : keys_(keys) {} + + std::string operator()(std::string const& val) const + { + return "\"" + val + "\""; + } + + std::string operator()(value_null) const + { + return "null"; + } + + std::string operator()(value_bool val) const + { + return val ? "true" : "false"; + } + + std::string operator()(value_integer val) const + { + std::string str; + util::to_string(str, val); + return str; + } + + std::string operator()(value_double val) const + { + std::string str; + util::to_string(str, val); + return str; + } + + std::string operator()(mapnik::json::geojson_array const& array) const + { + std::string str = "["; + bool first = true; + for (auto const& val : array) + { + if (first) first = false; + else str += ","; + str += mapnik::util::apply_visitor(*this, val); + } + str += "]"; + return str; + } + + std::string operator()(mapnik::json::geojson_object const& object) const + { + std::string str = "{"; + bool first = true; + for (auto const& kv : object) + { + auto itr = keys_.right.find(std::get<0>(kv)); + if (itr != keys_.right.end()) + { + if (first) first = false; + else str += ","; + str += "\"" + itr->second + "\""; + str += ":"; + str += mapnik::util::apply_visitor(*this, kv.second); + } + } + str += "}"; + return str; + } + template + std::string operator()(T const&) const + { + return ""; + } + + keys_map const& keys_; +}; + +struct attribute_value_visitor +{ +public: + attribute_value_visitor(mapnik::transcoder const& tr, keys_map const& keys) + : tr_(tr), + keys_(keys) {} + + mapnik::value operator()(std::string const& val) const + { + return mapnik::value(tr_.transcode(val.c_str())); + } + + mapnik::value operator()(mapnik::json::geojson_array const& array) const + { + std::string str = stringifier(keys_)(array); + return mapnik::value(tr_.transcode(str.c_str())); + } + + mapnik::value operator()(mapnik::json::geojson_object const& object) const + { + std::string str = stringifier(keys_)(object); + return mapnik::value(tr_.transcode(str.c_str())); + } + + mapnik::value operator() (mapnik::value_bool val) const + { + return mapnik::value(val); + } + + mapnik::value operator() (mapnik::value_integer val) const + { + return mapnik::value(val); + } + + mapnik::value operator() (mapnik::value_double val) const + { + return mapnik::value(val); + } + + template + mapnik::value operator()(T const& val) const + { + return mapnik::value_null{}; + } + + mapnik::transcoder const& tr_; + mapnik::json::keys_map const& keys_; +}; + +void create_feature(feature_impl & feature, + mapnik::json::geojson_value const& value, + mapnik::json::keys_map const& keys, + mapnik::transcoder const& tr) +{ + + if (!value.is()) + { + throw std::runtime_error("Expecting an GeoJSON object"); + } + mapnik::json::geojson_object const& feature_value = mapnik::util::get(value); + for (auto const& elem : feature_value) + { + auto const key = std::get<0>(elem); + if (key == mapnik::json::well_known_names::geometry) + { + auto const& geom_value = std::get<1>(elem); + if (!geom_value.is()) + { + throw std::runtime_error("\"geometry\": xxx <-- expecting an JSON object here"); + } + auto const& geometry = mapnik::util::get(geom_value); + mapnik::geometry::geometry_types geom_type; + mapnik::json::positions const* coordinates = nullptr; + for (auto & elem2 : geometry) + { + auto const key2 = std::get<0>(elem2); + if (key2 == mapnik::json::well_known_names::type) + { + auto const& geom_type_value = std::get<1>(elem2); + if (!geom_type_value.is()) + { + throw std::runtime_error("\"type\": xxx <-- expecting an GeoJSON geometry type here"); + } + geom_type = mapnik::util::get(geom_type_value); + if (geom_type == mapnik::geometry::geometry_types::GeometryCollection) + { + throw std::runtime_error("GeometryCollections are not allowed"); + } + } + else if (key2 == mapnik::json::well_known_names::coordinates) + { + auto const& coordinates_value = std::get<1>(elem2); + if (!coordinates_value.is()) + { + throw std::runtime_error("\"coordinates\": xxx <-- expecting an GeoJSON positions here"); + } + coordinates = &mapnik::util::get(coordinates_value); + } + } + + mapnik::geometry::geometry geom; + mapnik::json::create_geometry(geom, geom_type, *coordinates); + feature.set_geometry(std::move(geom)); + } + else if (key == mapnik::json::well_known_names::properties) + { + auto const& prop_value = std::get<1>(elem); + if (!prop_value.is()) + { + throw std::runtime_error("\"properties\": xxx <-- expecting an JSON object here"); + } + auto const& properties = mapnik::util::get(prop_value); + auto end = keys.right.end(); + for (auto const& kv : properties) + { + auto itr = keys.right.find(std::get<0>(kv)); + if (itr != end) + { + feature.put_new(itr->second, + mapnik::util::apply_visitor(mapnik::json::attribute_value_visitor(tr, keys), + std::get<1>(kv))); + } + } + } + } +} + +}} + +#endif //MAPNIK_JSON_CREATE_FEATURE_HPP diff --git a/include/mapnik/json/geometry_util.hpp b/include/mapnik/json/create_geometry.hpp similarity index 61% rename from include/mapnik/json/geometry_util.hpp rename to include/mapnik/json/create_geometry.hpp index 82c4158b0..5f241efc1 100644 --- a/include/mapnik/json/geometry_util.hpp +++ b/include/mapnik/json/create_geometry.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,15 +20,16 @@ * *****************************************************************************/ -#ifndef MAPNIK_JSON_GEOMETRY_UTIL_HPP -#define MAPNIK_JSON_GEOMETRY_UTIL_HPP +#ifndef MAPNIK_JSON_CREATE_GEOMETRY_HPP +#define MAPNIK_JSON_CREATE_GEOMETRY_HPP #include -#include -#include +#include +#include namespace mapnik { namespace json { +namespace { // geometries template struct create_point @@ -36,14 +37,17 @@ struct create_point explicit create_point(Geometry & geom) : geom_(geom) {} - void operator() (position const& pos) const + void operator() (point const& pos) const { mapnik::geometry::point point(pos.x, pos.y); geom_ = std::move(point); } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -53,23 +57,23 @@ struct create_linestring explicit create_linestring(Geometry & geom) : geom_(geom) {} - void operator() (positions const& ring) const + void operator() (ring const& points) const { - std::size_t size = ring.size(); - if (size > 1) + mapnik::geometry::line_string line; + std::size_t size = points.size(); + line.reserve(size); + for (auto && pt : points) { - mapnik::geometry::line_string line; - line.reserve(size); - for (auto && pt : ring) - { - line.emplace_back(std::move(pt)); - } - geom_ = std::move(line); + line.emplace_back(std::move(pt)); } + geom_ = std::move(line); } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -80,18 +84,17 @@ struct create_polygon explicit create_polygon(Geometry & geom) : geom_(geom) {} - void operator() (std::vector const& rings) const + void operator() (rings const& rngs) const { mapnik::geometry::polygon poly; - std::size_t num_rings = rings.size(); + std::size_t num_rings = rngs.size(); poly.reserve(num_rings); - for ( std::size_t i = 0; i < num_rings; ++i) { - std::size_t size = rings[i].size(); + std::size_t size = rngs[i].size(); mapnik::geometry::linear_ring ring; ring.reserve(size); - for ( auto && pt : rings[i]) + for ( auto && pt : rngs[i]) { ring.emplace_back(std::move(pt)); } @@ -102,7 +105,10 @@ struct create_polygon } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -114,7 +120,7 @@ struct create_multipoint explicit create_multipoint(Geometry & geom) : geom_(geom) {} - void operator() (positions const& points) const + void operator() (ring const& points) const { mapnik::geometry::multi_point multi_point; multi_point.reserve(points.size()); @@ -126,7 +132,10 @@ struct create_multipoint } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -137,12 +146,12 @@ struct create_multilinestring explicit create_multilinestring(Geometry & geom) : geom_(geom) {} - void operator() (std::vector const& rings) const + void operator() (rings const& rngs) const { mapnik::geometry::multi_line_string multi_line; - multi_line.reserve(rings.size()); + multi_line.reserve(rngs.size()); - for (auto const& ring : rings) + for (auto const& ring : rngs) { mapnik::geometry::line_string line; line.reserve(ring.size()); @@ -156,7 +165,10 @@ struct create_multilinestring } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -167,11 +179,11 @@ struct create_multipolygon explicit create_multipolygon(Geometry & geom) : geom_(geom) {} - void operator()(std::vector > const& rings_array) const + void operator()(rings_array const& rngs_arr) const { mapnik::geometry::multi_polygon multi_poly; - multi_poly.reserve(rings_array.size()); - for (auto const& rings : rings_array) + multi_poly.reserve(rngs_arr.size()); + for (auto const& rings : rngs_arr) { mapnik::geometry::polygon poly; std::size_t num_rings = rings.size(); @@ -195,44 +207,44 @@ struct create_multipolygon } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; +} // anonymous ns -struct create_geometry_impl +template +void create_geometry (Geometry & geom, int type, mapnik::json::positions const& coords) { - using result_type = void; - template - void operator() (Geometry & geom, int type, mapnik::json::coordinates const& coords) const + switch (type) { - switch (type) - { - case 1 ://Point - util::apply_visitor(create_point(geom), coords); - break; - case 2 ://LineString - util::apply_visitor(create_linestring(geom), coords); - break; - case 3 ://Polygon - util::apply_visitor(create_polygon(geom), coords); - break; - case 4 ://MultiPoint - util::apply_visitor(create_multipoint(geom), coords); - break; - case 5 ://MultiLineString - util::apply_visitor(create_multilinestring(geom), coords); - break; - case 6 ://MultiPolygon - util::apply_visitor(create_multipolygon(geom), coords); - break; - default: - break; - } - + case 1 ://Point + util::apply_visitor(create_point(geom), coords); + break; + case 2 ://LineString + util::apply_visitor(create_linestring(geom), coords); + break; + case 3 ://Polygon + util::apply_visitor(create_polygon(geom), coords); + break; + case 4 ://MultiPoint + util::apply_visitor(create_multipoint(geom), coords); + break; + case 5 ://MultiLineString + util::apply_visitor(create_multilinestring(geom), coords); + break; + case 6 ://MultiPolygon + util::apply_visitor(create_multipolygon(geom), coords); + break; + default: + throw std::runtime_error("Failed to parse geojson geometry"); + break; } -}; +} }} -#endif // MAPNIK_JSON_GEOMETRY_UTIL_HPP +#endif // MAPNIK_JSON_CREATE_GEOMETRY_HPP diff --git a/include/mapnik/json/error_handler.hpp b/include/mapnik/json/error_handler.hpp deleted file mode 100644 index 1e66427ad..000000000 --- a/include/mapnik/json/error_handler.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_JSON_ERROR_HANDLER_HPP -#define MAPNIK_JSON_ERROR_HANDLER_HPP - -#include - -#pragma GCC diagnostic push -#include -#include -namespace boost { namespace spirit { struct info; } } -#pragma GCC diagnostic pop - -// mapnik -#ifdef MAPNIK_LOG -#include -#endif - -// stl -#include -#include -#include - - -namespace mapnik { namespace json { - -template -struct error_handler -{ - using result_type = boost::spirit::qi::error_handler_result; - result_type operator() ( - Iterator, - Iterator end, - Iterator err_pos, - boost::spirit::info const& what) const - { -#ifdef MAPNIK_LOG - std::stringstream s; - using difference_type = typename std::iterator_traits::difference_type; - auto start_err = err_pos; - std::advance(err_pos, std::min(std::distance(err_pos, end), difference_type(16))); - auto end_err = err_pos; - assert(end_err <= end); - s << "Mapnik GeoJSON parsing error:" << what << " expected but got: " << std::string(start_err, end_err); - MAPNIK_LOG_ERROR(error_handler) << s.str(); -#endif - return boost::spirit::qi::fail; - } -}; - -}} - -#endif // MAPNIK_JSON_ERROR_HANDLER_HPP diff --git a/include/mapnik/json/extract_bounding_box_grammar.hpp b/include/mapnik/json/extract_bounding_box_grammar.hpp deleted file mode 100644 index 906e7126d..000000000 --- a/include/mapnik/json/extract_bounding_box_grammar.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP -#define MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP - -// mapnik -#include -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; - -template > -struct extract_bounding_box_grammar : - qi::grammar -{ - using position_type = mapnik::geometry::point; - using boxes_type = Boxes; - using box_type = typename Boxes::value_type::first_type; - extract_bounding_box_grammar(); - // rules - qi::rule start; - qi::rule, void(boxes_type&), space_type> features; - qi::rule, void(boxes_type&, Iterator const&), space_type> feature; - qi::rule, box_type(), space_type> coords; - qi::rule(), space_type> pos; - qi::rule ring; - qi::rule rings; - qi::rule rings_array; - // generic JSON support - json::generic_json json; -}; - -}} - -#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp deleted file mode 100644 index bdc1b98b2..000000000 --- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp +++ /dev/null @@ -1,157 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include -// boost -#include -#include -#include -#include -#include -#include -// stl -#include -#include - -namespace mapnik { namespace json { - -struct calculate_bounding_box_impl -{ - using result_type = void; - template - result_type operator() (T0 & bbox, T1 const& pos) const - { - if (pos) - { - typename T0::value_type x = pos->x; - typename T0::value_type y = pos->y; - if (!bbox.valid()) - { - bbox.init(x, y); - } - else - { - bbox.expand_to_include(x, y); - } - } - } -}; - -struct push_box_impl -{ - using result_type = void; - template - void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const - { - if (box.valid()) boxes.emplace_back(box, - std::make_pair(std::distance(begin, - range.begin()), - std::distance(range.begin(), range.end()))); - } -}; - -namespace repo = boost::spirit::repository; - -template -extract_bounding_box_grammar::extract_bounding_box_grammar() - : extract_bounding_box_grammar::base_type(start, "GeoJSON bounding boxes") -{ - qi::lit_type lit; - qi::double_type double_; - qi::_val_type _val; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::omit_type omit; - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::_a_type _a; - qi::_b_type _b; - qi::eps_type eps; - qi::raw_type raw; - qi::char_type char_; - qi::no_skip_type no_skip; - boost::spirit::repository::qi::iter_pos_type iter_pos; - using qi::fail; - using qi::on_error; - - // phoenix functions - boost::phoenix::function push_box; - boost::phoenix::function calculate_bounding_box; - // error handler - boost::phoenix::function const error_handler; - - start = features(_r1) - ; - - features = no_skip[iter_pos[_a = _1]] >> -(lit('{') - >> *((json.key_value - lit("\"features\"")) >> lit(',')) - >> lit("\"features\"") - >> lit(':')) - >> lit('[') >> -(feature(_r1,_a) % lit(',')) >> lit(']') - ; - - feature = raw[lit('{')[_a = 1] - >> *(eps(_a > 0) >> ( - lit("\"FeatureCollection\"") > eps(false) // fail if nested FeatureCollection - | - lit('{')[_a += 1] - | - lit('}')[_a -= 1] - | - coords[_b = _1] - | - json.string_ - | - char_))][push_box(_r1, _r2, _b, _1)] - ; - - coords = lit("\"coordinates\"") - >> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a] - ; - - pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']') - ; - - ring = lit('[') >> pos[calculate_bounding_box(_r1,_1)] % lit(',') > lit(']') - ; - - rings = lit('[') >> ring(_r1) % lit(',') > lit(']') - ; - - rings_array = lit('[') >> rings(_r1) % lit(',') > lit(']') - ; - - coords.name("Coordinates"); - pos.name("Position"); - ring.name("Ring"); - rings.name("Rings"); - rings_array.name("Rings array"); - - // error handler - on_error(coords, error_handler(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/extract_bounding_boxes_x3.hpp b/include/mapnik/json/extract_bounding_boxes_x3.hpp new file mode 100644 index 000000000..39ede302c --- /dev/null +++ b/include/mapnik/json/extract_bounding_boxes_x3.hpp @@ -0,0 +1,35 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + + +#ifndef MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP +#define MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP + +namespace mapnik { namespace json { + +template +void extract_bounding_boxes(Iterator & start, Iterator const& end, Boxes & boxes); + +}} + + +#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP diff --git a/include/mapnik/json/extract_bounding_boxes_x3_config.hpp b/include/mapnik/json/extract_bounding_boxes_x3_config.hpp new file mode 100644 index 000000000..885c066c1 --- /dev/null +++ b/include/mapnik/json/extract_bounding_boxes_x3_config.hpp @@ -0,0 +1,117 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_CONFIG_HPP +#define MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_CONFIG_HPP + +#include +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +//auto feature_collection_impl = x3::with(std::ref(bracket_counter)) +// [x3::with(std::ref(keys)) +// [x3::with(std::ref(callback)) +// [mapnik::json::grammar::feature_collection] +// ]]; + +namespace mapnik { namespace json { + +template +struct extract_positions +{ + using boxes_type = Boxes; + using box_type = typename boxes_type::value_type::first_type; + + extract_positions(Iterator start, Boxes & boxes) + : start_(start), + boxes_(boxes) {} + + template + void operator() (T const& val) const + { + auto const& r = std::get<0>(val); + auto const& b = std::get<1>(val); + if (b.valid()) + { + auto offset = std::distance(start_, r.begin()); + auto size = std::distance(r.begin(), r.end()); + boxes_.emplace_back(std::make_pair(box_type(b.minx(), b.miny(), b.maxx(), b.maxy()), std::make_pair(offset, size))); + //boxes_.emplace_back(std::make_tuple(bbox,offset, size)); + } + } + Iterator start_; + Boxes & boxes_; +}; + +using box_type = mapnik::box2d; +using boxes_type = std::vector>>; +using callback_type = extract_positions; + +using box_type_f = mapnik::box2d; +using boxes_type_f = std::vector>>; +using callback_type_f = extract_positions; + + +namespace grammar { + +struct bracket_tag; +struct feature_callback_tag; + +namespace x3 = boost::spirit::x3; +using space_type = x3::standard::space_type; +//using iterator_type = char const*; + +using phrase_parse_context_type = x3::phrase_parse_context::type; + +using context_type = x3::with_context const, + phrase_parse_context_type>::type; + +using extract_bounding_boxes_context_type = + x3::with_context const, + x3::with_context const, + context_type>::type>::type; + +using extract_bounding_boxes_reverse_context_type = + x3::with_context const, + x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type>::type; + + +using extract_bounding_boxes_context_type_f = + x3::with_context const, + x3::with_context const, + context_type>::type>::type; + +using extract_bounding_boxes_reverse_context_type_f = + x3::with_context const, + x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type>::type; + +}}} + +#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_CONFIG_HPP diff --git a/include/mapnik/json/feature_collection_grammar.hpp b/include/mapnik/json/feature_collection_grammar.hpp deleted file mode 100644 index c71801c3f..000000000 --- a/include/mapnik/json/feature_collection_grammar.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_FEATURE_COLLECTION_GRAMMAR_HPP -#define MAPNIK_FEATURE_COLLECTION_GRAMMAR_HPP - -// mapnik -#include -#include -#include -#include - -// spirit::qi -#include -#include - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; - -struct default_feature_callback -{ - default_feature_callback(std::vector & features) - : features_(features) {} - void operator() (feature_ptr const& feature) - { - features_.push_back(feature); - } - std::vector & features_; -}; - -struct apply_feature_callback -{ - using result_type = void; - template - void operator() (Callback & callback, Feature const& feature) const - { - callback(feature); - } -}; - -template > -struct feature_collection_grammar : - qi::grammar -{ - feature_collection_grammar(mapnik::transcoder const& tr); - // grammars - feature_grammar feature_g; - // rules - qi::rule start; // START - qi::rule feature_collection; - qi::rule type; - qi::rule features; - qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature; - // phoenix functions - phoenix::function on_feature; - // error handler - boost::phoenix::function const error_handler; -}; - -template > -struct feature_grammar_callback : - qi::grammar -{ - feature_grammar_callback(mapnik::transcoder const& tr); - // grammars - feature_grammar feature_g; - geometry_grammar geometry_g; - // rules - qi::rule start; // START - qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature; - qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry; - // phoenix functions - phoenix::function set_geometry; - phoenix::function on_feature; - // error handler - boost::phoenix::function const error_handler; -}; - - -}} - -#endif // MAPNIK_FEATURE_COLLECTION_GRAMMAR_HPP diff --git a/include/mapnik/json/feature_collection_grammar_impl.hpp b/include/mapnik/json/feature_collection_grammar_impl.hpp deleted file mode 100644 index b2836af37..000000000 --- a/include/mapnik/json/feature_collection_grammar_impl.hpp +++ /dev/null @@ -1,122 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - - -// mapnik -#include -#include - -// spirit::qi -#include -#include - -namespace mapnik { namespace json { - -template -feature_collection_grammar::feature_collection_grammar(mapnik::transcoder const& tr) - : feature_collection_grammar::base_type(start,"start"), - feature_g(tr) -{ - qi::lit_type lit; - qi::eps_type eps; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_a_type _a; - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::_r3_type _r3; - using phoenix::construct; - using phoenix::new_; - using phoenix::val; - using qi::on_error; - using qi::fail; - start = feature_collection(_r1, _r2, _r3) - ; - - feature_collection = lit('{') > (type | features(_r1, _r2, _r3) | feature_g.json_.key_value) % lit(',') > lit('}') - ; - - type = lit("\"type\"") > lit(':') > lit("\"FeatureCollection\"") - ; - - features = lit("\"features\"") - > lit(':') > lit('[') > - ( lit(']') | ((feature(_r1, _r2, _r3) [_r2 +=1] % lit(',')) > lit(']'))) - ; - - feature = eps[_a = phoenix::construct(new_(_r1, _r2))] - > feature_g(*_a)[on_feature(_r3,_a)] - ; - - start.name("start"); - feature_collection.name("FeatureCollection"); - type.name("type"); - features.name("features"); - feature.name("feature"); - feature_g.name("feature-grammar"); - on_error(feature_collection, error_handler(_1, _2, _3, _4)); -} - - -template -feature_grammar_callback::feature_grammar_callback(mapnik::transcoder const& tr) - : feature_grammar_callback::base_type(start,"start"), - feature_g(tr) -{ - qi::lit_type lit; - qi::eps_type eps; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_a_type _a; - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::_r3_type _r3; - using phoenix::construct; - using phoenix::new_; - using phoenix::val; - using qi::on_error; - using qi::fail; - start = feature_from_geometry(_r1, _r2, _r3) | feature(_r1, _r2, _r3) - ; - - feature = eps[_a = phoenix::construct(new_(_r1, _r2))] - >> feature_g(*_a)[on_feature(_r3,_a)] - ; - - feature_from_geometry = - eps[_a = phoenix::construct(new_(_r1, _r2))] - >> geometry_g[set_geometry(*_a, _1)] [on_feature(_r3, _a)] - ; - - start.name("start"); - feature.name("feature"); - feature_from_geometry.name("feature-from-geometry"); - feature_g.name("feature-grammar"); - geometry_g.name("geometry-grammar"); - on_error(feature, error_handler(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/feature_generator_grammar.hpp b/include/mapnik/json/feature_generator_grammar.hpp index 9eaa3bb99..6da343feb 100644 --- a/include/mapnik/json/feature_generator_grammar.hpp +++ b/include/mapnik/json/feature_generator_grammar.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -63,17 +63,6 @@ struct end_container } }; -template <> -struct transform_attribute, - mapnik::geometry::geometry const& , karma::domain> -{ - using type = mapnik::geometry::geometry const&; - static type pre(const boost::fusion::cons& f) - { - return boost::fusion::at >(f).get_geometry(); - } -}; - }}} namespace mapnik { namespace json { @@ -91,6 +80,15 @@ struct get_id } }; +struct extract_geometry +{ + using result_type = mapnik::geometry::geometry const&; + template + result_type operator() (T const& f) const + { + return f.get_geometry(); + } +}; template struct feature_generator_grammar : @@ -101,6 +99,7 @@ struct feature_generator_grammar : geometry_generator_grammar > geometry; properties_generator_grammar properties; boost::phoenix::function > id_; + boost::phoenix::function geom_; }; }} diff --git a/include/mapnik/json/feature_generator_grammar_impl.hpp b/include/mapnik/json/feature_generator_grammar_impl.hpp index f819baa80..3bb56dff9 100644 --- a/include/mapnik/json/feature_generator_grammar_impl.hpp +++ b/include/mapnik/json/feature_generator_grammar_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,11 +22,6 @@ #include -#include -#include -#include -#include - namespace mapnik { namespace json { template @@ -40,7 +35,7 @@ feature_generator_grammar::feature_generator_gramma feature = lit("{\"type\":\"Feature\",\"id\":") << uint_[_1 = id_(_val)] - << lit(",\"geometry\":") << geometry + << lit(",\"geometry\":") << geometry[_1 = geom_(_val)] << lit(",\"properties\":") << properties << lit('}') ; diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp deleted file mode 100644 index fae8ed58a..000000000 --- a/include/mapnik/json/feature_grammar.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_FEATURE_GRAMMAR_HPP -#define MAPNIK_FEATURE_GRAMMAR_HPP - -// mapnik -#include -#include -#include -#include -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -namespace fusion = boost::fusion; - -struct put_property -{ - using result_type = void; - explicit put_property(mapnik::transcoder const& tr) - : tr_(tr) {} - template - result_type operator() (T0 & feature, T1 const& key, T2 && val) const - { - feature.put_new(key, mapnik::util::apply_visitor(attribute_value_visitor(tr_),val)); - } - mapnik::transcoder const& tr_; -}; - -struct set_geometry_impl -{ - using result_type = void; - template - result_type operator() (T0 & feature, T1 && geom) const - { - return feature.set_geometry(std::move(geom)); - } -}; - -template > -struct feature_grammar : qi::grammar -{ - explicit feature_grammar(mapnik::transcoder const& tr); - // generic JSON - generic_json json_; - // geoJSON - qi::rule start; - qi::rule, void(FeatureType&), space_type> feature; - qi::rule feature_part; - qi::rule feature_type; - qi::rule properties; - qi::rule, void(FeatureType &),space_type> attributes; - // functions - phoenix::function put_property_; - phoenix::function set_geometry; - // error handler - boost::phoenix::function const error_handler; - // geometry - geometry_grammar geometry_grammar_; -}; - -}} - -#endif // MAPNIK_FEATURE_GRAMMAR_HPP diff --git a/include/mapnik/json/feature_grammar_impl.hpp b/include/mapnik/json/feature_grammar_impl.hpp deleted file mode 100644 index bdda650cc..000000000 --- a/include/mapnik/json/feature_grammar_impl.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include - -namespace mapnik { namespace json { - -template -feature_grammar::feature_grammar(mapnik::transcoder const& tr) - : feature_grammar::base_type(start,"feature"), - json_(), - put_property_(put_property(tr)) -{ - qi::lit_type lit; - qi::long_long_type long_long; - qi::double_type double_; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_a_type _a; - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::eps_type eps; - qi::char_type char_; - using qi::fail; - using qi::on_error; - using phoenix::new_; - using phoenix::construct; - - // geojson types - feature_type = lit("\"type\"") > lit(':') > lit("\"Feature\"") - ; - - start = feature(_r1); - - feature = eps[_a = false] > lit('{') > - feature_part(_r1, _a) % lit(',') - > eps(_a) > lit('}') - ; - - feature_part = feature_type[_r2 = true] - | - (lit("\"geometry\"") > lit(':') > geometry_grammar_[set_geometry(_r1, _1)]) - | - properties(_r1) - | - json_.key_value - ; - - properties = lit("\"properties\"") - > lit(':') > ((lit('{') > -attributes(_r1) > lit('}')) | lit("null")) - ; - - attributes = (json_.string_ [_a = _1] > lit(':') > json_.value [put_property_(_r1,_a,_1)]) % lit(',') - ; - - feature.name("Feature"); - feature_type.name("type"); - properties.name("properties"); - attributes.name("Attributes"); - on_error(feature, error_handler(_1, _2, _3, _4)); - -} - -}} diff --git a/include/mapnik/json/feature_grammar_x3.hpp b/include/mapnik/json/feature_grammar_x3.hpp new file mode 100644 index 000000000..b3425e88f --- /dev/null +++ b/include/mapnik/json/feature_grammar_x3.hpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_FEATURE_GRAMMAR_X3_HPP +#define MAPNIK_JSON_FEATURE_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +using feature_grammar_type = x3::rule; +using geometry_grammar_type = x3::rule >; + +BOOST_SPIRIT_DECLARE(feature_grammar_type); +BOOST_SPIRIT_DECLARE(geometry_grammar_type); + +} + +grammar::feature_grammar_type const& feature_grammar(); +grammar::geometry_grammar_type const& geometry_grammar(); + + +}} + +#endif // MAPNIK_JSON_FEATURE_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/feature_grammar_x3_def.hpp b/include/mapnik/json/feature_grammar_x3_def.hpp new file mode 100644 index 000000000..1e18faeec --- /dev/null +++ b/include/mapnik/json/feature_grammar_x3_def.hpp @@ -0,0 +1,318 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_FEATURE_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_FEATURE_GRAMMAR_X3_DEF_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace mapnik { namespace json { + +struct stringifier +{ + std::string operator()(std::string const& val) const + { + return "\"" + val + "\""; + } + + std::string operator()(value_null) const + { + return "null"; + } + + std::string operator()(value_bool val) const + { + return val ? "true" : "false"; + } + + std::string operator()(value_integer val) const + { + std::string str; + util::to_string(str, val); + return str; + } + + std::string operator()(value_double val) const + { + std::string str; + util::to_string(str, val); + return str; + } + + std::string operator()(std::vector const& array) const + { + std::string str = "["; + bool first = true; + for (auto const& val : array) + { + if (first) first = false; + else str += ","; + str += mapnik::util::apply_visitor(*this, val); + } + str += "]"; + return str; + } + + std::string operator()(std::vector> const& object) const + { + std::string str = "{"; + bool first = true; + for (auto const& kv : object) + { + if (first) first = false; + else str += ","; + str += "\"" + kv.first + "\""; + str += ":"; + str += mapnik::util::apply_visitor(*this, kv.second); + } + str += "}"; + return str; + } +}; + +struct attribute_value_visitor +{ +public: + attribute_value_visitor(mapnik::transcoder const& tr) + : tr_(tr) {} + + mapnik::value operator()(std::string const& val) const + { + return mapnik::value(tr_.transcode(val.c_str())); + } + + mapnik::value operator()(std::vector const& array) const + { + std::string str = stringifier()(array); + return mapnik::value(tr_.transcode(str.c_str())); + } + + mapnik::value operator()(std::vector > const& object) const + { + std::string str = stringifier()(object); + return mapnik::value(tr_.transcode(str.c_str())); + } + + template + mapnik::value operator()(T const& val) const + { + return mapnik::value(val); + } + + mapnik::transcoder const& tr_; +}; + +namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::lit; +using x3::omit; +using x3::char_; + +namespace { +auto const& value = generic_json_grammar(); +// import unicode string rule +auto const& geojson_string = unicode_string_grammar(); +// import positions rule +auto const& positions_rule = positions_grammar(); +} + +// geometry types symbols +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"", mapnik::geometry::geometry_types::Point) + ("\"LineString\"", mapnik::geometry::geometry_types::LineString) + ("\"Polygon\"", mapnik::geometry::geometry_types::Polygon) + ("\"MultiPoint\"", mapnik::geometry::geometry_types::MultiPoint) + ("\"MultiLineString\"", mapnik::geometry::geometry_types::MultiLineString ) + ("\"MultiPolygon\"",mapnik::geometry::geometry_types::MultiPolygon) + ("\"GeometryCollection\"",mapnik::geometry::geometry_types::GeometryCollection) + ; + } +} geometry_type_symbols; + +auto assign_name = [](auto const& ctx) +{ + std::get<0>(_val(ctx)) = std::move(_attr(ctx)); +}; +auto assign_value = [](auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto const assign_geometry_type = [] (auto const& ctx) +{ + std::get<0>(_val(ctx)) = _attr(ctx); +}; + +auto const create_geometry = [] (auto const& ctx) +{ + mapnik::geometry::geometry geom; + auto const type = std::get<0>(_attr(ctx)); + if (type == mapnik::geometry::geometry_types::GeometryCollection) + { + _val(ctx) = std::move(std::get<2>(_attr(ctx))); + } + else + { + auto const& coordinates = std::get<1>(_attr(ctx)); + mapnik::json::create_geometry(geom, type, coordinates); + _val(ctx) = std::move(geom); + } +}; + +auto const assign_geometry = [] (auto const& ctx) +{ + mapnik::feature_impl & feature = x3::get(ctx); + feature.set_geometry(std::move(_attr(ctx))); +}; + +auto const push_geometry = [] (auto const& ctx) +{ + mapnik::geometry::geometry geom; + auto const type = std::get<0>(_attr(ctx)); + auto const& coordinates = std::get<1>(_attr(ctx)); + mapnik::json::create_geometry(geom, type, coordinates); + _val(ctx).push_back(std::move(geom)); +}; + +auto const assign_positions = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto const assign_collection = [] (auto const& ctx) +{ + std::get<2>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_property = [](auto const& ctx) +{ + mapnik::feature_impl & feature = x3::get(ctx); + mapnik::transcoder const& tr = x3::get(ctx); + feature.put_new(std::get<0>(_attr(ctx)), + mapnik::util::apply_visitor(attribute_value_visitor(tr), + std::get<1>(_attr(ctx)))); +}; + + +//exported rules +feature_grammar_type const feature_rule = "Feature Rule"; +geometry_grammar_type const geometry_rule = "Feature Rule"; + +// rules +x3::rule const feature_type = "Feature Type"; +x3::rule const geometry_type = "Geometry Type"; +x3::rule const coordinates = "Coordinates"; +x3::rule>> const geometry_tuple = "Geometry"; +x3::rule> const property = "Property"; +x3::rule const properties = "Properties"; +x3::rule const feature_part = "Feature part"; +x3::rule> const geometry_collection = "GeometryCollection"; + +auto const feature_type_def = lit("\"type\"") > lit(':') > lit("\"Feature\""); + +auto const geometry_type_def = lit("\"type\"") > lit(':') > geometry_type_symbols; + +auto const coordinates_def = lit("\"coordinates\"") > lit(':') > positions_rule; + +auto const geometry_collection_def = lit("\"geometries\"") > lit(':') + > lit('[') + > ((lit('{') > geometry_tuple[push_geometry] > lit('}')) % lit(',')) + > lit(']'); + +auto const geometry_tuple_def = (geometry_type[assign_geometry_type] + | + coordinates[assign_positions] + | + geometry_collection[assign_collection] + | + (omit[geojson_string] > lit(':') > omit[value])) % lit(','); + + +auto const property_def = geojson_string[assign_name] > lit(':') > value[assign_value]; + +auto const properties_def = property[assign_property] % lit(','); + +auto const feature_part_def = feature_type + | + (lit("\"geometry\"") > lit(':') > geometry_rule[assign_geometry]) + | + (lit("\"properties\"") > lit(':') > lit('{') > -properties > lit('}')) + | + (omit[geojson_string] > lit(':') > omit[value]) + ; + + +auto const feature_rule_def = lit('{') > feature_part % lit(',') > lit('}'); + + +auto const geometry_rule_def = (lit('{') > geometry_tuple[create_geometry] > lit('}')) | lit("null"); + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + feature_type, + geometry_type, + coordinates, + geometry_tuple, + property, + properties, + feature_part, + feature_rule, + geometry_rule, + geometry_collection + ); +#pragma GCC diagnostic pop + +}}} + +namespace mapnik { namespace json { + +grammar::feature_grammar_type const& feature_grammar() +{ + return grammar::feature_rule; +} + +grammar::geometry_grammar_type const& geometry_grammar() +{ + return grammar::geometry_rule; +} + +}} + +#endif // MAPNIK_JSON_FEATURE_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/feature_parser.hpp b/include/mapnik/json/feature_parser.hpp index 433d19e30..7c0cf3198 100644 --- a/include/mapnik/json/feature_parser.hpp +++ b/include/mapnik/json/feature_parser.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,25 +25,12 @@ // mapnik #include -#include - -// boost -#include -#include +// stl +#include namespace mapnik { namespace json { -inline bool from_geojson(std::string const& json, mapnik::feature_impl & feature) -{ - static const mapnik::transcoder tr("utf8"); - using iterator_type = char const*; - static const mapnik::json::feature_grammar g(tr); - using namespace boost::spirit; - standard::space_type space; - iterator_type start = json.c_str(); - iterator_type end = start + json.length(); - return qi::phrase_parse(start, end, (g)(boost::phoenix::ref(feature)), space); -} +bool from_geojson(std::string const& json, mapnik::feature_impl & feature); }} diff --git a/include/mapnik/json/generic_json.hpp b/include/mapnik/json/generic_json.hpp deleted file mode 100644 index 65c04c47d..000000000 --- a/include/mapnik/json/generic_json.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_GENERIC_JSON_HPP -#define MAPNIK_GENERIC_JSON_HPP - -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -#include - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; -namespace standard = boost::spirit::standard; -namespace phoenix = boost::phoenix; -using space_type = standard::space_type; - -struct json_value; - -using json_array = std::vector; -using json_object_element = std::pair; -using json_object = std::vector; -using json_value_base = mapnik::util::variant, - mapnik::util::recursive_wrapper >; -struct json_value : json_value_base -{ -#if __cpp_inheriting_constructors >= 200802 - - using json_value_base::json_value_base; - -#else - - json_value() = default; - - template - json_value(T && val) - : json_value_base(std::forward(val)) {} - -#endif -}; - -using uchar = std::uint32_t; // a unicode code point - -// unicode string grammar via boost/libs/spirit/example/qi/json/json/parser/grammar.hpp - -template -struct unicode_string : qi::grammar -{ - unicode_string(); - qi::rule escape; - qi::rule char_esc; - qi::rule double_quoted; -}; - - -struct push_utf8 -{ - using result_type = void; - - void operator()(std::string& utf8, uchar code_point) const - { - typedef std::back_insert_iterator insert_iter; - insert_iter out_iter(utf8); - boost::utf8_output_iterator utf8_iter(out_iter); - *utf8_iter++ = code_point; - } -}; - -struct push_esc -{ - using result_type = void; - - void operator()(std::string& utf8, uchar c) const - { - switch (c) - { - case ' ': utf8 += ' '; break; - case '\t': utf8 += '\t'; break; - case '0': utf8 += char(0); break; - case 'a': utf8 += 0x7; break; - case 'b': utf8 += 0x8; break; - case 't': utf8 += 0x9; break; - case 'n': utf8 += 0xA; break; - case 'v': utf8 += 0xB; break; - case 'f': utf8 += 0xC; break; - case 'r': utf8 += 0xD; break; - case 'e': utf8 += 0x1B; break; - case '"': utf8 += '"'; break; - case '/': utf8 += '/'; break; - case '\\': utf8 += '\\'; break; - case '_': push_utf8()(utf8, 0xA0); break; - case 'N': push_utf8()(utf8, 0x85); break; - case 'L': push_utf8()(utf8, 0x2028); break; - case 'P': push_utf8()(utf8, 0x2029); break; - } - } -}; - -template< typename Iterator> -unicode_string::unicode_string() - : unicode_string::base_type(double_quoted) -{ - qi::char_type char_; - qi::_val_type _val; - qi::_r1_type _r1; - qi::_1_type _1; - qi::lit_type lit; - qi::eol_type eol; - qi::repeat_type repeat; - qi::hex_type hex; - - using boost::spirit::qi::uint_parser; - using boost::phoenix::function; - using boost::phoenix::ref; - - uint_parser hex4; - uint_parser hex8; - function push_utf8; - function push_esc; - - escape = - ('x' > hex) [push_utf8(_r1, _1)] - | - ('u' > hex4) [push_utf8(_r1, _1)] - | - ('U' > hex8) [push_utf8(_r1, _1)] - | - char_("0abtnvfre\"/\\N_LP \t") [push_esc(_r1, _1)] - | - eol // continue to next line - ; - - char_esc = - '\\' > escape(_r1) - ; - - double_quoted = - '"' - > *(char_esc(_val) | (~char_('"')) [_val += _1]) - > '"' - ; -} - -template -struct generic_json : qi::grammar -{ - generic_json(); - qi::rule value; - qi::int_parser int__; - unicode_string string_; - qi::rule key_value; - qi::rule number; - qi::rule object; - qi::rule array; - qi::real_parser> strict_double; - // conversions - boost::phoenix::function> integer_converter; - boost::phoenix::function> double_converter; -}; - -}} - -#endif // MAPNIK_GENERIC_JSON_HPP diff --git a/include/mapnik/path_expression_grammar.hpp b/include/mapnik/json/generic_json_grammar_x3.hpp similarity index 56% rename from include/mapnik/path_expression_grammar.hpp rename to include/mapnik/json/generic_json_grammar_x3.hpp index 61a3db7ed..1dce6b161 100644 --- a/include/mapnik/path_expression_grammar.hpp +++ b/include/mapnik/json/generic_json_grammar_x3.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,40 +20,32 @@ * *****************************************************************************/ -#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP -#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP - -// mapnik -#include +#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP +#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP +#include #pragma GCC diagnostic push #include -#include +#include #pragma GCC diagnostic pop -// stl -#include #include -namespace mapnik -{ +namespace mapnik { namespace json { -using namespace boost; -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -namespace standard_wide = boost::spirit::standard_wide; +namespace x3 = boost::spirit::x3; -using standard_wide::space_type; - -template -struct path_expression_grammar : qi::grammar(), space_type> -{ - path_expression_grammar(); - qi::rule() , space_type> expr; - qi::rule attr; - qi::rule str; -}; +namespace grammar { +using generic_json_grammar_type = x3::rule; +using generic_json_key_value_type = x3::rule; +BOOST_SPIRIT_DECLARE(generic_json_grammar_type); +BOOST_SPIRIT_DECLARE(generic_json_key_value_type); } -#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP +grammar::generic_json_grammar_type const& generic_json_grammar(); +grammar::generic_json_key_value_type const& generic_json_key_value(); + +}} + +#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/generic_json_grammar_x3_def.hpp b/include/mapnik/json/generic_json_grammar_x3_def.hpp new file mode 100644 index 000000000..64570eeb1 --- /dev/null +++ b/include/mapnik/json/generic_json_grammar_x3_def.hpp @@ -0,0 +1,133 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +auto make_null = [] (auto const& ctx) +{ + _val(ctx) = mapnik::value_null{}; +}; + +auto make_true = [] (auto const& ctx) +{ + _val(ctx) = true; +}; + +auto make_false = [] (auto const& ctx) +{ + _val(ctx) = false; +}; + +auto assign = [](auto const& ctx) +{ + _val(ctx) = _attr(ctx); +}; + +auto assign_key = [](auto const& ctx) +{ + std::get<0>(_val(ctx)) = _attr(ctx); +}; + +auto assign_value = [](auto const& ctx) +{ + std::get<1>(_val(ctx)) = _attr(ctx); +}; + + +using x3::lit; +using x3::string; +// exported rules +// start +generic_json_grammar_type const value("JSON Value"); +generic_json_key_value_type const key_value("JSON Object element"); +// rules +x3::rule const object("JSON Object"); +x3::rule const array("JSON Array"); +x3::rule const number("JSON Number"); + +auto const json_double = x3::real_parser>(); +auto const json_integer = x3::int_parser(); + +// import unicode string rule +namespace { auto const& json_string = mapnik::json::unicode_string_grammar(); } + // generic json types +auto const value_def = object | array | json_string | number + ; + +auto const key_value_def = json_string[assign_key] > lit(':') > value[assign_value] + ; + +auto const object_def = lit('{') + > -(key_value % lit(',')) + > lit('}') + ; + +auto const array_def = lit('[') + > -(value % lit(',')) + > lit(']') + ; + +auto const number_def = json_double[assign] + | json_integer[assign] + | lit("true") [make_true] + | lit ("false") [make_false] + | lit("null")[make_null] + ; + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + value, + object, + key_value, + array, + number + ); + +#pragma GCC diagnostic pop + +}}} + +namespace mapnik { namespace json { + +grammar::generic_json_grammar_type const& generic_json_grammar() +{ + return grammar::value; +} +grammar::generic_json_key_value_type const& generic_json_key_value() +{ + return grammar::key_value; +} + +}} + +#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/geojson_grammar_x3.hpp b/include/mapnik/json/geojson_grammar_x3.hpp new file mode 100644 index 000000000..b5dda0b35 --- /dev/null +++ b/include/mapnik/json/geojson_grammar_x3.hpp @@ -0,0 +1,83 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GEOJSON_GRAMMAR_X3_HPP +#define MAPNIK_JSON_GEOJSON_GRAMMAR_X3_HPP + +#include +#include +#include +#include +#include +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +#include + +namespace mapnik { namespace json { + +namespace x3 = boost::spirit::x3; +struct geojson_value; +using geojson_array = std::vector; +using geojson_object_element = std::pair; +using geojson_object = std::vector; +using geojson_value_base = mapnik::util::variant; +struct geojson_value : geojson_value_base +{ +#if __cpp_inheriting_constructors >= 200802 + + using geojson_value_base::geojson_value_base; + +#else + + geojson_value() = default; + + template + geojson_value(T && val) + : geojson_value_base(std::forward(val)) {} + +#endif +}; + +namespace grammar { + +using geojson_grammar_type = x3::rule; +using key_value_type = x3::rule; +BOOST_SPIRIT_DECLARE(geojson_grammar_type, key_value_type); +} + +grammar::geojson_grammar_type const& geojson_grammar(); +grammar::key_value_type const& key_value_grammar(); + +}} + +#endif // MAPNIK_JSON_GEOJSON_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/geojson_grammar_x3_def.hpp b/include/mapnik/json/geojson_grammar_x3_def.hpp new file mode 100644 index 000000000..10dd81aab --- /dev/null +++ b/include/mapnik/json/geojson_grammar_x3_def.hpp @@ -0,0 +1,183 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP + + +#include +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +auto make_null = [] (auto const& ctx) +{ + _val(ctx) = mapnik::value_null{}; +}; + +auto make_true = [] (auto const& ctx) +{ + _val(ctx) = true; +}; + +auto make_false = [] (auto const& ctx) +{ + _val(ctx) = false; +}; + +auto assign = [](auto const& ctx) +{ + _val(ctx) = std::move(_attr(ctx)); +}; + +auto assign_key = [](auto const& ctx) +{ + std::string const& name = _attr(ctx); + keys_map & keys = x3::get(ctx); + auto result = keys.insert(keys_map::value_type(name, keys.size() + 1)); + std::get<0>(_val(ctx)) = result.first->right; +}; + +auto assign_value = [](auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +using x3::lit; +using x3::string; +using x3::lexeme; + +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Feature\"",mapnik::geometry::geometry_types(0xff)) // this is a temp hack FIXME + ("\"Point\"", mapnik::geometry::geometry_types::Point) + ("\"LineString\"", mapnik::geometry::geometry_types::LineString) + ("\"Polygon\"", mapnik::geometry::geometry_types::Polygon) + ("\"MultiPoint\"", mapnik::geometry::geometry_types::MultiPoint) + ("\"MultiLineString\"", mapnik::geometry::geometry_types::MultiLineString ) + ("\"MultiPolygon\"",mapnik::geometry::geometry_types::MultiPolygon) + ("\"GeometryCollection\"",mapnik::geometry::geometry_types::GeometryCollection) + ; + } +} geometry_type_sym; + +// exported rules +// start +geojson_grammar_type const value("JSON Value"); +key_value_type const key_value("JSON key/value"); +// rules +x3::rule const object("JSON Object"); +x3::rule const array("JSON Array"); +x3::rule const number("JSON Number"); +//x3::rule key_value("JSON key/value"); +// GeoJSON +x3::rule const coordinates("GeoJSON Coordinates"); +x3::rule const geometry_type("GeoJSON Geometry Type"); +x3::rule const geojson_key_value("GeoJSON Key/Value Type"); +auto const geojson_double = x3::real_parser>(); +auto const geojson_integer = x3::int_parser(); + +// import unicode string rule +namespace { auto const& geojson_string = mapnik::json::unicode_string_grammar(); } +// import positions rule +namespace { auto const& positions_rule = mapnik::json::positions_grammar(); } + +// GeoJSON types +auto const value_def = object | array | geojson_string | number + ; + +auto const coordinates_def = lexeme[lit('"') >> (string("coordinates") > lit('"'))][assign_key] + > lit(':') > (positions_rule[assign_value] | value[assign_value]) + ; + +auto const geometry_type_def = lexeme[lit('"') >> (string("type") > lit('"'))][assign_key] + > lit(':') > (geometry_type_sym[assign_value] | value[assign_value]) + ; + +auto const key_value_def = geojson_string[assign_key] > lit(':') > value[assign_value] + ; + +auto const geojson_key_value_def = + geometry_type + | + coordinates + | + key_value + ; + +auto const object_def = lit('{') + > -(geojson_key_value % lit(',')) + > lit('}') + ; + +auto const array_def = lit('[') + > -(value % lit(',')) + > lit(']') + ; + +auto const number_def = geojson_double[assign] + | geojson_integer[assign] + | lit("true") [make_true] + | lit ("false") [make_false] + | lit("null")[make_null] + ; + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + value, + geometry_type, + coordinates, + object, + key_value, + geojson_key_value, + array, + number + ); + +#pragma GCC diagnostic pop + +}}} + +namespace mapnik { namespace json { + +grammar::geojson_grammar_type const& geojson_grammar() +{ + return grammar::value; +} + +grammar::key_value_type const& key_value_grammar() +{ + return grammar::key_value; +} + +}} + +#endif // MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp index 931c41629..7d4e9df28 100644 --- a/include/mapnik/json/geometry_generator_grammar.hpp +++ b/include/mapnik/json/geometry_generator_grammar.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,13 +26,10 @@ // mapnik #include #include -#include // boost #pragma GCC diagnostic push #include #include -#include -#include #include // for vc++ and android whose c++11 libs lack std::trunc #include #pragma GCC diagnostic pop @@ -43,18 +40,6 @@ namespace karma = boost::spirit::karma; namespace detail { -template -struct get_type -{ - using result_type = mapnik::geometry::geometry_types; - template - result_type operator() (T const& geom) const - { - auto type = mapnik::geometry::geometry_type(geom); - return type; - } -}; - template struct json_coordinate_policy : karma::real_policies { @@ -88,29 +73,28 @@ struct json_coordinate_policy : karma::real_policies template struct geometry_generator_grammar : - karma::grammar + karma::grammar { + using coord_type = typename Geometry::coordinate_type; geometry_generator_grammar(); - karma::rule geometry; - karma::rule, Geometry const&() > geometry_dispatch; - karma::rule const&()> point; - karma::rule const&()> point_coord; - karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; - karma::rule const&()> polygon; - karma::rule const&()> polygon_coord; - karma::rule const&()> linearring_coord; - karma::rule const& ()> multi_point; - karma::rule const& ()> multi_point_coord; - karma::rule const& ()> multi_linestring; - karma::rule const& ()> multi_linestring_coord; - karma::rule const& ()> multi_polygon; - karma::rule const& ()> multi_polygon_coord; - karma::rule const& ()> geometry_collection; - karma::rule const& ()> geometries; - boost::phoenix::function > geometry_type; - karma::real_generator > coordinate; - + karma::rule geometry; + karma::rule()> point; + karma::rule()> point_coord; + karma::rule()> linestring; + karma::rule()> linestring_coord; + karma::rule()> polygon; + karma::rule()> polygon_coord; + karma::rule()> linear_ring_coord; + karma::rule()> multi_point; + karma::rule()> multi_point_coord; + karma::rule()> multi_linestring; + karma::rule ()> multi_linestring_coord; + karma::rule()> multi_polygon; + karma::rule()> multi_polygon_coord; + karma::rule()> geometry_collection; + karma::rule()> geometries; + // + karma::real_generator > coordinate; }; }} diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp index 952bb739f..1298803bb 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,92 +22,79 @@ // mapnik #include -#include -#include -#include +#include -// boost -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop namespace mapnik { namespace json { namespace karma = boost::spirit::karma; -namespace phoenix = boost::phoenix; template geometry_generator_grammar::geometry_generator_grammar() : geometry_generator_grammar::base_type(geometry) { - boost::spirit::karma::_val_type _val; - boost::spirit::karma::_1_type _1; - boost::spirit::karma::_a_type _a; boost::spirit::karma::lit_type lit; - boost::spirit::karma::uint_type uint_; - boost::spirit::karma::eps_type eps; - geometry = geometry_dispatch.alias() - ; - - geometry_dispatch = eps[_a = geometry_type(_val)] << - (&uint_(geometry::geometry_types::Point)[_1 = _a] - << (point | lit("null"))) + geometry = + point | - (&uint_(geometry::geometry_types::LineString)[_1 = _a] - << (linestring | lit("null"))) + linestring | - (&uint_(geometry::geometry_types::Polygon)[_1 = _a] - << (polygon | lit("null"))) + polygon | - (&uint_(geometry::geometry_types::MultiPoint)[_1 = _a] - << (multi_point | lit("null"))) + multi_point | - (&uint_(geometry::geometry_types::MultiLineString)[_1 = _a] - << (multi_linestring | lit("null"))) + multi_linestring | - (&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a] - << (multi_polygon | lit("null"))) + multi_polygon | - (&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a] - << (geometry_collection | lit("null"))) + geometry_collection | - lit("null") + lit("null") // geometry_empty ; point = lit("{\"type\":\"Point\",\"coordinates\":") << point_coord << lit("}") ; - linestring = lit("{\"type\":\"LineString\",\"coordinates\":[") << linestring_coord << lit("]}") + + linestring = lit("{\"type\":\"LineString\",\"coordinates\":") << linestring_coord << lit("}") ; - polygon = lit("{\"type\":\"Polygon\",\"coordinates\":[") << polygon_coord << lit("]}") + + polygon = lit("{\"type\":\"Polygon\",\"coordinates\":") << polygon_coord << lit("}") ; - multi_point = lit("{\"type\":\"MultiPoint\",\"coordinates\":[") << multi_point_coord << lit("]}") + + multi_point = lit("{\"type\":\"MultiPoint\",\"coordinates\":") << multi_point_coord << lit("}") ; - multi_linestring = lit("{\"type\":\"MultiLineString\",\"coordinates\":[") << multi_linestring_coord << lit("]}") + + multi_linestring = lit("{\"type\":\"MultiLineString\",\"coordinates\":") << multi_linestring_coord << lit("}") ; - multi_polygon = lit("{\"type\":\"MultiPolygon\",\"coordinates\":[") << multi_polygon_coord << lit("]}") + + multi_polygon = lit("{\"type\":\"MultiPolygon\",\"coordinates\":") << multi_polygon_coord << lit("}") ; + geometry_collection = lit("{\"type\":\"GeometryCollection\",\"geometries\":[") << geometries << lit("]}") ; + point_coord = lit('[') << coordinate << lit(',') << coordinate << lit(']') ; - linestring_coord = point_coord % lit(',') + + linestring_coord = lit('[') << -(point_coord % lit(',')) << lit(']') ; - linearring_coord = point_coord % lit(',') + + linear_ring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')//linestring_coord.alias() ; - polygon_coord = (lit('[') << linearring_coord << lit(']')) % lit(',') + + polygon_coord = lit('[') << linear_ring_coord % lit(',') << lit(']') ; - multi_point_coord = linestring_coord.alias() + + multi_point_coord = lit('[') << -(point_coord % lit(',')) << lit(']');//linestring_coord.alias() ; - multi_linestring_coord = (lit('[') << linestring_coord << lit(']')) % lit(',') + + multi_linestring_coord = lit('[') << linestring_coord % lit(',') << lit(']') ; - multi_polygon_coord = (lit('[') << polygon_coord << lit(']')) % lit(',') + + multi_polygon_coord = lit('[') << polygon_coord % lit(',') << lit("]") ; + geometries = geometry % lit(',') ; } diff --git a/include/mapnik/json/geometry_grammar.hpp b/include/mapnik/json/geometry_grammar.hpp deleted file mode 100644 index fc0d3a43d..000000000 --- a/include/mapnik/json/geometry_grammar.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_GEOMETRY_GRAMMAR_HPP -#define MAPNIK_GEOMETRY_GRAMMAR_HPP - -// mapnik -#include // for geometry_type -#include -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; - -template > -struct geometry_grammar : - qi::grammar() ,space_type> -{ - geometry_grammar(); - qi::rule(), space_type> start; - qi::rule, mapnik::geometry::geometry(), space_type> geometry; - qi::rule&), space_type> geometry_part; - qi::rule(), space_type> geometry_collection; - qi::symbols geometry_type_dispatch; - positions_grammar coordinates; - boost::phoenix::function create_geometry; - // generic JSON - generic_json json_; - // error handler - ErrorHandler error_handler; -}; - -}} - -#endif // MAPNIK_GEOMETRY_GRAMMAR_HPP diff --git a/include/mapnik/json/geometry_grammar_impl.hpp b/include/mapnik/json/geometry_grammar_impl.hpp deleted file mode 100644 index 171894c78..000000000 --- a/include/mapnik/json/geometry_grammar_impl.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include -#include -#include -// boost -#include -#include - -namespace mapnik { namespace json { - -template -geometry_grammar::geometry_grammar() - : geometry_grammar::base_type(start,"geometry"), - coordinates(error_handler) -{ - qi::lit_type lit; - qi::int_type int_; - qi::double_type double_; - qi::_val_type _val; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_a_type _a; - qi::_b_type _b; - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::_r3_type _r3; - qi::eps_type eps; - using qi::fail; - using qi::on_error; - using phoenix::push_back; - - start = geometry.alias() | lit("null"); - - geometry = lit('{')[_a = 0] - > (geometry_part(_a, _b, _val) % lit(','))[create_geometry(_val, _a, _b)] - > lit('}'); - - geometry_part = ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_r1 = _1]) - | - (lit("\"coordinates\"") > lit(':') > coordinates[_r2 = _1]) - | - (lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[_r3 = _1] > lit(']')) - | - json_.key_value) - ; - - geometry_collection = geometry[push_back(_val, _1)] % lit(',') - ; - geometry_type_dispatch.add - ("\"Point\"",1) - ("\"LineString\"",2) - ("\"Polygon\"",3) - ("\"MultiPoint\"",4) - ("\"MultiLineString\"",5) - ("\"MultiPolygon\"",6) - ("\"GeometryCollection\"",7) - ; - - // give some rules names - geometry.name("Geometry"); - geometry_collection.name("GeometryCollection"); - geometry_type_dispatch.name("type: (Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon|GeometryCollection)"); - coordinates.name("coordinates"); - // error handler - auto error_handler_function = boost::phoenix::function(error_handler); - on_error(start, error_handler_function(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/svg/svg_points_grammar.hpp b/include/mapnik/json/geometry_grammar_x3.hpp similarity index 62% rename from include/mapnik/svg/svg_points_grammar.hpp rename to include/mapnik/json/geometry_grammar_x3.hpp index afbe7ee09..a630f6b05 100644 --- a/include/mapnik/svg/svg_points_grammar.hpp +++ b/include/mapnik/json/geometry_grammar_x3.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,31 +20,32 @@ * *****************************************************************************/ -#ifndef SVG_POINTS_GRAMMAR_HPP -#define SVG_POINTS_GRAMMAR_HPP +#ifndef MAPNIK_GEOMETRY_GRAMMAR_X3_HPP +#define MAPNIK_GEOMETRY_GRAMMAR_X3_HPP // mapnik -#include +#include // for geometry_type #pragma GCC diagnostic push #include -#include +#include #pragma GCC diagnostic pop -namespace mapnik { namespace svg { +// mapnik +#include -using namespace boost::spirit; -using namespace boost::phoenix; +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using geometry_grammar_type = x3::rule>; + +BOOST_SPIRIT_DECLARE(geometry_grammar_type); + +} + +grammar::geometry_grammar_type const& geometry_grammar(); -template -struct svg_points_grammar : qi::grammar -{ - // ctor - svg_points_grammar(); - // rules - qi::rule start; - qi::rule(), SkipType> coord; -}; }} -#endif // SVG_POINTS_GRAMMAR_HPP +#endif // MAPNIK_GEOMETRY_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/geometry_grammar_x3_def.hpp b/include/mapnik/json/geometry_grammar_x3_def.hpp new file mode 100644 index 000000000..69d5a2e90 --- /dev/null +++ b/include/mapnik/json/geometry_grammar_x3_def.hpp @@ -0,0 +1,161 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GEOMETRY_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_GEOMETRY_GRAMMAR_X3_DEF_HPP + +// mapnik +#include +#include +#include +#include +#include +#include +#include +#include +// boost +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::lit; +using x3::_pass; +using x3::omit; + +auto create_geometry = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + mapnik::json::create_geometry_impl()(_val(ctx), std::get<0>(attr), std::get<1>(attr)); +}; + +auto assign_element = [] (auto const& ctx) +{ + _val(ctx) = std::move(_attr(ctx)); +}; + +namespace { +template +struct assign_geometry_element_visitor : util::noncopyable +{ + assign_geometry_element_visitor(T & t) + : t_(t) {} + + void operator() (int const& type) + { + std::get<0>(t_) = type; + } + void operator () (::mapnik::json::positions const& p) + { + std::get<1>(t_) = p; + } + + T & t_; +}; + +} + +auto assign_geometry_element = [] (auto const& ctx) +{ + assign_geometry_element_visitor v(_val(ctx)); + mapnik::util::apply_visitor(v, _attr(ctx)); +}; + +auto assign_collection = [] (auto const& ctx) +{ + auto & val = _val(ctx); + std::get<0>(val) = 7; //GeometryCollection + std::get<1>(val) = std::move(_attr(ctx)); +}; + +auto push_geometry = [] (auto const& ctx) +{ + _val(ctx).emplace_back(std::move(_attr(ctx))); +}; + +// start rule +geometry_grammar_type const geometry("Geometry"); +// rules +x3::rule> const geometry_element("Geometry Element"); +x3::rule> const geometry_tuple("Geometry Tuple"); +x3::rule> const geometry_collection("Geometry Collection"); +// import positions rule +namespace { auto const& pos = positions_grammar(); } +// import generic JSON key:value rule +namespace { auto const& json_key_value = generic_json_key_value(); } + +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"",1) + ("\"LineString\"",2) + ("\"Polygon\"",3) + ("\"MultiPoint\"",4) + ("\"MultiLineString\"",5) + ("\"MultiPolygon\"",6) + ("\"GeometryCollection\"",7) + ; + } +} geometry_type; + +auto const geometry_def = (lit('{') > (geometry_tuple)[create_geometry] > lit('}')) | lit("null") + ; + +auto const geometry_tuple_def = geometry_element[assign_geometry_element] % lit(',') + ; + +auto const geometry_element_def = + (lit("\"type\"") > lit(":") > geometry_type[assign_element]) + | + (lit("\"coordinates\"") > lit(':') > pos[assign_element]) + | + (lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[assign_collection] > lit(']')) + | + omit[json_key_value] + ; + +auto const geometry_collection_def = geometry[push_geometry] % lit(',') + ; + +BOOST_SPIRIT_DEFINE( + geometry, + geometry_element, + geometry_tuple, + geometry_collection + ); + +}}} + +namespace mapnik { namespace json { +grammar::geometry_grammar_type const& geometry_grammar() +{ + return grammar::geometry; +} +}} + + +#endif // MAPNIK_JSON_GEOMETRY_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/geometry_parser.hpp b/include/mapnik/json/geometry_parser.hpp index 761c193f8..a4fded3f0 100644 --- a/include/mapnik/json/geometry_parser.hpp +++ b/include/mapnik/json/geometry_parser.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/json/json_grammar_config.hpp b/include/mapnik/json/json_grammar_config.hpp new file mode 100644 index 000000000..26c117201 --- /dev/null +++ b/include/mapnik/json/json_grammar_config.hpp @@ -0,0 +1,118 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_GRAMMAR_CONFIG_HPP +#define MAPNIK_JSON_GRAMMAR_CONFIG_HPP + +#include +#include +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace json { + +enum well_known_names +{ + id = 1, + type, + features, + geometry, + coordinates, + properties +}; + +constexpr char const* wkn_to_string(well_known_names val) +{ + switch(val) + { + case id: return "id"; + case type: return "type"; + case features: return "features"; + case geometry: return "geometry"; + case coordinates: return "coordinates"; + case properties: return "properties"; + default: return "unknown"; + } +} + + +using keys_map = boost::bimap, + boost::bimaps::set_of>; + +inline keys_map get_keys() +{ + keys_map keys = boost::assign::list_of + ("type", well_known_names::type) + ("features", well_known_names::features) + ("geometry", well_known_names::geometry) + ("coordinates", well_known_names::coordinates) + ("properties", well_known_names::properties) + ("id", well_known_names::id) + ; + return keys; +} + +namespace grammar { + +struct keys_tag; +struct transcoder_tag; +struct feature_tag; + +namespace x3 = boost::spirit::x3; +using space_type = x3::standard::space_type; +using iterator_type = char const*; + +using phrase_parse_context_type = x3::phrase_parse_context::type; +using context_type = x3::with_context const, + phrase_parse_context_type>::type; + +using feature_context_type = x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type; + +// our spirit x3 grammars needs this one with changed order of feature_impl and transcoder (??) +using feature_context_const_type = x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type; + +// helper macro +#define BOOST_SPIRIT_INSTANTIATE_UNUSED(rule_type, Iterator, Context) \ + template bool parse_rule( \ + rule_type rule_ \ + , Iterator& first, Iterator const& last \ + , Context const& context, boost::spirit::x3::unused_type const& ); \ + /***/ + +}}} + +#endif // MAPNIK_JSON_GRAMMAR_CONFIG_HPP diff --git a/include/mapnik/json/json_value.hpp b/include/mapnik/json/json_value.hpp new file mode 100644 index 000000000..8d6c1b09a --- /dev/null +++ b/include/mapnik/json/json_value.hpp @@ -0,0 +1,65 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_JSON_VALUE_HPP +#define MAPNIK_JSON_JSON_VALUE_HPP + +// mapnik +#include +#include +// stl +#include +#include + +namespace mapnik { namespace json { + +struct json_value; + +using json_array = std::vector; +using json_object_element = std::pair; +using json_object = std::vector; +using json_value_base = mapnik::util::variant; +struct json_value : json_value_base +{ +#if __cpp_inheriting_constructors >= 200802 + + using json_value_base::json_value_base; + +#else + + json_value() = default; + + template + json_value(T && val) + : json_value_base(std::forward(val)) {} + +#endif +}; +}} + +#endif // MAPNIK_JSON_JSON_VALUE_HPP diff --git a/src/json/mapnik_json_feature_collection_grammar.cpp b/include/mapnik/json/parse_feature.hpp similarity index 66% rename from src/json/mapnik_json_feature_collection_grammar.cpp rename to include/mapnik/json/parse_feature.hpp index e262d7cfc..b0d775e78 100644 --- a/src/json/mapnik_json_feature_collection_grammar.cpp +++ b/include/mapnik/json/parse_feature.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,10 +20,22 @@ * *****************************************************************************/ -#include -#include -#include -using iterator_type = char const*; -template struct mapnik::json::feature_collection_grammar ; -template struct mapnik::json::feature_grammar_callback ; +#ifndef MAPNIK_JSON_PARSE_FEATURE_HPP +#define MAPNIK_JSON_PARSE_FEATURE_HPP + +#include +#include + +namespace mapnik { namespace json { + +template +void parse_feature(Iterator start, Iterator end, feature_impl& feature, mapnik::transcoder const& tr = mapnik::transcoder("utf8")); + +template +void parse_geometry(Iterator start, Iterator end, feature_impl& feature); + +}} + + +#endif // MAPNIK_JSON_PARSE_FEATURE_HPP diff --git a/include/mapnik/json/positions_grammar.hpp b/include/mapnik/json/positions_grammar.hpp deleted file mode 100644 index 6984300f9..000000000 --- a/include/mapnik/json/positions_grammar.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_JSON_POSITIONS_GRAMMAR_HPP -#define MAPNIK_JSON_POSITIONS_GRAMMAR_HPP - -// mapnik -#include -#include -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; -namespace standard = boost::spirit::standard; -using space_type = standard::space_type; - -template > -struct positions_grammar : - qi::grammar -{ - positions_grammar(ErrorHandler & error_handler); - qi::rule coords; - qi::rule(), space_type> pos; - qi::rule ring; - qi::rule(), space_type> rings; - qi::rule >(), space_type> rings_array; -}; - -}} - -#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_HPP diff --git a/include/mapnik/json/positions_grammar_impl.hpp b/include/mapnik/json/positions_grammar_impl.hpp deleted file mode 100644 index 65f2a93c0..000000000 --- a/include/mapnik/json/positions_grammar_impl.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include -// boost -#include -#include -#include -#include -#include -// stl -#include -#include - -namespace mapnik { namespace json { - -struct set_position_impl -{ - using result_type = void; - template - result_type operator() (T0 & coords, T1 const& pos) const - { - if (pos) coords = *pos; - } -}; - -struct push_position_impl -{ - using result_type = void; - template - result_type operator() (T0 & coords, T1 const& pos) const - { - if (pos) coords.emplace_back(*pos); - } -}; - -template -positions_grammar::positions_grammar(ErrorHandler & error_handler) - : positions_grammar::base_type(coords,"coordinates") -{ - qi::lit_type lit; - qi::double_type double_; - qi::_val_type _val; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::omit_type omit; - using qi::fail; - using qi::on_error; - - boost::phoenix::function set_position; - boost::phoenix::function push_position; - - coords = rings_array[_val = _1] | rings [_val = _1] | ring[_val = _1] | pos[set_position(_val,_1)] - ; - pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']') - ; - ring = lit('[') >> pos[push_position(_val,_1)] % lit(',') > lit(']') - ; - rings = lit('[') >> ring % lit(',') > lit(']') - ; - rings_array = lit('[') >> rings % lit(',') > lit(']') - ; - coords.name("Coordinates"); - pos.name("Position"); - ring.name("Ring"); - rings.name("Rings"); - rings_array.name("Rings array"); - - // error handler - auto error_handler_function = boost::phoenix::function(error_handler); - on_error(coords, error_handler_function(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/positions_grammar_x3.hpp b/include/mapnik/json/positions_grammar_x3.hpp new file mode 100644 index 000000000..55827907e --- /dev/null +++ b/include/mapnik/json/positions_grammar_x3.hpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_POSITIONS_GRAMMAR_X3_HPP +#define MAPNIK_JSON_POSITIONS_GRAMMAR_X3_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +// mapnik +#include +#include + +namespace mapnik { namespace json { + +namespace grammar { + +namespace x3 = boost::spirit::x3; +using positions_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(positions_grammar_type); + +} + +grammar::positions_grammar_type const& positions_grammar(); + +}} + +#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/positions_grammar_x3_def.hpp b/include/mapnik/json/positions_grammar_x3_def.hpp new file mode 100644 index 000000000..7312ee79d --- /dev/null +++ b/include/mapnik/json/positions_grammar_x3_def.hpp @@ -0,0 +1,67 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_POSITIONS_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_POSITIONS_GRAMMAR_X3_DEF_HPP + +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::lit; +using x3::double_; +using x3::no_case; +using x3::omit; + +// start rule +positions_grammar_type const positions("Positions"); +// rules +x3::rule const point("Position"); +x3::rule const ring("Ring"); +x3::rule const rings("Rings"); +x3::rule const rings_array("RingsArray"); + +auto const positions_def = rings_array | rings | ring | point ; +auto const point_def = lit('[') > double_ > lit(',') > double_ > omit[*(lit(',') > double_)] > lit(']'); +auto const ring_def = lit('[') >> -(point % lit(',')) >> lit(']'); +auto const rings_def = lit('[') >> (ring % lit(',') > lit(']')); +auto const rings_array_def = lit('[') >> (rings % lit(',') > lit(']')); + +BOOST_SPIRIT_DEFINE( + positions, + point, + ring, + rings, + rings_array + ); +}}} + +namespace mapnik { namespace json { +grammar::positions_grammar_type const& positions_grammar() +{ + return grammar::positions; +} +}} + +#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/positions.hpp b/include/mapnik/json/positions_x3.hpp similarity index 82% rename from include/mapnik/json/positions.hpp rename to include/mapnik/json/positions_x3.hpp index 9ad10f99a..38a56a647 100644 --- a/include/mapnik/json/positions.hpp +++ b/include/mapnik/json/positions_x3.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,10 +30,11 @@ namespace mapnik { namespace json { struct empty {}; - -using position = mapnik::geometry::point; -using positions = std::vector; -using coordinates = util::variant, std::vector > > ; +using point = mapnik::geometry::point; +using ring = std::vector; +using rings = std::vector; +using rings_array = std::vector; +using positions = util::variant; }} diff --git a/include/mapnik/json/properties_generator_grammar.hpp b/include/mapnik/json/properties_generator_grammar.hpp index 69145b8ab..fd925b825 100644 --- a/include/mapnik/json/properties_generator_grammar.hpp +++ b/include/mapnik/json/properties_generator_grammar.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ #ifndef MAPNIK_JSON_PROPERTIES_GENERATOR_GRAMMAR_HPP #define MAPNIK_JSON_PROPERTIES_GENERATOR_GRAMMAR_HPP -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/json/properties_generator_grammar_impl.hpp b/include/mapnik/json/properties_generator_grammar_impl.hpp index eff4565b5..d3d81026f 100644 --- a/include/mapnik/json/properties_generator_grammar_impl.hpp +++ b/include/mapnik/json/properties_generator_grammar_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,12 @@ #include +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop + namespace mapnik { namespace json { namespace karma = boost::spirit::karma; @@ -52,7 +58,7 @@ escaped_string::escaped_string() } template -properties_generator_grammar::properties_generator_grammar() +properties_generator_grammar::properties_generator_grammar() : properties_generator_grammar::base_type(properties), quote_("\"") { @@ -63,14 +69,13 @@ properties_generator_grammar::properties_generator boost::spirit::karma::string_type kstring; boost::spirit::karma::eps_type eps; using boost::phoenix::at_c; - properties = lit('{') << -(pair % lit(',')) << lit('}') ; pair = lit('"') - << kstring[_1 = boost::phoenix::at_c<0>(_val)] << lit('"') + << kstring[_1 = at_c<0>(_val)] << lit('"') << lit(':') << value[_1 = extract_string_(at_c<1>(_val))] ; @@ -80,13 +85,6 @@ properties_generator_grammar::properties_generator kstring[_1 = at_c<0>(_val)] ; - // FIXME http://boost-spirit.com/home/articles/karma-examples/creating-your-own-generator-component-for-spirit-karma/ - //value = (value_null_| bool_ | int__ | double_ | ustring)//[_1 = value_base_(_r1)] - // ; - //value_null_ = kstring[_1 = "null"] - // ; - //ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)] - // ; } }} diff --git a/include/mapnik/json/stringifier.hpp b/include/mapnik/json/stringifier.hpp index 44b9425d8..af5a39778 100644 --- a/include/mapnik/json/stringifier.hpp +++ b/include/mapnik/json/stringifier.hpp @@ -24,7 +24,7 @@ #define MAPNIK_JSON_STRINGIFIER_HPP // mapnik -#include +#include #include #include // stl diff --git a/include/mapnik/json/topojson_grammar.hpp b/include/mapnik/json/topojson_grammar.hpp deleted file mode 100644 index c21be95fe..000000000 --- a/include/mapnik/json/topojson_grammar.hpp +++ /dev/null @@ -1,206 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_TOPOJSON_GRAMMAR_HPP -#define MAPNIK_TOPOJSON_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik { namespace topojson { - -namespace qi = boost::spirit::qi; -namespace fusion = boost::fusion; -using space_type = mapnik::json::space_type; - -struct create_point -{ - using result_type = mapnik::topojson::point; - template - result_type operator()(T0 & coord, T1 & props) const - { - mapnik::topojson::point pt; - if (coord.template is()) - { - auto const& coord_ = coord.template get(); - pt.coord = coord_; - pt.props = props; - } - return pt; - } -}; - -struct create_multi_point -{ - using result_type = mapnik::topojson::multi_point; - template - result_type operator()(T0 & coords, T1 & props) const - { - mapnik::topojson::multi_point mpt; - if (coords.template is>()) - { - auto const& points = coords.template get>(); - mpt. points = points; - mpt.props = props; - } - return mpt; - } -}; - -struct create_line_string -{ - using result_type = mapnik::topojson::linestring; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::linestring line; - if (arcs.template is>()) - { - auto const& arcs_ = arcs.template get>(); - line.rings = arcs_; - line.props = props; - } - return line; - } -}; - -struct create_multi_line_string -{ - using result_type = mapnik::topojson::multi_linestring; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::multi_linestring mline; - if (arcs.template is>>()) - { - auto const& arcs_ = arcs.template get>>(); - mline.lines = arcs_; - mline.props = props; - } - return mline; - } -}; - -struct create_polygon -{ - using result_type = mapnik::topojson::polygon; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::polygon poly; - if (arcs.template is>>()) - { - auto const& arcs_ = arcs.template get>>(); - poly.rings = arcs_; - poly.props = props; - } - return poly; - } -}; - -struct create_multi_polygon -{ - using result_type = mapnik::topojson::multi_polygon; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::multi_polygon mpoly; - if (arcs.template is>>>()) - { - auto const& arcs_ = arcs.template get>>>(); - mpoly.polygons = arcs_; - mpoly.props = props; - } - return mpoly; - } -}; - - -struct create_geometry_impl -{ - using result_type = mapnik::topojson::geometry; - template - result_type operator()(T0 geom_type, T1 & coord, T2 & arcs, T3 & props) const - { - switch (geom_type) - { - case 1: //Point - return create_point()(coord, props); - case 2: //LineString - return create_line_string()(arcs, props); - case 3: //Polygon - return create_polygon()(arcs, props); - case 4: //MultiPoint - return create_multi_point()(coord, props); - case 5: //MultiLineString - return create_multi_line_string()(arcs, props); - case 6: //MultiPolygon - return create_multi_polygon()(arcs, props); - default: - break; - } - return mapnik::topojson::geometry(); //empty - } -}; - -using coordinates_type = util::variant>; -using arcs_type = util::variant, std::vector>, std::vector>>>; -template > -struct topojson_grammar : qi::grammar - -{ - topojson_grammar(); -private: - // generic JSON support - json::generic_json json; - // topoJSON - qi::rule topology; - qi::rule()> objects; - qi::rule()> arcs; - qi::rule arc; - qi::rule coordinate_; - qi::rule coordinates; - qi::rule transform; - qi::rule bbox; - qi::rule, mapnik::topojson::geometry(), space_type> geometry; - qi::rule&)> geometry_collection; - qi::rule()> ring; - qi::rule>()> rings; - qi::rule rings_array; - // properties - qi::rule properties_; - qi::symbols geometry_type_dispatch; -}; - -}} - -#endif //MAPNIK_TOPOJSON_GRAMMAR_HPP diff --git a/include/mapnik/json/topojson_grammar_impl.hpp b/include/mapnik/json/topojson_grammar_impl.hpp deleted file mode 100644 index 07b3a9756..000000000 --- a/include/mapnik/json/topojson_grammar_impl.hpp +++ /dev/null @@ -1,206 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::coordinate, - (double, x) - (double, y) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::arc, - (std::list, coordinates) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::transform, - (double, scale_x) - (double, scale_y) - (double, translate_x) - (double, translate_y) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::bounding_box, - (double, minx) - (double, miny) - (double, maxx) - (double, maxy) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::topology, - (std::vector, geometries) - (std::vector, arcs) - (boost::optional, tr) - (boost::optional, bbox) - ) - - - -namespace mapnik { namespace topojson { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -namespace fusion = boost::fusion; - -template -topojson_grammar::topojson_grammar() - : topojson_grammar::base_type(topology, "topojson") -{ - qi::lit_type lit; - qi::double_type double_; - qi::int_type int_; - qi::omit_type omit; - qi::_val_type _val; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_r1_type _r1; - qi::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::_d_type _d; - using qi::fail; - using qi::on_error; - using phoenix::push_back; - - geometry_type_dispatch.add - ("\"Point\"",1) - ("\"LineString\"",2) - ("\"Polygon\"",3) - ("\"MultiPoint\"",4) - ("\"MultiLineString\"",5) - ("\"MultiPolygon\"",6) - ("\"GeometryCollection\"",7) - ; - - // error handler - boost::phoenix::function const error_handler; - boost::phoenix::function const create_geometry; - - // topo json - topology = lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"Topology\"") - >> ( (lit(',') >> objects ) ^ ( lit(',') >> arcs) ^ (lit(',') >> transform) ^ (lit(',') >> bbox)) - >> lit('}') - ; - - transform = lit("\"transform\"") >> lit(':') >> lit('{') - >> lit("\"scale\"") >> lit(':') - >> lit('[') - >> double_ >> lit(',') - >> double_ >> lit(']') >> lit(',') - >> lit("\"translate\"") >> lit(':') - >> lit('[') >> double_ >> lit(',') >> double_ >> lit(']') - >> lit('}') - ; - - bbox = lit("\"bbox\"") >> lit(':') - >> lit('[') >> double_ >> lit(',') >> double_ - >> lit(',') >> double_ >> lit(',') >> double_ - >> lit(']') - ; - - objects = lit("\"objects\"") - >> lit(':') - >> lit('{') - >> -((omit[json.string_] - >> lit(':') - >> (geometry_collection(_val) | geometry[push_back(_val, _1)]) % lit(','))) - >> lit('}') - ; - - geometry = lit('{')[_a = 0] - > ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1]) - | - (lit("\"coordinates\"") > lit(':') > coordinates[_b = _1]) - | - (lit("\"arcs\"") > lit(':') > rings_array[_c = _1]) - | - properties_[_d = _1] - | - json.key_value) % lit(',') - > lit('}')[_val = create_geometry(_a, _b, _c, _d)] - ; - - - geometry_collection = lit('{') - >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"") - >> lit(',') >> lit("\"geometries\"") >> lit(':') - >> lit('[') - >> -(geometry[push_back(_r1, _1)] % lit(',')) - >> lit(']') - >> lit('}') - ; - - ring = lit('[') >> -(int_ % lit(',')) >> lit(']') - ; - rings = lit('[') >> -(ring % lit(',')) >> lit(']') - ; - rings_array = lit('[') >> -(rings % lit(',')) >> lit(']') - | - rings - | - ring - ; - - properties_ = lit("\"properties\"") - >> lit(':') - >> lit('{') >> (json.string_ >> lit(':') >> json.value) % lit(',') >> lit('}') - ; - - arcs = lit("\"arcs\"") >> lit(':') - >> lit('[') >> -( arc % lit(',')) >> lit(']') ; - - arc = lit('[') >> -(coordinate_ % lit(',')) >> lit(']') ; - - coordinate_ = lit('[') > double_ > lit(',') > double_ > lit(']'); - - coordinates = (lit('[') >> coordinate_ % lit(',') > lit(']')) - | coordinate_; - - topology.name("topology"); - transform.name("transform"); - objects.name("objects"); - arc.name("arc"); - arcs.name("arcs"); - json.value.name("value"); - coordinate_.name("coordinate"); - geometry.name("geometry"); - properties_.name("properties"); - geometry_collection.name("geometry_collection"); - // error handler - on_error(topology, error_handler(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/topojson_grammar_x3.hpp b/include/mapnik/json/topojson_grammar_x3.hpp new file mode 100644 index 000000000..6f5d58eb0 --- /dev/null +++ b/include/mapnik/json/topojson_grammar_x3.hpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_TOPOJSON_GRAMMAR_X3_HPP +#define MAPNIK_TOPOJSON_GRAMMAR_X3_HPP + +// mapnik +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using topojson_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(topojson_grammar_type); + +} + +grammar::topojson_grammar_type const& topojson_grammar(); + +}} + +#endif //MAPNIK_TOPOJSON_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/topojson_grammar_x3_def.hpp b/include/mapnik/json/topojson_grammar_x3_def.hpp new file mode 100644 index 000000000..bddbed3eb --- /dev/null +++ b/include/mapnik/json/topojson_grammar_x3_def.hpp @@ -0,0 +1,445 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_TOPOJSON_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_TOPOJSON_GRAMMAR_X3_DEF_HPP + +#include +#include +#include +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::coordinate, + (double, x) + (double, y) + ) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::arc, + (std::list, coordinates) + ) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::transform, + (double, scale_x) + (double, scale_y) + (double, translate_x) + (double, translate_y) + ) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::bounding_box, + (double, minx) + (double, miny) + (double, maxx) + (double, maxy) + ) + +namespace mapnik { namespace json { namespace grammar { + +using index_type = topojson::index_type; +struct create_point +{ + using result_type = mapnik::topojson::point; + template + result_type operator()(T0 & coord, T1 & props) const + { + mapnik::topojson::point pt; + if (coord.template is()) + { + auto const& coord_ = coord.template get(); + pt.coord = coord_; + pt.props = props; + } + return pt; + } +}; + +struct create_multi_point +{ + using result_type = mapnik::topojson::multi_point; + template + result_type operator()(T0 & coords, T1 & props) const + { + mapnik::topojson::multi_point mpt; + if (coords.template is>()) + { + auto const& points = coords.template get>(); + mpt. points = points; + mpt.props = props; + } + return mpt; + } +}; + +struct create_line_string +{ + using result_type = mapnik::topojson::linestring; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::linestring line; + if (arcs.template is>()) + { + auto const& arcs_ = arcs.template get>(); + line.rings = arcs_; + line.props = props; + } + return line; + } +}; + +struct create_multi_line_string +{ + using result_type = mapnik::topojson::multi_linestring; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::multi_linestring mline; + if (arcs.template is>>()) + { + auto const& arcs_ = arcs.template get>>(); + mline.lines = arcs_; + mline.props = props; + } + return mline; + } +}; + +struct create_polygon +{ + using result_type = mapnik::topojson::polygon; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::polygon poly; + if (arcs.template is>>()) + { + auto const& arcs_ = arcs.template get>>(); + poly.rings = arcs_; + poly.props = props; + } + return poly; + } +}; + +struct create_multi_polygon +{ + using result_type = mapnik::topojson::multi_polygon; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::multi_polygon mpoly; + if (arcs.template is>>>()) + { + auto const& arcs_ = arcs.template get>>>(); + mpoly.polygons = arcs_; + mpoly.props = props; + } + return mpoly; + } +}; + + +auto create_geometry = [] (auto const& ctx) +{ + auto const geom_type = std::get<0>(_attr(ctx)); + auto const& coord = std::get<1>(_attr(ctx)); + auto const& arcs = std::get<2>(_attr(ctx)); + auto const& props = std::get<3>(_attr(ctx)); + mapnik::topojson::geometry geom; //empty + switch (geom_type) + { + case 1: //Point + geom = create_point()(coord, props); + break; + case 2: //LineString + geom = create_line_string()(arcs, props); + break; + case 3: //Polygon + geom = create_polygon()(arcs, props); + break; + case 4: //MultiPoint + geom = create_multi_point()(coord, props); + break; + case 5: //MultiLineString + geom = create_multi_line_string()(arcs, props); + break; + case 6: //MultiPolygon + geom = create_multi_polygon()(arcs, props); + break; + } + _val(ctx) = std::move(geom); +}; + + +auto assign_bbox = [] (auto const& ctx) +{ + _val(ctx).bbox = std::move(_attr(ctx)); +}; + +auto assign_transform = [] (auto const& ctx) +{ + _val(ctx).tr = std::move(_attr(ctx)); +}; + +auto assign_arcs = [] (auto const& ctx) +{ + _val(ctx).arcs = std::move(_attr(ctx)); +}; + +auto assign_objects = [] (auto const& ctx) +{ + _val(ctx).geometries = std::move(_attr(ctx)); +}; + + +auto push_geometry = [] (auto const& ctx) +{ + _val(ctx).push_back(std::move(_attr(ctx))); +}; + +auto push_collection = [] (auto const& ctx) +{ + auto & dest = _val(ctx); + auto & src = _attr(ctx); + if (dest.empty()) dest = std::move(src); + else + { + dest.reserve(dest.size() + src.size()); + dest.insert(std::end(dest), + std::make_move_iterator(std::begin(src)), + std::make_move_iterator(std::end(src))); + } +}; + + +auto assign_geometry_type = [] (auto const& ctx) +{ + std::get<0>(_val(ctx)) = _attr(ctx); +}; + +auto assign_coordinates = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_rings = [] (auto const& ctx) +{ + std::get<2>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_properties = [] (auto const& ctx) +{ + std::get<3>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_prop_name = [] (auto const& ctx) +{ + std::get<0>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_prop_value = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::double_; +using x3::int_; +using x3::omit; +using x3::char_; +namespace +{ +// import unicode string rule +auto const& json_string = json::unicode_string_grammar(); +// json value +auto const& json_value = json::generic_json_grammar(); +} + +using coordinates_type = util::variant>; +using arcs_type = util::variant, + std::vector>, + std::vector>>>; + +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"",1) + ("\"LineString\"",2) + ("\"Polygon\"",3) + ("\"MultiPoint\"",4) + ("\"MultiLineString\"",5) + ("\"MultiPolygon\"",6) + ; + } +} geometry_type; + +// start rule +topojson_grammar_type const topology = "Topology"; +// rules +x3::rule const transform = "Transform"; +x3::rule const bbox = "Bounding Box"; +x3::rule> const objects= "Objects"; +x3::rule const property = "Property"; +x3::rule const properties = "Properties"; +x3::rule const geometry = "Geometry"; +x3::rule> const geometry_collection = "Geometry Collection"; +x3::rule> const geometry_tuple = "Geometry Tuple"; +x3::rule const coordinate = "Coordinate"; +x3::rule const coordinates = "Coordinates"; +x3::rule const arc = "Arc"; +x3::rule> const arcs = "Arcs"; +x3::rule> const ring = "Ring"; +x3::rule>> const rings = "Rings"; +x3::rule const rings_array = "Rings Array"; + +// defs +auto const topology_def = lit('{') > + -(((lit("\"type\"") > lit(':') > lit("\"Topology\"")) + | + bbox[assign_bbox] + | + transform[assign_transform] + | + objects[assign_objects] + | + arcs[assign_arcs]) % lit(',')) + > lit('}') + ; + + +auto const transform_def = lit("\"transform\"") > lit(':') > lit('{') + > lit("\"scale\"") > lit(':') + > lit('[') + > double_ > lit(',') + > double_ > lit(']') > lit(',') + > lit("\"translate\"") > lit(':') + > lit('[') > double_ > lit(',') > double_ > lit(']') + > lit('}') + ; + +auto const bbox_def = lit("\"bbox\"") > lit(':') + > lit('[') > double_ > lit(',') > double_ + > lit(',') > double_ > lit(',') > double_ + > lit(']') + ; + + +auto const objects_def = lit("\"objects\"") > lit(':') + > lit('{') + > ((omit[*~char_(':')] > lit(':') > ((geometry_collection[push_collection] | geometry[push_geometry]))) % lit(',')) + > lit('}') + ; + +auto const geometry_tuple_def = + ((lit("\"type\"") > lit(':') > geometry_type[assign_geometry_type]) + | + (lit("\"coordinates\"") > lit(':') > coordinates[assign_coordinates]) + | + (lit("\"arcs\"") > lit(':') > rings_array[assign_rings]) + | + properties[assign_properties] + | + (omit[json_string] > lit(':') > omit[json_value])) % lit(',') + ; + +auto const geometry_def = lit("{") > geometry_tuple[create_geometry] > lit("}"); + +auto const geometry_collection_def = (lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"") >> -omit[lit(',') >> bbox]) + > lit(',') > lit("\"geometries\"") > lit(':') + > lit('[') + > -(geometry[push_geometry] % lit(',')) + > lit(']') + > lit('}') + ; + + +auto const ring_def = lit('[') >> (int_ % lit(',')) >> lit(']') + ; +auto const rings_def = lit('[') >> (ring % lit(',')) >> lit(']') + ; +auto const rings_array_def = (lit('[') >> (rings % lit(',')) >> lit(']')) + | + rings + | + ring + ; + +auto const property_def = json_string[assign_prop_name] > lit(':') > json_value[assign_prop_value] + ; + +auto const properties_def = lit("\"properties\"") + > lit(':') + > lit('{') > (property % lit(',')) > lit('}') + ; + +auto const arcs_def = lit("\"arcs\"") >> lit(':') >> lit('[') >> -( arc % lit(',')) >> lit(']') ; + +auto const arc_def = lit('[') >> -(coordinate % lit(',')) >> lit(']') ; + +auto const coordinate_def = lit('[') >> double_ >> lit(',') >> double_ >> omit[*(lit(',') >> double_)] >> lit(']'); + +auto const coordinates_def = (lit('[') >> coordinate % lit(',') >> lit(']')) | coordinate; + +BOOST_SPIRIT_DEFINE( + topology, + transform, + bbox, + objects, + geometry_tuple, + geometry, + geometry_collection, + ring, + rings, + rings_array, + property, + properties, + arcs, + arc, + coordinate, + coordinates + ); + +}}} + +namespace mapnik { namespace json { +grammar::topojson_grammar_type const& topojson_grammar() +{ + return grammar::topology; +} +}} + +#endif //MAPNIK_TOPOJSON_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp index dc4166475..0ac888602 100644 --- a/include/mapnik/json/topojson_utils.hpp +++ b/include/mapnik/json/topojson_utils.hpp @@ -24,13 +24,13 @@ #define MAPNIK_TOPOJSON_UTILS_HPP // mapnik -#include +#include #include #include #include #include -#include -#include +#include +#include namespace mapnik { namespace topojson { diff --git a/include/mapnik/json/topology.hpp b/include/mapnik/json/topology.hpp index 048c85528..97d44f7b6 100644 --- a/include/mapnik/json/topology.hpp +++ b/include/mapnik/json/topology.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ #ifndef MAPNIK_TOPOLOGY_HPP #define MAPNIK_TOPOLOGY_HPP -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/json/unicode_string_grammar_x3.hpp b/include/mapnik/json/unicode_string_grammar_x3.hpp new file mode 100644 index 000000000..4415a0046 --- /dev/null +++ b/include/mapnik/json/unicode_string_grammar_x3.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP +#define MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +class unicode_string_tag; +using unicode_string_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(unicode_string_grammar_type); + +} + +grammar::unicode_string_grammar_type const& unicode_string_grammar(); + +}} + +#endif // MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/unicode_string_grammar_x3_def.hpp b/include/mapnik/json/unicode_string_grammar_x3_def.hpp new file mode 100644 index 000000000..fd0bcebe1 --- /dev/null +++ b/include/mapnik/json/unicode_string_grammar_x3_def.hpp @@ -0,0 +1,159 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP + +#include +// boost +#include +// +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using uchar = std::uint32_t; // a unicode code point + +auto append = [](auto const& ctx) +{ + _val(ctx) += _attr(ctx); +}; + +namespace detail { + +void push_utf8_impl(std::string & str, uchar code_point) +{ + using insert_iterator = std::back_insert_iterator; + insert_iterator iter(str); + boost::utf8_output_iterator utf8_iter(iter); + *utf8_iter++ = code_point; +} +} + +auto push_char = [](auto const& ctx) { _val(ctx).push_back(_attr(ctx));}; + +auto push_utf8 = [](auto const& ctx) { detail::push_utf8_impl(_val(ctx), _attr(ctx));}; + +auto push_utf16 = [](auto const& ctx) +{ + using iterator_type = std::vector::const_iterator; + auto const& utf16 = _attr(ctx); + try + { + boost::u16_to_u32_iterator itr(utf16.begin()); + boost::u16_to_u32_iterator end(utf16.end()); + for (; itr != end; ++itr) + { + detail::push_utf8_impl(_val(ctx), *itr); + } + } + catch( ... ) + { + // caught + } +}; + +auto push_esc = [] (auto const& ctx) +{ + std::string & utf8 = _val(ctx); + char c = _attr(ctx); + switch (c) + { + case ' ': utf8 += ' '; break; + case '\t': utf8 += '\t'; break; + case '0': utf8 += char(0); break; + case 'a': utf8 += 0x7; break; + case 'b': utf8 += 0x8; break; + case 't': utf8 += 0x9; break; + case 'n': utf8 += 0xA; break; + case 'v': utf8 += 0xB; break; + case 'f': utf8 += 0xC; break; + case 'r': utf8 += 0xD; break; + case 'e': utf8 += 0x1B; break; + case '"': utf8 += '"'; break; + case '/': utf8 += '/'; break; + case '\\': utf8 += '\\'; break; + case '_': detail::push_utf8_impl(utf8, 0xA0); break; + case 'N': detail::push_utf8_impl(utf8, 0x85); break; + case 'L': detail::push_utf8_impl(utf8, 0x2028); break; + case 'P': detail::push_utf8_impl(utf8, 0x2029); break; + } +}; + +using x3::lit; +using x3::char_; +using x3::eol; +using x3::no_skip; + +x3::uint_parser const hex2 {}; +x3::uint_parser const hex4 {}; +x3::uint_parser const hex8 {}; + +// start rule +unicode_string_grammar_type const unicode_string("Unicode String"); +// rules +x3::rule const double_quoted("Double-quoted string"); +x3::rule const escaped("Escaped Character"); +x3::rule const escaped_unicode("Escaped Unicode code point(s)"); +x3::rule> const utf16_string("UTF16 encoded string"); + +auto unicode_string_def = double_quoted + ; +auto utf16_string_def = lit('u') > hex4 > *(lit("\\u") > hex4) + ; +auto escaped_unicode_def = + (lit('x') > hex2[push_char]) + | + utf16_string[push_utf16] + | + (lit('U') > hex8[push_utf8]) + ; +auto const escaped_def = lit('\\') > + (escaped_unicode[append] + | + char_("0abtnvfre\"/\\N_LP \t")[push_esc] + | + eol) // continue to next line + ; +auto const double_quoted_def = lit('"') > no_skip[*(escaped[append] | (~char_('"'))[append])] > lit('"'); + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + unicode_string, + double_quoted, + escaped, + escaped_unicode, + utf16_string + ); + +#pragma GCC diagnostic pop + +} +grammar::unicode_string_grammar_type const& unicode_string_grammar() +{ + return grammar::unicode_string; +} +}} + +#endif // MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/value_converters.hpp b/include/mapnik/json/value_converters.hpp index 384ecb88c..1f92aa97b 100644 --- a/include/mapnik/json/value_converters.hpp +++ b/include/mapnik/json/value_converters.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp index f751f31c3..135a6daa8 100644 --- a/include/mapnik/label_collision_detector.hpp +++ b/include/mapnik/label_collision_detector.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #pragma GCC diagnostic push #include diff --git a/include/mapnik/layer.hpp b/include/mapnik/layer.hpp index a00b4885f..43e8760c2 100644 --- a/include/mapnik/layer.hpp +++ b/include/mapnik/layer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,8 @@ // mapnik #include -#include +#include +#include // stl #include @@ -96,6 +97,18 @@ public: */ std::vector& styles(); + /*! \brief Add a child layer by copying it. + * @param l The layer to add. + */ + void add_layer(layer const& l); + + /*! \brief Add a child layer by moving it. + * @param l The layer to add. + */ + void add_layer(layer && l); + + std::vector const& layers() const; + /*! * @param minimum_scale_denom The minimum scale denominator */ @@ -197,6 +210,12 @@ public: */ box2d envelope() const; + // compositing + void set_comp_op(composite_mode_e comp_op); + boost::optional comp_op() const; + void set_opacity(double opacity); + double get_opacity() const; + void set_maximum_extent(box2d const& box); boost::optional > const& maximum_extent() const; void reset_maximum_extent(); @@ -215,9 +234,12 @@ private: bool cache_features_; std::string group_by_; std::vector styles_; + std::vector layers_; datasource_ptr ds_; boost::optional buffer_size_; boost::optional > maximum_extent_; + boost::optional comp_op_; + double opacity_; }; } diff --git a/include/mapnik/load_map.hpp b/include/mapnik/load_map.hpp index 30a04eb07..4ec42d55d 100644 --- a/include/mapnik/load_map.hpp +++ b/include/mapnik/load_map.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/make_unique.hpp b/include/mapnik/make_unique.hpp index f6fd4a230..b967a5241 100644 --- a/include/mapnik/make_unique.hpp +++ b/include/mapnik/make_unique.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,11 +23,11 @@ #ifndef MAPNIK_MAKE_UNIQUE_HPP #define MAPNIK_MAKE_UNIQUE_HPP -#include - // http://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11 #if defined(_MSC_VER) && _MSC_VER < 1800 || !defined(_MSC_VER) && __cplusplus <= 201103L +#include + namespace std { // C++14 backfill from http://herbsutter.com/gotw/_102/ diff --git a/include/mapnik/map.hpp b/include/mapnik/map.hpp index 9f582791b..309be53de 100644 --- a/include/mapnik/map.hpp +++ b/include/mapnik/map.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/mapnik/mapped_memory_cache.hpp b/include/mapnik/mapped_memory_cache.hpp index 1ac8d877e..d00f4396b 100644 --- a/include/mapnik/mapped_memory_cache.hpp +++ b/include/mapnik/mapped_memory_cache.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/marker.hpp b/include/mapnik/marker.hpp index 1feb0fecf..e4222e10f 100644 --- a/include/mapnik/marker.hpp +++ b/include/mapnik/marker.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/marker_cache.hpp b/include/mapnik/marker_cache.hpp index 47aa5558e..5a59eaca3 100644 --- a/include/mapnik/marker_cache.hpp +++ b/include/mapnik/marker_cache.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index 8ba3c6f4b..fc688c16c 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,14 +25,14 @@ #include #include -#include -#include +#include +#include #include #include #include // for svg_storage_type #include #include -#include +#include #include #include #include @@ -50,8 +50,6 @@ namespace mapnik { struct clip_poly_tag; -using svg_attribute_type = agg::pod_bvector; - template struct vector_markers_dispatch : util::noncopyable { diff --git a/include/mapnik/markers_placement.hpp b/include/mapnik/markers_placement.hpp index 0d4319115..c164f307a 100644 --- a/include/mapnik/markers_placement.hpp +++ b/include/mapnik/markers_placement.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/markers_placements/basic.hpp b/include/mapnik/markers_placements/basic.hpp index abcef5ea6..15233bafa 100644 --- a/include/mapnik/markers_placements/basic.hpp +++ b/include/mapnik/markers_placements/basic.hpp @@ -24,7 +24,7 @@ #define MAPNIK_MARKERS_PLACEMENTS_BASIC_HPP // mapnik -#include +#include #include #include #include diff --git a/include/mapnik/markers_placements/interior.hpp b/include/mapnik/markers_placements/interior.hpp index 6a2705e15..987c28991 100644 --- a/include/mapnik/markers_placements/interior.hpp +++ b/include/mapnik/markers_placements/interior.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ #include #include -#include +#include namespace mapnik { diff --git a/include/mapnik/markers_placements/line.hpp b/include/mapnik/markers_placements/line.hpp index bc99cc937..c1ab435c6 100644 --- a/include/mapnik/markers_placements/line.hpp +++ b/include/mapnik/markers_placements/line.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/include/mapnik/markers_placements/point.hpp b/include/mapnik/markers_placements/point.hpp index 6e2f1dafb..7ae070a70 100644 --- a/include/mapnik/markers_placements/point.hpp +++ b/include/mapnik/markers_placements/point.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_MARKERS_PLACEMENTS_POINT_HPP #include -#include +#include #include namespace mapnik { diff --git a/include/mapnik/markers_placements/vertext_first.hpp b/include/mapnik/markers_placements/vertext_first.hpp index ce1b415b3..59943c709 100644 --- a/include/mapnik/markers_placements/vertext_first.hpp +++ b/include/mapnik/markers_placements/vertext_first.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/markers_placements/vertext_last.hpp b/include/mapnik/markers_placements/vertext_last.hpp index 62c94a66a..077fd8eca 100644 --- a/include/mapnik/markers_placements/vertext_last.hpp +++ b/include/mapnik/markers_placements/vertext_last.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/memory_datasource.hpp b/include/mapnik/memory_datasource.hpp index 9b589741f..11a64069d 100644 --- a/include/mapnik/memory_datasource.hpp +++ b/include/mapnik/memory_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/memory_featureset.hpp b/include/mapnik/memory_featureset.hpp index cc5005b42..2f3cb6f07 100644 --- a/include/mapnik/memory_featureset.hpp +++ b/include/mapnik/memory_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,9 +24,9 @@ #define MAPNIK_MEMORY_FEATURESET_HPP // mapnik -#include +#include #include -#include +#include #include #include #include diff --git a/include/mapnik/octree.hpp b/include/mapnik/octree.hpp index 007e6960e..f085f219b 100644 --- a/include/mapnik/octree.hpp +++ b/include/mapnik/octree.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/offset_converter.hpp b/include/mapnik/offset_converter.hpp index 310ed808a..c54f3b5f9 100644 --- a/include/mapnik/offset_converter.hpp +++ b/include/mapnik/offset_converter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -77,18 +77,18 @@ struct offset_converter return threshold_; } - void set_offset(double value) + void set_offset(double val) { - if (offset_ != value) + if (offset_ != val) { - offset_ = value; + offset_ = val; reset(); } } - void set_threshold(double value) + void set_threshold(double val) { - threshold_ = value; + threshold_ = val; // no need to reset(), since threshold doesn't affect // offset vertices' computation, it only controls how // far will we be looking for self-intersections @@ -269,7 +269,7 @@ private: if (position < -1e-6) return -1; return 0; } - + void displace2(vertex2d & v1, vertex2d const& v0, vertex2d const& v2, double a, double b) const { double sa = offset_ * std::sin(a); @@ -284,14 +284,14 @@ private: double abs_hcasa = std::abs(hcasa); double abs_hsa = std::abs(hsa); double abs_hca = std::abs(hca); - - vertex2d v_tmp(vertex2d::no_init); + + vertex2d v_tmp(vertex2d::no_init); v_tmp.x = v1.x - sa - hca; v_tmp.y = v1.y + ca - hsa; v_tmp.cmd = v1.cmd; - + int same = point_line_position(v0, v2, v_tmp)*point_line_position(v0, v2, v1); - + if (same >= 0 && std::abs(h) < 10) { v1.x = v_tmp.x; @@ -314,14 +314,14 @@ private: v1.y = v1.y + ca - hsa; } else - { + { if (abs_hsaca*abs_hsaca + abs_hcasa*abs_hcasa > abs_offset*abs_offset) { double d = (abs_hsaca*abs_hsaca + abs_hcasa*abs_hcasa); d = d < 1e-6 ? 1. : d; double scale = (abs_offset*abs_offset)/d; v1.x = v1.x + hcasa*scale; - v1.y = v1.y + hsaca*scale; + v1.y = v1.y + hsaca*scale; } else { @@ -330,8 +330,7 @@ private: } } } - - + status init_vertices() { if (status_ != initial) // already initialized @@ -482,8 +481,9 @@ private: } start_v2.x = v2.x; start_v2.y = v2.y; + vertex2d tmp_prev(vertex2d::no_init); - + while (i < points.size()) { v1 = v2; @@ -576,7 +576,7 @@ private: tmp_prev.cmd = v1.cmd; tmp_prev.x = v1.x; tmp_prev.y = v1.y; - + if (v1.cmd == SEG_MOVETO) { if (bulge_steps == 0) diff --git a/include/mapnik/palette.hpp b/include/mapnik/palette.hpp index 1276d1302..2f5dc3091 100644 --- a/include/mapnik/palette.hpp +++ b/include/mapnik/palette.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/params.hpp b/include/mapnik/params.hpp index 535cacb38..f53a4e651 100644 --- a/include/mapnik/params.hpp +++ b/include/mapnik/params.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/params_impl.hpp b/include/mapnik/params_impl.hpp index f127c4cf2..f7534d666 100644 --- a/include/mapnik/params_impl.hpp +++ b/include/mapnik/params_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #include diff --git a/include/mapnik/parse_path.hpp b/include/mapnik/parse_path.hpp index e5b5882ab..3b1eb2524 100644 --- a/include/mapnik/parse_path.hpp +++ b/include/mapnik/parse_path.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/path.hpp b/include/mapnik/path.hpp index fc1cdab1a..3f713a553 100644 --- a/include/mapnik/path.hpp +++ b/include/mapnik/path.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include namespace mapnik { namespace detail { @@ -70,9 +70,9 @@ public: return static_cast(type_ >> geometry_bits); } - void set_type(types type) + void set_type(types _type) { - type_ = type; + type_ = _type; } container_type const& data() const diff --git a/include/mapnik/path_expression.hpp b/include/mapnik/path_expression.hpp index b3dde7dab..1cc4a949d 100644 --- a/include/mapnik/path_expression.hpp +++ b/include/mapnik/path_expression.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/path_expression_grammar_x3.hpp b/include/mapnik/path_expression_grammar_x3.hpp new file mode 100644 index 000000000..60bfd2bb4 --- /dev/null +++ b/include/mapnik/path_expression_grammar_x3.hpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP +#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP + +// mapnik +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct path_expression_class; // top-most ID +using path_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(path_expression_grammar_type); + +} + +grammar::path_expression_grammar_type const& path_expression_grammar(); + +} + +#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/path_expression_grammar_x3_def.hpp b/include/mapnik/path_expression_grammar_x3_def.hpp new file mode 100644 index 000000000..73e940a5c --- /dev/null +++ b/include/mapnik/path_expression_grammar_x3_def.hpp @@ -0,0 +1,63 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +// mapnik +#include +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::standard_wide::char_; +using x3::lexeme; +auto create_string = [](auto & ctx) { _val(ctx).push_back(_attr(ctx)); }; +auto create_attribute = [](auto & ctx) { _val(ctx).push_back(mapnik::attribute(_attr(ctx))); }; +// top-most rule +path_expression_grammar_type const path_expression("path_expression"); +// rules +x3::rule const attr_expression("attribute"); +x3::rule const str_expression("string"); + +auto const attr_expression_def = +(char_ - ']'); +auto const str_expression_def = lexeme[+(char_ -'[')]; +auto const path_expression_def = *(str_expression[create_string] | ('[' > attr_expression[create_attribute] > ']')); + +BOOST_SPIRIT_DEFINE( + path_expression, + attr_expression, + str_expression +); + +}} + +namespace mapnik { + +grammar::path_expression_grammar_type const& path_expression_grammar() +{ + return grammar::path_expression; +} + +} + +#endif //MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/pixel_position.hpp b/include/mapnik/pixel_position.hpp index 93cdb4f7f..09381345c 100644 --- a/include/mapnik/pixel_position.hpp +++ b/include/mapnik/pixel_position.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/pixel_types.hpp b/include/mapnik/pixel_types.hpp index b0d6304b3..f341155c8 100644 --- a/include/mapnik/pixel_types.hpp +++ b/include/mapnik/pixel_types.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/plugin.hpp b/include/mapnik/plugin.hpp index 68e7de620..99c1e8d1e 100644 --- a/include/mapnik/plugin.hpp +++ b/include/mapnik/plugin.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/png_io.hpp b/include/mapnik/png_io.hpp index 9f8b38d8f..827df4cdb 100644 --- a/include/mapnik/png_io.hpp +++ b/include/mapnik/png_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -48,14 +48,17 @@ namespace mapnik { struct png_options { int colors; + int filters; int compression; int strategy; int trans_mode; double gamma; bool paletted; bool use_hextree; + png_options() : colors(256), + filters(PNG_FILTER_NONE), compression(Z_DEFAULT_COMPRESSION), strategy(Z_DEFAULT_STRATEGY), trans_mode(-1), @@ -97,7 +100,7 @@ void save_as_png(T1 & file, mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE); + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, opts.filters); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { @@ -120,7 +123,7 @@ void save_as_png(T1 & file, (opts.trans_mode == 0) ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT); const std::unique_ptr row_pointers(new png_bytep[image.height()]); - for (unsigned int i = 0; i < image.height(); i++) + for (unsigned int i = 0; i < image.height(); ++i) { row_pointers[i] = const_cast(reinterpret_cast(image.get_row(i))); } @@ -141,7 +144,7 @@ void reduce_8(T const& in, unsigned height = in.height(); std::vector alphaCount(alpha.size()); - for(unsigned i=0; i0; j--) + for(int j=levels-1; j>0; --j) { if (U2ALPHA(val)>=limits[j] && trees[j].colors()>0) { @@ -166,12 +169,12 @@ void reduce_8(T const& in, if (idx>=0 && idx < static_cast(alpha.size())) { alpha[idx]+=U2ALPHA(val); - alphaCount[idx]++; + ++alphaCount[idx]; } row_out[x] = index; } } - for(unsigned i=0; i alphaCount(alpha.size()); - for(unsigned i=0; i0; j--) + for(int j=levels-1; j>0; --j) { if (U2ALPHA(val)>=limits[j] && trees[j].colors()>0) { @@ -217,7 +220,7 @@ void reduce_4(T const& in, if (idx>=0 && idx < static_cast(alpha.size())) { alpha[idx]+=U2ALPHA(val); - alphaCount[idx]++; + ++alphaCount[idx]; } if (x%2 == 0) { @@ -226,7 +229,7 @@ void reduce_4(T const& in, row_out[x>>1] |= index; } } - for(unsigned i=0; i const& palette, unsigned width, unsigned height, unsigned color_depth, - std::vector const&alpha, + std::vector const& alpha, png_options const& opts) { png_voidp error_ptr=0; @@ -271,7 +274,7 @@ void save_as_png(T & file, std::vector const& palette, mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE); + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, opts.filters); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { @@ -302,7 +305,7 @@ void save_as_png(T & file, std::vector const& palette, { std::vector trans(alpha.size()); unsigned alphaSize=0;//truncate to nonopaque values - for(unsigned i=0; i < alpha.size(); i++) + for(unsigned i=0; i < alpha.size(); ++i) { trans[i]=alpha[i]; if (alpha[i]<255) @@ -317,7 +320,7 @@ void save_as_png(T & file, std::vector const& palette, } png_write_info(png_ptr, info_ptr); - for (unsigned i=0;i(image.get_row(i))); } @@ -346,7 +349,7 @@ void save_as_png8_oct(T1 & file, } else { - for(int i=0; i<256; i++) + for(int i=0; i<256; ++i) { alphaHist[i] = 0; } @@ -355,11 +358,11 @@ void save_as_png8_oct(T1 & file, for (unsigned x = 0; x < width; ++x) { unsigned val = U2ALPHA(static_cast(image.get_row(y)[x])); - alphaHist[val]++; + ++alphaHist[val]; meanAlpha += val; if (val>0 && val<255) { - semiCount++; + ++semiCount; } } } @@ -371,17 +374,17 @@ void save_as_png8_oct(T1 & file, limits[0] = 0; limits[1] = (opts.trans_mode!=0 && alphaHist[0]>0)?1:0; limits[TRANSPARENCY_LEVELS] = 256; - for(unsigned j=2; j12 && cols[j] trees[MAX_OCTREE_LEVELS]; - for(unsigned j=1; j0; j--) + for(unsigned j=TRANSPARENCY_LEVELS-1; j>0; --j) { if (cols[j]>0 && U2ALPHA(val)>=limits[j]) { @@ -495,7 +498,7 @@ void save_as_png8_oct(T1 & file, palette.push_back(rgb(0,0,0)); } - for(unsigned j=1; j0) { diff --git a/include/mapnik/pool.hpp b/include/mapnik/pool.hpp index c37aab4e3..96a305fce 100644 --- a/include/mapnik/pool.hpp +++ b/include/mapnik/pool.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/proj_strategy.hpp b/include/mapnik/proj_strategy.hpp index a8366fc5a..6330e233d 100644 --- a/include/mapnik/proj_strategy.hpp +++ b/include/mapnik/proj_strategy.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/proj_transform.hpp b/include/mapnik/proj_transform.hpp index 71d678ef4..28791dd3d 100644 --- a/include/mapnik/proj_transform.hpp +++ b/include/mapnik/proj_transform.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/projection.hpp b/include/mapnik/projection.hpp index 0869bb2d6..ddc4ff843 100644 --- a/include/mapnik/projection.hpp +++ b/include/mapnik/projection.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/ptree_helpers.hpp b/include/mapnik/ptree_helpers.hpp index 6a9c91e56..3bdb26aea 100644 --- a/include/mapnik/ptree_helpers.hpp +++ b/include/mapnik/ptree_helpers.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/quad_tree.hpp b/include/mapnik/quad_tree.hpp index c15f09f26..1d72b3f46 100644 --- a/include/mapnik/quad_tree.hpp +++ b/include/mapnik/quad_tree.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,11 +24,13 @@ #define MAPNIK_QUAD_TREE_HPP // mapnik -#include +#include #include #include + // stl -#include +#include +#include #include #include @@ -83,12 +85,12 @@ class quad_tree : util::noncopyable int num_subnodes() const { - int count = 0; + int _count = 0; for (int i = 0; i < 4; ++i) { - if (children_[i]) ++count; + if (children_[i]) ++_count; } - return count; + return _count; } ~node () {} }; @@ -164,9 +166,9 @@ public: int count_items() const { - int count = 0; - count_items(root_, count); - return count; + int _count = 0; + count_items(root_, _count); + return _count; } void trim() { @@ -276,23 +278,23 @@ private: if (!n) return 0; else { - int count = 1; + int _count = 1; for (int i = 0; i < 4; ++i) { - count += count_nodes(n->children_[i]); + _count += count_nodes(n->children_[i]); } - return count; + return _count; } } - void count_items(node const* n,int& count) const + void count_items(node const* n, int& _count) const { if (n) { - count += n->cont_.size(); + _count += n->cont_.size(); for (int i = 0; i < 4; ++i) { - count_items(n->children_[i],count); + count_items(n->children_[i],_count); } } } diff --git a/include/mapnik/query.hpp b/include/mapnik/query.hpp index 5d5a6e7c8..07da0caac 100644 --- a/include/mapnik/query.hpp +++ b/include/mapnik/query.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_QUERY_HPP //mapnik -#include +#include #include // stl @@ -40,12 +40,12 @@ public: using resolution_type = std::tuple; query(box2d const& bbox, - resolution_type const& resolution, - double scale_denominator, + resolution_type const& _resolution, + double _scale_denominator, box2d const& unbuffered_bbox) : bbox_(bbox), - resolution_(resolution), - scale_denominator_(scale_denominator), + resolution_(_resolution), + scale_denominator_(_scale_denominator), filter_factor_(1.0), unbuffered_bbox_(unbuffered_bbox), names_(), @@ -53,11 +53,11 @@ public: {} query(box2d const& bbox, - resolution_type const& resolution, - double scale_denominator = 1.0) + resolution_type const& _resolution, + double _scale_denominator = 1.0) : bbox_(bbox), - resolution_(resolution), - scale_denominator_(scale_denominator), + resolution_(_resolution), + scale_denominator_(_scale_denominator), filter_factor_(1.0), unbuffered_bbox_(bbox), names_(), diff --git a/include/mapnik/raster.hpp b/include/mapnik/raster.hpp index 02022d359..35a067f03 100644 --- a/include/mapnik/raster.hpp +++ b/include/mapnik/raster.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_RASTER_HPP // mapnik -#include +#include #include #include #include @@ -52,9 +52,9 @@ public: data_(std::move(data)), filter_factor_(filter_factor) {} - void set_nodata(double nodata) + void set_nodata(double _nodata) { - nodata_ = nodata; + nodata_ = _nodata; } boost::optional const& nodata() const diff --git a/include/mapnik/raster_colorizer.hpp b/include/mapnik/raster_colorizer.hpp index 690549746..448dc9e9d 100644 --- a/include/mapnik/raster_colorizer.hpp +++ b/include/mapnik/raster_colorizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common.hpp b/include/mapnik/renderer_common.hpp index c9d181b42..1c48ad3f5 100644 --- a/include/mapnik/renderer_common.hpp +++ b/include/mapnik/renderer_common.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ #include // for MAPNIK_DECL #include // for face_manager, etc -#include // for box2d +#include // for box2d #include // for view_transform #include #include diff --git a/include/mapnik/renderer_common/apply_vertex_converter.hpp b/include/mapnik/renderer_common/apply_vertex_converter.hpp index 503dc4176..b79912d57 100644 --- a/include/mapnik/renderer_common/apply_vertex_converter.hpp +++ b/include/mapnik/renderer_common/apply_vertex_converter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common/clipping_extent.hpp b/include/mapnik/renderer_common/clipping_extent.hpp index aabacf36f..dcd678103 100644 --- a/include/mapnik/renderer_common/clipping_extent.hpp +++ b/include/mapnik/renderer_common/clipping_extent.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_CLIPPING_EXTENT_HPP -#include +#include namespace mapnik { diff --git a/include/mapnik/renderer_common/pattern_alignment.hpp b/include/mapnik/renderer_common/pattern_alignment.hpp index 12f746d32..053901188 100644 --- a/include/mapnik/renderer_common/pattern_alignment.hpp +++ b/include/mapnik/renderer_common/pattern_alignment.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common/process_building_symbolizer.hpp b/include/mapnik/renderer_common/process_building_symbolizer.hpp index d65df2544..9c157c7c3 100644 --- a/include/mapnik/renderer_common/process_building_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_building_symbolizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common/process_point_symbolizer.hpp b/include/mapnik/renderer_common/process_point_symbolizer.hpp index ef0863fd6..4365240eb 100644 --- a/include/mapnik/renderer_common/process_point_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_point_symbolizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,9 +29,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp index 6fd2524fc..4322793f0 100644 --- a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common/process_raster_symbolizer.hpp b/include/mapnik/renderer_common/process_raster_symbolizer.hpp index 7ca90a0af..c700327c4 100644 --- a/include/mapnik/renderer_common/process_raster_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_raster_symbolizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common/render_group_symbolizer.hpp b/include/mapnik/renderer_common/render_group_symbolizer.hpp index e7b1b2248..65cc0f94f 100644 --- a/include/mapnik/renderer_common/render_group_symbolizer.hpp +++ b/include/mapnik/renderer_common/render_group_symbolizer.hpp @@ -42,9 +42,9 @@ struct render_thunk_list_dispatch { offset_ = offset; - for (render_thunk_ptr const& thunk : thunks) + for (render_thunk const& thunk : thunks) { - util::apply_visitor(std::ref(*this), *thunk); + util::apply_visitor(std::ref(*this), thunk); } } diff --git a/include/mapnik/renderer_common/render_pattern.hpp b/include/mapnik/renderer_common/render_pattern.hpp index acb989731..e9953e215 100644 --- a/include/mapnik/renderer_common/render_pattern.hpp +++ b/include/mapnik/renderer_common/render_pattern.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/renderer_common/render_thunk.hpp b/include/mapnik/renderer_common/render_thunk.hpp index 2a957d260..66b108bb9 100644 --- a/include/mapnik/renderer_common/render_thunk.hpp +++ b/include/mapnik/renderer_common/render_thunk.hpp @@ -107,8 +107,7 @@ struct text_render_thunk : util::movable using render_thunk = util::variant; -using render_thunk_ptr = std::unique_ptr; -using render_thunk_list = std::list; +using render_thunk_list = std::list; } // namespace mapnik diff --git a/include/mapnik/request.hpp b/include/mapnik/request.hpp index 74c085197..c1b70c268 100644 --- a/include/mapnik/request.hpp +++ b/include/mapnik/request.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include namespace mapnik { diff --git a/include/mapnik/rule.hpp b/include/mapnik/rule.hpp index 1c98eaf59..018297ae9 100644 --- a/include/mapnik/rule.hpp +++ b/include/mapnik/rule.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/rule_cache.hpp b/include/mapnik/rule_cache.hpp index 3d6f7d025..857873734 100644 --- a/include/mapnik/rule_cache.hpp +++ b/include/mapnik/rule_cache.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/safe_cast.hpp b/include/mapnik/safe_cast.hpp index d8973032e..7e638e8a6 100644 --- a/include/mapnik/safe_cast.hpp +++ b/include/mapnik/safe_cast.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/save_map.hpp b/include/mapnik/save_map.hpp index 80317b356..99d3beacb 100644 --- a/include/mapnik/save_map.hpp +++ b/include/mapnik/save_map.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/scale_denominator.hpp b/include/mapnik/scale_denominator.hpp index fb09cefd9..68cad70d2 100644 --- a/include/mapnik/scale_denominator.hpp +++ b/include/mapnik/scale_denominator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/segment.hpp b/include/mapnik/segment.hpp index 4463382b8..6aace570c 100644 --- a/include/mapnik/segment.hpp +++ b/include/mapnik/segment.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/simplify_converter.hpp b/include/mapnik/simplify_converter.hpp index 248842504..a8a6c377b 100644 --- a/include/mapnik/simplify_converter.hpp +++ b/include/mapnik/simplify_converter.hpp @@ -120,11 +120,11 @@ public: return algorithm_; } - void set_simplify_algorithm(simplify_algorithm_e value) + void set_simplify_algorithm(simplify_algorithm_e val) { - if (algorithm_ != value) + if (algorithm_ != val) { - algorithm_ = value; + algorithm_ = val; reset(); } } @@ -134,11 +134,11 @@ public: return tolerance_; } - void set_simplify_tolerance(double value) + void set_simplify_tolerance(double val) { - if (tolerance_ != value) + if (tolerance_ != val) { - tolerance_ = value; + tolerance_ = val; reset(); } } diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index c0a9adbb9..b3fd21367 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -176,9 +176,9 @@ public: span_image_resample_rgba_affine(source_type & src, interpolator_type & inter, - agg::image_filter_lut const & filter, + agg::image_filter_lut const & _filter, boost::optional const & nodata_value) : - agg::span_image_resample_rgba_affine(src, inter, filter) + agg::span_image_resample_rgba_affine(src, inter, _filter) { } }; diff --git a/include/mapnik/sql_utils.hpp b/include/mapnik/sql_utils.hpp index 2720e8424..96ec79342 100644 --- a/include/mapnik/sql_utils.hpp +++ b/include/mapnik/sql_utils.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,12 +33,77 @@ #pragma GCC diagnostic pop // stl -#include -#include +#include +#include #include namespace mapnik { namespace sql_utils { + struct quoted_string + { + std::string const* operator-> () const { return &str; } + std::string const& str; + char const quot; + }; + + inline quoted_string identifier(std::string const& str) + { + return { str, '"' }; + } + + inline quoted_string literal(std::string const& str) + { + return { str, '\'' }; + } + + inline std::ostream& operator << (std::ostream& os, quoted_string qs) + { + std::size_t pos = 0, next; + + os.put(qs.quot); + while ((next = qs->find(qs.quot, pos)) != std::string::npos) + { + os.write(qs->data() + pos, next - pos + 1); + os.put(qs.quot); + pos = next + 1; + } + if ((next = qs->size()) > pos) + { + os.write(qs->data() + pos, next - pos); + } + return os.put(qs.quot); + } + + // Does nothing if `str` doesn't start with `quot`. + // Otherwise erases the opening quote, collapses inner quote pairs, + // and erases everything from the closing quote to the end of the + // string. The closing quote is the first non-paired quote after the + // opening one. For a well-formed quoted string, it is also the last + // character, so nothing gets lost. + inline void unquote(char quot, std::string & str) + { + if (!str.empty() && str.front() == quot) + { + std::size_t di = 0; + for (std::size_t si = 1; si < str.size(); ++si) + { + char c = str[si]; + if (c == quot && (++si >= str.size() || str[si] != quot)) + break; + str[di++] = c; + } + str.erase(di); + } + } + + inline std::string unquote_copy(char quot, std::string const& str) + { + std::string tmp(str); + sql_utils::unquote(quot, tmp); + return tmp; + } + + [[deprecated("flawed")]] inline std::string unquote_double(std::string const& sql) { std::string table_name = sql; @@ -46,6 +111,7 @@ namespace mapnik { namespace sql_utils { return table_name; } + [[deprecated("flawed")]] inline std::string unquote(std::string const& sql) { std::string table_name = sql; @@ -53,11 +119,75 @@ namespace mapnik { namespace sql_utils { return table_name; } + [[deprecated("flawed")]] inline void quote_attr(std::ostringstream & s, std::string const& field) { s << ",\"" << field << "\""; } + const std::regex re_from{ + "\\bFROM\\b" + , std::regex::icase + }; + + const std::regex re_table_name{ + "\\s*(\\w+|(\"[^\"]*\")+)" // $1 = schema + "(\\.(\\w+|(\"[^\"]*\")+))?" // $4 = table + "\\s*" + }; + + inline bool table_from_sql(std::string const& sql, + std::string & schema, + std::string & table) + { + std::smatch m; + auto start = sql.begin(); + auto end = sql.end(); + auto flags = std::regex_constants::match_default; + auto found = std::regex_match(start, end, m, re_table_name); + auto extract_matched_parts = [&]() + { + if (m[4].matched) + { + table.assign(m[4].first, m[4].second); + schema.assign(m[1].first, m[1].second); + } + else + { + table.assign(m[1].first, m[1].second); + schema.clear(); + } + }; + + if (found) + { + // input is not subquery, just "[schema.]table" + extract_matched_parts(); + } + else + { + // search "FROM [schema.]table" in subquery + while (std::regex_search(start, end, m, re_from, flags)) + { + start = m[0].second; + if (std::regex_search(start, end, m, re_table_name, + std::regex_constants::match_continuous)) + { + extract_matched_parts(); + found = true; + start = m[0].second; + } + flags = std::regex_constants::match_prev_avail; + } + } + if (found) + { + sql_utils::unquote('"', schema); + sql_utils::unquote('"', table); + } + return found; + } + inline std::string table_from_sql(std::string const& sql) { std::string table_name = sql; diff --git a/include/mapnik/sse.hpp b/include/mapnik/sse.hpp index 603af7cd2..4e9d96445 100644 --- a/include/mapnik/sse.hpp +++ b/include/mapnik/sse.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/stringify_macro.hpp b/include/mapnik/stringify_macro.hpp index 41f947467..a450b98c8 100644 --- a/include/mapnik/stringify_macro.hpp +++ b/include/mapnik/stringify_macro.hpp @@ -20,7 +20,12 @@ * *****************************************************************************/ +#ifndef MAPNIK_STRINGIFY_MACRO_HPP +#define MAPNIK_STRINGIFY_MACRO_HPP + #ifndef MAPNIK_STRINGIFY #define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n) #define MAPNIK_STRINGIFY_HELPER(n) #n -#endif \ No newline at end of file +#endif + +#endif // MAPNIK_STRINGIFY_MACRO_HPP diff --git a/include/mapnik/svg/geometry_svg_generator.hpp b/include/mapnik/svg/geometry_svg_generator.hpp index 24135e5a6..e06db6f39 100644 --- a/include/mapnik/svg/geometry_svg_generator.hpp +++ b/include/mapnik/svg/geometry_svg_generator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/geometry_svg_generator_impl.hpp b/include/mapnik/svg/geometry_svg_generator_impl.hpp index 57df89f96..98df1cb44 100644 --- a/include/mapnik/svg/geometry_svg_generator_impl.hpp +++ b/include/mapnik/svg/geometry_svg_generator_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ *****************************************************************************/ // mapnik -#include +#include #include namespace mapnik { namespace svg { diff --git a/include/mapnik/svg/output/svg_generator.hpp b/include/mapnik/svg/output/svg_generator.hpp index 1b3f18dea..f3f2414f3 100644 --- a/include/mapnik/svg/output/svg_generator.hpp +++ b/include/mapnik/svg/output/svg_generator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,7 @@ #include #include #include -#include +#include namespace mapnik { namespace svg { diff --git a/include/mapnik/svg/output/svg_output_attributes.hpp b/include/mapnik/svg/output/svg_output_attributes.hpp index 00deeea26..21644a8bd 100644 --- a/include/mapnik/svg/output/svg_output_attributes.hpp +++ b/include/mapnik/svg/output/svg_output_attributes.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,8 @@ * *****************************************************************************/ -#ifndef MAPNIK_SVG_OUTPUT_ATTRIBUTES -#define MAPNIK_SVG_OUTPUT_ATTRIBUTES +#ifndef MAPNIK_SVG_OUTPUT_ATTRIBUTES_HPP +#define MAPNIK_SVG_OUTPUT_ATTRIBUTES_HPP // mapnik #include @@ -121,12 +121,12 @@ namespace mapnik { namespace svg { fill_color_("#000000") {} - rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& fill_color) + rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& _fill_color) : x_(x), y_(y), width_(width), height_(height), - fill_color_(fill_color.to_hex_string()) + fill_color_(_fill_color.to_hex_string()) {} void set_x(const int x); @@ -199,4 +199,4 @@ namespace mapnik { namespace svg { }; }} -#endif // MAPNIK_SVG_OUTPUT_ATTRIBUTES +#endif // MAPNIK_SVG_OUTPUT_ATTRIBUTES_HPP diff --git a/include/mapnik/svg/output/svg_output_grammars.hpp b/include/mapnik/svg/output/svg_output_grammars.hpp index 5657e2606..d4f1bb6d1 100644 --- a/include/mapnik/svg/output/svg_output_grammars.hpp +++ b/include/mapnik/svg/output/svg_output_grammars.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/output/svg_output_grammars_impl.hpp b/include/mapnik/svg/output/svg_output_grammars_impl.hpp index ef856a05e..6ada195fd 100644 --- a/include/mapnik/svg/output/svg_output_grammars_impl.hpp +++ b/include/mapnik/svg/output/svg_output_grammars_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/output/svg_path_iterator.hpp b/include/mapnik/svg/output/svg_path_iterator.hpp index 639788ae4..779abd771 100644 --- a/include/mapnik/svg/output/svg_path_iterator.hpp +++ b/include/mapnik/svg/output/svg_path_iterator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/output/svg_renderer.hpp b/include/mapnik/svg/output/svg_renderer.hpp index 037ec0ddb..dbfa3477b 100644 --- a/include/mapnik/svg/output/svg_renderer.hpp +++ b/include/mapnik/svg/output/svg_renderer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,7 @@ #include #include #include // for rule, symbolizers -#include // for box2d +#include // for box2d #include // for color #include // for view_transform #include // for composite_mode_e @@ -131,9 +131,9 @@ public: return painted_; } - void painted(bool painted) + void painted(bool _painted) { - painted_ = painted; + painted_ = _painted; } inline eAttributeCollectionPolicy attribute_collection_policy() const diff --git a/include/mapnik/svg/svg_converter.hpp b/include/mapnik/svg/svg_converter.hpp index 9cf3c9c16..66edc5d0b 100644 --- a/include/mapnik/svg/svg_converter.hpp +++ b/include/mapnik/svg/svg_converter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/path_expression_grammar_impl.hpp b/include/mapnik/svg/svg_grammar_config_x3.hpp similarity index 52% rename from include/mapnik/path_expression_grammar_impl.hpp rename to include/mapnik/svg/svg_grammar_config_x3.hpp index 22002bf33..3666cebb9 100644 --- a/include/mapnik/path_expression_grammar_impl.hpp +++ b/include/mapnik/svg/svg_grammar_config_x3.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,43 +20,32 @@ * *****************************************************************************/ -// mapnik -#include -#include - +#ifndef MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP +#define MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP +#include #pragma GCC diagnostic push #include -#include -#include -#include +#include #pragma GCC diagnostic pop -namespace mapnik -{ +namespace mapnik { namespace svg { namespace grammar { -template -path_expression_grammar::path_expression_grammar() - : path_expression_grammar::base_type(expr) -{ - standard_wide::char_type char_; - qi::_1_type _1; - qi::_val_type _val; - qi::lit_type lit; - qi::lexeme_type lexeme; - using phoenix::push_back; - using boost::phoenix::construct; +class relative_tag; +class svg_path_tag; +class svg_transform_tag; - expr = - * ( - str [ push_back(_val, _1)] - | - ( '[' >> attr [ push_back(_val, construct( _1 )) ] >> ']') - ) - ; +namespace x3 = boost::spirit::x3; +using space_type = x3::standard::space_type; +using iterator_type = char const*; - attr %= +(char_ - ']'); - str %= lexeme[+(char_ -'[')]; -} +using phrase_parse_context_type = x3::phrase_parse_context::type; +using svg_parse_context_type = x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type; -} +inline double deg2rad(double deg) {return (M_PI * deg) / 180.0;} + +}}} + +#endif // MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP diff --git a/include/mapnik/svg/svg_parser.hpp b/include/mapnik/svg/svg_parser.hpp index 63caacd8b..8246bac91 100644 --- a/include/mapnik/svg/svg_parser.hpp +++ b/include/mapnik/svg/svg_parser.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/svg_parser_exception.hpp b/include/mapnik/svg/svg_parser_exception.hpp index 89139da88..8732e0259 100644 --- a/include/mapnik/svg/svg_parser_exception.hpp +++ b/include/mapnik/svg/svg_parser_exception.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,9 +38,9 @@ public: svg_parser_exception(std::string const& message) : message_(message) {} - ~svg_parser_exception() throw() {} + ~svg_parser_exception() {} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } diff --git a/include/mapnik/svg/svg_path_adapter.hpp b/include/mapnik/svg/svg_path_adapter.hpp index 8b4fb6bf2..288491030 100644 --- a/include/mapnik/svg/svg_path_adapter.hpp +++ b/include/mapnik/svg/svg_path_adapter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/svg/svg_path_attributes.hpp b/include/mapnik/svg/svg_path_attributes.hpp index 80bf46349..e4acbba49 100644 --- a/include/mapnik/svg/svg_path_attributes.hpp +++ b/include/mapnik/svg/svg_path_attributes.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/svg_path_commands.hpp b/include/mapnik/svg/svg_path_commands.hpp index 7e7ab5fef..26a5bba6b 100644 --- a/include/mapnik/svg/svg_path_commands.hpp +++ b/include/mapnik/svg/svg_path_commands.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/svg/svg_path_grammar.hpp b/include/mapnik/svg/svg_path_grammar.hpp deleted file mode 100644 index a65b27266..000000000 --- a/include/mapnik/svg/svg_path_grammar.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2016 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_SVG_PATH_GRAMMAR_HPP -#define MAPNIK_SVG_PATH_GRAMMAR_HPP - -// spirit -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; - -template -struct svg_path_grammar : qi::grammar -{ - // ctor - svg_path_grammar(); - // rules - qi::rule start; - qi::rule cmd; - qi::rule drawto_cmd; - qi::rule, void(PathType&), SkipType> M; // M,m - qi::rule, void(PathType&), SkipType> L; // L,l - qi::rule, void(PathType&), SkipType> H; // H,h - qi::rule, void(PathType&), SkipType> V; // V,v - qi::rule, void(PathType&), SkipType> C; // C,c - qi::rule, void(PathType&), SkipType> S; // S,s - qi::rule, void(PathType&), SkipType> Q; // Q,q - qi::rule, void(PathType&), SkipType> T; // T,t - qi::rule, void(PathType&), SkipType> A; // A,a - qi::rule Z; // Z,z - qi::rule(), SkipType> coord; -}; - -}} - - -#endif // MAPNIK_SVG_PATH_GRAMMAR_HPP diff --git a/include/mapnik/svg/svg_path_grammar_impl.hpp b/include/mapnik/svg/svg_path_grammar_impl.hpp deleted file mode 100644 index 5d5fd1a7a..000000000 --- a/include/mapnik/svg/svg_path_grammar_impl.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2016 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// NOTE: This is an implementation header file and is only meant to be included -// from implementation files. It therefore doesn't have an include guard. - -// mapnik -#include -#include - -// spirit -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; -using namespace boost::phoenix; - - -template -svg_path_grammar::svg_path_grammar() - : svg_path_grammar::base_type(start) -{ - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_5_type _5; - qi::_a_type _a; - qi::lit_type lit; - qi::_r1_type _r1; - qi::double_type double_; - qi::int_type int_; - qi::no_case_type no_case; - - // commands - function move_to_; - function hline_to_; - function vline_to_; - function line_to_; - function curve4_; - function curve4_smooth_; - function curve3_; - function curve3_smooth_; - function arc_to_; - function close_; - // - start = +cmd(_r1); - - cmd = M(_r1) >> *drawto_cmd(_r1); - - drawto_cmd = L(_r1) | H(_r1) | V(_r1) | C(_r1) | S(_r1) | Q(_r1) | T(_r1) | A(_r1) | Z(_r1); - - M = (lit('M')[_a = false] | lit('m')[_a = true]) >> coord[move_to_(_r1, _1, _a)] // move_to - >> *(-lit(',') >> coord[line_to_(_r1, _1, _a)]); // *line_to - - H = (lit('H')[_a = false] | lit('h')[_a = true]) - >> (double_[ hline_to_(_r1, _1,_a) ] % -lit(',')) ; // +hline_to - - V = (lit('V')[_a = false] | lit('v')[_a = true]) - >> (double_ [ vline_to_(_r1, _1,_a) ] % -lit(',')); // +vline_to - - L = (lit('L')[_a = false] | lit('l')[_a = true]) - >> (coord [ line_to_(_r1, _1, _a) ] % -lit(',')); // +line_to - - C = (lit('C')[_a = false] | lit('c')[_a = true]) - >> ((coord >> -lit(',') >> coord >> -lit(',') >> coord)[curve4_(_r1, _1, _2, _3, _a)] % -lit(',')); // +curve4 - - S = (lit('S')[_a = false] | lit('s')[_a = true]) - >> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_r1, _1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto) - - Q = (lit('Q')[_a = false] | lit('q')[_a = true]) - >> ((coord >> -lit(',') >> coord) [ curve3_(_r1, _1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto) - - T = (lit('T')[_a = false] | lit('t')[_a = true]) - >> ((coord ) [ curve3_smooth_(_r1, _1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto) - - A = (lit('A')[_a = false] | lit('a')[_a = true]) - >> ((coord >> -lit(',') >> double_ >> -lit(',') >> int_ >> -lit(',') >> int_ >> -lit(',') >> coord) - [arc_to_(_r1, _1, _2, _3, _4, _5, _a)] % -lit(',')); // arc_to; - - Z = no_case[lit('z')] [close_(_r1)]; // close path - - coord = double_ >> -lit(',') >> double_; -} - -} // namespace svg -} // namespace mapnik diff --git a/include/mapnik/svg/svg_path_grammar_x3.hpp b/include/mapnik/svg/svg_path_grammar_x3.hpp new file mode 100644 index 000000000..80882fce1 --- /dev/null +++ b/include/mapnik/svg/svg_path_grammar_x3.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_SVG_PATH_GRAMMAR_X3_HPP +#define MAPNIK_SVG_PATH_GRAMMAR_X3_HPP + +#include + +namespace mapnik { namespace svg { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using svg_path_grammar_type = x3::rule; +using svg_points_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(svg_path_grammar_type, + svg_points_grammar_type); + +} + +grammar::svg_path_grammar_type const& svg_path_grammar(); + +grammar::svg_points_grammar_type const& svg_points_grammar(); + +}} + +#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP diff --git a/include/mapnik/svg/svg_path_grammar_x3_def.hpp b/include/mapnik/svg/svg_path_grammar_x3_def.hpp new file mode 100644 index 000000000..b1bed97aa --- /dev/null +++ b/include/mapnik/svg/svg_path_grammar_x3_def.hpp @@ -0,0 +1,203 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP +#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP + +// mapnik +#include +#include +#include +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::double_; +using x3::int_; +using x3::no_case; + +using coord_type = std::tuple; + +auto const move_to = [] (auto const& ctx) +{ + x3::get(ctx).get().move_to(std::get<0>(_attr(ctx)), std::get<1>(_attr(ctx)), x3::get(ctx)); +}; + +auto const line_to = [] (auto const & ctx) +{ + x3::get(ctx).get().line_to(std::get<0>(_attr(ctx)), std::get<1>(_attr(ctx)), x3::get(ctx)); +}; + +auto const hline_to = [] (auto const& ctx) +{ + x3::get(ctx).get().hline_to(_attr(ctx), x3::get(ctx)); +}; + +auto const vline_to = [] (auto const& ctx) +{ + x3::get(ctx).get().vline_to(_attr(ctx), x3::get(ctx)); +}; + +auto const curve4 = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& p0 = boost::fusion::at_c<0>(attr); + auto const& p1 = boost::fusion::at_c<1>(attr); + auto const& p2 = boost::fusion::at_c<2>(attr); + x3::get(ctx).get().curve4(std::get<0>(p0),std::get<1>(p0), + std::get<0>(p1),std::get<1>(p1), + std::get<0>(p2),std::get<1>(p2), + x3::get(ctx)); +}; + +auto const curve4_smooth = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& p0 = boost::fusion::at_c<0>(attr); + auto const& p1 = boost::fusion::at_c<1>(attr); + x3::get(ctx).get().curve4(std::get<0>(p0),std::get<1>(p0), + std::get<0>(p1),std::get<1>(p1), + x3::get(ctx)); +}; + +auto const curve3 = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& p0 = boost::fusion::at_c<0>(attr); + auto const& p1 = boost::fusion::at_c<1>(attr); + x3::get(ctx).get().curve3(std::get<0>(p0),std::get<1>(p0), + std::get<0>(p1),std::get<1>(p1), + x3::get(ctx)); +}; + +auto const curve3_smooth = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + x3::get(ctx).get().curve3(std::get<0>(attr),std::get<1>(attr), + x3::get(ctx)); +}; + + +auto const arc_to = [] (auto & ctx) +{ + auto const& attr = _attr(ctx); + auto const& p = boost::fusion::at_c<0>(attr); + double angle = boost::fusion::at_c<1>(attr); + int large_arc_flag = boost::fusion::at_c<2>(attr); + int sweep_flag = boost::fusion::at_c<3>(attr); + auto const& v = boost::fusion::at_c<4>(attr); + x3::get(ctx).get().arc_to(std::get<0>(p),std::get<1>(p), + deg2rad(angle), large_arc_flag, sweep_flag, + std::get<0>(v),std::get<1>(v), + x3::get(ctx)); +}; + +auto const close_path = [] (auto const& ctx) +{ + x3::get(ctx).get().close_subpath(); +}; + +auto const relative = [] (auto const& ctx) +{ + x3::get(ctx).get() = true; +}; + +auto const absolute = [] (auto const& ctx) +{ + x3::get(ctx).get() = false; +}; + +// exported rules +svg_path_grammar_type const svg_path = "SVG Path"; +svg_points_grammar_type const svg_points = "SVG_Points"; + +// rules +auto const coord = x3::rule{} = double_ > -lit(',') > double_; + +auto const svg_points_def = coord[move_to] // move_to + > *(-lit(',') >> coord[line_to]); // *line_to + +auto const M = x3::rule {} = (lit('M')[absolute] | lit('m')[relative]) + > svg_points ; + +auto const H = x3::rule {} = (lit('H')[absolute] | lit('h')[relative]) + > (double_[ hline_to] % -lit(',')) ; // +hline_to + +auto const V = x3::rule {} = (lit('V')[absolute] | lit('v')[relative]) + > (double_[ vline_to] % -lit(',')) ; // +vline_to + +auto const L = x3::rule {} = (lit('L')[absolute] | lit('l')[relative]) + > (coord [line_to] % -lit(',')); // +line_to + +auto const C = x3::rule {} = (lit('C')[absolute] | lit('c')[relative]) + > ((coord > -lit(',') > coord > -lit(',') > coord)[curve4] % -lit(',')); // +curve4 + +auto const S = x3::rule {} = (lit('S')[absolute] | lit('s')[relative]) + > ((coord > -lit(',') > coord) [curve4_smooth] % -lit(',')); // +curve4_smooth (smooth curveto) + +auto const Q = x3::rule {} = (lit('Q')[absolute] | lit('q')[relative]) + > ((coord > -lit(',') > coord) [curve3] % -lit(',')); // +curve3 (quadratic-bezier-curveto) + +auto const T = x3::rule {} = (lit('T')[absolute] | lit('t')[relative]) + > ((coord ) [curve3_smooth] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto) + +auto const A = x3::rule {} = (lit('A')[absolute] | lit('a')[relative]) + > ((coord > -lit(',') > double_ > -lit(',') > int_ > -lit(',') > int_ > -lit(',') > coord) + [arc_to] % -lit(',')); // arc_to; + +auto const Z = x3::rule{} = no_case[lit('z')] [close_path]; // close path + +auto const drawto_cmd = x3::rule {} = L | H | V | C | S | Q | T | A | Z; + +auto const cmd = x3::rule {} = M > *drawto_cmd ; + +auto const svg_path_def = +cmd; + +#pragma GCC diagnostic push +#include +BOOST_SPIRIT_DEFINE( + svg_path, + svg_points + ); +#pragma GCC diagnostic pop + +} + +grammar::svg_path_grammar_type const& svg_path_grammar() +{ + return grammar::svg_path; +} + +grammar::svg_points_grammar_type const& svg_points_grammar() +{ + return grammar::svg_points; +} + +}} + +#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP diff --git a/include/mapnik/svg/svg_path_parser.hpp b/include/mapnik/svg/svg_path_parser.hpp index 5633b2ea9..444badbf5 100644 --- a/include/mapnik/svg/svg_path_parser.hpp +++ b/include/mapnik/svg/svg_path_parser.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,6 @@ // mapnik #include #include -#include // stl #include @@ -40,12 +39,12 @@ template bool parse_points(const char* wkt, PathType& p); template -bool MAPNIK_DECL parse_svg_transform(const char* wkt, TransformType& tr); +bool parse_svg_transform(const char* wkt, TransformType& tr); // extern template bool MAPNIK_DECL parse_path(const char*, svg_converter_type&); extern template bool MAPNIK_DECL parse_points(const char*, svg_converter_type&); -extern template bool MAPNIK_DECL parse_svg_transform(const char*, svg_converter_type&); +extern template bool MAPNIK_DECL parse_svg_transform(const char*, agg::trans_affine&); } } diff --git a/include/mapnik/svg/svg_points_grammar_impl.hpp b/include/mapnik/svg/svg_points_grammar_impl.hpp deleted file mode 100644 index 5d56f7e25..000000000 --- a/include/mapnik/svg/svg_points_grammar_impl.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// NOTE: This is an implementation header file and is only meant to be included -// from implementation files. It therefore doesn't have an include guard. -// mapnik -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; -using namespace boost::phoenix; - -template -svg_points_grammar::svg_points_grammar() - : svg_points_grammar::base_type(start) -{ - qi::_1_type _1; - qi::_r1_type _r1; - qi::lit_type lit; - qi::double_type double_; - // commands - function move_to_; - function line_to_; - function close_; - - start = coord[move_to_(_r1, _1, false)] // move_to - >> *(-lit(',') >> coord [ line_to_(_r1, _1,false) ] ); // *line_to - - coord = double_ >> -lit(',') >> double_; -} - -}} diff --git a/include/mapnik/svg/svg_renderer_agg.hpp b/include/mapnik/svg/svg_renderer_agg.hpp index d99575b4d..9183dd7e6 100644 --- a/include/mapnik/svg/svg_renderer_agg.hpp +++ b/include/mapnik/svg/svg_renderer_agg.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,8 +26,8 @@ // mapnik #include #include -#include -#include +#include +#include #include #if defined(GRID_RENDERER) diff --git a/include/mapnik/svg/svg_storage.hpp b/include/mapnik/svg/svg_storage.hpp index c360ecf52..120c27b1c 100644 --- a/include/mapnik/svg/svg_storage.hpp +++ b/include/mapnik/svg/svg_storage.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_SVG_STORAGE_HPP // mapnik -#include +#include #include namespace mapnik { diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp deleted file mode 100644 index 895112d4a..000000000 --- a/include/mapnik/svg/svg_transform_grammar.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_SVG_TRANSFORM_GRAMMAR_HPP -#define MAPNIK_SVG_TRANSFORM_GRAMMAR_HPP - -// mapnik -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; - -template -struct svg_transform_grammar : qi::grammar -{ - // ctor - svg_transform_grammar(); - // rules - qi::rule start; - qi::rule transform_; - qi::rule matrix; - qi::rule translate; - qi::rule scale; - qi::rule, void(TransformType&), SkipType> rotate; - qi::rule skewX; - qi::rule skewY; -}; - -}} - -#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_HPP diff --git a/include/mapnik/svg/svg_transform_grammar_impl.hpp b/include/mapnik/svg/svg_transform_grammar_impl.hpp deleted file mode 100644 index 65c05ab2c..000000000 --- a/include/mapnik/svg/svg_transform_grammar_impl.hpp +++ /dev/null @@ -1,172 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// NOTE: This is an implementation header file and is only meant to be included -// from implementation files. It therefore doesn't have an include guard. -// mapnik -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; -using namespace boost::fusion; -using namespace boost::phoenix; - -inline double deg2rad(double d) -{ - return M_PI * d / 180.0; -} - -struct process_matrix -{ - using result_type = void; - template - void operator () (TransformType & tr, double a, double b, double c, double d, double e, double f) const - { - tr = agg::trans_affine(a,b,c,d,e,f) * tr; - } -}; - -struct process_rotate -{ - using result_type = void; - - template - void operator () (TransformType & tr, T0 a, T1 cx, T2 cy) const - { - if (cx == 0.0 && cy == 0.0) - { - tr = agg::trans_affine_rotation(deg2rad(a)) * tr; - } - else - { - agg::trans_affine t = agg::trans_affine_translation(-cx,-cy); - t *= agg::trans_affine_rotation(deg2rad(a)); - t *= agg::trans_affine_translation(cx, cy); - tr = t * tr; - } - } -}; - -struct process_translate -{ - using result_type = void; - template - void operator () (TransformType & tr, T0 tx, T1 ty) const - { - if (ty) tr = agg::trans_affine_translation(tx,*ty) * tr; - else tr = agg::trans_affine_translation(tx,0.0) * tr; - } -}; - -struct process_scale -{ - using result_type = void; - template - void operator () (TransformType & tr, T0 sx, T1 sy) const - { - if (sy) tr = agg::trans_affine_scaling(sx,*sy) * tr; - else tr = agg::trans_affine_scaling(sx,sx) * tr; - } -}; - - -struct process_skew -{ - using result_type = void; - - template - void operator () (TransformType & tr, T0 skew_x, T1 skew_y) const - { - tr = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr; - } -}; - -template -svg_transform_grammar::svg_transform_grammar() - : svg_transform_grammar::base_type(start) -{ - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_5_type _5; - qi::_6_type _6; - qi::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::_r1_type _r1; - qi::lit_type lit; - qi::double_type double_; - qi::no_case_type no_case; - - // actions - function matrix_action; - function rotate_action; - function translate_action; - function scale_action; - function skew_action; - - start = +transform_(_r1) ; - - transform_ = matrix(_r1) | rotate(_r1) | translate(_r1) | scale(_r1) | rotate(_r1) | skewX(_r1) | skewY (_r1) ; - - matrix = no_case[lit("matrix")] >> lit('(') - >> (double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_)[matrix_action(_r1, _1, _2, _3, _4, _5, _6)] >> lit(')'); - - translate = no_case[lit("translate")] - >> lit('(') >> (double_ >> -lit(',') >> -double_)[translate_action(_r1, _1, _2)] >> lit(')'); - - scale = no_case[lit("scale")] - >> lit('(') >> (double_ >> -lit(',') >> -double_)[scale_action(_r1, _1, _2)] >> lit(')'); - - rotate = no_case[lit("rotate")] - >> lit('(') - >> double_[_a = _1] >> -lit(',') - >> -(double_ [_b = _1] >> -lit(',') >> double_[_c = _1]) - >> lit(')') [ rotate_action(_r1, _a,_b,_c)]; - - skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_r1, _1, 0.0)] >> lit(')'); - - skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(_r1, 0.0, _1)] >> lit(')'); - -} - -}} diff --git a/include/mapnik/svg/svg_transform_grammar_x3.hpp b/include/mapnik/svg/svg_transform_grammar_x3.hpp new file mode 100644 index 000000000..c0fb12915 --- /dev/null +++ b/include/mapnik/svg/svg_transform_grammar_x3.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP +#define MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP + +// mapnik +#include + +namespace mapnik { namespace svg { namespace grammar { + +using namespace boost::spirit::x3; + +using svg_transform_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(svg_transform_grammar_type); + +} + +grammar::svg_transform_grammar_type const& svg_transform_grammar(); + +}} + +#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP diff --git a/include/mapnik/svg/svg_transform_grammar_x3_def.hpp b/include/mapnik/svg/svg_transform_grammar_x3_def.hpp new file mode 100644 index 000000000..47b6030ce --- /dev/null +++ b/include/mapnik/svg/svg_transform_grammar_x3_def.hpp @@ -0,0 +1,163 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_DEF_HPP +#define MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_DEF_HPP + +// mapnik +#include +// boost::fusion +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop +// agg +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::double_; +using x3::no_case; + +auto const matrix_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto a = boost::fusion::at_c<0>(attr); + auto b = boost::fusion::at_c<1>(attr); + auto c = boost::fusion::at_c<2>(attr); + auto d = boost::fusion::at_c<3>(attr); + auto e = boost::fusion::at_c<4>(attr); + auto f = boost::fusion::at_c<5>(attr); + tr = agg::trans_affine(a, b, c, d, e, f) * tr; +}; + +auto const rotate_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto a = boost::fusion::at_c<0>(attr); + auto cx = boost::fusion::at_c<1>(attr) ? *boost::fusion::at_c<1>(attr) : 0.0; + auto cy = boost::fusion::at_c<2>(attr) ? *boost::fusion::at_c<2>(attr) : 0.0; + if (cx == 0.0 && cy == 0.0) + { + tr = agg::trans_affine_rotation(deg2rad(a)) * tr; + } + else + { + agg::trans_affine t = agg::trans_affine_translation(-cx,-cy); + t *= agg::trans_affine_rotation(deg2rad(a)); + t *= agg::trans_affine_translation(cx, cy); + tr = t * tr; + } +}; + +auto const translate_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto tx = boost::fusion::at_c<0>(attr); + auto ty = boost::fusion::at_c<1>(attr); + if (ty) tr = agg::trans_affine_translation(tx, *ty) * tr; + else tr = agg::trans_affine_translation(tx,0.0) * tr; +}; + +auto const scale_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto sx = boost::fusion::at_c<0>(attr); + auto sy = boost::fusion::at_c<1>(attr); + if (sy) tr = agg::trans_affine_scaling(sx, *sy) * tr; + else tr = agg::trans_affine_scaling(sx, sx) * tr; +}; + +auto const skewX_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto skew_x = _attr(ctx); + tr = agg::trans_affine_skewing(deg2rad(skew_x), 0.0) * tr; +}; + +auto const skewY_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto skew_y= _attr(ctx); + tr = agg::trans_affine_skewing(0.0, deg2rad(skew_y)) * tr; +}; + +//exported rule +svg_transform_grammar_type const svg_transform = "SVG Transform"; +// rules +auto const matrix = x3::rule {} = no_case[lit("matrix")] + > lit('(') > (double_ > -lit(',') + > double_ > -lit(',') + > double_ > -lit(',') + > double_ > -lit(',') + > double_ > -lit(',') + > double_)[matrix_action] + > lit(')'); + +auto const translate = x3::rule {} = no_case[lit("translate")] + > lit('(') > (double_ > -lit(',') >> -double_)[translate_action] > lit(')'); + +auto const scale = x3::rule {} = no_case[lit("scale")] + > lit('(') > (double_ > -lit(',') > -double_)[scale_action] > lit(')'); + +auto const rotate = x3::rule {} = no_case[lit("rotate")] + > lit('(') + > (double_ > -(lit(',') > double_) > -(lit(',') > double_))[rotate_action] + > lit(')') ; + +auto const skewX = x3::rule {} = no_case[lit("skewX")] + > lit('(') > double_ [ skewX_action] > lit(')'); +auto const skewY = x3::rule {} = no_case[lit("skewY")] + > lit('(') > double_ [ skewY_action] > lit(')'); + +auto const transform = x3::rule {} = matrix | rotate | translate | scale /*| rotate*/ | skewX | skewY ; + +auto const svg_transform_def = +transform ; + +#pragma GCC diagnostic push +#include +BOOST_SPIRIT_DEFINE( + svg_transform + ); +#pragma GCC diagnostic pop + +} + +grammar::svg_transform_grammar_type const& svg_transform_grammar() +{ + return grammar::svg_transform; +} + +}} + + +#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP diff --git a/include/mapnik/symbolizer.hpp b/include/mapnik/symbolizer.hpp index 9308ecd7b..9cdb96f70 100644 --- a/include/mapnik/symbolizer.hpp +++ b/include/mapnik/symbolizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -462,7 +462,7 @@ T get(symbolizer_base const& sym, keys key) { return util::apply_visitor(extract_raw_value(), itr->second); } - return T(); + return T{}; } @@ -487,7 +487,7 @@ boost::optional get_optional(symbolizer_base const& sym, keys key) { return util::apply_visitor(extract_raw_value(), itr->second); } - return boost::optional(); + return boost::optional{}; } } diff --git a/include/mapnik/symbolizer_base.hpp b/include/mapnik/symbolizer_base.hpp index f07cf3d2a..be1529216 100644 --- a/include/mapnik/symbolizer_base.hpp +++ b/include/mapnik/symbolizer_base.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #include #include @@ -100,18 +100,13 @@ struct strict_value : value_base_type { strict_value() = default; - strict_value(const char* val) + strict_value(const char* val) noexcept(false) : value_base_type(std::string(val)) {} - template - strict_value(T const& obj) - : value_base_type(typename detail::mapnik_value_type::type(obj)) - {} - - template + template > strict_value(T && obj) - noexcept(std::is_nothrow_constructible::value) - : value_base_type(std::forward(obj)) + noexcept(std::is_nothrow_constructible::value) + : value_base_type(U(std::forward(obj))) {} }; diff --git a/include/mapnik/symbolizer_default_values.hpp b/include/mapnik/symbolizer_default_values.hpp index ea5e5c02e..3f918fb2f 100644 --- a/include/mapnik/symbolizer_default_values.hpp +++ b/include/mapnik/symbolizer_default_values.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include @@ -369,6 +369,13 @@ struct symbolizer_default // font-feature-settings +// extend +template <> +struct symbolizer_default +{ + static value_double value() { return 0.0; } +}; + } // namespace mapnik #endif // MAPNIK_SYMBOLIZER_DEFAULT_VALUES_HPP diff --git a/include/mapnik/symbolizer_dispatch.hpp b/include/mapnik/symbolizer_dispatch.hpp index 52f65bcfc..cb43b7b65 100644 --- a/include/mapnik/symbolizer_dispatch.hpp +++ b/include/mapnik/symbolizer_dispatch.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/symbolizer_enumerations.hpp b/include/mapnik/symbolizer_enumerations.hpp index 7a3e72fd8..e24f079a9 100644 --- a/include/mapnik/symbolizer_enumerations.hpp +++ b/include/mapnik/symbolizer_enumerations.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/symbolizer_hash.hpp b/include/mapnik/symbolizer_hash.hpp index 9c2baa4e4..afd5cd3de 100644 --- a/include/mapnik/symbolizer_hash.hpp +++ b/include/mapnik/symbolizer_hash.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/symbolizer_keys.hpp b/include/mapnik/symbolizer_keys.hpp index 15919dc1b..1d395c015 100644 --- a/include/mapnik/symbolizer_keys.hpp +++ b/include/mapnik/symbolizer_keys.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -92,6 +92,7 @@ enum class keys : std::uint8_t direction, avoid_edges, ff_settings, + extend, MAX_SYMBOLIZER_KEY }; diff --git a/include/mapnik/symbolizer_utils.hpp b/include/mapnik/symbolizer_utils.hpp index cea99000c..e18cf2a8c 100644 --- a/include/mapnik/symbolizer_utils.hpp +++ b/include/mapnik/symbolizer_utils.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,13 +30,13 @@ #include #include #include -#include #include #include #include #include #include -#include +#include +#include #include #include diff --git a/include/mapnik/text/evaluated_format_properties_ptr.hpp b/include/mapnik/text/evaluated_format_properties_ptr.hpp index 472865181..351261339 100644 --- a/include/mapnik/text/evaluated_format_properties_ptr.hpp +++ b/include/mapnik/text/evaluated_format_properties_ptr.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/face.hpp b/include/mapnik/text/face.hpp index 3d797a1f2..9158e258b 100644 --- a/include/mapnik/text/face.hpp +++ b/include/mapnik/text/face.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -72,10 +72,13 @@ public: bool glyph_dimensions(glyph_info &glyph) const; + inline bool is_color() const { return color_font_;} + ~font_face(); private: FT_Face face_; + bool color_font_ = false; }; using face_ptr = std::shared_ptr; diff --git a/include/mapnik/text/font_feature_settings.hpp b/include/mapnik/text/font_feature_settings.hpp index 8bc3e33c6..e6b8d7b6c 100644 --- a/include/mapnik/text/font_feature_settings.hpp +++ b/include/mapnik/text/font_feature_settings.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/font_library.hpp b/include/mapnik/text/font_library.hpp index 163aad3d6..31ef063ab 100644 --- a/include/mapnik/text/font_library.hpp +++ b/include/mapnik/text/font_library.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/formatting/base.hpp b/include/mapnik/text/formatting/base.hpp index da47d5d54..68aa33392 100644 --- a/include/mapnik/text/formatting/base.hpp +++ b/include/mapnik/text/formatting/base.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/formatting/format.hpp b/include/mapnik/text/formatting/format.hpp index c540abd13..76deed1a5 100644 --- a/include/mapnik/text/formatting/format.hpp +++ b/include/mapnik/text/formatting/format.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/formatting/layout.hpp b/include/mapnik/text/formatting/layout.hpp index 6892ce72b..de6d35e5a 100644 --- a/include/mapnik/text/formatting/layout.hpp +++ b/include/mapnik/text/formatting/layout.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/formatting/list.hpp b/include/mapnik/text/formatting/list.hpp index 45c4217db..3f9914dcc 100644 --- a/include/mapnik/text/formatting/list.hpp +++ b/include/mapnik/text/formatting/list.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/formatting/registry.hpp b/include/mapnik/text/formatting/registry.hpp index 7328d2b9c..ed974fc10 100644 --- a/include/mapnik/text/formatting/registry.hpp +++ b/include/mapnik/text/formatting/registry.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/formatting/text.hpp b/include/mapnik/text/formatting/text.hpp index 012288507..46766422e 100644 --- a/include/mapnik/text/formatting/text.hpp +++ b/include/mapnik/text/formatting/text.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/glyph_info.hpp b/include/mapnik/text/glyph_info.hpp index 3950f9dd2..fc177440d 100644 --- a/include/mapnik/text/glyph_info.hpp +++ b/include/mapnik/text/glyph_info.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/glyph_positions.hpp b/include/mapnik/text/glyph_positions.hpp index aa08e3376..e8d732cf3 100644 --- a/include/mapnik/text/glyph_positions.hpp +++ b/include/mapnik/text/glyph_positions.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_TEXT_GLYPH_POSITIONS_HPP //mapnik -#include +#include #include #include #include diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp index 8b574b095..bee119557 100644 --- a/include/mapnik/text/harfbuzz_shaper.hpp +++ b/include/mapnik/text/harfbuzz_shaper.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -80,17 +80,16 @@ static void shape_text(text_line & line, line.reserve(length); auto hb_buffer_deleter = [](hb_buffer_t * buffer) { hb_buffer_destroy(buffer);}; - const std::unique_ptr buffer(hb_buffer_create(),hb_buffer_deleter); + const std::unique_ptr buffer(hb_buffer_create(), hb_buffer_deleter); hb_buffer_pre_allocate(buffer.get(), safe_cast(length)); mapnik::value_unicode_string const& text = itemizer.text(); - for (auto const& text_item : list) { face_set_ptr face_set = font_manager.get_face_set(text_item.format_->face_name, text_item.format_->fontset); double size = text_item.format_->text_size * scale_factor; face_set->set_unscaled_character_sizes(); std::size_t num_faces = face_set->size(); - std::size_t pos = 0; + font_feature_settings const& ff_settings = text_item.format_->ff_settings; int ff_count = safe_cast(ff_settings.count()); @@ -101,83 +100,116 @@ static void shape_text(text_line & line, hb_glyph_info_t glyph; hb_glyph_position_t position; }; - // this table is filled with information for rendering each glyph, so that - // several font faces can be used in a single text_item - std::vector glyphinfos; - unsigned valid_glyphs = 0; + // this table is filled with information for rendering each glyph, so that + // several font faces can be used in a single text_item + std::size_t pos = 0; + std::vector> glyphinfos; + + glyphinfos.resize(text.length()); for (auto const& face : *face_set) { ++pos; hb_buffer_clear_contents(buffer.get()); hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, static_cast(text_item.end - text_item.start)); - hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR); + hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL) ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script)); hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr)); // https://github.com/mapnik/test-data-visual/pull/25 - #if HB_VERSION_MAJOR > 0 - #if HB_VERSION_ATLEAST(1, 0 , 5) +#if HB_VERSION_MAJOR > 0 +#if HB_VERSION_ATLEAST(1, 0 , 5) hb_ft_font_set_load_flags(font,FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); - #endif - #endif +#endif +#endif hb_shape(font, buffer.get(), ff_settings.get_features(), ff_count); hb_font_destroy(font); unsigned num_glyphs = hb_buffer_get_length(buffer.get()); + hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer.get(), &num_glyphs); + hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), &num_glyphs); - // if the number of rendered glyphs has increased, we need to resize the table - if (num_glyphs > glyphinfos.size()) + unsigned cluster = 0; + bool in_cluster = false; + std::vector clusters; + + for (unsigned i = 0; i < num_glyphs; ++i) { - glyphinfos.resize(num_glyphs); - } - - hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer.get(), nullptr); - hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), nullptr); - - // Check if all glyphs are valid. - for (unsigned i=0; iglyph_dimensions(g)) - { - g.face = theface; - g.scale_multiplier = size / theface->get_face()->units_per_EM; - //Overwrite default advance with better value provided by HarfBuzz - g.unscaled_advance = gpos.x_advance; - g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier); - double tmp_height = g.height(); - if (tmp_height > max_glyph_height) max_glyph_height = tmp_height; - width_map[char_index] += g.advance(); - line.add_glyph(std::move(g), scale_factor); + auto const& gpos = info.position; + auto const& glyph = info.glyph; + unsigned char_index = glyph.cluster; + glyph_info g(glyph.codepoint,char_index,text_item.format_); + if (info.glyph.codepoint != 0) g.face = info.face; + else g.face = face; + if (g.face->glyph_dimensions(g)) + { + g.scale_multiplier = g.face->get_face()->units_per_EM > 0 ? + (size / g.face->get_face()->units_per_EM) : (size / 2048.0) ; + //Overwrite default advance with better value provided by HarfBuzz + g.unscaled_advance = gpos.x_advance; + g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier); + double tmp_height = g.height(); + if (g.face->is_color()) + { + tmp_height = size; + } + if (tmp_height > max_glyph_height) max_glyph_height = tmp_height; + width_map[char_index] += g.advance(); + line.add_glyph(std::move(g), scale_factor); + } } } line.update_max_char_height(max_glyph_height); diff --git a/include/mapnik/text/icu_shaper.hpp b/include/mapnik/text/icu_shaper.hpp index 39bc590bb..2f3373e9c 100644 --- a/include/mapnik/text/icu_shaper.hpp +++ b/include/mapnik/text/icu_shaper.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/itemizer.hpp b/include/mapnik/text/itemizer.hpp index 5087ce06f..70e99322e 100644 --- a/include/mapnik/text/itemizer.hpp +++ b/include/mapnik/text/itemizer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ //mapnik #include -#include +#include #include #include diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp index 3b02d8924..195dba80d 100644 --- a/include/mapnik/text/placement_finder.hpp +++ b/include/mapnik/text/placement_finder.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ #define MAPNIK_PLACEMENT_FINDER_HPP //mapnik -#include +#include #include #include #include @@ -67,8 +67,6 @@ private: bool single_line_placement(vertex_cache &pp, text_upright_e orientation); // Moves dx pixels but makes sure not to fall of the end. void path_move_dx(vertex_cache & pp, double dx); - // Normalize angle in range [-pi, +pi]. - static double normalize_angle(double angle); // Adjusts user defined spacing to place an integer number of labels. double get_spacing(double path_length, double layout_width) const; // Checks for collision. diff --git a/include/mapnik/text/placement_finder_impl.hpp b/include/mapnik/text/placement_finder_impl.hpp index 1b8f84147..efebf3d76 100644 --- a/include/mapnik/text/placement_finder_impl.hpp +++ b/include/mapnik/text/placement_finder_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,12 +21,9 @@ *****************************************************************************/ // mapnik -//#include -//#include #include #include #include -//#include #include #include #include diff --git a/include/mapnik/text/placements/base.hpp b/include/mapnik/text/placements/base.hpp index 0b93fb8e8..8e075f575 100644 --- a/include/mapnik/text/placements/base.hpp +++ b/include/mapnik/text/placements/base.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/placements/dummy.hpp b/include/mapnik/text/placements/dummy.hpp index e83808f45..3e39dd678 100644 --- a/include/mapnik/text/placements/dummy.hpp +++ b/include/mapnik/text/placements/dummy.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/placements/list.hpp b/include/mapnik/text/placements/list.hpp index c21a4d87c..5da67e85b 100644 --- a/include/mapnik/text/placements/list.hpp +++ b/include/mapnik/text/placements/list.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -50,8 +50,8 @@ private: class text_placement_info_list : public text_placement_info { public: - text_placement_info_list(text_placements_list const* parent, double scale_factor) : - text_placement_info(parent, scale_factor), + text_placement_info_list(text_placements_list const* parent, double _scale_factor) : + text_placement_info(parent, _scale_factor), state(0), parent_(parent) {} bool next() const; private: diff --git a/include/mapnik/text/placements/registry.hpp b/include/mapnik/text/placements/registry.hpp index f8d8aefb1..76ec5e285 100644 --- a/include/mapnik/text/placements/registry.hpp +++ b/include/mapnik/text/placements/registry.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/placements/simple.hpp b/include/mapnik/text/placements/simple.hpp index ea0d73c5e..9f7bf91bc 100644 --- a/include/mapnik/text/placements/simple.hpp +++ b/include/mapnik/text/placements/simple.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/properties_util.hpp b/include/mapnik/text/properties_util.hpp index 5b92ed306..d280f5657 100644 --- a/include/mapnik/text/properties_util.hpp +++ b/include/mapnik/text/properties_util.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/renderer.hpp b/include/mapnik/text/renderer.hpp index 692ada3cd..267a1bae5 100644 --- a/include/mapnik/text/renderer.hpp +++ b/include/mapnik/text/renderer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,6 +28,7 @@ #include #include #include +#include #pragma GCC diagnostic push #include @@ -51,8 +52,13 @@ struct glyph_t { FT_Glyph image; detail::evaluated_format_properties const& properties; - glyph_t(FT_Glyph image_, detail::evaluated_format_properties const& properties_) - : image(image_), properties(properties_) {} + pixel_position pos; + double size; + glyph_t(FT_Glyph image_, detail::evaluated_format_properties const& properties_, pixel_position const& pos_, double size_) + : image(image_), + properties(properties_), + pos(pos_), + size(size_) {} }; class text_renderer : private util::noncopyable diff --git a/include/mapnik/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp index 83a3c1939..222c6f89e 100644 --- a/include/mapnik/text/symbolizer_helpers.hpp +++ b/include/mapnik/text/symbolizer_helpers.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -59,7 +59,7 @@ struct placement_finder_adapter }; -using vertex_converter_type = vertex_converter; +using vertex_converter_type = vertex_converter; class base_symbolizer_helper { diff --git a/include/mapnik/text/text_layout.hpp b/include/mapnik/text/text_layout.hpp index 2e59cdc8b..a79a0caf8 100644 --- a/include/mapnik/text/text_layout.hpp +++ b/include/mapnik/text/text_layout.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,9 +23,9 @@ #define MAPNIK_TEXT_LAYOUT_HPP //mapnik -#include +#include #include -#include +#include #include #include #include @@ -143,8 +143,8 @@ private: // note: this probably isn't the best solution. it would be better to have an object for each cluster, but // it needs to be implemented with no overhead. std::map width_map_; - double width_; - double height_; + double width_ = 0.0; + double height_ = 0.0; unsigned glyphs_count_; // output @@ -173,7 +173,7 @@ private: bool rotate_displacement_ = false; double text_ratio_ = 0.0; pixel_position displacement_ = {0,0}; - box2d bounds_; + box2d bounds_ = {0, 0, 0, 0}; // children text_layout_vector child_layout_list_; diff --git a/include/mapnik/text/text_line.hpp b/include/mapnik/text/text_line.hpp index cf47026df..81e7d7e72 100644 --- a/include/mapnik/text/text_line.hpp +++ b/include/mapnik/text/text_line.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/text/text_properties.hpp b/include/mapnik/text/text_properties.hpp index 511ba3a28..677cd3230 100644 --- a/include/mapnik/text/text_properties.hpp +++ b/include/mapnik/text/text_properties.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -96,7 +96,8 @@ enum directions_e : std::uint8_t SOUTHEAST, NORTHWEST, SOUTHWEST, - EXACT_POSITION + EXACT_POSITION, + CENTER }; using fontset_map = std::map; diff --git a/include/mapnik/tiff_io.hpp b/include/mapnik/tiff_io.hpp index b80142906..1b31cb94c 100644 --- a/include/mapnik/tiff_io.hpp +++ b/include/mapnik/tiff_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/timer.hpp b/include/mapnik/timer.hpp index 8111ff645..347fda4d2 100644 --- a/include/mapnik/timer.hpp +++ b/include/mapnik/timer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/tolerance_iterator.hpp b/include/mapnik/tolerance_iterator.hpp index 2b9512c8b..448a0af3b 100644 --- a/include/mapnik/tolerance_iterator.hpp +++ b/include/mapnik/tolerance_iterator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/parse_transform.hpp b/include/mapnik/transform/parse_transform.hpp similarity index 97% rename from include/mapnik/parse_transform.hpp rename to include/mapnik/transform/parse_transform.hpp index 68e605c40..8d4c4899b 100644 --- a/include/mapnik/parse_transform.hpp +++ b/include/mapnik/transform/parse_transform.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/transform_expression.hpp b/include/mapnik/transform/transform_expression.hpp similarity index 92% rename from include/mapnik/transform_expression.hpp rename to include/mapnik/transform/transform_expression.hpp index b43f69170..18256efee 100644 --- a/include/mapnik/transform_expression.hpp +++ b/include/mapnik/transform/transform_expression.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include #include @@ -55,6 +55,8 @@ struct matrix_node expr_node e_; expr_node f_; + matrix_node() = default; + template explicit matrix_node(T const& m) : a_(m.sx), b_(m.shy), c_(m.shx), d_(m.sy), e_(m.tx), f_(m.ty) {} @@ -69,6 +71,8 @@ struct translate_node expr_node tx_; expr_node ty_; + translate_node() = default; + translate_node(expr_node const& tx, boost::optional const& ty) : tx_(tx) @@ -80,6 +84,8 @@ struct scale_node expr_node sx_; expr_node sy_; + scale_node() = default; + scale_node(expr_node const& sx, boost::optional const& sy) : sx_(sx) @@ -94,6 +100,8 @@ struct rotate_node expr_node cx_; expr_node cy_; + rotate_node() = default; + explicit rotate_node(expr_node const& angle) : angle_(angle) {} @@ -123,16 +131,16 @@ struct rotate_node struct skewX_node { expr_node angle_; - - explicit skewX_node(expr_node const& angle) + skewX_node() = default; + skewX_node(expr_node const& angle) : angle_(angle) {} }; struct skewY_node { expr_node angle_; - - explicit skewY_node(expr_node const& angle) + skewY_node() = default; + skewY_node(expr_node const& angle) : angle_(angle) {} }; @@ -225,9 +233,9 @@ bool is_null_node (T const& node) } // namespace detail -using transform_node = detail::transform_node ; -using transform_list = std::vector ; -using transform_list_ptr = std::shared_ptr ; +using transform_node = detail::transform_node; +using transform_list = std::vector; +using transform_list_ptr = std::shared_ptr; MAPNIK_DECL std::string to_expression_string(transform_node const& node); MAPNIK_DECL std::string to_expression_string(transform_list const& list); diff --git a/include/mapnik/transform/transform_expression_grammar_x3.hpp b/include/mapnik/transform/transform_expression_grammar_x3.hpp new file mode 100644 index 000000000..4cc5237f2 --- /dev/null +++ b/include/mapnik/transform/transform_expression_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_TRANSFORM_GRAMMAR_X3_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace grammar { + +struct transform_expression_class; // top-most ID +using transform_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(transform_expression_grammar_type); + +}} // ns + +namespace mapnik +{ +grammar::transform_expression_grammar_type const& transform_expression_grammar(); +} + +#endif diff --git a/include/mapnik/transform/transform_expression_grammar_x3_def.hpp b/include/mapnik/transform/transform_expression_grammar_x3_def.hpp new file mode 100644 index 000000000..76c439391 --- /dev/null +++ b/include/mapnik/transform/transform_expression_grammar_x3_def.hpp @@ -0,0 +1,223 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop + +// skewX +BOOST_FUSION_ADAPT_STRUCT(mapnik::skewX_node, + (mapnik::expr_node, angle_)) + +// skewY +BOOST_FUSION_ADAPT_STRUCT(mapnik::skewY_node, + (mapnik::expr_node, angle_)) + + +// Following specializations are required to avoid trasferring mapnik::skewX/Y nodes as underlying expressions +// +// template +// inline void +// move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple +// { +// dest = std::move(fusion::front(src)); +// } +// which will fail to compile with latest (more strict) `mapbox::variant` (boost_1_61) + +namespace boost { namespace spirit { namespace x3 { namespace traits { +template <> +inline void move_to(mapnik::skewX_node && src, mapnik::detail::transform_node& dst) +{ + dst = std::move(src); +} + +template <> +inline void move_to(mapnik::skewY_node && src, mapnik::detail::transform_node& dst) +{ + dst = std::move(src); +} + +}}}} + + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +namespace ascii = boost::spirit::x3::ascii; + +// [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] + +// The value of the ‘transform’ attribute is a , which +// is defined as a list of transform definitions, which are applied in +// the order provided. The individual transform definitions are +// separated by whitespace and/or a comma. + +using x3::double_; +using x3::no_skip; +using x3::no_case; +using x3::lit; + +auto const create_expr_node = [](auto const& ctx) +{ + _val(ctx) = _attr(ctx); +}; + +auto const construct_matrix = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& a = boost::fusion::at>(attr); + auto const& b = boost::fusion::at>(attr); + auto const& c = boost::fusion::at>(attr); + auto const& d = boost::fusion::at>(attr); + auto const& e = boost::fusion::at>(attr); + auto const& f = boost::fusion::at>(attr); + _val(ctx) = mapnik::matrix_node(a, b, c, d, e, f); +}; + +auto const construct_translate = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& dx = boost::fusion::at>(attr); + auto const& dy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::translate_node(dx, dy); +}; + +auto const construct_scale = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& sx = boost::fusion::at>(attr); + auto const& sy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::scale_node(sx, sy); +}; + +auto const construct_rotate = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& a = boost::fusion::at>(attr); + auto const& sx = boost::fusion::at>(attr); //optional + auto const& sy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::rotate_node(a, sx, sy); +}; + +// starting rule +transform_expression_grammar_type const transform("transform"); +// rules +x3::rule transform_list_rule("transform list"); +x3::rule transform_node_rule("transform node"); +x3::rule matrix("matrix node"); +x3::rule translate("translate node"); +x3::rule scale("scale node"); +x3::rule rotate("rotate node"); +x3::rule skewX("skew X node"); +x3::rule skewY("skew Y node"); +x3::rule expr("Expression"); +x3::rule sep_expr("Separated Expression"); + +// start +auto const transform_def = transform_list_rule; + +auto const transform_list_rule_def = transform_node_rule % *lit(','); + +auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; + +// number or attribute +auto const atom = x3::rule {} = double_[create_expr_node] + ; + +auto const sep_atom = x3::rule {} = -lit(',') >> double_[create_expr_node] + ; + +auto const expr_def = expression_grammar(); +// Individual arguments in lists containing one or more compound +// expressions are separated by a comma. +auto const sep_expr_def = lit(',') > expr + ; + +// matrix( ) +auto const matrix_def = no_case[lit("matrix")] > '(' + > ((atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom >> lit(')'))[construct_matrix] + | + (expr > sep_expr > sep_expr > sep_expr > sep_expr > sep_expr > lit(')'))[construct_matrix]) + ; + +// translate( []) +auto const translate_def = no_case[lit("translate")] > lit('(') + > (( atom >> -sep_atom >> lit(')'))[construct_translate] + | + ( expr > -sep_expr > lit(')'))[construct_translate] + ); + +// scale( []) +auto const scale_def = no_case[lit("scale")] > lit('(') + > (( atom >> -sep_atom >> lit(')'))[construct_scale] + | + ( expr > -sep_expr > lit(')'))[construct_scale] + ); + +// rotate( [ ]) +auto const rotate_def = no_case[lit("rotate")] > lit('(') + > ((atom >> -sep_atom >> -sep_atom >> lit(')'))[construct_rotate] + | + (expr > -sep_expr > -sep_expr > lit(')'))[construct_rotate] + ); + +// skewX() +auto const skewX_def = no_case[lit("skewX")] + > '(' > expr > ')'; + +// skewY() +auto const skewY_def = no_case[lit("skewY")] + > '(' > expr > ')'; + +BOOST_SPIRIT_DEFINE ( + expr, + sep_expr, + transform, + transform_list_rule, + transform_node_rule, + matrix, + translate, + scale, + rotate, + skewX, + skewY); + +}} // ns + +namespace mapnik +{ +grammar::transform_expression_grammar_type const& transform_expression_grammar() +{ + return grammar::transform; +} +} + +#endif diff --git a/include/mapnik/transform_processor.hpp b/include/mapnik/transform/transform_processor.hpp similarity index 98% rename from include/mapnik/transform_processor.hpp rename to include/mapnik/transform/transform_processor.hpp index b1d8eab73..1e780b320 100644 --- a/include/mapnik/transform_processor.hpp +++ b/include/mapnik/transform/transform_processor.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include diff --git a/include/mapnik/transform_expression_grammar.hpp b/include/mapnik/transform_expression_grammar.hpp deleted file mode 100644 index f3945f39b..000000000 --- a/include/mapnik/transform_expression_grammar.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP -#define MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -// spirit -#include - -namespace mapnik { - - namespace qi = boost::spirit::qi; - - template - struct transform_expression_grammar - : qi::grammar - { - explicit transform_expression_grammar(); - - using node_rule = qi::rule; - using list_rule = qi::rule; - - // rules - qi::rule attr; - qi::rule atom; - qi::rule expr; - qi::rule sep_atom; - qi::rule sep_expr; - qi::rule start; - qi::rule transform_; - qi::rule matrix; - qi::rule translate; - qi::rule scale; - qi::rule rotate; - qi::rule skewX; - qi::rule skewY; - mapnik::expression_grammar g_; - }; - -} // namespace mapnik - -#endif // MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP diff --git a/include/mapnik/transform_expression_grammar_impl.hpp b/include/mapnik/transform_expression_grammar_impl.hpp deleted file mode 100644 index 4b8c2b92a..000000000 --- a/include/mapnik/transform_expression_grammar_impl.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include - -// boost -#include -#include -#include - - -namespace mapnik { - -namespace qi = boost::spirit::qi; - -template -transform_expression_grammar::transform_expression_grammar() - : transform_expression_grammar::base_type(start) -{ - using boost::phoenix::construct; - qi::_1_type _1; - qi::_4_type _4; - qi::_2_type _2; - qi::_5_type _5; - qi::_3_type _3; - qi::_6_type _6; - qi::_val_type _val; - qi::double_type double_; - qi::lit_type lit; - qi::no_case_type no_case; - - // [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] - - // The value of the ‘transform’ attribute is a , which - // is defined as a list of transform definitions, which are applied in - // the order provided. The individual transform definitions are - // separated by whitespace and/or a comma. - - start = transform_ % *lit(',') ; - - transform_ = matrix | translate | scale | rotate | skewX | skewY ; - - // matrix( ) - matrix = no_case[lit("matrix")] - >> (lit('(') - >> ( atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom - >> sep_atom >> lit(')') - | expr >> sep_expr >> sep_expr >> sep_expr >> sep_expr - >> sep_expr >> lit(')') - )) - [ _val = construct(_1,_2,_3,_4,_5,_6) ]; - - // translate( []) - translate = no_case[lit("translate")] - >> lit('(') - >> ( ( atom >> -sep_atom >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -sep_expr >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // scale( []) - scale = no_case[lit("scale")] - >> lit('(') - >> ( ( atom >> -sep_atom >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -sep_expr >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // rotate( [ ]) - rotate = no_case[lit("rotate")] - >> lit('(') - >> ( ( atom >> -( sep_atom >> sep_atom ) >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -( sep_expr >> sep_expr ) >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // skewX() - skewX = no_case[lit("skewX")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - // skewY() - skewY = no_case[lit("skewY")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - // number or attribute - atom = double_ [ _val = _1 ] - | attr [ _val = construct(_1) ]; - - // Individual arguments in lists consiting solely of numbers and/or - // attributes are separated by whitespace and/or a comma. - sep_atom = -lit(',') >> atom [ _val = _1 ]; - - // Individual arguments in lists containing one or more compound - // expressions are separated by a comma. - sep_expr = lit(',') >> expr [ _val = _1 ]; - - attr = g_.attr.alias(); - expr = g_.expr.alias(); -} - -} diff --git a/include/mapnik/transform_path_adapter.hpp b/include/mapnik/transform_path_adapter.hpp index 08212703f..fbb7a75ee 100644 --- a/include/mapnik/transform_path_adapter.hpp +++ b/include/mapnik/transform_path_adapter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/unicode.hpp b/include/mapnik/unicode.hpp index f3b270cb9..48b433f68 100644 --- a/include/mapnik/unicode.hpp +++ b/include/mapnik/unicode.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ //mapnik #include #include -#include +#include // std #include diff --git a/include/mapnik/util/const_rendering_buffer.hpp b/include/mapnik/util/const_rendering_buffer.hpp index 97b98ca65..5ee9de7f1 100644 --- a/include/mapnik/util/const_rendering_buffer.hpp +++ b/include/mapnik/util/const_rendering_buffer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -58,4 +58,4 @@ struct rendering_buffer }} -#endif // MAPNIK_CONST_RENDERING_BUFFER_HPP \ No newline at end of file +#endif // MAPNIK_CONST_RENDERING_BUFFER_HPP diff --git a/include/mapnik/util/container_adapter.hpp b/include/mapnik/util/container_adapter.hpp index 8c70c4c2a..63d25163c 100644 --- a/include/mapnik/util/container_adapter.hpp +++ b/include/mapnik/util/container_adapter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/conversions.hpp b/include/mapnik/util/conversions.hpp index 284d20e03..009e9315c 100644 --- a/include/mapnik/util/conversions.hpp +++ b/include/mapnik/util/conversions.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include // stl #include diff --git a/include/mapnik/util/dasharray_parser.hpp b/include/mapnik/util/dasharray_parser.hpp index 7c5d26711..191da098f 100644 --- a/include/mapnik/util/dasharray_parser.hpp +++ b/include/mapnik/util/dasharray_parser.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/feature_to_geojson.hpp b/include/mapnik/util/feature_to_geojson.hpp index ad3c0a7d4..b6e5797c4 100644 --- a/include/mapnik/util/feature_to_geojson.hpp +++ b/include/mapnik/util/feature_to_geojson.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,23 +20,18 @@ * *****************************************************************************/ -#ifndef MAPNIK_FEATURE_TO_GEOJSON_HPP -#define MAPNIK_FEATURE_TO_GEOJSON_HPP +#ifndef MAPNIK_UTIL_FEATURE_TO_GEOJSON_HPP +#define MAPNIK_UTIL_FEATURE_TO_GEOJSON_HPP // mapnik - -#include +#include +// stl +#include namespace mapnik { namespace util { -inline bool to_geojson(std::string & json, mapnik::feature_impl const& feat) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::json::feature_generator_grammar grammar; - sink_type sink(json); - return boost::spirit::karma::generate(sink, grammar, feat); -} +bool to_geojson(std::string & json, mapnik::feature_impl const& feat); }} -#endif // MAPNIK_FEATURE_TO_GEOJSON_HPP +#endif // MAPNIK_UTIL_FEATURE_TO_GEOJSON_HPP diff --git a/include/mapnik/util/featureset_buffer.hpp b/include/mapnik/util/featureset_buffer.hpp index 8689a41e9..ff2a8b39e 100644 --- a/include/mapnik/util/featureset_buffer.hpp +++ b/include/mapnik/util/featureset_buffer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/file_io.hpp b/include/mapnik/util/file_io.hpp index b8bc22f01..00c925006 100644 --- a/include/mapnik/util/file_io.hpp +++ b/include/mapnik/util/file_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -83,7 +83,8 @@ public: if (!size_) return nullptr; std::fseek(file_.get(), 0, SEEK_SET); data_type buffer(new char[size_]); - std::fread(buffer.get(), size_, 1, file_.get()); + auto count = std::fread(buffer.get(), size_, 1, file_.get()); + if (count != 1) return nullptr; return buffer; } private: diff --git a/include/mapnik/util/fs.hpp b/include/mapnik/util/fs.hpp index 03905cb45..57abef0a4 100644 --- a/include/mapnik/util/fs.hpp +++ b/include/mapnik/util/fs.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/geometry_to_ds_type.hpp b/include/mapnik/util/geometry_to_ds_type.hpp index 7791285ac..cbd0841a9 100644 --- a/include/mapnik/util/geometry_to_ds_type.hpp +++ b/include/mapnik/util/geometry_to_ds_type.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -42,7 +42,7 @@ namespace detail { struct datasource_geometry_type { - mapnik::datasource_geometry_t operator () (mapnik::geometry::geometry_empty const&) const + mapnik::datasource_geometry_t operator () (mapnik::geometry::geometry_empty const&) const { return mapnik::datasource_geometry_t::Unknown; } diff --git a/include/mapnik/util/geometry_to_geojson.hpp b/include/mapnik/util/geometry_to_geojson.hpp index 71c867eb7..02d3bd34f 100644 --- a/include/mapnik/util/geometry_to_geojson.hpp +++ b/include/mapnik/util/geometry_to_geojson.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/geometry_to_svg.hpp b/include/mapnik/util/geometry_to_svg.hpp index 9efb55134..f95567ab3 100644 --- a/include/mapnik/util/geometry_to_svg.hpp +++ b/include/mapnik/util/geometry_to_svg.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index f16ad240a..bf3a3dd10 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include // stl #include @@ -229,7 +229,7 @@ struct geometry_to_wkb return util::apply_visitor(*this, geom); } - result_type operator() (geometry::geometry_empty const&) const + result_type operator() (geometry::geometry_empty const&) const { return result_type(); } diff --git a/include/mapnik/util/geometry_to_wkt.hpp b/include/mapnik/util/geometry_to_wkt.hpp index 3c81ef440..73637d04e 100644 --- a/include/mapnik/util/geometry_to_wkt.hpp +++ b/include/mapnik/util/geometry_to_wkt.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,29 +24,15 @@ #define MAPNIK_GEOMETRY_TO_WKT_HPP // mapnik -#include -#include - -// boost -#include +#include +// stl +#include namespace mapnik { namespace util { -inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::wkt::wkt_generator_grammar> generator; - sink_type sink(wkt); - return boost::spirit::karma::generate(sink, generator, geom); -} +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom); -inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::wkt::wkt_generator_grammar> generator; - sink_type sink(wkt); - return boost::spirit::karma::generate(sink, generator, geom); -} +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom); }} diff --git a/include/mapnik/util/hsl.hpp b/include/mapnik/util/hsl.hpp index d060da92f..5776570cf 100644 --- a/include/mapnik/util/hsl.hpp +++ b/include/mapnik/util/hsl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/is_clockwise.hpp b/include/mapnik/util/is_clockwise.hpp index 93951df38..6ec532769 100644 --- a/include/mapnik/util/is_clockwise.hpp +++ b/include/mapnik/util/is_clockwise.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/math.hpp b/include/mapnik/util/math.hpp index 4b24893b1..fed1c7bbf 100644 --- a/include/mapnik/util/math.hpp +++ b/include/mapnik/util/math.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/noncopyable.hpp b/include/mapnik/util/noncopyable.hpp index 7a6a9f8f7..44bb3654e 100644 --- a/include/mapnik/util/noncopyable.hpp +++ b/include/mapnik/util/noncopyable.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/path_iterator.hpp b/include/mapnik/util/path_iterator.hpp index 19b69ce26..e7c6b92b5 100644 --- a/include/mapnik/util/path_iterator.hpp +++ b/include/mapnik/util/path_iterator.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/rounding_cast.hpp b/include/mapnik/util/rounding_cast.hpp index d67c066cc..512363b23 100644 --- a/include/mapnik/util/rounding_cast.hpp +++ b/include/mapnik/util/rounding_cast.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/singleton.hpp b/include/mapnik/util/singleton.hpp index fcb0275ef..61c5b6962 100644 --- a/include/mapnik/util/singleton.hpp +++ b/include/mapnik/util/singleton.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/spatial_index.hpp b/include/mapnik/util/spatial_index.hpp index 720667768..0f271526e 100644 --- a/include/mapnik/util/spatial_index.hpp +++ b/include/mapnik/util/spatial_index.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ //mapnik #include -#include +#include #include #include // stl diff --git a/include/mapnik/util/spirit_transform_attribute.hpp b/include/mapnik/util/spirit_transform_attribute.hpp index e53d335a1..31b80e38c 100644 --- a/include/mapnik/util/spirit_transform_attribute.hpp +++ b/include/mapnik/util/spirit_transform_attribute.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/timer.hpp b/include/mapnik/util/timer.hpp index e29a8eae1..7c8ff67d3 100644 --- a/include/mapnik/util/timer.hpp +++ b/include/mapnik/util/timer.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/trim.hpp b/include/mapnik/util/trim.hpp index 60320331b..9b0e5c7c5 100644 --- a/include/mapnik/util/trim.hpp +++ b/include/mapnik/util/trim.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/utf_conv_win.hpp b/include/mapnik/util/utf_conv_win.hpp index 68e28ec15..f6c0ea19a 100644 --- a/include/mapnik/util/utf_conv_win.hpp +++ b/include/mapnik/util/utf_conv_win.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/util/variant.hpp b/include/mapnik/util/variant.hpp index 27993ce3f..2451cea0c 100644 --- a/include/mapnik/util/variant.hpp +++ b/include/mapnik/util/variant.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,15 +32,7 @@ template using recursive_wrapper = typename mapbox::util::recursive_wrapper; template -class variant : public mapbox::util::variant -{ -public: - // tell spirit that this is an adapted variant - struct adapted_variant_tag; - using types = std::tuple; - // inherit ctor's - using mapbox::util::variant::variant; -}; +using variant = typename mapbox::util::variant; // unary visitor interface // const diff --git a/include/mapnik/util/variant_io.hpp b/include/mapnik/util/variant_io.hpp index 02f0be5ca..bdbfcdbbc 100644 --- a/include/mapnik/util/variant_io.hpp +++ b/include/mapnik/util/variant_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_UTIL_VARIANT_IO_HPP -namespace mapnik { namespace util { +namespace mapbox { namespace util { namespace detail { diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index 9ee732385..0618e8abe 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,8 +25,8 @@ // mapnik #include -#include -#include +#include +#include #include @@ -47,30 +47,20 @@ class MAPNIK_DECL value : public value_base public: value() = default; - // conversion from type T is done via a temporary of type U, which - // is determined by mapnik_value_type; - // enable_if< decay != value > is necessary to avoid ill-formed - // recursion in noexcept specifier; and it also prevents using this - // constructor where implicitly-declared copy/move should be used - // (e.g. value(value&)) - template ::value, - detail::mapnik_value_type_decay - >::type::type> + // Conversion from type T is done via a temporary value or reference + // of type U, which is determined by mapnik_value_type_t. + // + // CAVEAT: We don't check `noexcept(conversion from T to U)`. + // But since the type U is either value_bool, value_integer, + // value_double or T &&, this conversion SHOULD NEVER throw. + template > value(T && val) - noexcept(noexcept(U(std::forward(val))) && - std::is_nothrow_constructible::value) + noexcept(std::is_nothrow_constructible::value) : value_base(U(std::forward(val))) {} - template ::value, - detail::mapnik_value_type_decay - >::type::type> + template > value& operator=(T && val) - noexcept(noexcept(U(std::forward(val))) && - std::is_nothrow_assignable::value) + noexcept(std::is_nothrow_assignable::value) { value_base::operator=(U(std::forward(val))); return *this; @@ -115,7 +105,7 @@ operator << (std::basic_ostream& out, // hash function inline std::size_t hash_value(value const& val) { - return mapnik_hash_value(val); + return mapnik::value_hash(val); } } // namespace value_adl_barrier @@ -157,7 +147,7 @@ struct hash { size_t operator()(mapnik::value const& val) const { - return mapnik::mapnik_hash_value(val); + return mapnik::value_hash(val); } }; diff --git a/include/mapnik/value_error.hpp b/include/mapnik/value/error.hpp similarity index 91% rename from include/mapnik/value_error.hpp rename to include/mapnik/value/error.hpp index 68df62255..f371f7bae 100644 --- a/include/mapnik/value_error.hpp +++ b/include/mapnik/value/error.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,12 +38,11 @@ public: value_error( std::string const& what ) : what_( what ) - { - } + {} - virtual ~value_error() throw() {} + virtual ~value_error() {} - virtual const char * what() const throw() + virtual const char * what() const noexcept { return what_.c_str(); } @@ -56,6 +55,7 @@ public: protected: mutable std::string what_; }; + } #endif // MAPNIK_VALUE_ERROR_HPP diff --git a/include/mapnik/value_hash.hpp b/include/mapnik/value/hash.hpp similarity index 75% rename from include/mapnik/value_hash.hpp rename to include/mapnik/value/hash.hpp index 80e10d855..86bb190ad 100644 --- a/include/mapnik/value_hash.hpp +++ b/include/mapnik/value/hash.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include // stl #include @@ -35,12 +35,9 @@ #pragma GCC diagnostic pop -namespace mapnik { namespace detail { +namespace mapnik { -inline void hash_combine(std::size_t & seed, std::size_t val) -{ - seed ^= val + 0x9e3779b9 + (seed << 6) + (seed >> 2); -} +namespace detail { struct value_hasher { @@ -54,11 +51,6 @@ struct value_hasher return static_cast(val.hashCode()); } - std::size_t operator()(value_integer val) const - { - return static_cast(val); - } - template std::size_t operator()(T const& val) const { @@ -70,12 +62,9 @@ struct value_hasher } // namespace detail template -std::size_t mapnik_hash_value(T const& val) +std::size_t value_hash(T const& val) { - std::size_t seed = 0; - detail::hash_combine(seed, util::apply_visitor(detail::value_hasher(), val)); - detail::hash_combine(seed, val.which()); - return seed; + return util::apply_visitor(detail::value_hasher(), val); } } // namespace mapnik diff --git a/include/mapnik/value_types.hpp b/include/mapnik/value/types.hpp similarity index 61% rename from include/mapnik/value_types.hpp rename to include/mapnik/value/types.hpp index 235133a34..93ee0859a 100644 --- a/include/mapnik/value_types.hpp +++ b/include/mapnik/value/types.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,7 @@ // mapnik #include +#include #include @@ -34,7 +35,6 @@ #pragma GCC diagnostic pop // stl -#include #include #include @@ -152,90 +152,23 @@ inline std::istream& operator>> ( std::istream & s, value_null & ) namespace detail { -// to mapnik::value_type conversions traits -template -struct is_value_bool -{ - constexpr static bool value = std::is_same::value; -}; -template -struct is_value_integer -{ - constexpr static bool value = std::is_integral::value && !std::is_same::value; -}; +// Helper metafunction for mapnik::value construction and assignment. +// Returns: +// value_bool if T is bool +// value_integer if T is an integral type (except bool) +// value_double if T is a floating-point type +// T && otherwise -template -struct is_value_double -{ - constexpr static bool value = std::is_floating_point::value; -}; - -template -struct is_value_unicode_string -{ - constexpr static bool value = std::is_same::value; -}; - -template -struct is_value_string -{ - constexpr static bool value = std::is_same::value; -}; - -template -struct is_value_null -{ - constexpr static bool value = std::is_same::value; -}; - -template -struct mapnik_value_type -{ - using type = T; -}; - -// value_null -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_null; -}; - -// value_bool -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_bool; -}; - -// value_integer -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_integer; -}; - -// value_double -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_double; -}; - -// value_unicode_string -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_unicode_string const&; -}; - -template -using mapnik_value_type_decay = mapnik_value_type::type>; - -template -using is_same_decay = std::is_same::type, - typename std::decay::type>; +template > +using mapnik_value_type_t = + conditional_t< + std::is_same::value, value_bool, + conditional_t< + std::is_integral
::value, value_integer, + conditional_t< + std::is_floating_point
::value, value_double, + T && >>>; } // namespace detail diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp index deba4287c..c6eecef02 100644 --- a/include/mapnik/version.hpp +++ b/include/mapnik/version.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,8 +26,8 @@ #include #define MAPNIK_MAJOR_VERSION 3 -#define MAPNIK_MINOR_VERSION 0 -#define MAPNIK_PATCH_VERSION 12 +#define MAPNIK_MINOR_VERSION 1 +#define MAPNIK_PATCH_VERSION 0 #define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION) diff --git a/include/mapnik/vertex.hpp b/include/mapnik/vertex.hpp index 92b6a0b4f..25c5213e4 100644 --- a/include/mapnik/vertex.hpp +++ b/include/mapnik/vertex.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/vertex_adapters.hpp b/include/mapnik/vertex_adapters.hpp index 4dbdcd2e5..eeee90785 100644 --- a/include/mapnik/vertex_adapters.hpp +++ b/include/mapnik/vertex_adapters.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define MAPNIK_VERTEX_ADAPTERS_HPP #include -#include +#include #include namespace mapnik { namespace geometry { diff --git a/include/mapnik/vertex_cache.hpp b/include/mapnik/vertex_cache.hpp index 9df786e62..abacb14de 100644 --- a/include/mapnik/vertex_cache.hpp +++ b/include/mapnik/vertex_cache.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/vertex_converters.hpp b/include/mapnik/vertex_converters.hpp index ba1829472..05c0d74fc 100644 --- a/include/mapnik/vertex_converters.hpp +++ b/include/mapnik/vertex_converters.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,10 +32,11 @@ #include #include #include -#include +#include #include #include #include +#include #pragma GCC diagnostic push #include @@ -65,6 +66,7 @@ struct stroke_tag {}; struct dash_tag {}; struct affine_transform_tag {}; struct offset_transform_tag {}; +struct extend_tag {}; namespace detail { @@ -254,6 +256,23 @@ struct converter_traits } }; +template +struct converter_traits +{ + using geometry_type = T; + using conv_type = extend_converter; + + template + static void setup(geometry_type & geom, Args const& args) + { + auto const& sym = args.sym; + auto const& feat = args.feature; + auto const& vars = args.vars; + double extend = get(sym, feat, vars); + geom.set_extend(extend * args.scale_factor); + } +}; + template struct is_switchable diff --git a/include/mapnik/vertex_processor.hpp b/include/mapnik/vertex_processor.hpp index 57f6b4112..5d30b77da 100644 --- a/include/mapnik/vertex_processor.hpp +++ b/include/mapnik/vertex_processor.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,8 +39,8 @@ struct vertex_processor { util::apply_visitor(*this, geom); } - template - void operator() (geometry_empty const&) const + + void operator() (geometry_empty const&) const { // no-op } diff --git a/include/mapnik/vertex_vector.hpp b/include/mapnik/vertex_vector.hpp index a55f5ec20..6b397f41f 100644 --- a/include/mapnik/vertex_vector.hpp +++ b/include/mapnik/vertex_vector.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/view_strategy.hpp b/include/mapnik/view_strategy.hpp index 0d1125b97..951012d97 100644 --- a/include/mapnik/view_strategy.hpp +++ b/include/mapnik/view_strategy.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/view_transform.hpp b/include/mapnik/view_transform.hpp index 74fa89cf7..96cde0a4c 100644 --- a/include/mapnik/view_transform.hpp +++ b/include/mapnik/view_transform.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include namespace mapnik diff --git a/include/mapnik/warning_ignore.hpp b/include/mapnik/warning_ignore.hpp index ccbf16925..fe0f4f83d 100644 --- a/include/mapnik/warning_ignore.hpp +++ b/include/mapnik/warning_ignore.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/warning_ignore_agg.hpp b/include/mapnik/warning_ignore_agg.hpp index 2f44c5c78..f741e7a07 100644 --- a/include/mapnik/warning_ignore_agg.hpp +++ b/include/mapnik/warning_ignore_agg.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/warp.hpp b/include/mapnik/warp.hpp index abf010851..46c11e8b3 100644 --- a/include/mapnik/warp.hpp +++ b/include/mapnik/warp.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include namespace mapnik { diff --git a/include/mapnik/webp_io.hpp b/include/mapnik/webp_io.hpp index 225ff2f50..81862e08a 100644 --- a/include/mapnik/webp_io.hpp +++ b/include/mapnik/webp_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/well_known_srs.hpp b/include/mapnik/well_known_srs.hpp index d175ef528..09ed22275 100644 --- a/include/mapnik/well_known_srs.hpp +++ b/include/mapnik/well_known_srs.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -52,11 +52,11 @@ static const double EARTH_DIAMETER = EARTH_RADIUS * 2.0; static const double EARTH_CIRCUMFERENCE = EARTH_DIAMETER * M_PI; static const double MAXEXTENT = EARTH_CIRCUMFERENCE / 2.0; static const double M_PI_by2 = M_PI / 2; -static const double D2R = M_PI / 180; -static const double R2D = 180 / M_PI; -static const double M_PIby360 = M_PI / 360; -static const double MAXEXTENTby180 = MAXEXTENT / 180; -static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180 * D2R)) - M_PI_by2); +static const double D2R = M_PI / 180.0; +static const double R2D = 180.0 / M_PI; +static const double M_PIby360 = M_PI / 360.0; +static const double MAXEXTENTby180 = MAXEXTENT / 180.0; +static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180.0 * D2R)) - M_PI_by2); static const std::string MAPNIK_LONGLAT_PROJ = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"; static const std::string MAPNIK_GMERC_PROJ = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"; @@ -64,24 +64,23 @@ boost::optional is_well_known_srs(std::string const& srs); boost::optional is_known_geographic(std::string const& srs); -static inline bool lonlat2merc(double * x, double * y , int point_count) +static inline bool lonlat2merc(double * x, double * y, std::size_t point_count) { - for(int i=0; i 180) x[i] = 180; else if (x[i] < -180) x[i] = -180; if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE; else if (y[i] < -MAX_LATITUDE) y[i] = -MAX_LATITUDE; x[i] = x[i] * MAXEXTENTby180; - y[i] = std::log(std::tan((90 + y[i]) * M_PIby360)) * R2D; - y[i] = y[i] * MAXEXTENTby180; + y[i] = std::log(std::tan((90.0 + y[i]) * M_PIby360)) * R2D * MAXEXTENTby180; } return true; } -static inline bool merc2lonlat(double * x, double * y , int point_count) +static inline bool merc2lonlat(double * x, double * y, std::size_t point_count) { - for(int i=0; i MAXEXTENT) x[i] = MAXEXTENT; else if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT; diff --git a/include/mapnik/wkb.hpp b/include/mapnik/wkb.hpp index 98b3d30c9..dcbe45d8b 100644 --- a/include/mapnik/wkb.hpp +++ b/include/mapnik/wkb.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/wkt/wkt_factory.hpp b/include/mapnik/wkt/wkt_factory.hpp index 14f509dda..722fc18d6 100644 --- a/include/mapnik/wkt/wkt_factory.hpp +++ b/include/mapnik/wkt/wkt_factory.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,24 +25,12 @@ // mapnik #include - -#include -#include - // stl #include namespace mapnik { -inline bool from_wkt(std::string const& wkt, mapnik::geometry::geometry & geom) -{ - using namespace boost::spirit; - static const mapnik::wkt::wkt_grammar g; - ascii::space_type space; - std::string::const_iterator first = wkt.begin(); - std::string::const_iterator last = wkt.end(); - return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(geom)), space); -} +bool from_wkt(std::string const& wkt, mapnik::geometry::geometry & geom); } diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index 2df1bd7cc..c8ea23da6 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,12 +26,10 @@ // mapnik #include #include -#include #pragma GCC diagnostic push #include #include -#include #include // for vc++ and android whose c++11 libs lack std::trunc #include #pragma GCC diagnostic pop @@ -39,22 +37,9 @@ namespace mapnik { namespace wkt { namespace karma = boost::spirit::karma; -namespace phoenix = boost::phoenix; namespace detail { -template -struct get_type -{ - using result_type = mapnik::geometry::geometry_types; - template - result_type operator() (T const& geom) const - { - auto type = mapnik::geometry::geometry_type(geom); - return type; - } -}; - template struct wkt_coordinate_policy : karma::real_policies { @@ -102,31 +87,27 @@ struct coordinate_generator template struct wkt_generator_grammar : - karma::grammar + karma::grammar { using coordinate_type = typename Geometry::coordinate_type; wkt_generator_grammar(); // rules - karma::rule geometry; - karma::rule, Geometry const&() > geometry_dispatch; - karma::rule const&()> point; - karma::rule const&()> point_coord; - karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; - karma::rule const&()> polygon; - karma::rule const&()> polygon_coord; - karma::rule const&()> ring; - //karma::rule > const&()> interior_ring_coord; - karma::rule const& ()> multi_point; - karma::rule const& ()> multi_point_coord; - karma::rule const& ()> multi_linestring; - karma::rule const& ()> multi_linestring_coord; - karma::rule const& ()> multi_polygon; - karma::rule const& ()> multi_polygon_coord; - karma::rule const& ()> geometry_collection; - karma::rule const& ()> geometries; - boost::phoenix::function > geometry_type; - karma::symbols empty; + karma::rule geometry; + karma::rule()> point; + karma::rule()> point_coord; + karma::rule()> linestring; + karma::rule()> linestring_coord; + karma::rule()> polygon; + karma::rule()> polygon_coord; + karma::rule()> linear_ring_coord; + karma::rule()> multi_point; + karma::rule()> multi_point_coord; + karma::rule()> multi_linestring; + karma::rule()> multi_linestring_coord; + karma::rule()> multi_polygon; + karma::rule()> multi_polygon_coord; + karma::rule()> geometry_collection; + karma::rule()> geometries; // typename detail::coordinate_generator::generator coordinate; }; diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp index ea000ca92..cdbb4546b 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,13 +22,7 @@ // mapnik #include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop +#include namespace mapnik { namespace wkt { @@ -36,81 +30,68 @@ template wkt_generator_grammar::wkt_generator_grammar() : wkt_generator_grammar::base_type(geometry) { - boost::spirit::karma::_val_type _val; - boost::spirit::karma::_1_type _1; - boost::spirit::karma::_a_type _a; boost::spirit::karma::lit_type lit; - boost::spirit::karma::uint_type uint_; - boost::spirit::karma::eps_type eps; - - empty.add - (geometry::geometry_types::Point, "POINT EMPTY") - (geometry::geometry_types::LineString, "LINESTRING EMPTY") - (geometry::geometry_types::Polygon, "POLYGON EMPTY") - (geometry::geometry_types::MultiPoint, "MULTIPOINT EMPTY") - (geometry::geometry_types::MultiLineString, "MULTILINESTRING EMPTY") - (geometry::geometry_types::MultiPolygon, "MULTIPOLYGON EMPTY") - (geometry::geometry_types::GeometryCollection, "GEOMETRYCOLLECTION EMPTY") - ; - - geometry = geometry_dispatch.alias() - ; - - geometry_dispatch = eps[_a = geometry_type(_val)] << - (&uint_(geometry::geometry_types::Point)[_1 = _a] - << point) + geometry = + point | - (&uint_(geometry::geometry_types::LineString)[_1 = _a] - << (linestring | empty[_1 = _a])) + linestring | - (&uint_(geometry::geometry_types::Polygon)[_1 = _a] - << (polygon | empty[_1 = _a])) + polygon | - (&uint_(geometry::geometry_types::MultiPoint)[_1 = _a] - << ( multi_point | empty[_1 = _a])) + multi_point | - (&uint_(geometry::geometry_types::MultiLineString)[_1 = _a] - << (multi_linestring | empty[_1 = _a])) + multi_linestring | - (&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a] - << (multi_polygon | empty[_1 = _a])) + multi_polygon | - (&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a] - << (geometry_collection | empty[_1 = _a])) + geometry_collection | - (&uint_(geometry::geometry_types::Unknown)[_1 = _a] - << lit("POINT EMPTY")) // special case for geometry_empty as mapnik::geometry::point can't be empty + lit("POINT EMPTY") // special case for geometry_empty ; point = lit("POINT(") << point_coord << lit(")") ; - linestring = lit("LINESTRING(") << linestring_coord << lit(")") + + linestring = lit("LINESTRING") << (linestring_coord | lit(" EMPTY")) ; - polygon = lit("POLYGON(") << polygon_coord << lit(")") + + polygon = lit("POLYGON") << (polygon_coord | lit(" EMPTY")) ; - multi_point = lit("MULTIPOINT(") << multi_point_coord << lit(")") + + multi_point = lit("MULTIPOINT") << (multi_point_coord | lit(" EMPTY")) ; - multi_linestring = lit("MULTILINESTRING(") << multi_linestring_coord << lit(")") + + multi_linestring = lit("MULTILINESTRING") << (multi_linestring_coord | lit(" EMPTY")) ; - multi_polygon = lit("MULTIPOLYGON(") << multi_polygon_coord << lit(")") + + multi_polygon = lit("MULTIPOLYGON") << (multi_polygon_coord | lit(" EMPTY")) ; - geometry_collection = lit("GEOMETRYCOLLECTION(") << geometries << lit(")") + + geometry_collection = lit("GEOMETRYCOLLECTION") << (lit("(") << geometries << lit(")") | lit(" EMPTY")) ; + point_coord = coordinate << lit(' ') << coordinate ; - linestring_coord = point_coord % lit(',') + + linestring_coord = lit('(') << point_coord % lit(',') << lit(')') ; - polygon_coord = ring % lit(',')//<< interior_ring_coord + + linear_ring_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias() ; - ring = lit('(') << linestring_coord << lit(')') + + polygon_coord = linear_ring_coord % lit(',') ; - multi_point_coord = linestring_coord.alias() + + multi_point_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias() ; - multi_linestring_coord = (lit('(') << linestring_coord << lit(')')) % lit(',') + + multi_linestring_coord = lit("(") << linestring_coord % lit(',') << lit(")") ; - multi_polygon_coord = (lit('(') << polygon_coord << lit(')')) % lit(',') + + multi_polygon_coord = lit("(") << polygon_coord % lit(',') << lit(")") ; - geometries = geometry % lit(',') + + geometries = geometry % lit(',') ; } diff --git a/include/mapnik/wkt/wkt_grammar.hpp b/include/mapnik/wkt/wkt_grammar.hpp deleted file mode 100644 index 55750b838..000000000 --- a/include/mapnik/wkt/wkt_grammar.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_WKT_GRAMMAR_HPP -#define MAPNIK_WKT_GRAMMAR_HPP - -// mapnik -#include -#include -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - - -namespace mapnik { namespace wkt { - -using namespace boost::spirit; - -namespace detail { - -struct assign -{ - using result_type = void; - template - void operator() (T0 & geom, T1 && obj) const - { - geom = std::move(obj); - } -}; - -struct move_part -{ - using result_type = void; - template - void operator() (Geometry & geom, Part && part) const - { - geom.push_back(std::move(part)); - } -}; - - -struct set_ring -{ - using result_type = void; - template - void operator() (Polygon & poly, Ring && ring) const - { - poly.push_back(std::move(ring)); - } -}; - -} - -template -struct wkt_grammar : qi::grammar &) , ascii::space_type> -{ - wkt_grammar(); - qi::rule &), ascii::space_type> geometry_tagged_text; - qi::rule &), ascii::space_type> point_tagged_text; - qi::rule &), ascii::space_type> linestring_tagged_text; - qi::rule &), ascii::space_type> polygon_tagged_text; - qi::rule &), ascii::space_type> multipoint_tagged_text; - qi::rule &), ascii::space_type> multilinestring_tagged_text; - qi::rule &), ascii::space_type> multipolygon_tagged_text; - qi::rule &), ascii::space_type> geometrycollection_tagged_text; - qi::rule(), ascii::space_type> point_text; - qi::rule(), ascii::space_type> linestring_text; - qi::rule(), ascii::space_type> linearring_text; - qi::rule(), ascii::space_type> polygon_text; - qi::rule(), ascii::space_type> multipoint_text; - qi::rule(), ascii::space_type> multilinestring_text; - qi::rule(), ascii::space_type> multipolygon_text; - qi::rule >, - mapnik::geometry::geometry_collection(), ascii::space_type> geometrycollection_text; - qi::rule(), ascii::space_type> point; - qi::rule(), ascii::space_type> points; - qi::rule(), ascii::space_type> ring_points; - qi::rule empty_set; - boost::phoenix::function assign; - boost::phoenix::function move_part; - boost::phoenix::function set_ring; -}; - -}} - -#endif // MAPNIK_WKT_GRAMMAR_HPP diff --git a/include/mapnik/wkt/wkt_grammar_impl.hpp b/include/mapnik/wkt/wkt_grammar_impl.hpp deleted file mode 100644 index 33caab6bc..000000000 --- a/include/mapnik/wkt/wkt_grammar_impl.hpp +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace wkt { - -using namespace boost::spirit; - -template -wkt_grammar::wkt_grammar() - : wkt_grammar::base_type(geometry_tagged_text) -{ - qi::eps_type eps; - qi::_r1_type _r1; - qi::_val_type _val; - qi::lit_type lit; - qi::no_case_type no_case; - qi::double_type double_; - qi::_1_type _1; - qi::_a_type _a; - using boost::phoenix::construct; - using boost::phoenix::at_c; - geometry_tagged_text = point_tagged_text(_r1) - | linestring_tagged_text(_r1) - | polygon_tagged_text(_r1) - | multipoint_tagged_text(_r1) - | multilinestring_tagged_text(_r1) - | multipolygon_tagged_text(_r1) - | geometrycollection_tagged_text(_r1) - ; - - // ::= point - point_tagged_text = no_case[lit("POINT")] - >> (point_text[assign(_r1,_1)] | empty_set[assign(_r1,construct>())]) - ; - // ::= | - point_text = (lit("(") >> point >> lit(')')) - //| empty_set - we're catching 'POINT EMPTY' case in point_tagged_text rule ^^ by creating geometry_empty - // because our geometry::point can't be empty - ; - - // ::= linestring - linestring_tagged_text = no_case[lit("LINESTRING")] - >> linestring_text[assign(_r1,_1)] - ; - - // ::= | { }* - linestring_text = points | empty_set - ; - - // ::= polygon - polygon_tagged_text = no_case[lit("POLYGON")] - >> polygon_text[assign(_r1,_1)] - ; - - // ::= | { }* - polygon_text = - lit('(') >> linearring_text[set_ring(_val,_1)] % lit(',') >> lit(')') - | - empty_set - ; - - linearring_text = ring_points - | - empty_set - ; - // ::= multipoint - multipoint_tagged_text = no_case[lit("MULTIPOINT")] - >> multipoint_text[assign(_r1,_1)] - ; - - // ::= | { }* - multipoint_text = (lit('(') - >> point_text % lit(',') - >> lit(')')) - | - (lit('(') - >> point % lit(',') - >> lit(')')) - | - empty_set - ; - - // ::= multilinestring - multilinestring_tagged_text = no_case[lit("MULTILINESTRING")] - >> multilinestring_text[assign(_r1,_1)] ; - - // ::= | { }* - multilinestring_text = (lit('(') - >> points[move_part(_val,_1)] % lit(',') - >> lit(')')) | empty_set; - - // ::= multipolygon - multipolygon_tagged_text = no_case[lit("MULTIPOLYGON")] - >> multipolygon_text[assign(_r1,_1)] ; - - // ::= | { }* - multipolygon_text = (lit('(') - >> polygon_text[move_part(_val,_1)] % lit(',') - >> lit(')')) - | - empty_set; - - // geometry collection tagged text - geometrycollection_tagged_text = no_case[lit("GEOMETRYCOLLECTION")] - >> geometrycollection_text[assign(_r1,_1)] - ; - - // geometry collection text - geometrycollection_text = (lit('(') - >> ( eps[_a = construct >()] - >> geometry_tagged_text(_a)[move_part(_val,_a)] % lit(',')) - >> lit(')')) - | - empty_set; - // points - points = lit('(') >> point % lit(',') >> lit(')') - ; - // ring points - ring_points = lit('(') >> point % lit(',') >> lit(')') - ; - // point - point = double_ >> double_ - ; - - // - empty_set = no_case[lit("EMPTY")]; -} - -}} diff --git a/include/mapnik/wkt/wkt_grammar_x3.hpp b/include/mapnik/wkt/wkt_grammar_x3.hpp new file mode 100644 index 000000000..a0b6be0f0 --- /dev/null +++ b/include/mapnik/wkt/wkt_grammar_x3.hpp @@ -0,0 +1,49 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_WKT_GRAMMAR_X3_HPP +#define MAPNIK_WKT_GRAMMAR_X3_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct wkt_class; // top-most ID +using wkt_grammar_type = x3::rule>; + +BOOST_SPIRIT_DECLARE(wkt_grammar_type); + +}} + +namespace mapnik +{ +grammar::wkt_grammar_type const& wkt_grammar(); +} + + +#endif // MAPNIK_WKT_GRAMMAR_X3_HPP diff --git a/include/mapnik/wkt/wkt_grammar_x3_def.hpp b/include/mapnik/wkt/wkt_grammar_x3_def.hpp new file mode 100644 index 000000000..b8d5065d1 --- /dev/null +++ b/include/mapnik/wkt/wkt_grammar_x3_def.hpp @@ -0,0 +1,138 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_WKT_GRAMMAR_X3_DEF_HPP +#define MAPNIK_WKT_GRAMMAR_X3_DEF_HPP + +#include +#include + +#if defined(__GNUC__) +// instantiate `is_substitute` for reference T and reference Attribute +// fixes gcc6 compilation issue +namespace boost { namespace spirit { namespace x3 { namespace traits { + +template +struct is_substitute + : is_substitute {}; +}}}} +#endif + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +namespace ascii = boost::spirit::x3::ascii; +using x3::lit; +using x3::double_; +using x3::no_case; + +// functors +auto make_empty = [](auto const& ctx) +{ + _val(ctx) = geometry::geometry_empty(); +}; + +auto add_ring = [](auto const& ctx) +{ + auto & ring = reinterpret_cast &>(_attr(ctx)); + _val(ctx).push_back(std::move(ring)); +}; + +// start rule +wkt_grammar_type const wkt("wkt"); +// rules +x3::rule const empty("EMPTY"); +x3::rule > const point("POINT"); +x3::rule > const line_string("LINESTRING"); +x3::rule > const polygon("POLYGON"); +x3::rule > const multi_point("MULTIPOINT"); +x3::rule > const multi_line_string("MULTILINESTRING"); +x3::rule > const multi_polygon("MULTIPOLYGON"); +x3::rule > const geometry_collection("GEOMETRYCOLLECTION"); + +x3::rule > const point_text("point-text"); +x3::rule > const positions("positions"); +x3::rule > const polygon_rings("polygon-rings"); +x3::rule > const points("points"); +x3::rule > const lines("lines"); +x3::rule > const polygons("polygons"); +x3::rule > const geometries("geometries"); + + +auto const point_text_def = '(' > double_ > double_ > ')'; +auto const positions_def = lit('(') > (double_ > double_) % lit(',') > lit(')'); +//auto const polygon_rings_def = '(' > positions[set_exterior] > *(lit(',') > positions[add_hole]) > ')'; +auto const polygon_rings_def = '(' > positions[add_ring] % lit(',') > ')'; +auto const points_def = (lit('(') >> ((point_text_def % ',') > lit(')'))) | positions_def ; +auto const lines_def = lit('(') > (positions_def % lit(',')) > lit(')'); +auto const polygons_def = lit('(') > (polygon_rings % lit(',')) > lit(')'); +auto const geometries_def = lit('(') > -(wkt % ',') > lit(')'); + +// +auto const wkt_def = point | line_string | polygon | multi_point | multi_line_string | multi_polygon | geometry_collection; + +// EMPTY +auto const empty_def = no_case["EMPTY"][make_empty]; +// POINT +auto const point_def = no_case["POINT"] > (point_text | empty); +// LINESTRING +auto const line_string_def = no_case["LINESTRING"] > (positions | no_case["EMPTY"]); +// POLYGON +auto const polygon_def = no_case["POLYGON"] > (polygon_rings | no_case["EMPTY"]); +// MULTIPOINT +auto const multi_point_def = no_case["MULTIPOINT"] > (points | no_case["EMPTY"]); +// MULTILINESTRING +auto const multi_line_string_def = no_case["MULTILINESTRING"] > (lines | no_case["EMPTY"]); +// MULTIPOLYGON +auto const multi_polygon_def = no_case["MULTIPOLYGON"] > (polygons | no_case["EMPTY"]); +// GEOMETRYCOLLECTION +auto const geometry_collection_def = no_case["GEOMETRYCOLLECTION"] > (geometries | no_case["EMPTY"]); + +BOOST_SPIRIT_DEFINE( + wkt, + point_text, + positions, + points, + lines, + polygons, + geometries, + empty, + point, + line_string, + polygon_rings, + polygon, + multi_point, + multi_line_string, + multi_polygon, + geometry_collection + ); +}} + +namespace mapnik +{ +grammar::wkt_grammar_type const& wkt_grammar() +{ + return grammar::wkt; +} +} + +#endif // MAPNIK_WKT_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/xml_attribute_cast.hpp b/include/mapnik/xml_attribute_cast.hpp index cafa7e79a..1beafe5be 100644 --- a/include/mapnik/xml_attribute_cast.hpp +++ b/include/mapnik/xml_attribute_cast.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,7 @@ //mapnik #include -#include +#include #include #include #include diff --git a/include/mapnik/xml_loader.hpp b/include/mapnik/xml_loader.hpp index 5fe98af0c..2cb73a3c4 100644 --- a/include/mapnik/xml_loader.hpp +++ b/include/mapnik/xml_loader.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/include/mapnik/xml_node.hpp b/include/mapnik/xml_node.hpp index bf7130c20..8aa2048b6 100644 --- a/include/mapnik/xml_node.hpp +++ b/include/mapnik/xml_node.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,8 @@ * *****************************************************************************/ -#ifndef MAPNIK_XML_NODE_H -#define MAPNIK_XML_NODE_H +#ifndef MAPNIK_XML_NODE_HPP +#define MAPNIK_XML_NODE_HPP //mapnik #include // for MAPNIK_DECL @@ -53,8 +53,8 @@ class MAPNIK_DECL node_not_found: public std::exception { public: node_not_found(std::string const& node_name); - virtual const char* what() const throw(); - ~node_not_found() throw (); + virtual const char* what() const noexcept; + ~node_not_found(); private: std::string node_name_; protected: @@ -65,8 +65,8 @@ class MAPNIK_DECL attribute_not_found: public std::exception { public: attribute_not_found(std::string const& node_name, std::string const& attribute_name); - virtual const char* what() const throw(); - ~attribute_not_found() throw (); + virtual const char* what() const noexcept; + ~attribute_not_found(); private: std::string node_name_; std::string attribute_name_; @@ -78,8 +78,8 @@ class MAPNIK_DECL more_than_one_child: public std::exception { public: more_than_one_child(std::string const& node_name); - virtual const char* what() const throw(); - ~more_than_one_child() throw (); + virtual const char* what() const noexcept; + ~more_than_one_child(); private: std::string node_name_; protected: @@ -150,4 +150,4 @@ private: } //ns mapnik -#endif // MAPNIK_XML_NODE_H +#endif // MAPNIK_XML_NODE_HPP diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index 535d96763..e0e00a914 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,8 @@ * *****************************************************************************/ -#ifndef MAPNIK_XML_TREE_H -#define MAPNIK_XML_TREE_H +#ifndef MAPNIK_XML_TREE_HPP +#define MAPNIK_XML_TREE_HPP // mapnik #include @@ -50,4 +50,4 @@ public: } //ns mapnik -#endif // MAPNIK_XML_TREE_H +#endif // MAPNIK_XML_TREE_HPP diff --git a/mason_latest.sh b/mason_latest.sh deleted file mode 100755 index cf064953b..000000000 --- a/mason_latest.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -MASON_NAME=mapnik -MASON_VERSION=latest -MASON_LIB_FILE=lib/libmapnik-wkt.a - -# warning: may break when https://github.com/mapbox/mason/issues/141 lands -# hence we are pinned for now to older mason in bootstrap.sh -. ./.mason/mason.sh - -set -eu - -function mason_load_source { - export MASON_BUILD_PATH=$(pwd) -} - -function mason_compile { - HERE=$(pwd) - make install - # this is to adapt to when mapnik is not installed in MASON_PREFIX - # originally (to make it easier to publish locally as a stopgap) - MAPNIK_PREFIX=$(mapnik-config --prefix) - if [[ ${MAPNIK_PREFIX} != ${MASON_PREFIX} ]]; then - mkdir -p ${MASON_PREFIX}/lib - mkdir -p ${MASON_PREFIX}/include - mkdir -p ${MASON_PREFIX}/bin - cp -r ${MAPNIK_PREFIX}/lib/*mapnik* ${MASON_PREFIX}/lib/ - cp -r ${MAPNIK_PREFIX}/include/mapnik ${MASON_PREFIX}/include/ - cp -r ${MAPNIK_PREFIX}/bin/mapnik* ${MASON_PREFIX}/bin/ - cp -r ${MAPNIK_PREFIX}/bin/shapeindex ${MASON_PREFIX}/bin/ - fi - if [[ $(uname -s) == 'Darwin' ]]; then - install_name_tool -id @loader_path/lib/libmapnik.dylib ${MASON_PREFIX}"/lib/libmapnik.dylib"; - PLUGINDIR=${MASON_PREFIX}"/lib/mapnik/input/*.input"; - for f in $PLUGINDIR; do - echo $f; - echo $(basename $f); - install_name_tool -id plugins/input/$(basename $f) $f; - install_name_tool -change "${MAPNIK_PREFIX}/lib/libmapnik.dylib" @loader_path/../../lib/libmapnik.dylib $f; - done; - BINDIR=${MASON_PREFIX}"/bin/*"; - for f in $BINDIR; do - echo $f; - echo $(basename $f); - if [[ $(file $f) =~ 'Mach-O' ]]; then - install_name_tool -id bin/$(basename $f) $f; - install_name_tool -change "${MAPNIK_PREFIX}/lib/libmapnik.dylib" @loader_path/../lib/libmapnik.dylib $f; - fi - done; - fi; - python -c "data=open('$MASON_PREFIX/bin/mapnik-config','r').read();open('$MASON_PREFIX/bin/mapnik-config','w').write(data.replace('$HERE','.'))" - find ${MASON_PREFIX} -name "*.pyc" -exec rm {} \; -} - -function mason_cflags { - : -} - -function mason_ldflags { - : -} - -function mason_clean { - echo "Done" -} - -mason_run "$@" diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 322940528..49c6c660d 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,9 +38,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp index 71cf2ea71..b21570d05 100644 --- a/plugins/input/csv/csv_datasource.hpp +++ b/plugins/input/csv/csv_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,10 +28,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include "csv_utils.hpp" #pragma GCC diagnostic push diff --git a/plugins/input/csv/csv_featureset.cpp b/plugins/input/csv/csv_featureset.cpp index f73b52a54..b73f2e4b3 100644 --- a/plugins/input/csv/csv_featureset.cpp +++ b/plugins/input/csv/csv_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -73,7 +73,7 @@ mapnik::feature_ptr csv_featureset::parse_feature(char const* beg, char const* e { auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); @@ -97,7 +97,10 @@ mapnik::feature_ptr csv_featureset::next() std::fseek(file_.get(), file_offset, SEEK_SET); std::vector record; record.resize(size); - std::fread(record.data(), size, 1, file_.get()); + if (std::fread(record.data(), size, 1, file_.get()) != 1) + { + return mapnik::feature_ptr(); + } auto const* start = record.data(); auto const* end = start + record.size(); #endif diff --git a/plugins/input/csv/csv_featureset.hpp b/plugins/input/csv/csv_featureset.hpp index 8828fa4a5..f9850a2bc 100644 --- a/plugins/input/csv/csv_featureset.hpp +++ b/plugins/input/csv/csv_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/csv/csv_getline.hpp b/plugins/input/csv/csv_getline.hpp index 9dfe5de49..8259cb305 100644 --- a/plugins/input/csv/csv_getline.hpp +++ b/plugins/input/csv/csv_getline.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/csv/csv_index_featureset.cpp b/plugins/input/csv/csv_index_featureset.cpp index 493d65daf..3498dc37f 100644 --- a/plugins/input/csv/csv_index_featureset.cpp +++ b/plugins/input/csv/csv_index_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -90,7 +90,7 @@ mapnik::feature_ptr csv_index_featureset::parse_feature(char const* beg, char co { auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); @@ -119,7 +119,10 @@ mapnik::feature_ptr csv_index_featureset::next() std::fseek(file_.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file_.get()); + if (std::fread(record.data(), pos.second, 1, file_.get()) != 1) + { + return mapnik::feature_ptr(); + } auto const* start = record.data(); auto const* end = start + record.size(); #endif diff --git a/plugins/input/csv/csv_index_featureset.hpp b/plugins/input/csv/csv_index_featureset.hpp index e57a356c9..ac1a1ed91 100644 --- a/plugins/input/csv/csv_index_featureset.hpp +++ b/plugins/input/csv/csv_index_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/csv/csv_inline_featureset.cpp b/plugins/input/csv/csv_inline_featureset.cpp index 54c8f14f9..893410fb9 100644 --- a/plugins/input/csv/csv_inline_featureset.cpp +++ b/plugins/input/csv/csv_inline_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -58,7 +58,7 @@ mapnik::feature_ptr csv_inline_featureset::parse_feature(std::string const& str) auto const* end = start + str.size(); auto values = csv_utils::parse_line(start, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); diff --git a/plugins/input/csv/csv_inline_featureset.hpp b/plugins/input/csv/csv_inline_featureset.hpp index 4873cecaa..342a5b2bb 100644 --- a/plugins/input/csv/csv_inline_featureset.hpp +++ b/plugins/input/csv/csv_inline_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/csv/csv_utils.cpp b/plugins/input/csv/csv_utils.cpp index b35942d4c..f85cee4ec 100644 --- a/plugins/input/csv/csv_utils.cpp +++ b/plugins/input/csv/csv_utils.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,14 +23,14 @@ // mapnik #include #include -#include +#include #include #include #include #include #include // csv grammar -#include +#include // #include "csv_getline.hpp" #include "csv_utils.hpp" @@ -192,14 +192,17 @@ bool valid(geometry_column_locator const& locator, std::size_t max_size) } // namespace detail -static const mapnik::csv_line_grammar line_g; -static const mapnik::csv_white_space_skipper skipper{}; - mapnik::csv_line parse_line(char const* start, char const* end, char separator, char quote, std::size_t num_columns) { + namespace x3 = boost::spirit::x3; + auto parser = x3::with(quote) + [ x3::with(separator) + [ mapnik::csv_line_grammar()] + ]; + mapnik::csv_line values; if (num_columns > 0) values.reserve(num_columns); - if (!boost::spirit::qi::phrase_parse(start, end, (line_g)(separator, quote), skipper, values)) + if (!x3::phrase_parse(start, end, parser, mapnik::csv_white_space, values)) { throw mapnik::datasource_exception("Failed to parse CSV line:\n" + std::string(start, end)); } @@ -285,7 +288,10 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) { auto headers = csv_utils::parse_line(csv_line, separator_, quote_); // skip blank lines - if (headers.size() > 0 && headers[0].empty()) ++line_number; + if (headers.size() == 1 && headers[0].empty()) + { + ++line_number; + } else { std::size_t index = 0; @@ -300,7 +306,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) std::ostringstream s; s << "CSV Plugin: expected a column header at line "; s << line_number << ", column " << index; - s << " - ensure this row contains valid header fields: '"; + s << " - expected fields: '"; s << csv_line; throw mapnik::datasource_exception(s.str()); } @@ -338,7 +344,6 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) std::string str("CSV Plugin: could not detect column(s) with the name(s) of wkt, geojson, x/y, or "); str += "latitude/longitude in:\n"; str += csv_line; - str += "\n - this is required for reading geometry data"; throw mapnik::datasource_exception(str); } @@ -406,7 +411,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) } auto geom = extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { auto box = mapnik::geometry::envelope(geom); if (!extent_initialized_) diff --git a/plugins/input/csv/csv_utils.hpp b/plugins/input/csv/csv_utils.hpp index df976e3a7..0200cca1e 100644 --- a/plugins/input/csv/csv_utils.hpp +++ b/plugins/input/csv/csv_utils.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,9 +24,9 @@ #define MAPNIK_CSV_UTILS_DATASOURCE_HPP // mapnik -#include +#include #include -#include +#include #include #include #include diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index 2454ed65b..b98ed1e93 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index 3fc3036c8..53cdece2c 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 1377322e3..70d8ef73b 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp index f2f66f796..3d0ebeafc 100644 --- a/plugins/input/gdal/gdal_featureset.hpp +++ b/plugins/input/gdal/gdal_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 60fd7b715..906b204b9 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,6 @@ #pragma GCC diagnostic push #include #include -#include #pragma GCC diagnostic pop // mapnik @@ -40,8 +39,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -49,12 +48,12 @@ #include #include #include -#include -#include -#include +#include #include #include #include +#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #pragma GCC diagnostic push @@ -156,9 +155,9 @@ geojson_datasource::geojson_datasource(parameters const& params) std::string file_buffer; file_buffer.resize(file.size()); - std::fread(&file_buffer[0], file.size(), 1, file.get()); + auto count = std::fread(&file_buffer[0], file.size(), 1, file.get()); char const* start = file_buffer.c_str(); - char const* end = start + file_buffer.length(); + char const* end = (count == 1) ? start + file_buffer.length() : start; #else boost::optional mapped_region = mapnik::mapped_memory_cache::instance().find(filename_, false); @@ -182,14 +181,12 @@ geojson_datasource::geojson_datasource(parameters const& params) } namespace { + using box_type = box2d; using boxes_type = std::vector>>; using base_iterator_type = char const*; const mapnik::transcoder geojson_datasource_static_tr("utf8"); -const mapnik::json::feature_collection_grammar geojson_datasource_static_fc_grammar(geojson_datasource_static_tr); -const mapnik::json::feature_grammar_callback geojson_datasource_static_feature_callback_grammar(geojson_datasource_static_tr); -const mapnik::json::feature_grammar geojson_datasource_static_feature_grammar(geojson_datasource_static_tr); -const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; + } void geojson_datasource::initialise_descriptor(mapnik::feature_ptr const& feature) @@ -229,15 +226,15 @@ void geojson_datasource::initialise_disk_index(std::string const& filename) std::fseek(file.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file.get()); + auto count = std::fread(record.data(), pos.second, 1, file.get()); auto const* start = record.data(); - auto const* end = start + record.size(); + auto const* end = (count == 1) ? start + record.size() : start; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, -1)); - using namespace boost::spirit; - standard::space_type space; - if (!boost::spirit::qi::phrase_parse(start, end, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || start != end) + try + { + mapnik::json::parse_feature(start, end, *feature, geojson_datasource_static_tr); + } + catch (...) { throw std::runtime_error("Failed to parse geojson feature"); } @@ -246,29 +243,84 @@ void geojson_datasource::initialise_disk_index(std::string const& filename) desc_.order_by_name(); } +namespace mapnik { namespace json { + +template +void parse_geometry_or_feature(Iterator& itr, Iterator const& end, feature_impl& feature, transcoder const& tr ) +{ + Iterator start = itr; + try + { + parse_feature(start, end, feature, tr); + } + catch (...) + { + start = itr; + parse_geometry(start, end, feature); + } +} + +}} + + template void geojson_datasource::initialise_index(Iterator start, Iterator end) { boxes_type boxes; - boost::spirit::standard::space_type space; + mapnik::context_ptr ctx = std::make_shared(); Iterator itr = start; - if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) + try { + mapnik::json::extract_bounding_boxes(itr, end, boxes); + // bulk insert initialise r-tree + tree_ = std::make_unique(boxes); + // calculate total extent + std::size_t feature_count = 0; + + for (auto const& item : boxes) + { + auto const& box = std::get<0>(item); + auto const& geometry_index = std::get<1>(item); + if (!extent_.valid()) extent_ = box; + else extent_.expand_to_include(box); + if (feature_count++ < num_features_to_query_) + { + // parse first N features to extract attributes schema. + // NOTE: this doesn't yield correct answer for geoJSON in general, just an indication + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,-1)); // temp feature + Iterator itr2 = start + geometry_index.first; + Iterator end2 = itr2 + geometry_index.second; + try + { + mapnik::json::parse_feature(itr2, end2, *feature, geojson_datasource_static_tr); + } + catch (...) + { + throw std::runtime_error("Failed to parse geojson feature"); + } + initialise_descriptor(feature); + } + } + } + catch (...) + { + cache_features_ = true; // force caching single feature itr = start; // reset iteraror - // try parsing as single Feature or single Geometry JSON - mapnik::context_ptr ctx = std::make_shared(); std::size_t start_id = 1; - mapnik::json::default_feature_callback callback(features_); - bool result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_callback_grammar) - (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, start_id)); // single feature + try + { + mapnik::json::parse_geometry_or_feature(itr, end, *feature, geojson_datasource_static_tr); + } + catch (...) { if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file from in-memory string"); else throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file '" + filename_ + "'"); } + features_.push_back(std::move(feature)); + using values_container = std::vector< std::pair>>; values_container values; values.reserve(features_.size()); @@ -298,82 +350,48 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end) // packing algorithm tree_ = std::make_unique(values); } - else - { - // bulk insert initialise r-tree - tree_ = std::make_unique(boxes); - // calculate total extent - std::size_t feature_count = 0; - mapnik::context_ptr ctx = std::make_shared(); - for (auto const& item : boxes) - { - auto const& box = std::get<0>(item); - auto const& geometry_index = std::get<1>(item); - if (!extent_.valid()) extent_ = box; - else extent_.expand_to_include(box); - if (feature_count++ < num_features_to_query_) - { - // parse first N features to extract attributes schema. - // NOTE: this doesn't yield correct answer for geoJSON in general, just an indication - Iterator itr2 = start + geometry_index.first; - Iterator end2 = itr2 + geometry_index.second; - mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,-1)); // temp feature - if (!boost::spirit::qi::phrase_parse(itr2, end2, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || itr2 != end2) - { - throw std::runtime_error("Failed to parse geojson feature"); - } - - initialise_descriptor(feature); - } - } - } desc_.order_by_name(); } template void geojson_datasource::parse_geojson(Iterator start, Iterator end) { - using boost::spirit::qi::expectation_failure; - boost::spirit::standard::space_type space; mapnik::context_ptr ctx = std::make_shared(); std::size_t start_id = 1; - - mapnik::json::default_feature_callback callback(features_); Iterator itr = start; - try { - bool result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_fc_grammar) - (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) + boxes_type boxes; + mapnik::json::extract_bounding_boxes(itr, end, boxes); + + if (itr != end) throw std::runtime_error("Malformed GeoJSON"); //ensure we've consumed all input + + for (auto const& item : boxes) { - itr = start; - // try parsing as single Feature or single Geometry JSON - result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_callback_grammar) - (boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) - { - if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file from in-memory string"); - else throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + filename_ + "'"); - } + auto const& geometry_index = std::get<1>(item); + Iterator itr2 = start + geometry_index.first; + Iterator end2 = itr2 + geometry_index.second; + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, start_id++)); + mapnik::json::parse_feature(itr2, end2, *feature, geojson_datasource_static_tr); + features_.push_back(std::move(feature)); } } - catch (expectation_failure const& ex) + catch (...) { itr = start; // try parsing as single Feature or single Geometry JSON - bool result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_callback_grammar) - (boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, start_id)); // single feature + try { - if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file from in-memory string"); - else throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + filename_ + "'"); + mapnik::json::parse_geometry_or_feature(itr, end, *feature, geojson_datasource_static_tr); } + catch (...) + { + if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file from in-memory string"); + else throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file '" + filename_ + "'"); + } + + features_.push_back(std::move(feature)); } using values_container = std::vector< std::pair>>; @@ -389,7 +407,6 @@ void geojson_datasource::parse_geojson(Iterator start, Iterator end) if (geometry_index == 0) { extent_ = box; - } else { @@ -454,15 +471,15 @@ boost::optional geojson_datasource::get_geometry_ std::fseek(file.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file.get()); + auto count = std::fread(record.data(), pos.second, 1, file.get()); auto const* start = record.data(); - auto const* end = start + record.size(); + auto const* end = (count == 1) ? start + record.size() : start; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, -1)); // temp feature - using namespace boost::spirit; - standard::space_type space; - if (!boost::spirit::qi::phrase_parse(start, end, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || start != end) + try + { + mapnik::json::parse_feature(start, end, *feature, geojson_datasource_static_tr); + } + catch (...) { throw std::runtime_error("Failed to parse geojson feature"); } @@ -516,19 +533,21 @@ boost::optional geojson_datasource::get_geometry_ std::fseek(file.get(), file_offset, SEEK_SET); std::vector json; json.resize(size); - std::fread(json.data(), size, 1, file.get()); - + auto count_objects = std::fread(json.data(), size, 1, file.get()); using chr_iterator_type = char const*; chr_iterator_type start2 = json.data(); - chr_iterator_type end2 = start2 + json.size(); + chr_iterator_type end2 = (count_objects == 1) ? start2 + json.size() : start2; - using namespace boost::spirit; - standard::space_type space; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, -1)); // temp feature - if (!qi::phrase_parse(start2, end2, (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space)) + try + { + mapnik::json::parse_feature(start2, end2, *feature, geojson_datasource_static_tr); + } + catch (...) { throw std::runtime_error("Failed to parse geojson feature"); } + result = mapnik::util::to_ds_type(feature->get_geometry()); if (result) { diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index e295cb1d6..cbe7b9b12 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/geojson/geojson_featureset.cpp b/plugins/input/geojson/geojson_featureset.cpp index 1976f03ba..1d718527b 100644 --- a/plugins/input/geojson/geojson_featureset.cpp +++ b/plugins/input/geojson/geojson_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/geojson/geojson_featureset.hpp b/plugins/input/geojson/geojson_featureset.hpp index e055b9777..995df35ce 100644 --- a/plugins/input/geojson/geojson_featureset.hpp +++ b/plugins/input/geojson/geojson_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/geojson/geojson_index_featureset.cpp b/plugins/input/geojson/geojson_index_featureset.cpp index 4cd139899..b5e0fc66a 100644 --- a/plugins/input/geojson/geojson_index_featureset.cpp +++ b/plugins/input/geojson/geojson_index_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,10 +24,12 @@ #include "geojson_index_featureset.hpp" #include #include -#include #include #include -#include +#include +#include +#include +#include // stl #include #include @@ -85,19 +87,14 @@ mapnik::feature_ptr geojson_index_featureset::next() std::fseek(file_.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file_.get()); + auto count = std::fread(record.data(), pos.second, 1, file_.get()); auto const* start = record.data(); - auto const* end = start + record.size(); + auto const* end = (count == 1) ? start + record.size() : start; #endif static const mapnik::transcoder tr("utf8"); - static const mapnik::json::feature_grammar grammar(tr); - using namespace boost::spirit; - standard::space_type space; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, feature_id_++)); - if (!qi::phrase_parse(start, end, (grammar)(boost::phoenix::ref(*feature)), space) || start != end) - { - throw std::runtime_error("Failed to parse GeoJSON feature"); - } + using mapnik::json::grammar::iterator_type; + mapnik::json::parse_feature(start, end, *feature, tr); // throw on failure // skip empty geometries if (mapnik::geometry::is_empty(feature->get_geometry())) continue; diff --git a/plugins/input/geojson/geojson_index_featureset.hpp b/plugins/input/geojson/geojson_index_featureset.hpp index 41e8e84ba..9b9b03428 100644 --- a/plugins/input/geojson/geojson_index_featureset.hpp +++ b/plugins/input/geojson/geojson_index_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/geojson/geojson_memory_index_featureset.cpp b/plugins/input/geojson/geojson_memory_index_featureset.cpp index 32b851373..f26e098e2 100644 --- a/plugins/input/geojson/geojson_memory_index_featureset.cpp +++ b/plugins/input/geojson/geojson_memory_index_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,17 +21,18 @@ *****************************************************************************/ // mapnik +#include "geojson_memory_index_featureset.hpp" + #include #include -#include #include -#include +#include +#include + // stl #include #include -#include "geojson_memory_index_featureset.hpp" - geojson_memory_index_featureset::geojson_memory_index_featureset(std::string const& filename, array_type && index_array) : @@ -60,19 +61,13 @@ mapnik::feature_ptr geojson_memory_index_featureset::next() std::fseek(file_.get(), file_offset, SEEK_SET); std::vector json; json.resize(size); - std::fread(json.data(), size, 1, file_.get()); + auto count = std::fread(json.data(), size, 1, file_.get()); using chr_iterator_type = char const*; chr_iterator_type start = json.data(); - chr_iterator_type end = start + json.size(); + chr_iterator_type end = (count == 1) ? start + json.size() : start; static const mapnik::transcoder tr("utf8"); - static const mapnik::json::feature_grammar grammar(tr); - using namespace boost::spirit; - standard::space_type space; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, feature_id_++)); - if (!qi::phrase_parse(start, end, (grammar)(boost::phoenix::ref(*feature)), space) || start != end) - { - throw std::runtime_error("Failed to parse geojson feature"); - } + mapnik::json::parse_feature(start, end, *feature, tr); // throw on failure // skip empty geometries if (mapnik::geometry::is_empty(feature->get_geometry())) continue; diff --git a/plugins/input/geojson/geojson_memory_index_featureset.hpp b/plugins/input/geojson/geojson_memory_index_featureset.hpp index a29751d67..888ccd52d 100644 --- a/plugins/input/geojson/geojson_memory_index_featureset.hpp +++ b/plugins/input/geojson/geojson_memory_index_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index e409e81a0..91ba612ad 100644 --- a/plugins/input/ogr/ogr_converter.cpp +++ b/plugins/input/ogr/ogr_converter.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/ogr/ogr_converter.hpp b/plugins/input/ogr/ogr_converter.hpp index 8b7f909af..452ee250e 100644 --- a/plugins/input/ogr/ogr_converter.hpp +++ b/plugins/input/ogr/ogr_converter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index 706a376e3..b23304968 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/ogr/ogr_datasource.hpp b/plugins/input/ogr/ogr_datasource.hpp index 0edeae9dc..35f48f644 100644 --- a/plugins/input/ogr/ogr_datasource.hpp +++ b/plugins/input/ogr/ogr_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/input/ogr/ogr_featureset.cpp b/plugins/input/ogr/ogr_featureset.cpp index 267ebc017..f3182b1f2 100644 --- a/plugins/input/ogr/ogr_featureset.cpp +++ b/plugins/input/ogr/ogr_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,16 +22,16 @@ // mapnik #include -#include +#include #include -#include +#include #include #include #include #include -#include +#include #include -#include +#include // ogr #include "ogr_featureset.hpp" diff --git a/plugins/input/ogr/ogr_featureset.hpp b/plugins/input/ogr/ogr_featureset.hpp index 6a594ec52..8f73cc6df 100644 --- a/plugins/input/ogr/ogr_featureset.hpp +++ b/plugins/input/ogr/ogr_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/ogr/ogr_index.hpp b/plugins/input/ogr/ogr_index.hpp index e661d21b0..7a6f0047c 100644 --- a/plugins/input/ogr/ogr_index.hpp +++ b/plugins/input/ogr/ogr_index.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,15 +20,15 @@ * *****************************************************************************/ -#ifndef OGR_INDEX_HH -#define OGR_INDEX_HH +#ifndef OGR_INDEX_HPP +#define OGR_INDEX_HPP // stl #include #include // mapnik -#include +#include #include using mapnik::box2d; @@ -102,4 +102,4 @@ void ogr_index::read_envelope(IStream& file, box2d& en file.read(reinterpret_cast(&envelope), sizeof(envelope)); } -#endif // OGR_INDEX_HH +#endif // OGR_INDEX_HPP diff --git a/plugins/input/ogr/ogr_index_featureset.cpp b/plugins/input/ogr/ogr_index_featureset.cpp index 54b91f470..6f087fd25 100644 --- a/plugins/input/ogr/ogr_index_featureset.cpp +++ b/plugins/input/ogr/ogr_index_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,16 +21,16 @@ *****************************************************************************/ // mapnik -#include +#include #include #include -#include +#include #include #include #include #include #include -#include +#include // boost #if defined(MAPNIK_MEMORY_MAPPED_FILE) diff --git a/plugins/input/ogr/ogr_index_featureset.hpp b/plugins/input/ogr/ogr_index_featureset.hpp index 93d3a327f..961e1c259 100644 --- a/plugins/input/ogr/ogr_index_featureset.hpp +++ b/plugins/input/ogr/ogr_index_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/ogr/ogr_layer_ptr.hpp b/plugins/input/ogr/ogr_layer_ptr.hpp index 28df28b21..2c50816d9 100644 --- a/plugins/input/ogr/ogr_layer_ptr.hpp +++ b/plugins/input/ogr/ogr_layer_ptr.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/pgraster/pgraster_datasource.cpp b/plugins/input/pgraster/pgraster_datasource.cpp index e6eddf758..11ade8da2 100644 --- a/plugins/input/pgraster/pgraster_datasource.cpp +++ b/plugins/input/pgraster/pgraster_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,15 +36,15 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include #include -#include #pragma GCC diagnostic pop // stl +#include // FLT_MAX #include #include #include @@ -53,28 +53,19 @@ DATASOURCE_PLUGIN(pgraster_datasource) -const double pgraster_datasource::FMAX = std::numeric_limits::max(); const std::string pgraster_datasource::RASTER_COLUMNS = "raster_columns"; const std::string pgraster_datasource::RASTER_OVERVIEWS = "raster_overviews"; const std::string pgraster_datasource::SPATIAL_REF_SYS = "spatial_ref_system"; using std::shared_ptr; using mapnik::attribute_descriptor; +using mapnik::sql_utils::identifier; +using mapnik::sql_utils::literal; using mapnik::value_integer; -namespace { - - // TODO: move to sql_utils - std::string quote_ident(std::string& s) { - return "\"" + s + "\""; // TODO: escape internal quotes - } - -}; - pgraster_datasource::pgraster_datasource(parameters const& params) : datasource(params), table_(*params.get("table", "")), - schema_(""), raster_table_(*params.get("raster_table", "")), raster_field_(*params.get("raster_field", "")), key_field_(*params.get("key_field", "")), @@ -94,10 +85,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params) params.get("user"), params.get("password"), params.get("connect_timeout", "4")), - bbox_token_("!bbox!"), - scale_denom_token_("!scale_denominator!"), - pixel_width_token_("!pixel_width!"), - pixel_height_token_("!pixel_height!"), + re_tokens_("!(@?\\w+)!"), // matches !mapnik_var! or !@user_var! pool_max_size_(*params_.get("max_size", 10)), persist_connection_(*params.get("persist_connection", true)), extent_from_subquery_(*params.get("extent_from_subquery", false)), @@ -141,160 +129,112 @@ pgraster_datasource::pgraster_datasource(parameters const& params) ConnectionManager::instance().registerPool(creator_, *initial_size, pool_max_size_); CnxPool_ptr pool = ConnectionManager::instance().getPool(creator_.id()); - if (pool) + if (!pool) return; + + shared_ptr conn = pool->borrowObject(); + if (!conn) return; + + if (conn->isOK()) { - shared_ptr conn = pool->borrowObject(); - if (!conn) return; + desc_.set_encoding(conn->client_encoding()); - if (conn->isOK()) + if (raster_table_.empty()) { + mapnik::sql_utils::table_from_sql + (table_, parsed_schema_, parsed_table_); - desc_.set_encoding(conn->client_encoding()); - - if (raster_table_.empty()) + // non-trivial subqueries (having no FROM) make it + // impossible to use overviews + // TODO: improve "table_from_sql" ? + auto nsp = table_.find_first_not_of(" \t\r\n"); + if (nsp != std::string::npos && table_[nsp] == '(') { - raster_table_ = mapnik::sql_utils::table_from_sql(table_); - // non-trivial subqueries (having no FROM) make it - // impossible to use overviews - // TODO: improve "table_from_sql" ? - if ( raster_table_[raster_table_.find_first_not_of(" \t\r\n")] == '(' ) - { - raster_table_.clear(); if ( use_overviews_ ) { - std::ostringstream err; - err << "Pgraster Plugin: overviews cannot be used " - "with non-trivial subqueries"; - MAPNIK_LOG_WARN(pgraster) << err.str(); - use_overviews_ = false; + std::ostringstream err; + err << "Pgraster Plugin: overviews cannot be used " + "with non-trivial subqueries"; + MAPNIK_LOG_WARN(pgraster) << err.str(); + use_overviews_ = false; } if ( ! extent_from_subquery_ ) { - std::ostringstream err; - err << "Pgraster Plugin: extent can only be computed " - "from subquery as we could not found table source"; - MAPNIK_LOG_WARN(pgraster) << err.str(); - extent_from_subquery_ = true; + std::ostringstream err; + err << "Pgraster Plugin: extent can only be computed " + "from subquery as we could not found table source"; + MAPNIK_LOG_WARN(pgraster) << err.str(); + extent_from_subquery_ = true; } - - } } + } + else + { + mapnik::sql_utils::table_from_sql + (raster_table_, parsed_schema_, parsed_table_); + } - std::string::size_type idx = raster_table_.find_last_of('.'); - if (idx != std::string::npos) - { - schema_ = raster_table_.substr(0, idx); - raster_table_ = raster_table_.substr(idx + 1); - } - - // If we do not know either the geometry_field or the srid or we - // want to use overviews but do not know about schema, or - // no extent was specified, then attempt to fetch the missing - // information from a raster_columns entry. - // - // This will return no records if we are querying a bogus table returned - // from the simplistic table parsing in table_from_sql() or if - // the table parameter references a table, view, or subselect not - // registered in the geometry columns. - // - geometryColumn_ = mapnik::sql_utils::unquote_double(raster_field_); - if (!raster_table_.empty() && ( - geometryColumn_.empty() || srid_ == 0 || - (schema_.empty() && use_overviews_) || - ! extent_initialized_ - )) - { + // If we do not know either the geometry_field or the srid or we + // want to use overviews but do not know about schema, or + // no extent was specified, then attempt to fetch the missing + // information from a raster_columns entry. + // + // This will return no records if we are querying a bogus table returned + // from the simplistic table parsing in table_from_sql() or if + // the table parameter references a table, view, or subselect not + // registered in the geometry columns. + // + geometryColumn_ = mapnik::sql_utils::unquote_copy('"', raster_field_); + if (!parsed_table_.empty() && ( + geometryColumn_.empty() || srid_ == 0 || + (parsed_schema_.empty() && use_overviews_) || + ! extent_initialized_ + )) + { #ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::init(get_srid_and_geometry_column)"); + mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::init(get_srid_and_geometry_column)"); #endif - std::ostringstream s; + std::ostringstream s; - try + try + { + s << "SELECT r_raster_column col, srid, r_table_schema"; + if ( ! extent_initialized_ ) { + s << ", st_xmin(extent) xmin, st_ymin(extent) ymin" + << ", st_xmax(extent) xmax, st_ymax(extent) ymax"; + } + s << " FROM " << RASTER_COLUMNS + << " WHERE r_table_name=" << literal(parsed_table_); + if (!parsed_schema_.empty()) { - s << "SELECT r_raster_column col, srid, r_table_schema"; - if ( ! extent_initialized_ ) { - s << ", st_xmin(extent) xmin, st_ymin(extent) ymin" - << ", st_xmax(extent) xmax, st_ymax(extent) ymax"; - } - s << " FROM " - << RASTER_COLUMNS << " WHERE r_table_name='" - << mapnik::sql_utils::unquote_double(raster_table_) - << "'"; - if (! schema_.empty()) + s << " AND r_table_schema=" << literal(parsed_schema_); + } + if (!geometryColumn_.empty()) + { + s << " AND r_raster_column=" << literal(geometryColumn_); + } + MAPNIK_LOG_DEBUG(pgraster) << + "pgraster_datasource: running query " << s.str(); + shared_ptr rs = conn->executeQuery(s.str()); + if (rs->next()) + { + geometryColumn_ = rs->getValue("col"); + if ( ! extent_initialized_ ) { - s << " AND r_table_schema='" - << mapnik::sql_utils::unquote_double(schema_) - << "'"; - } - if (! raster_field_.empty()) - { - s << " AND r_raster_column='" - << mapnik::sql_utils::unquote_double(raster_field_) - << "'"; - } - MAPNIK_LOG_DEBUG(pgraster) << - "pgraster_datasource: running query " << s.str(); - shared_ptr rs = conn->executeQuery(s.str()); - if (rs->next()) - { - geometryColumn_ = rs->getValue("col"); - if ( ! extent_initialized_ ) + double lox, loy, hix, hiy; + if (mapnik::util::string2double(rs->getValue("xmin"), lox) && + mapnik::util::string2double(rs->getValue("ymin"), loy) && + mapnik::util::string2double(rs->getValue("xmax"), hix) && + mapnik::util::string2double(rs->getValue("ymax"), hiy)) { - double lox, loy, hix, hiy; - if (mapnik::util::string2double(rs->getValue("xmin"), lox) && - mapnik::util::string2double(rs->getValue("ymin"), loy) && - mapnik::util::string2double(rs->getValue("xmax"), hix) && - mapnik::util::string2double(rs->getValue("ymax"), hiy)) - { extent_.init(lox, loy, hix, hiy); extent_initialized_ = true; MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Layer extent=" << extent_; - } - else - { + } + else + { MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Could not determine extent from query: " << s.str(); - } - } - if (srid_ == 0) - { - const char* srid_c = rs->getValue("srid"); - if (srid_c != nullptr) - { - int result = 0; - const char * end = srid_c + std::strlen(srid_c); - if (mapnik::util::string2int(srid_c, end, result)) - { - srid_ = result; - } - } - } - if ( schema_.empty() ) - { - schema_ = rs->getValue("r_table_schema"); } } - else - { - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str(); - } - rs->close(); - } - catch (mapnik::datasource_exception const& ex) { - // let this pass on query error and use the fallback below - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: metadata query failed: " << ex.what(); - } - - // If we still do not know the srid then we can try to fetch - // it from the 'table_' parameter, which should work even if it is - // a subselect as long as we know the geometry_field to query - if (! geometryColumn_.empty() && srid_ <= 0) - { - s.str(""); - - s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM " - << populate_tokens(table_) << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;"; - - shared_ptr rs = conn->executeQuery(s.str()); - if (rs->next()) + if (srid_ == 0) { const char* srid_c = rs->getValue("srid"); if (srid_c != nullptr) @@ -307,275 +247,312 @@ pgraster_datasource::pgraster_datasource(parameters const& params) } } } - rs->close(); - } - } - - // If overviews were requested, take note of the max scale - // of each available overview, sorted by scale descending - if ( use_overviews_ ) - { - std::ostringstream err; - if ( schema_.empty() ) - { - err << "Pgraster Plugin: unable to lookup available table" - << " overviews due to unknown schema"; - throw mapnik::datasource_exception(err.str()); - } - if ( geometryColumn_.empty() ) - { - err << "Pgraster Plugin: unable to lookup available table" - << " overviews due to unknown column name"; - throw mapnik::datasource_exception(err.str()); - } - - std::ostringstream s; - s << "select " - "r.r_table_schema sch, " - "r.r_table_name tab, " - "r.r_raster_column col, " - "greatest(abs(r.scale_x), abs(r.scale_y)) scl " - "from" - " raster_overviews o," - " raster_columns r " - "where" - " o.r_table_schema = '" - << mapnik::sql_utils::unquote_double(schema_) - << "' and o.r_table_name = '" - << mapnik::sql_utils::unquote_double(raster_table_) - << "' and o.r_raster_column = '" - << mapnik::sql_utils::unquote_double(geometryColumn_) - << "' and r.r_table_schema = o.o_table_schema" - " and r.r_table_name = o.o_table_name" - " and r.r_raster_column = o.o_raster_column" - " ORDER BY scl ASC"; - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: running query " << s.str(); - shared_ptr rs = conn->executeQuery(s.str()); - while (rs->next()) - { - pgraster_overview ov = pgraster_overview(); - - ov.schema = rs->getValue("sch"); - ov.table = rs->getValue("tab"); - ov.column = rs->getValue("col"); - ov.scale = atof(rs->getValue("scl")); - - if(ov.scale == 0.0f) - { - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: found invalid overview " - << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; - continue; - } - - overviews_.push_back(ov); - - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: found overview " << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; - } - rs->close(); - if ( overviews_.empty() ) { - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no overview found for " << schema_ << "." << raster_table_ << "." << geometryColumn_; - } - } - - // detect primary key - if (*autodetect_key_field && key_field_.empty()) - { -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_primary_key)"); -#endif - - std::ostringstream s; - s << "SELECT a.attname, a.attnum, t.typname, t.typname in ('int2','int4','int8') " - "AS is_int FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n, pg_index i " - "WHERE a.attnum > 0 AND a.attrelid = c.oid " - "AND a.atttypid = t.oid AND c.relnamespace = n.oid " - "AND c.oid = i.indrelid AND i.indisprimary = 't' " - "AND t.typname !~ '^geom' AND c.relname =" - << " '" << mapnik::sql_utils::unquote_double(raster_table_) << "' " - //"AND a.attnum = ANY (i.indkey) " // postgres >= 8.1 - << "AND (i.indkey[0]=a.attnum OR i.indkey[1]=a.attnum OR i.indkey[2]=a.attnum " - "OR i.indkey[3]=a.attnum OR i.indkey[4]=a.attnum OR i.indkey[5]=a.attnum " - "OR i.indkey[6]=a.attnum OR i.indkey[7]=a.attnum OR i.indkey[8]=a.attnum " - "OR i.indkey[9]=a.attnum) "; - if (! schema_.empty()) - { - s << "AND n.nspname='" - << mapnik::sql_utils::unquote_double(schema_) - << "' "; - } - s << "ORDER BY a.attnum"; - - shared_ptr rs_key = conn->executeQuery(s.str()); - if (rs_key->next()) - { - unsigned int result_rows = rs_key->size(); - if (result_rows == 1) + if (parsed_schema_.empty()) { - bool is_int = (std::string(rs_key->getValue(3)) == "t"); - if (is_int) - { - const char* key_field_string = rs_key->getValue(0); - if (key_field_string) - { - key_field_ = std::string(key_field_string); - - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: auto-detected key field of '" - << key_field_ << "' on table '" << raster_table_ << "'"; - } - } - else - { - // throw for cases like a numeric primary key, which is invalid - // as it should be floating point (int numerics are useless) - std::ostringstream err; - err << "PostGIS Plugin: Error: '" - << rs_key->getValue(0) - << "' on table '" - << raster_table_ - << "' is not a valid integer primary key field\n"; - throw mapnik::datasource_exception(err.str()); - } - } - else if (result_rows > 1) - { - std::ostringstream err; - err << "PostGIS Plugin: Error: '" - << "multi column primary key detected but is not supported"; - throw mapnik::datasource_exception(err.str()); - } - } - rs_key->close(); - } - - // if a globally unique key field/primary key is required - // but still not known at this point, then throw - if (*autodetect_key_field && key_field_.empty()) - { - throw mapnik::datasource_exception(std::string("PostGIS Plugin: Error: primary key required") - + " but could not be detected for table '" + - raster_table_ + "', please supply 'key_field' option to specify field to use for primary key"); - } - - if (srid_ == 0) - { - srid_ = -1; - - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Table " << table_ << " is using SRID=" << srid_; - } - - // At this point the geometry_field may still not be known - // but we'll catch that where more useful... - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using SRID=" << srid_; - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using geometry_column=" << geometryColumn_; - - // collect attribute desc -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_column_description)"); -#endif - - std::ostringstream s; - s << "SELECT * FROM " << populate_tokens(table_) << " LIMIT 0"; - - shared_ptr rs = conn->executeQuery(s.str()); - int count = rs->getNumFields(); - bool found_key_field = false; - for (int i = 0; i < count; ++i) - { - std::string fld_name = rs->getFieldName(i); - int type_oid = rs->getTypeOID(i); - - // validate type of key_field - if (! found_key_field && ! key_field_.empty() && fld_name == key_field_) - { - if (type_oid == 20 || type_oid == 21 || type_oid == 23) - { - found_key_field = true; - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); - } - else - { - std::ostringstream error_s; - error_s << "invalid type '"; - - std::ostringstream type_s; - type_s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; - - shared_ptr rs_oid = conn->executeQuery(type_s.str()); - if (rs_oid->next()) - { - error_s << rs_oid->getValue("typname") - << "' (oid:" << rs_oid->getValue("oid") << ")"; - } - else - { - error_s << "oid:" << type_oid << "'"; - } - - rs_oid->close(); - error_s << " for key_field '" << fld_name << "' - " - << "must be an integer primary key"; - - rs->close(); - throw mapnik::datasource_exception(error_s.str()); + parsed_schema_ = rs->getValue("r_table_schema"); } } else { - switch (type_oid) - { - case 16: // bool - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Boolean)); - break; - case 20: // int8 - case 21: // int2 - case 23: // int4 - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); - break; - case 700: // float4 - case 701: // float8 - case 1700: // numeric - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Double)); - break; - case 1042: // bpchar - case 1043: // varchar - case 25: // text - case 705: // literal - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::String)); - break; - default: // should not get here -#ifdef MAPNIK_LOG - s.str(""); - s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; - - shared_ptr rs_oid = conn->executeQuery(s.str()); - if (rs_oid->next()) - { - std::string typname(rs_oid->getValue("typname")); - if (typname != "geometry" && typname != "raster") - { - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type=" << typname - << " (oid:" << rs_oid->getValue("oid") << ")"; - } - } - else - { - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type_oid=" << type_oid; - } - rs_oid->close(); -#endif - break; - } + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str(); } + rs->close(); + } + catch (mapnik::datasource_exception const& ex) { + // let this pass on query error and use the fallback below + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: metadata query failed: " << ex.what(); } - rs->close(); + // If we still do not know the srid then we can try to fetch + // it from the 'table_' parameter, which should work even if it is + // a subselect as long as we know the geometry_field to query + if (! geometryColumn_.empty() && srid_ <= 0) + { + s.str(""); + s << "SELECT ST_SRID(" << identifier(geometryColumn_) + << ") AS srid FROM " << populate_tokens(table_) + << " WHERE " << identifier(geometryColumn_) + << " IS NOT NULL LIMIT 1"; + + shared_ptr rs = conn->executeQuery(s.str()); + if (rs->next()) + { + const char* srid_c = rs->getValue("srid"); + if (srid_c != nullptr) + { + int result = 0; + const char * end = srid_c + std::strlen(srid_c); + if (mapnik::util::string2int(srid_c, end, result)) + { + srid_ = result; + } + } + } + rs->close(); + } } - // Close explicitly the connection so we can 'fork()' without sharing open connections - conn->close(); + // If overviews were requested, take note of the max scale + // of each available overview, sorted by scale descending + if ( use_overviews_ ) + { + std::ostringstream err; + if (parsed_schema_.empty()) + { + err << "Pgraster Plugin: unable to lookup available table" + << " overviews due to unknown schema"; + throw mapnik::datasource_exception(err.str()); + } + if (geometryColumn_.empty()) + { + err << "Pgraster Plugin: unable to lookup available table" + << " overviews due to unknown column name"; + throw mapnik::datasource_exception(err.str()); + } + std::ostringstream s; + s << "select " + "r.r_table_schema sch, " + "r.r_table_name tab, " + "r.r_raster_column col, " + "greatest(abs(r.scale_x), abs(r.scale_y)) scl " + "from" + " raster_overviews o," + " raster_columns r " + "where" + " o.r_table_schema = " << literal(parsed_schema_) + << " and o.r_table_name = " << literal(parsed_table_) + << " and o.r_raster_column = " << literal(geometryColumn_) + << " and r.r_table_schema = o.o_table_schema" + " and r.r_table_name = o.o_table_name" + " and r.r_raster_column = o.o_raster_column" + " ORDER BY scl ASC"; + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: running query " << s.str(); + shared_ptr rs = conn->executeQuery(s.str()); + while (rs->next()) + { + pgraster_overview ov = pgraster_overview(); + + ov.schema = rs->getValue("sch"); + ov.table = rs->getValue("tab"); + ov.column = rs->getValue("col"); + ov.scale = atof(rs->getValue("scl")); + + if(ov.scale == 0.0f) + { + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: found invalid overview " + << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; + continue; + } + + overviews_.push_back(ov); + + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: found overview " + << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; + } + rs->close(); + if ( overviews_.empty() ) { + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no overview found for " + << parsed_schema_ << "." << parsed_table_ << "." << geometryColumn_; + } + } + + // detect primary key + if (*autodetect_key_field && key_field_.empty()) + { +#ifdef MAPNIK_STATS + mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_primary_key)"); +#endif + + std::ostringstream s; + s << "SELECT a.attname, a.attnum, t.typname, t.typname in ('int2','int4','int8') " + "AS is_int FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n, pg_index i " + "WHERE a.attnum > 0 AND a.attrelid = c.oid " + "AND a.atttypid = t.oid AND c.relnamespace = n.oid " + "AND c.oid = i.indrelid AND i.indisprimary = 't' " + "AND t.typname !~ '^geom' AND c.relname = " << literal(parsed_table_) << " " + //"AND a.attnum = ANY (i.indkey) " // postgres >= 8.1 + << "AND (i.indkey[0]=a.attnum OR i.indkey[1]=a.attnum OR i.indkey[2]=a.attnum " + "OR i.indkey[3]=a.attnum OR i.indkey[4]=a.attnum OR i.indkey[5]=a.attnum " + "OR i.indkey[6]=a.attnum OR i.indkey[7]=a.attnum OR i.indkey[8]=a.attnum " + "OR i.indkey[9]=a.attnum) "; + if (!parsed_schema_.empty()) + { + s << "AND n.nspname=" << literal(parsed_schema_) << ' '; + } + s << "ORDER BY a.attnum"; + + shared_ptr rs_key = conn->executeQuery(s.str()); + if (rs_key->next()) + { + unsigned int result_rows = rs_key->size(); + if (result_rows == 1) + { + bool is_int = (std::string(rs_key->getValue(3)) == "t"); + if (is_int) + { + const char* key_field_string = rs_key->getValue(0); + if (key_field_string) + { + key_field_ = std::string(key_field_string); + + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: auto-detected key field of '" + << key_field_ << "' on table '" << parsed_table_ << "'"; + } + } + else + { + // throw for cases like a numeric primary key, which is invalid + // as it should be floating point (int numerics are useless) + std::ostringstream err; + err << "PostGIS Plugin: Error: '" + << rs_key->getValue(0) + << "' on table '" + << parsed_table_ + << "' is not a valid integer primary key field\n"; + throw mapnik::datasource_exception(err.str()); + } + } + else if (result_rows > 1) + { + std::ostringstream err; + err << "PostGIS Plugin: Error: '" + << "multi column primary key detected but is not supported"; + throw mapnik::datasource_exception(err.str()); + } + } + rs_key->close(); + } + + // if a globally unique key field/primary key is required + // but still not known at this point, then throw + if (*autodetect_key_field && key_field_.empty()) + { + throw mapnik::datasource_exception( + "PostGIS Plugin: Error: primary key required" + " but could not be detected for table '" + + parsed_table_ + "', please supply 'key_field'" + " option to specify field to use for primary key"); + } + + if (srid_ == 0) + { + srid_ = -1; + + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Table " << table_ << " is using SRID=" << srid_; + } + + // At this point the geometry_field may still not be known + // but we'll catch that where more useful... + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using SRID=" << srid_; + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using geometry_column=" << geometryColumn_; + + // collect attribute desc +#ifdef MAPNIK_STATS + mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_column_description)"); +#endif + + std::ostringstream s; + s << "SELECT * FROM " << populate_tokens(table_) << " LIMIT 0"; + + shared_ptr rs = conn->executeQuery(s.str()); + int count = rs->getNumFields(); + bool found_key_field = false; + for (int i = 0; i < count; ++i) + { + std::string fld_name = rs->getFieldName(i); + int type_oid = rs->getTypeOID(i); + + // validate type of key_field + if (! found_key_field && ! key_field_.empty() && fld_name == key_field_) + { + if (type_oid == 20 || type_oid == 21 || type_oid == 23) + { + found_key_field = true; + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); + } + else + { + std::ostringstream error_s; + error_s << "invalid type '"; + + std::ostringstream type_s; + type_s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; + + shared_ptr rs_oid = conn->executeQuery(type_s.str()); + if (rs_oid->next()) + { + error_s << rs_oid->getValue("typname") + << "' (oid:" << rs_oid->getValue("oid") << ")"; + } + else + { + error_s << "oid:" << type_oid << "'"; + } + + rs_oid->close(); + error_s << " for key_field '" << fld_name << "' - " + << "must be an integer primary key"; + + rs->close(); + throw mapnik::datasource_exception(error_s.str()); + } + } + else + { + switch (type_oid) + { + case 16: // bool + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Boolean)); + break; + case 20: // int8 + case 21: // int2 + case 23: // int4 + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); + break; + case 700: // float4 + case 701: // float8 + case 1700: // numeric + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Double)); + break; + case 1042: // bpchar + case 1043: // varchar + case 25: // text + case 705: // literal + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::String)); + break; + default: // should not get here +#ifdef MAPNIK_LOG + s.str(""); + s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; + + shared_ptr rs_oid = conn->executeQuery(s.str()); + if (rs_oid->next()) + { + std::string typname(rs_oid->getValue("typname")); + if (typname != "geometry" && typname != "raster") + { + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type=" << typname + << " (oid:" << rs_oid->getValue("oid") << ")"; + } + } + else + { + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type_oid=" << type_oid; + } + rs_oid->close(); +#endif + break; + } + } + } + + rs->close(); } + + // Close explicitly the connection so we can 'fork()' without sharing open connections + conn->close(); } pgraster_datasource::~pgraster_datasource() @@ -627,10 +604,10 @@ std::string pgraster_datasource::sql_bbox(box2d const& env) const b << "ST_SetSRID("; } - b << "'BOX3D("; + b << "'BOX("; b << std::setprecision(16); b << env.minx() << " " << env.miny() << ","; - b << env.maxx() << " " << env.maxy() << ")'::box3d"; + b << env.maxx() << " " << env.maxy() << ")'::box2d"; if (srid_ > 0) { @@ -642,77 +619,76 @@ std::string pgraster_datasource::sql_bbox(box2d const& env) const std::string pgraster_datasource::populate_tokens(std::string const& sql) const { - std::string populated_sql = sql; - - if (boost::algorithm::icontains(sql, bbox_token_)) - { - box2d max_env(-1.0 * FMAX, -1.0 * FMAX, FMAX, FMAX); - const std::string max_box = sql_bbox(max_env); - boost::algorithm::replace_all(populated_sql, bbox_token_, max_box); - } - - if (boost::algorithm::icontains(sql, scale_denom_token_)) - { - std::ostringstream ss; - ss << FMAX; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); - } - - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - std::ostringstream ss; - ss << 0; - boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str()); - } - - if (boost::algorithm::icontains(sql, pixel_height_token_)) - { - std::ostringstream ss; - ss << 0; - boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str()); - } - - return populated_sql; + return populate_tokens(sql, FLT_MAX, + box2d(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX), + 0, 0, mapnik::attributes{}, false); } -std::string pgraster_datasource::populate_tokens(std::string const& sql, double scale_denom, box2d const& env, double pixel_width, double pixel_height) const +std::string pgraster_datasource::populate_tokens(std::string const& sql, + double scale_denom, + box2d const& env, + double pixel_width, + double pixel_height, + mapnik::attributes const& vars, + bool intersect) const { - std::string populated_sql = sql; - std::string box = sql_bbox(env); + std::ostringstream populated_sql; + std::cmatch m; + char const* start = sql.data(); + char const* end = start + sql.size(); - if (boost::algorithm::icontains(populated_sql, scale_denom_token_)) + while (std::regex_search(start, end, m, re_tokens_)) { - std::ostringstream ss; - ss << scale_denom; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); + populated_sql.write(start, m[0].first - start); + start = m[0].second; + + auto m1 = boost::make_iterator_range(m[1].first, m[1].second); + if (m1.front() == '@') + { + std::string var_name(m1.begin() + 1, m1.end()); + auto itr = vars.find(var_name); + if (itr != vars.end()) + { + auto var_value = itr->second.to_string(); + populated_sql << literal(var_value); + } + else + { + populated_sql << "NULL"; // undefined @variable + } + } + else if (boost::algorithm::equals(m1, "bbox")) + { + populated_sql << sql_bbox(env); + intersect = false; + } + else if (boost::algorithm::equals(m1, "pixel_height")) + { + populated_sql << pixel_height; + } + else if (boost::algorithm::equals(m1, "pixel_width")) + { + populated_sql << pixel_width; + } + else if (boost::algorithm::equals(m1, "scale_denominator")) + { + populated_sql << scale_denom; + } + else + { + populated_sql << "NULL"; // unrecognized !token! + } } - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - std::ostringstream ss; - ss << pixel_width; - boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str()); - } + populated_sql.write(start, end - start); - if (boost::algorithm::icontains(sql, pixel_height_token_)) + if (intersect) { - std::ostringstream ss; - ss << pixel_height; - boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str()); - } - - if (boost::algorithm::icontains(populated_sql, bbox_token_)) - { - boost::algorithm::replace_all(populated_sql, bbox_token_, box); - return populated_sql; - } - else - { - std::ostringstream s; - if (intersect_min_scale_ > 0 && (scale_denom <= intersect_min_scale_)) { - s << " WHERE ST_Intersects(\"" << geometryColumn_ << "\"," << box << ")"; + populated_sql << " WHERE ST_Intersects(" + << identifier(geometryColumn_) << ", " + << sql_bbox(env) << ")"; } else if (intersect_max_scale_ > 0 && (scale_denom >= intersect_max_scale_)) { @@ -720,11 +696,13 @@ std::string pgraster_datasource::populate_tokens(std::string const& sql, double } else { - s << " WHERE \"" << geometryColumn_ << "\" && " << box; + populated_sql << " WHERE " + << identifier(geometryColumn_) << " && " + << sql_bbox(env); } - - return populated_sql + s.str(); } + + return populated_sql.str(); } @@ -852,19 +830,19 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ + s_error << parsed_table_ << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ << "'."; + s_error << parsed_table_ << "'."; throw mapnik::datasource_exception(s_error.str()); } @@ -877,6 +855,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process std::string table_with_bbox; std::string col = geometryColumn_; + table_with_bbox = table_; // possibly a subquery if ( use_overviews_ && !overviews_.empty()) { std::string sch = overviews_[0].schema; @@ -904,18 +883,12 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process << " not good for min out scale " << scale; } } - table_with_bbox = table_; // possibly a subquery - boost::algorithm::replace_all(table_with_bbox, - mapnik::sql_utils::unquote_double(raster_table_), tab); - boost::algorithm::replace_all(table_with_bbox, - mapnik::sql_utils::unquote_double(schema_), sch); - boost::algorithm::replace_all(table_with_bbox, - mapnik::sql_utils::unquote_double(geometryColumn_), col); - table_with_bbox = populate_tokens(table_with_bbox, - scale_denom, box, px_gw, px_gh); - } else { - table_with_bbox = populate_tokens(table_, scale_denom, box, px_gw, px_gh); + boost::algorithm::replace_all(table_with_bbox, parsed_table_, tab); + boost::algorithm::replace_all(table_with_bbox, parsed_schema_, sch); + boost::algorithm::replace_all(table_with_bbox, geometryColumn_, col); } + table_with_bbox = populate_tokens(table_with_bbox, scale_denom, box, + px_gw, px_gh, q.variables()); std::ostringstream s; @@ -927,21 +900,21 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process if (clip_rasters_) s << "ST_Clip("; - s << "\"" << col << "\""; + s << identifier(col); if (clip_rasters_) { s << ", ST_Expand(" << sql_bbox(box) - << ", greatest(abs(ST_ScaleX(\"" - << col << "\")), abs(ST_ScaleY(\"" - << col << "\")))))"; + << ", greatest(abs(ST_ScaleX(" + << identifier(col) << ")), abs(ST_ScaleY(" + << identifier(col) << ")))))"; } if (prescale_rasters_) { const double scale = std::min(px_gw, px_gh); - s << ", least(abs(ST_ScaleX(\"" << col - << "\"))::float8/" << scale - << ", 1.0), least(abs(ST_ScaleY(\"" << col - << "\"))::float8/" << scale << ", 1.0))"; + s << ", least(1.0, abs(ST_ScaleX(" << identifier(col) + << "))::float8/" << scale + << "), least(1.0, abs(ST_ScaleY(" << identifier(col) + << "))::float8/" << scale << "))"; // TODO: if band_ is given, we'll interpret as indexed so // the rescaling must NOT ruin it (use algorithm mode!) } @@ -957,14 +930,14 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process if (! key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); ctx->push(key_field_); for (; pos != end; ++pos) { if (*pos != key_field_) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -973,7 +946,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process { for (; pos != end; ++pos) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -1020,39 +993,39 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ + s_error << parsed_table_ << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ << "'."; + s_error << parsed_table_ << "'."; throw mapnik::datasource_exception(s_error.str()); } std::ostringstream s; - s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom"; + s << "SELECT ST_AsBinary(" << identifier(geometryColumn_) << ") AS geom"; mapnik::context_ptr ctx = std::make_shared(); auto const& desc = desc_.get_descriptors(); if (!key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); ctx->push(key_field_); for (auto const& attr_info : desc) { std::string const& name = attr_info.get_name(); if (name != key_field_) { - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } @@ -1062,13 +1035,14 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double for (auto const& attr_info : desc) { std::string const& name = attr_info.get_name(); - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } box2d box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol); - std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0); + std::string table_with_bbox = populate_tokens(table_, FLT_MAX, box, 0, 0, + mapnik::attributes{}); s << " FROM " << table_with_bbox; @@ -1101,9 +1075,9 @@ box2d pgraster_datasource::envelope() const { std::ostringstream s; - std::string col = mapnik::sql_utils::unquote_double(geometryColumn_); - std::string sch = mapnik::sql_utils::unquote_double(schema_); - std::string tab = mapnik::sql_utils::unquote_double(raster_table_); + std::string col = geometryColumn_; + std::string sch = parsed_schema_; + std::string tab = parsed_table_; if ( ! overviews_.empty() ) { @@ -1123,7 +1097,7 @@ box2d pgraster_datasource::envelope() const { s_error << sch << "."; } - s_error << raster_table_ << "' because we cannot determine the raster field name." + s_error << parsed_table_ << "' because we cannot determine the raster field name." << "\nPlease provide either an 'extent' parameter to skip this query, " << "a 'raster_field' and/or 'raster_table' parameter, or add " << "standard constraints to your raster table."; @@ -1143,20 +1117,20 @@ box2d pgraster_datasource::envelope() const throw mapnik::datasource_exception("Pgraster Plugin: " + s_error.str()); } s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Estimated_Extent('"; + << " FROM (SELECT ST_EstimatedExtent('"; if (! sch.empty()) { - s << mapnik::sql_utils::unquote_double(sch) << "','"; + s << literal(sch) << ','; } - s << mapnik::sql_utils::unquote_double(tab) << "','" - << mapnik::sql_utils::unquote_double(col) << "') as ext) as tmp"; + s << literal(tab) << ',' + << literal(col) << ") as ext) as tmp"; } else { s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Extent(" << quote_ident(col) << "::geometry) as ext from "; + << " FROM (SELECT ST_Extent(" << identifier(col) << "::geometry) as ext from "; if (extent_from_subquery_) { @@ -1168,12 +1142,12 @@ box2d pgraster_datasource::envelope() const { if (! sch.empty()) { - s << quote_ident(sch) << "."; + s << identifier(sch) << "."; } // but if the subquery does not limit records then querying the // actual table will be faster as indexes can be used - s << quote_ident(tab) << ") as tmp"; + s << identifier(tab) << ") as tmp"; } } diff --git a/plugins/input/pgraster/pgraster_datasource.hpp b/plugins/input/pgraster/pgraster_datasource.hpp index 221f196e4..0ffe762b5 100644 --- a/plugins/input/pgraster/pgraster_datasource.hpp +++ b/plugins/input/pgraster/pgraster_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,16 +32,17 @@ #include #include #include -#include +#include #include #include #include -#include +#include // boost #include // stl +#include #include #include #include @@ -90,24 +91,26 @@ public: private: std::string sql_bbox(box2d const& env) const; - std::string populate_tokens(std::string const& sql, double scale_denom, box2d const& env, double pixel_width, double pixel_height) const; + std::string populate_tokens(std::string const& sql, double scale_denom, + box2d const& env, + double pixel_width, double pixel_height, + mapnik::attributes const& vars, + bool intersect = true) const; std::string populate_tokens(std::string const& sql) const; std::shared_ptr get_resultset(std::shared_ptr &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx= processor_context_ptr()) const; static const std::string RASTER_COLUMNS; static const std::string RASTER_OVERVIEWS; static const std::string SPATIAL_REF_SYS; - static const double FMAX; const std::string uri_; const std::string username_; const std::string password_; // table name (schema qualified or not) or subquery const std::string table_; - // schema name (possibly extracted from table_) - std::string schema_; - // table name (possibly extracted from table_) - std::string raster_table_; + const std::string raster_table_; // possibly schema-qualified const std::string raster_field_; + std::string parsed_schema_; // extracted from raster_table_ or table_ + std::string parsed_table_; // extracted from raster_table_ or table_ std::string key_field_; mapnik::value_integer cursor_fetch_size_; mapnik::value_integer row_limit_; @@ -129,10 +132,7 @@ private: bool clip_rasters_; layer_descriptor desc_; ConnectionCreator creator_; - const std::string bbox_token_; - const std::string scale_denom_token_; - const std::string pixel_width_token_; - const std::string pixel_height_token_; + std::regex re_tokens_; int pool_max_size_; bool persist_connection_; bool extent_from_subquery_; diff --git a/plugins/input/pgraster/pgraster_featureset.cpp b/plugins/input/pgraster/pgraster_featureset.cpp index e2d4ccb50..8cf596ead 100644 --- a/plugins/input/pgraster/pgraster_featureset.cpp +++ b/plugins/input/pgraster/pgraster_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/pgraster/pgraster_featureset.hpp b/plugins/input/pgraster/pgraster_featureset.hpp index 25319b31a..d218b667d 100644 --- a/plugins/input/pgraster/pgraster_featureset.hpp +++ b/plugins/input/pgraster/pgraster_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #define PGRASTER_FEATURESET_HPP // mapnik -#include +#include #include #include #include diff --git a/plugins/input/pgraster/pgraster_wkb_reader.cpp b/plugins/input/pgraster/pgraster_wkb_reader.cpp index 4a9fd1c8f..aa2891c0e 100644 --- a/plugins/input/pgraster/pgraster_wkb_reader.cpp +++ b/plugins/input/pgraster/pgraster_wkb_reader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,7 +35,7 @@ #include #include #include -#include // for box2d +#include // for box2d #include #include diff --git a/plugins/input/pgraster/pgraster_wkb_reader.hpp b/plugins/input/pgraster/pgraster_wkb_reader.hpp index 02a22bc4a..d4cff13ad 100644 --- a/plugins/input/pgraster/pgraster_wkb_reader.hpp +++ b/plugins/input/pgraster/pgraster_wkb_reader.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +29,7 @@ // mapnik #include // for raster_ptr -#include +#include enum pgraster_color_interp { // Automatic color interpretation: diff --git a/plugins/input/postgis/asyncresultset.hpp b/plugins/input/postgis/asyncresultset.hpp index 9c30d57f3..68a5058e0 100644 --- a/plugins/input/postgis/asyncresultset.hpp +++ b/plugins/input/postgis/asyncresultset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/postgis/build.py b/plugins/input/postgis/build.py index 157952f45..635efb848 100644 --- a/plugins/input/postgis/build.py +++ b/plugins/input/postgis/build.py @@ -52,7 +52,6 @@ libraries = copy(plugin_env['LIBS']) if env['PLUGIN_LINKING'] == 'shared': libraries.append('boost_system%s' % env['BOOST_APPEND']) - libraries.append('boost_regex%s' % env['BOOST_APPEND']) libraries.insert(0,env['MAPNIK_NAME']) libraries.append(env['ICU_LIB_NAME']) diff --git a/plugins/input/postgis/connection.hpp b/plugins/input/postgis/connection.hpp index 3d33a2d67..d241eced2 100644 --- a/plugins/input/postgis/connection.hpp +++ b/plugins/input/postgis/connection.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/postgis/connection_manager.hpp b/plugins/input/postgis/connection_manager.hpp index 73656cbbc..e3de59191 100644 --- a/plugins/input/postgis/connection_manager.hpp +++ b/plugins/input/postgis/connection_manager.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/postgis/cursorresultset.hpp b/plugins/input/postgis/cursorresultset.hpp index 63bb9429c..b4bd1d5da 100644 --- a/plugins/input/postgis/cursorresultset.hpp +++ b/plugins/input/postgis/cursorresultset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/postgis/numeric2string.hpp b/plugins/input/postgis/numeric2string.hpp index 76c204f0c..35381f07e 100644 --- a/plugins/input/postgis/numeric2string.hpp +++ b/plugins/input/postgis/numeric2string.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index 10ce521d0..0e90ac5fb 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,16 +33,15 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include #include -#include -#include #pragma GCC diagnostic pop // stl +#include // FLT_MAX #include #include #include @@ -52,17 +51,17 @@ DATASOURCE_PLUGIN(postgis_datasource) -const double postgis_datasource::FMAX = std::numeric_limits::max(); const std::string postgis_datasource::GEOMETRY_COLUMNS = "geometry_columns"; const std::string postgis_datasource::SPATIAL_REF_SYS = "spatial_ref_system"; using std::shared_ptr; using mapnik::attribute_descriptor; +using mapnik::sql_utils::identifier; +using mapnik::sql_utils::literal; postgis_datasource::postgis_datasource(parameters const& params) : datasource(params), table_(*params.get("table", "")), - schema_(""), geometry_table_(*params.get("geometry_table", "")), geometry_field_(*params.get("geometry_field", "")), key_field_(*params.get("key_field", "")), @@ -79,10 +78,6 @@ postgis_datasource::postgis_datasource(parameters const& params) params.get("user"), params.get("password"), params.get("connect_timeout", "4")), - bbox_token_("!bbox!"), - scale_denom_token_("!scale_denominator!"), - pixel_width_token_("!pixel_width!"), - pixel_height_token_("!pixel_height!"), pool_max_size_(*params_.get("max_size", 10)), persist_connection_(*params.get("persist_connection", true)), extent_from_subquery_(*params.get("extent_from_subquery", false)), @@ -99,8 +94,7 @@ postgis_datasource::postgis_datasource(parameters const& params) simplify_prefilter_(*params_.get("simplify_prefilter", 0.0)), simplify_dp_preserve_(false), simplify_clip_resolution_(*params_.get("simplify_clip_resolution", 0.0)), - // TODO - use for known tokens too: "(@\\w+|!\\w+!)" - pattern_(boost::regex("(@\\w+)",boost::regex::normal | boost::regbase::icase)), + re_tokens_("!(@?\\w+)!"), // matches !mapnik_var! or !@user_var! // params below are for testing purposes only and may be removed at any time intersect_min_scale_(*params.get("intersect_min_scale", 0)), intersect_max_scale_(*params.get("intersect_max_scale", 0)), @@ -159,21 +153,13 @@ postgis_datasource::postgis_datasource(parameters const& params) desc_.set_encoding(conn->client_encoding()); - if (geometry_table_.empty()) - { - geometry_table_ = mapnik::sql_utils::table_from_sql(table_); - } + mapnik::sql_utils::table_from_sql( + geometry_table_.empty() ? table_ : geometry_table_, + parsed_schema_, parsed_table_); - std::string::size_type idx = geometry_table_.find_last_of('.'); - if (idx != std::string::npos) - { - schema_ = geometry_table_.substr(0, idx); - geometry_table_ = geometry_table_.substr(idx + 1); - } - - // NOTE: geometry_table_ how should ideally be a table name, but + // NOTE: parsed_table_ now should ideally be a table name, but // there are known edge cases where this will break down and - // geometry_table_ may even be empty: https://github.com/mapnik/mapnik/issues/2718 + // it may even be empty: https://github.com/mapnik/mapnik/issues/2718 // If we do not know both the geometry_field and the srid // then first attempt to fetch the geometry name from a geometry_columns entry. @@ -181,8 +167,8 @@ postgis_datasource::postgis_datasource(parameters const& params) // from the simplistic table parsing in table_from_sql() or if // the table parameter references a table, view, or subselect not // registered in the geometry columns. - geometryColumn_ = geometry_field_; - if (!geometry_table_.empty() && (geometryColumn_.empty() || srid_ == 0)) + geometryColumn_ = mapnik::sql_utils::unquote_copy('"', geometry_field_); + if (!parsed_table_.empty() && (geometryColumn_.empty() || srid_ == 0)) { #ifdef MAPNIK_STATS mapnik::progress_timer __stats2__(std::clog, "postgis_datasource::init(get_srid_and_geometry_column)"); @@ -191,21 +177,15 @@ postgis_datasource::postgis_datasource(parameters const& params) try { - s << "SELECT f_geometry_column, srid FROM " - << GEOMETRY_COLUMNS <<" WHERE f_table_name='" - << mapnik::sql_utils::unquote_double(geometry_table_) - << "'"; - if (! schema_.empty()) + s << "SELECT f_geometry_column, srid FROM " << GEOMETRY_COLUMNS + << " WHERE f_table_name=" << literal(parsed_table_); + if (!parsed_schema_.empty()) { - s << " AND f_table_schema='" - << mapnik::sql_utils::unquote_double(schema_) - << "'"; + s << " AND f_table_schema=" << literal(parsed_schema_); } - if (! geometry_field_.empty()) + if (!geometryColumn_.empty()) { - s << " AND f_geometry_column='" - << mapnik::sql_utils::unquote_double(geometry_field_) - << "'"; + s << " AND f_geometry_column=" << literal(geometryColumn_); } shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) @@ -237,26 +217,24 @@ postgis_datasource::postgis_datasource(parameters const& params) } // If we still do not know the srid then we can try to fetch - // it from the 'geometry_table_' parameter, which should work even if it is + // it from the 'parsed_table_' parameter, which should work even if it is // a subselect as long as we know the geometry_field to query if (!geometryColumn_.empty() && srid_ <= 0) { std::ostringstream s; - s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM "; - if (!geometry_table_.empty()) + s << "SELECT ST_SRID(" << identifier(geometryColumn_) + << ") AS srid FROM "; + if (!parsed_table_.empty()) { - if (!schema_.empty()) - { - s << schema_ << '.'; - } - s << geometry_table_; + append_geometry_table(s); } else { s << populate_tokens(table_); } - s << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;"; + s << " WHERE " << identifier(geometryColumn_) + << " IS NOT NULL LIMIT 1"; shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) @@ -288,18 +266,16 @@ postgis_datasource::postgis_datasource(parameters const& params) "WHERE a.attnum > 0 AND a.attrelid = c.oid " "AND a.atttypid = t.oid AND c.relnamespace = n.oid " "AND c.oid = i.indrelid AND i.indisprimary = 't' " - "AND t.typname !~ '^geom' AND c.relname =" - << " '" << mapnik::sql_utils::unquote_double(geometry_table_) << "' " + "AND t.typname !~ '^geom' AND c.relname = " + << literal(parsed_table_) << " " //"AND a.attnum = ANY (i.indkey) " // postgres >= 8.1 << "AND (i.indkey[0]=a.attnum OR i.indkey[1]=a.attnum OR i.indkey[2]=a.attnum " "OR i.indkey[3]=a.attnum OR i.indkey[4]=a.attnum OR i.indkey[5]=a.attnum " "OR i.indkey[6]=a.attnum OR i.indkey[7]=a.attnum OR i.indkey[8]=a.attnum " "OR i.indkey[9]=a.attnum) "; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s << "AND n.nspname='" - << mapnik::sql_utils::unquote_double(schema_) - << "' "; + s << "AND n.nspname=" << literal(parsed_schema_) << ' '; } s << "ORDER BY a.attnum"; @@ -318,7 +294,7 @@ postgis_datasource::postgis_datasource(parameters const& params) key_field_ = std::string(key_field_string); MAPNIK_LOG_DEBUG(postgis) << "postgis_datasource: auto-detected key field of '" - << key_field_ << "' on table '" << geometry_table_ << "'"; + << key_field_ << "' on table '" << parsed_table_ << "'"; } } else @@ -329,7 +305,7 @@ postgis_datasource::postgis_datasource(parameters const& params) err << "PostGIS Plugin: Error: '" << rs_key->getValue(0) << "' on table '" - << geometry_table_ + << parsed_table_ << "' is not a valid integer primary key field\n"; throw mapnik::datasource_exception(err.str()); } @@ -349,9 +325,11 @@ postgis_datasource::postgis_datasource(parameters const& params) // but still not known at this point, then throw if (*autodetect_key_field && key_field_.empty()) { - throw mapnik::datasource_exception(std::string("PostGIS Plugin: Error: primary key required") - + " but could not be detected for table '" + - geometry_table_ + "', please supply 'key_field' option to specify field to use for primary key"); + throw mapnik::datasource_exception( + "PostGIS Plugin: Error: primary key required" + " but could not be detected for table '" + + parsed_table_ + "', please supply 'key_field'" + " option to specify field to use for primary key"); } if (srid_ == 0) @@ -551,43 +529,9 @@ std::string postgis_datasource::sql_bbox(box2d const& env) const std::string postgis_datasource::populate_tokens(std::string const& sql) const { - std::string populated_sql = sql; - - if (boost::algorithm::icontains(sql, bbox_token_)) - { - box2d max_env(-1.0 * FMAX, -1.0 * FMAX, FMAX, FMAX); - const std::string max_box = sql_bbox(max_env); - boost::algorithm::replace_all(populated_sql, bbox_token_, max_box); - } - - if (boost::algorithm::icontains(sql, scale_denom_token_)) - { - std::ostringstream ss; - ss << FMAX; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); - } - - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - boost::algorithm::replace_all(populated_sql, pixel_width_token_, "0"); - } - - if (boost::algorithm::icontains(sql, pixel_height_token_)) - { - boost::algorithm::replace_all(populated_sql, pixel_height_token_, "0"); - } - - std::string copy2 = populated_sql; - std::list l; - boost::regex_split(std::back_inserter(l), copy2, pattern_); - if (!l.empty()) - { - for (auto const & token: l) - { - boost::algorithm::replace_all(populated_sql, token, "null"); - } - } - return populated_sql; + return populate_tokens(sql, FLT_MAX, + box2d(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX), + 0, 0, mapnik::attributes{}, false); } std::string postgis_datasource::populate_tokens( @@ -596,43 +540,66 @@ std::string postgis_datasource::populate_tokens( box2d const& env, double pixel_width, double pixel_height, - mapnik::attributes const& vars) const + mapnik::attributes const& vars, + bool intersect) const { - std::string populated_sql = sql; - std::string box = sql_bbox(env); + std::ostringstream populated_sql; + std::cmatch m; + char const* start = sql.data(); + char const* end = start + sql.size(); - if (boost::algorithm::icontains(populated_sql, scale_denom_token_)) + while (std::regex_search(start, end, m, re_tokens_)) { - std::ostringstream ss; - ss << scale_denom; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); + populated_sql.write(start, m[0].first - start); + start = m[0].second; + + auto m1 = boost::make_iterator_range(m[1].first, m[1].second); + if (m1.front() == '@') + { + std::string var_name(m1.begin() + 1, m1.end()); + auto itr = vars.find(var_name); + if (itr != vars.end()) + { + auto var_value = itr->second.to_string(); + populated_sql << literal(var_value); + } + else + { + populated_sql << "NULL"; // undefined @variable + } + } + else if (boost::algorithm::equals(m1, "bbox")) + { + populated_sql << sql_bbox(env); + intersect = false; + } + else if (boost::algorithm::equals(m1, "pixel_height")) + { + populated_sql << pixel_height; + } + else if (boost::algorithm::equals(m1, "pixel_width")) + { + populated_sql << pixel_width; + } + else if (boost::algorithm::equals(m1, "scale_denominator")) + { + populated_sql << scale_denom; + } + else + { + populated_sql << "NULL"; // unrecognized !token! + } } - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - std::ostringstream ss; - ss << pixel_width; - boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str()); - } + populated_sql.write(start, end - start); - if (boost::algorithm::icontains(sql, pixel_height_token_)) + if (intersect) { - std::ostringstream ss; - ss << pixel_height; - boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str()); - } - - if (boost::algorithm::icontains(populated_sql, bbox_token_)) - { - boost::algorithm::replace_all(populated_sql, bbox_token_, box); - } - else - { - std::ostringstream s; - if (intersect_min_scale_ > 0 && (scale_denom <= intersect_min_scale_)) { - s << " WHERE ST_Intersects(\"" << geometryColumn_ << "\"," << box << ")"; + populated_sql << " WHERE ST_Intersects(" + << identifier(geometryColumn_) << ", " + << sql_bbox(env) << ")"; } else if (intersect_max_scale_ > 0 && (scale_denom >= intersect_max_scale_)) { @@ -640,31 +607,34 @@ std::string postgis_datasource::populate_tokens( } else { - s << " WHERE \"" << geometryColumn_ << "\" && " << box; - } - populated_sql += s.str(); - } - std::string copy2 = populated_sql; - std::list l; - boost::regex_split(std::back_inserter(l), copy2, pattern_); - if (!l.empty()) - { - for (auto const & token: l) - { - auto itr = vars.find(token.substr(1,std::string::npos)); - if (itr != vars.end()) - { - boost::algorithm::replace_all(populated_sql, token, itr->second.to_string()); - } - else - { - boost::algorithm::replace_all(populated_sql, token, "null"); - } + populated_sql << " WHERE " + << identifier(geometryColumn_) << " && " + << sql_bbox(env); } } - return populated_sql; + + return populated_sql.str(); } +void postgis_datasource::append_geometry_table(std::ostream & os) const +{ + if (!geometry_table_.empty()) + { + os << geometry_table_; // assume datasource parameter is valid SQL + } + else if (!parsed_schema_.empty()) + { + os << identifier(parsed_schema_) << '.' << identifier(parsed_table_); + } + else if (!parsed_table_.empty()) + { + os << identifier(parsed_table_); + } + else + { + os << table_; // assume datasource parameter is valid SQL + } +} std::shared_ptr postgis_datasource::get_resultset(std::shared_ptr &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx) const { @@ -789,20 +759,11 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ - << "'. Please manually provide the 'geometry_field' parameter or add an entry " + append_geometry_table(s_error); + s_error << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ << "'."; + append_geometry_table(s_error); + s_error << "'."; throw mapnik::datasource_exception(s_error.str()); } @@ -833,7 +794,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { s << "ST_ClipByBox2D("; } - s << "\"" << geometryColumn_ << "\""; + s << identifier(geometryColumn_); // ! ST_ClipByBox2D() if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz) @@ -865,7 +826,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo } // Geometry column! - s << "\"" << geometryColumn_ << "\""; + s << identifier(geometryColumn_); // ! ST_SnapToGrid() if (simplify_geometries_ && simplify_snap_ratio_ > 0.0) @@ -903,7 +864,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo if (! key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); if (key_field_as_attribute_) { ctx->push(key_field_); @@ -913,7 +874,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { if (*pos != key_field_) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -922,7 +883,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { for (; pos != end; ++pos) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -963,33 +924,25 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t { std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ - << "'. Please manually provide the 'geometry_field' parameter or add an entry " + append_geometry_table(s_error); + s_error << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ << "'."; + append_geometry_table(s_error); + s_error << "'."; throw mapnik::datasource_exception(s_error.str()); } std::ostringstream s; - s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom"; + s << "SELECT ST_AsBinary(" << identifier(geometryColumn_) + << ") AS geom"; mapnik::context_ptr ctx = std::make_shared(); auto const& desc = desc_.get_descriptors(); if (!key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); if (key_field_as_attribute_) { ctx->push(key_field_); @@ -999,7 +952,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t std::string const& name = attr_info.get_name(); if (name != key_field_) { - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } @@ -1009,13 +962,14 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t for (auto const& attr_info : desc) { std::string const& name = attr_info.get_name(); - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } box2d box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol); - std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0, mapnik::attributes()); + std::string table_with_bbox = populate_tokens(table_, FLT_MAX, box, 0, 0, + mapnik::attributes{}); s << " FROM " << table_with_bbox; @@ -1053,12 +1007,8 @@ box2d postgis_datasource::envelope() const { std::ostringstream s_error; s_error << "PostGIS: unable to query the layer extent of table '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ << "' because we cannot determine the geometry field name." + append_geometry_table(s_error); + s_error << "' because we cannot determine the geometry field name." << "\nPlease provide either an 'extent' parameter to skip this query, " << "a 'geometry_field' and/or 'geometry_table' parameter, or add a " << "record to the 'geometry_columns' for your table."; @@ -1069,20 +1019,20 @@ box2d postgis_datasource::envelope() const if (estimate_extent_) { s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Estimated_Extent('"; - - if (! schema_.empty()) + << " FROM (SELECT ST_EstimatedExtent('"; + if (!parsed_schema_.empty()) { - s << mapnik::sql_utils::unquote_double(schema_) << "','"; + s << literal(parsed_schema_) << ','; } - s << mapnik::sql_utils::unquote_double(geometry_table_) << "','" - << mapnik::sql_utils::unquote_double(geometryColumn_) << "') as ext) as tmp"; + s << literal(parsed_table_) << ',' + << literal(geometryColumn_) << ") as ext) as tmp"; } else { s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Extent(" < postgis_datasource::envelope() const } else { - if (! schema_.empty()) - { - s << schema_ << "."; - } - // but if the subquery does not limit records then querying the // actual table will be faster as indexes can be used - s << geometry_table_ << ") as tmp"; + append_geometry_table(s); + s << ") as tmp"; } } @@ -1142,21 +1088,15 @@ boost::optional postgis_datasource::get_geometry_ std::string g_type; try { - s << "SELECT lower(type) as type FROM " - << GEOMETRY_COLUMNS <<" WHERE f_table_name='" - << mapnik::sql_utils::unquote_double(geometry_table_) - << "'"; - if (! schema_.empty()) + s << "SELECT lower(type) as type FROM " << GEOMETRY_COLUMNS + << " WHERE f_table_name=" << literal(parsed_table_); + if (!parsed_schema_.empty()) { - s << " AND f_table_schema='" - << mapnik::sql_utils::unquote_double(schema_) - << "'"; + s << " AND f_table_schema=" << literal(parsed_schema_); } - if (! geometry_field_.empty()) + if (!geometryColumn_.empty()) { - s << " AND f_geometry_column='" - << mapnik::sql_utils::unquote_double(geometry_field_) - << "'"; + s << " AND f_geometry_column=" << literal(geometryColumn_); } shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) @@ -1195,8 +1135,8 @@ boost::optional postgis_datasource::get_geometry_ std::string prev_type(""); - s << "SELECT ST_GeometryType(\"" - << geometryColumn_ << "\") AS geom" + s << "SELECT ST_GeometryType(" + << identifier(geometryColumn_) << ") AS geom" << " FROM " << populate_tokens(table_); if (row_limit_ > 0 && row_limit_ < 5) diff --git a/plugins/input/postgis/postgis_datasource.hpp b/plugins/input/postgis/postgis_datasource.hpp index 80ba89495..636ccd4e8 100644 --- a/plugins/input/postgis/postgis_datasource.hpp +++ b/plugins/input/postgis/postgis_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,19 +28,19 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include // boost #include -#include // stl #include +#include #include #include @@ -84,20 +84,22 @@ private: box2d const& env, double pixel_width, double pixel_height, - mapnik::attributes const& vars) const; + mapnik::attributes const& vars, + bool intersect = true) const; std::string populate_tokens(std::string const& sql) const; + void append_geometry_table(std::ostream & os) const; std::shared_ptr get_resultset(std::shared_ptr &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx= processor_context_ptr()) const; static const std::string GEOMETRY_COLUMNS; static const std::string SPATIAL_REF_SYS; - static const double FMAX; const std::string uri_; const std::string username_; const std::string password_; const std::string table_; - std::string schema_; - std::string geometry_table_; + const std::string geometry_table_; const std::string geometry_field_; + std::string parsed_schema_; + std::string parsed_table_; std::string key_field_; mapnik::value_integer cursor_fetch_size_; mapnik::value_integer row_limit_; @@ -109,10 +111,6 @@ private: bool simplify_geometries_; layer_descriptor desc_; ConnectionCreator creator_; - const std::string bbox_token_; - const std::string scale_denom_token_; - const std::string pixel_width_token_; - const std::string pixel_height_token_; int pool_max_size_; bool persist_connection_; bool extent_from_subquery_; @@ -126,7 +124,7 @@ private: mapnik::value_double simplify_prefilter_; bool simplify_dp_preserve_; mapnik::value_double simplify_clip_resolution_; - boost::regex pattern_; + std::regex re_tokens_; int intersect_min_scale_; int intersect_max_scale_; bool key_field_as_attribute_; diff --git a/plugins/input/postgis/postgis_featureset.cpp b/plugins/input/postgis/postgis_featureset.cpp index 25e2b6b4b..d0eed531a 100644 --- a/plugins/input/postgis/postgis_featureset.cpp +++ b/plugins/input/postgis/postgis_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/postgis/postgis_featureset.hpp b/plugins/input/postgis/postgis_featureset.hpp index 9ef8cb392..53b961c8a 100644 --- a/plugins/input/postgis/postgis_featureset.hpp +++ b/plugins/input/postgis/postgis_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #define POSTGIS_FEATURESET_HPP // mapnik -#include +#include #include #include #include diff --git a/plugins/input/postgis/resultset.hpp b/plugins/input/postgis/resultset.hpp index 915a5962d..dbbc8771b 100644 --- a/plugins/input/postgis/resultset.hpp +++ b/plugins/input/postgis/resultset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index e059247cd..cfdfccda7 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/raster/raster_datasource.hpp b/plugins/input/raster/raster_datasource.hpp index 7ff099086..cd2149c88 100644 --- a/plugins/input/raster/raster_datasource.hpp +++ b/plugins/input/raster/raster_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index 26cac964f..4a4cf441e 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/raster/raster_featureset.hpp b/plugins/input/raster/raster_featureset.hpp index 007689275..1b0b0222a 100644 --- a/plugins/input/raster/raster_featureset.hpp +++ b/plugins/input/raster/raster_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/raster/raster_info.cpp b/plugins/input/raster/raster_info.cpp index 54b17c412..984eb59b6 100644 --- a/plugins/input/raster/raster_info.cpp +++ b/plugins/input/raster/raster_info.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -44,7 +44,7 @@ raster_info::raster_info(const raster_info& rhs) { } -void raster_info::swap(raster_info& other) //throw() +void raster_info::swap(raster_info& other) { std::swap(file_,other.file_); std::swap(format_,other.format_); diff --git a/plugins/input/raster/raster_info.hpp b/plugins/input/raster/raster_info.hpp index f0208425a..356d4193d 100644 --- a/plugins/input/raster/raster_info.hpp +++ b/plugins/input/raster/raster_info.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/shape/dbf_test.cpp b/plugins/input/shape/dbf_test.cpp index c5e22f576..5c37bf293 100644 --- a/plugins/input/shape/dbf_test.cpp +++ b/plugins/input/shape/dbf_test.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/shape/dbfile.cpp b/plugins/input/shape/dbfile.cpp index d64d37384..3da607417 100644 --- a/plugins/input/shape/dbfile.cpp +++ b/plugins/input/shape/dbfile.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * *****************************************************************************/ // mapnik -#include +#include #include #include #include @@ -30,7 +30,7 @@ #pragma GCC diagnostic push #include -#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #include #include @@ -137,7 +137,7 @@ const field_descriptor& dbf_file::descriptor(int col) const } -void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw() +void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const { using namespace boost::spirit; @@ -187,9 +187,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat double val = 0.0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; - ascii::space_type space; - static qi::double_type double_; - if (qi::phrase_parse(itr,end,double_,space,val)) + x3::ascii::space_type space; + static x3::double_type double_; + if (x3::phrase_parse(itr,end,double_,space,val)) { f.put(name,val); } @@ -199,9 +199,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat mapnik::value_integer val = 0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; - ascii::space_type space; - static qi::int_parser numeric_parser; - if (qi::phrase_parse(itr, end, numeric_parser, space, val)) + x3::ascii::space_type space; + static x3::int_parser numeric_parser; + if (x3::phrase_parse(itr, end, numeric_parser, space, val)) { f.put(name,val); } diff --git a/plugins/input/shape/dbfile.hpp b/plugins/input/shape/dbfile.hpp index 9ff022400..fec46cc96 100644 --- a/plugins/input/shape/dbfile.hpp +++ b/plugins/input/shape/dbfile.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -77,7 +77,7 @@ public: field_descriptor const& descriptor(int col) const; void move_to(int index); std::string string_value(int col) const; - void add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw(); + void add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const; private: void read_header(); int read_short(); diff --git a/plugins/input/shape/shape_datasource.cpp b/plugins/input/shape/shape_datasource.cpp index 56d7a6aae..bc52acf50 100644 --- a/plugins/input/shape/shape_datasource.cpp +++ b/plugins/input/shape/shape_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -40,7 +40,7 @@ #include #include #include -#include +#include // stl #include diff --git a/plugins/input/shape/shape_datasource.hpp b/plugins/input/shape/shape_datasource.hpp index f702036eb..ea3fb5c39 100644 --- a/plugins/input/shape/shape_datasource.hpp +++ b/plugins/input/shape/shape_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,10 +28,10 @@ #include #include #include -#include +#include #include #include -#include +#include // boost #include diff --git a/plugins/input/shape/shape_featureset.cpp b/plugins/input/shape/shape_featureset.cpp index 490fa3d5e..46e482d3d 100644 --- a/plugins/input/shape/shape_featureset.cpp +++ b/plugins/input/shape/shape_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/shape/shape_featureset.hpp b/plugins/input/shape/shape_featureset.hpp index caa962554..b1f0b9f6f 100644 --- a/plugins/input/shape/shape_featureset.hpp +++ b/plugins/input/shape/shape_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "shape_io.hpp" diff --git a/plugins/input/shape/shape_index_featureset.cpp b/plugins/input/shape/shape_index_featureset.cpp index c4b1918d8..d32bcba78 100644 --- a/plugins/input/shape/shape_index_featureset.cpp +++ b/plugins/input/shape/shape_index_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/shape/shape_index_featureset.hpp b/plugins/input/shape/shape_index_featureset.hpp index d104e0f20..660204a82 100644 --- a/plugins/input/shape/shape_index_featureset.hpp +++ b/plugins/input/shape/shape_index_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ #include #include #include -#include +#include // boost diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index b5d3776e4..cafa04a7d 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include #include #include -#include +#include using mapnik::datasource_exception; const std::string shape_io::SHP = ".shp"; diff --git a/plugins/input/shape/shape_io.hpp b/plugins/input/shape/shape_io.hpp index 1828ebd54..f85d7eed9 100644 --- a/plugins/input/shape/shape_io.hpp +++ b/plugins/input/shape/shape_io.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include #include // mapnik -#include +#include #include #include // boost diff --git a/plugins/input/shape/shape_utils.cpp b/plugins/input/shape/shape_utils.cpp index 40d8fc6c3..4a6c8acd1 100644 --- a/plugins/input/shape/shape_utils.cpp +++ b/plugins/input/shape/shape_utils.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/shape/shape_utils.hpp b/plugins/input/shape/shape_utils.hpp index edb22225b..c77625e14 100644 --- a/plugins/input/shape/shape_utils.hpp +++ b/plugins/input/shape/shape_utils.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/shape/shapefile.hpp b/plugins/input/shape/shapefile.hpp index 15e5c7757..c00ffc3e4 100644 --- a/plugins/input/shape/shapefile.hpp +++ b/plugins/input/shape/shapefile.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,7 +32,7 @@ // mapnik #include #include -#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #pragma GCC diagnostic push diff --git a/plugins/input/sqlite/sqlite_connection.hpp b/plugins/input/sqlite/sqlite_connection.hpp index c87086d78..bc3c0d89b 100644 --- a/plugins/input/sqlite/sqlite_connection.hpp +++ b/plugins/input/sqlite/sqlite_connection.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp index 28add6453..e76ef41bb 100644 --- a/plugins/input/sqlite/sqlite_datasource.cpp +++ b/plugins/input/sqlite/sqlite_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,7 +34,7 @@ #include #include #include -#include +#include // boost #include diff --git a/plugins/input/sqlite/sqlite_datasource.hpp b/plugins/input/sqlite/sqlite_datasource.hpp index eab71e9e3..e73e0c3e8 100644 --- a/plugins/input/sqlite/sqlite_datasource.hpp +++ b/plugins/input/sqlite/sqlite_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,11 +28,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include // boost #include diff --git a/plugins/input/sqlite/sqlite_featureset.cpp b/plugins/input/sqlite/sqlite_featureset.cpp index 99a44db54..9226f40d0 100644 --- a/plugins/input/sqlite/sqlite_featureset.cpp +++ b/plugins/input/sqlite/sqlite_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,15 +23,15 @@ // mapnik #include #include -#include +#include #include #include #include #include -#include +#include #include -#include -#include +#include +#include // ogr #include "sqlite_featureset.hpp" diff --git a/plugins/input/sqlite/sqlite_featureset.hpp b/plugins/input/sqlite/sqlite_featureset.hpp index dc168676e..9e2f1c20a 100644 --- a/plugins/input/sqlite/sqlite_featureset.hpp +++ b/plugins/input/sqlite/sqlite_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/sqlite/sqlite_prepared.hpp b/plugins/input/sqlite/sqlite_prepared.hpp index db1355d67..9ddecbffd 100644 --- a/plugins/input/sqlite/sqlite_prepared.hpp +++ b/plugins/input/sqlite/sqlite_prepared.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include // boost diff --git a/plugins/input/sqlite/sqlite_resultset.hpp b/plugins/input/sqlite/sqlite_resultset.hpp index 6046387f9..042e02d07 100644 --- a/plugins/input/sqlite/sqlite_resultset.hpp +++ b/plugins/input/sqlite/sqlite_resultset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/sqlite/sqlite_utils.hpp b/plugins/input/sqlite/sqlite_utils.hpp index 959e3f7c6..235b9c035 100644 --- a/plugins/input/sqlite/sqlite_utils.hpp +++ b/plugins/input/sqlite/sqlite_utils.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,8 +35,8 @@ #include #include #include -#include -#include +#include +#include #pragma GCC diagnostic push #include diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp index 67bae443b..8a16dd3e2 100644 --- a/plugins/input/topojson/topojson_datasource.cpp +++ b/plugins/input/topojson/topojson_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,10 +31,10 @@ // mapnik #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -171,25 +171,27 @@ topojson_datasource::topojson_datasource(parameters const& params) } std::string file_buffer; file_buffer.resize(file.size()); - std::fread(&file_buffer[0], file.size(), 1, file.get()); - parse_topojson(file_buffer.c_str()); + auto count = std::fread(&file_buffer[0], file.size(), 1, file.get()); + if (count == 1) parse_topojson(file_buffer.c_str()); } } -namespace { -using iterator_type = const char*; -const mapnik::topojson::topojson_grammar g; -} - template void topojson_datasource::parse_topojson(T const& buffer) { - boost::spirit::standard::space_type space; auto itr = buffer; auto end = buffer + std::strlen(buffer); - bool result = boost::spirit::qi::phrase_parse(itr, end, g, space, topo_); - if (!result) + using space_type = boost::spirit::x3::standard::space_type; + try { + boost::spirit::x3::phrase_parse(itr, end, mapnik::json::topojson_grammar(), space_type(), topo_); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + std::clog << "failed to parse TopoJSON..." << std::endl; + std::clog << ex.what() << std::endl; + std::clog << "Expected: " << ex.which(); + std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << "...\"" << std::endl; throw mapnik::datasource_exception("topojson_datasource: Failed parse TopoJSON file '" + filename_ + "'"); } diff --git a/plugins/input/topojson/topojson_datasource.hpp b/plugins/input/topojson/topojson_datasource.hpp index ebc92aea2..c9b9165ae 100644 --- a/plugins/input/topojson/topojson_datasource.hpp +++ b/plugins/input/topojson/topojson_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/topojson/topojson_featureset.cpp b/plugins/input/topojson/topojson_featureset.cpp index 36dbdf9db..2cad74123 100644 --- a/plugins/input/topojson/topojson_featureset.cpp +++ b/plugins/input/topojson/topojson_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/topojson/topojson_featureset.hpp b/plugins/input/topojson/topojson_featureset.hpp index 44f833512..f767f0881 100644 --- a/plugins/input/topojson/topojson_featureset.hpp +++ b/plugins/input/topojson/topojson_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/scripts/travis-common.sh b/scripts/travis-common.sh index 56909b79d..d3ce79f10 100644 --- a/scripts/travis-common.sh +++ b/scripts/travis-common.sh @@ -46,15 +46,6 @@ git_submodule_update () { git submodule update "$@" } -# install and call pip -pip () { - if ! which pip >/dev/null; then - easy_install --user pip && \ - export PATH="$HOME/Library/Python/2.7/bin:$PATH" - fi - command pip "$@" -} - # commit_message_contains TEXT # - returns 0 (true) if TEXT is found in commit message # - case-insensitive, plain-text search, not regex @@ -83,22 +74,16 @@ config_override () { configure () { if enabled ${COVERAGE}; then ./configure "$@" PREFIX=${PREFIX} PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \ - COVERAGE=True DEBUG=True WARNING_CXXFLAGS="-Wno-unknown-warning-option" + COVERAGE=True DEBUG=True else - ./configure "$@" PREFIX=${PREFIX} WARNING_CXXFLAGS="-Wno-unknown-warning-option" + ./configure "$@" PREFIX=${PREFIX} fi # print final config values, sorted and indented sort -sk1,1 ./config.py | sed -e 's/^/ /' } coverage () { - ./mason_packages/.link/bin/cpp-coveralls \ - --gcov ${LLVM_COV} \ - --exclude mason_packages \ - --exclude .sconf_temp --exclude benchmark --exclude deps \ - --exclude scons --exclude test --exclude demo --exclude docs \ - --exclude fonts \ - > /dev/null + ./codecov -x "llvm-cov gcov" -Z } trigger_downstream() { diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index dc2c21514..ed28335ef 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,8 +41,8 @@ #include #include #include -#include #include +#include #pragma GCC diagnostic push #include @@ -71,47 +71,44 @@ namespace mapnik template agg_renderer::agg_renderer(Map const& m, T0 & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y) : feature_style_processor(m, scale_factor), - pixmap_(pixmap), - internal_buffer_(), - current_buffer_(&pixmap), - style_level_compositing_(false), + buffers_(), + internal_buffers_(m.width(), m.height()), + inflated_buffer_(), ras_ptr(new rasterizer), gamma_method_(GAMMA_POWER), gamma_(1.0), common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor) { - setup(m); + setup(m, pixmap); } template agg_renderer::agg_renderer(Map const& m, request const& req, attributes const& vars, T0 & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y) : feature_style_processor(m, scale_factor), - pixmap_(pixmap), - internal_buffer_(), - current_buffer_(&pixmap), - style_level_compositing_(false), + buffers_(), + internal_buffers_(req.width(), req.height()), + inflated_buffer_(), ras_ptr(new rasterizer), gamma_method_(GAMMA_POWER), gamma_(1.0), common_(m, req, vars, offset_x, offset_y, req.width(), req.height(), scale_factor) { - setup(m); + setup(m, pixmap); } template agg_renderer::agg_renderer(Map const& m, T0 & pixmap, std::shared_ptr detector, double scale_factor, unsigned offset_x, unsigned offset_y) : feature_style_processor(m, scale_factor), - pixmap_(pixmap), - internal_buffer_(), - current_buffer_(&pixmap), - style_level_compositing_(false), + buffers_(), + internal_buffers_(m.width(), m.height()), + inflated_buffer_(), ras_ptr(new rasterizer), gamma_method_(GAMMA_POWER), gamma_(1.0), common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor, detector) { - setup(m); + setup(m, pixmap); } template @@ -157,9 +154,11 @@ struct setup_agg_bg_visitor }; template -void agg_renderer::setup(Map const &m) +void agg_renderer::setup(Map const &m, buffer_type & pixmap) { - mapnik::set_premultiplied_alpha(pixmap_, true); + buffers_.emplace(pixmap); + + mapnik::set_premultiplied_alpha(pixmap, true); boost::optional const& bg = m.background(); if (bg) { @@ -167,13 +166,13 @@ void agg_renderer::setup(Map const &m) { mapnik::color bg_color = *bg; bg_color.premultiply(); - mapnik::fill(pixmap_, bg_color); + mapnik::fill(pixmap, bg_color); } else { mapnik::color bg_color = *bg; bg_color.set_premultiplied(true); - mapnik::fill(pixmap_,bg_color); + mapnik::fill(pixmap, bg_color); } } @@ -182,7 +181,7 @@ void agg_renderer::setup(Map const &m) { // NOTE: marker_cache returns premultiplied image, if needed std::shared_ptr bg_marker = mapnik::marker_cache::instance().find(*image_filename,true); - setup_agg_bg_visitor visitor(pixmap_, + setup_agg_bg_visitor visitor(pixmap, common_, m.background_image_comp_op(), m.background_image_opacity()); @@ -204,7 +203,7 @@ void agg_renderer::start_map_processing(Map const& map) template void agg_renderer::end_map_processing(Map const& map) { - mapnik::demultiply_alpha(pixmap_); + mapnik::demultiply_alpha(buffers_.top().get()); MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End map processing"; } @@ -226,28 +225,44 @@ void agg_renderer::start_layer_processing(layer const& lay, box2d { common_.query_extent_.clip(*maximum_extent); } + + if (lay.comp_op() || lay.get_opacity() < 1.0) + { + buffers_.emplace(internal_buffers_.push()); + set_premultiplied_alpha(buffers_.top().get(), true); + } + else + { + buffers_.emplace(buffers_.top().get()); + } } template -void agg_renderer::end_layer_processing(layer const&) +void agg_renderer::end_layer_processing(layer const& lyr) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End layer processing"; + + buffer_type & current_buffer = buffers_.top().get(); + buffers_.pop(); + buffer_type & previous_buffer = buffers_.top().get(); + + if (¤t_buffer != &previous_buffer) + { + composite_mode_e comp_op = lyr.comp_op() ? *lyr.comp_op() : src_over; + composite(previous_buffer, current_buffer, + comp_op, lyr.get_opacity(), + -common_.t_.offset(), + -common_.t_.offset()); + internal_buffers_.pop(); + } } template void agg_renderer::start_style_processing(feature_type_style const& st) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Start processing style"; - if (st.comp_op() || st.image_filters().size() > 0 || st.get_opacity() < 1) - { - style_level_compositing_ = true; - } - else - { - style_level_compositing_ = false; - } - if (style_level_compositing_) + if (st.comp_op() || st.image_filters().size() > 0 || st.get_opacity() < 1) { if (st.image_filters_inflate()) { @@ -266,81 +281,81 @@ void agg_renderer::start_style_processing(feature_type_style const& st) unsigned target_width = common_.width_ + (offset * 2); unsigned target_height = common_.height_ + (offset * 2); ras_ptr->clip_box(-int(offset*2),-int(offset*2),target_width,target_height); - if (!internal_buffer_ || - (internal_buffer_->width() < target_width || - internal_buffer_->height() < target_height)) + if (!inflated_buffer_ || + (inflated_buffer_->width() < target_width || + inflated_buffer_->height() < target_height)) { - internal_buffer_ = std::make_shared(target_width,target_height); + inflated_buffer_ = std::make_unique(target_width, target_height); } else { - mapnik::fill(*internal_buffer_, 0); // fill with transparent colour + mapnik::fill(*inflated_buffer_, 0); // fill with transparent colour } + buffers_.emplace(*inflated_buffer_); } else { - if (!internal_buffer_) - { - internal_buffer_ = std::make_shared(common_.width_,common_.height_); - } - else - { - mapnik::fill(*internal_buffer_, 0); // fill with transparent colour - } + buffers_.emplace(internal_buffers_.push()); common_.t_.set_offset(0); ras_ptr->clip_box(0,0,common_.width_,common_.height_); } - current_buffer_ = internal_buffer_.get(); - set_premultiplied_alpha(*current_buffer_,true); + set_premultiplied_alpha(buffers_.top().get(), true); } else { common_.t_.set_offset(0); ras_ptr->clip_box(0,0,common_.width_,common_.height_); - current_buffer_ = &pixmap_; + buffers_.emplace(buffers_.top().get()); } } template void agg_renderer::end_style_processing(feature_type_style const& st) { - if (style_level_compositing_) + buffer_type & current_buffer = buffers_.top().get(); + buffers_.pop(); + buffer_type & previous_buffer = buffers_.top().get(); + if (¤t_buffer != &previous_buffer) { bool blend_from = false; if (st.image_filters().size() > 0) { blend_from = true; - mapnik::filter::filter_visitor visitor(*current_buffer_, common_.scale_factor_); + mapnik::filter::filter_visitor visitor(current_buffer, common_.scale_factor_); for (mapnik::filter::filter_type const& filter_tag : st.image_filters()) { util::apply_visitor(visitor, filter_tag); } - mapnik::premultiply_alpha(*current_buffer_); + mapnik::premultiply_alpha(current_buffer); } if (st.comp_op()) { - composite(pixmap_, *current_buffer_, + composite(previous_buffer, current_buffer, *st.comp_op(), st.get_opacity(), -common_.t_.offset(), -common_.t_.offset()); } else if (blend_from || st.get_opacity() < 1.0) { - composite(pixmap_, *current_buffer_, + composite(previous_buffer, current_buffer, src_over, st.get_opacity(), -common_.t_.offset(), -common_.t_.offset()); } + if (¤t_buffer == &internal_buffers_.top()) + { + internal_buffers_.pop(); + } } if (st.direct_image_filters().size() > 0) { // apply any 'direct' image filters - mapnik::filter::filter_visitor visitor(pixmap_, common_.scale_factor_); + mapnik::filter::filter_visitor visitor(previous_buffer, common_.scale_factor_); for (mapnik::filter::filter_type const& filter_tag : st.direct_image_filters()) { util::apply_visitor(visitor, filter_tag); } - mapnik::premultiply_alpha(pixmap_); + mapnik::premultiply_alpha(previous_buffer); } MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End processing style"; } @@ -349,7 +364,7 @@ template struct agg_render_marker_visitor { agg_render_marker_visitor(renderer_common & common, - buffer_type * current_buffer, + buffer_type & current_buffer, std::unique_ptr const& ras_ptr, gamma_method_enum & gamma_method, double & gamma, @@ -377,7 +392,6 @@ struct agg_render_marker_visitor using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; using renderer_type = agg::renderer_scanline_aa_solid; - using svg_attribute_type = agg::pod_bvector; ras_ptr_->reset(); if (gamma_method_ != GAMMA_POWER || gamma_ != 1.0) @@ -387,10 +401,10 @@ struct agg_render_marker_visitor gamma_ = 1.0; } agg::scanline_u8 sl; - agg::rendering_buffer buf(current_buffer_->bytes(), - current_buffer_->width(), - current_buffer_->height(), - current_buffer_->row_size()); + agg::rendering_buffer buf(current_buffer_.bytes(), + current_buffer_.width(), + current_buffer_.height(), + current_buffer_.row_size()); pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast(comp_op_)); renderer_base renb(pixf); @@ -436,10 +450,10 @@ struct agg_render_marker_visitor gamma_ = 1.0; } agg::scanline_u8 sl; - agg::rendering_buffer buf(current_buffer_->bytes(), - current_buffer_->width(), - current_buffer_->height(), - current_buffer_->row_size()); + agg::rendering_buffer buf(current_buffer_.bytes(), + current_buffer_.width(), + current_buffer_.height(), + current_buffer_.row_size()); pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast(comp_op_)); renderer_base renb(pixf); @@ -454,7 +468,7 @@ struct agg_render_marker_visitor { double cx = 0.5 * width; double cy = 0.5 * height; - composite(*current_buffer_, marker.get_data(), + composite(current_buffer_, marker.get_data(), comp_op_, opacity_, std::floor(pos_.x - cx + .5), std::floor(pos_.y - cy + .5)); @@ -518,7 +532,7 @@ struct agg_render_marker_visitor private: renderer_common & common_; - buffer_type * current_buffer_; + buffer_type & current_buffer_; std::unique_ptr const& ras_ptr_; gamma_method_enum & gamma_method_; double & gamma_; @@ -537,7 +551,7 @@ void agg_renderer::render_marker(pixel_position const& pos, composite_mode_e comp_op) { agg_render_marker_visitor visitor(common_, - current_buffer_, + buffers_.top().get(), ras_ptr, gamma_method_, gamma_, @@ -551,23 +565,24 @@ void agg_renderer::render_marker(pixel_position const& pos, template bool agg_renderer::painted() { - return pixmap_.painted(); + return buffers_.top().get().painted(); } template void agg_renderer::painted(bool painted) { - pixmap_.painted(painted); + buffers_.top().get().painted(painted); } template void agg_renderer::debug_draw_box(box2d const& box, double x, double y, double angle) { - agg::rendering_buffer buf(current_buffer_->bytes(), - current_buffer_->width(), - current_buffer_->height(), - current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), + current_buffer.width(), + current_buffer.height(), + current_buffer.row_size()); debug_draw_box(buf, box, x, y, angle); } @@ -620,13 +635,13 @@ void agg_renderer::draw_geo_extent(box2d const& extent, mapnik::c unsigned rgba = color.rgba(); for (double x=x0; x +#include #pragma GCC diagnostic push #include @@ -61,7 +62,8 @@ void agg_renderer::process(building_symbolizer const& sym, using ren_base = agg::renderer_base; using renderer = agg::renderer_scanline_aa_solid; - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); agg::pixfmt_rgba32_pre pixf(buf); ren_base renb(pixf); diff --git a/src/agg/process_debug_symbolizer.cpp b/src/agg/process_debug_symbolizer.cpp index 137c2457d..7d0feed40 100644 --- a/src/agg/process_debug_symbolizer.cpp +++ b/src/agg/process_debug_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -234,7 +234,7 @@ void agg_renderer::process(debug_symbolizer const& sym, if (mode == DEBUG_SYM_MODE_RINGS) { - RingRenderer renderer(*ras_ptr,*current_buffer_,common_.t_,prj_trans); + RingRenderer renderer(*ras_ptr, buffers_.top().get(), common_.t_, prj_trans); render_ring_visitor apply(renderer); mapnik::util::apply_visitor(apply,feature.get_geometry()); } @@ -242,13 +242,13 @@ void agg_renderer::process(debug_symbolizer const& sym, { for (auto const& n : *common_.detector_) { - draw_rect(pixmap_, n.get().box); + draw_rect(buffers_.top().get(), n.get().box); } } else if (mode == DEBUG_SYM_MODE_VERTEX) { using apply_vertex_mode = apply_vertex_mode; - apply_vertex_mode apply(pixmap_, common_.t_, prj_trans); + apply_vertex_mode apply(buffers_.top().get(), common_.t_, prj_trans); util::apply_visitor(geometry::vertex_processor(apply), feature.get_geometry()); } } diff --git a/src/agg/process_dot_symbolizer.cpp b/src/agg/process_dot_symbolizer.cpp index cfb58c6e9..7f5291806 100644 --- a/src/agg/process_dot_symbolizer.cpp +++ b/src/agg/process_dot_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -119,7 +119,8 @@ void agg_renderer::process(dot_symbolizer const& sym, gamma_method_ = GAMMA_POWER; gamma_ = 1.0; } - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(),current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); using blender_type = agg::comp_op_adaptor_rgba_pre; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; diff --git a/src/agg/process_group_symbolizer.cpp b/src/agg/process_group_symbolizer.cpp index 6ba5605dc..486d714f2 100644 --- a/src/agg/process_group_symbolizer.cpp +++ b/src/agg/process_group_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -61,10 +61,10 @@ struct thunk_renderer : render_thunk_list_dispatch thunk_renderer(renderer_type &ren, std::unique_ptr const& ras_ptr, - buffer_type *buf, + buffer_type & buf, renderer_common &common) : ren_(ren), ras_ptr_(ras_ptr), buf_(buf), common_(common), - tex_(*buf, HALO_RASTERIZER_FULL, src_over, src_over, + tex_(buf, HALO_RASTERIZER_FULL, src_over, src_over, common.scale_factor_, common.font_manager_.get_stroker()) {} @@ -75,13 +75,12 @@ struct thunk_renderer : render_thunk_list_dispatch using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; using renderer_type = agg::renderer_scanline_aa_solid; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg::svg_renderer_agg; ras_ptr_->reset(); - buf_type render_buffer(buf_->bytes(), buf_->width(), buf_->height(), buf_->row_size()); + buf_type render_buffer(buf_.bytes(), buf_.width(), buf_.height(), buf_.row_size()); pixfmt_comp_type pixf(render_buffer); pixf.comp_op(static_cast(thunk.comp_op_)); renderer_base renb(pixf); @@ -102,7 +101,7 @@ struct thunk_renderer : render_thunk_list_dispatch using renderer_base = agg::renderer_base; ras_ptr_->reset(); - buf_type render_buffer(buf_->bytes(), buf_->width(), buf_->height(), buf_->row_size()); + buf_type render_buffer(buf_.bytes(), buf_.width(), buf_.height(), buf_.row_size()); pixfmt_comp_type pixf(render_buffer); pixf.comp_op(static_cast(thunk.comp_op_)); renderer_base renb(pixf); @@ -136,7 +135,7 @@ struct thunk_renderer : render_thunk_list_dispatch private: renderer_type &ren_; std::unique_ptr const& ras_ptr_; - buffer_type *buf_; + buffer_type & buf_; renderer_common &common_; text_renderer_type tex_; }; @@ -146,7 +145,7 @@ void agg_renderer::process(group_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { - thunk_renderer ren(*this, ras_ptr, current_buffer_, common_); + thunk_renderer ren(*this, ras_ptr, buffers_.top().get(), common_); render_group_symbolizer( sym, feature, common_.vars_, prj_trans, clipping_extent(common_), common_, diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp index dbbb7f26d..5e304cb8f 100644 --- a/src/agg/process_line_pattern_symbolizer.cpp +++ b/src/agg/process_line_pattern_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -61,14 +61,12 @@ template struct agg_renderer_process_visitor_l { agg_renderer_process_visitor_l(renderer_common & common, - buffer_type & pixmap, - buffer_type * current_buffer, + buffer_type & current_buffer, std::unique_ptr const& ras_ptr, line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) : common_(common), - pixmap_(pixmap), current_buffer_(current_buffer), ras_ptr_(ras_ptr), sym_(sym), @@ -79,83 +77,26 @@ struct agg_renderer_process_visitor_l void operator() (marker_svg const& marker) const { - using color = agg::rgba8; - using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; - using pattern_filter_type = agg::pattern_filter_bilinear_rgba8; - using pattern_type = agg::line_image_pattern; - using pixfmt_type = agg::pixfmt_custom_blend_rgba; - using renderer_base = agg::renderer_base; - using renderer_type = agg::renderer_outline_image; - using rasterizer_type = agg::rasterizer_outline_aa; - - value_double opacity = get(sym_, feature_, common_.vars_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional(sym_, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_); mapnik::box2d const& bbox_image = marker.get_data()->bounding_box() * image_tr; image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern(*ras_ptr_, marker, image_tr, 1.0, image); - - value_bool clip = get(sym_, feature_, common_.vars_); - value_double offset = get(sym_, feature_, common_.vars_); - value_double simplify_tolerance = get(sym_, feature_, common_.vars_); - value_double smooth = get(sym_, feature_, common_.vars_); - - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); - pixfmt_type pixf(buf); - pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); - renderer_base ren_base(pixf); - agg::pattern_filter_bilinear_rgba8 filter; - - pattern_source source(image, opacity); - pattern_type pattern (filter,source); - renderer_type ren(ren_base, pattern); - double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0); - int rast_clip_padding = static_cast(std::round(half_stroke)); - ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding); - rasterizer_type ras(ren); - - agg::trans_affine tr; - auto transform = get_optional(sym_, keys::geometry_transform); - if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_); - - box2d clip_box = clipping_extent(common_); - if (clip) - { - double padding = (double)(common_.query_extent_.width()/pixmap_.width()); - if (half_stroke > 1) - padding *= half_stroke; - if (std::fabs(offset) > 0) - padding *= std::fabs(offset) * 1.2; - padding *= common_.scale_factor_; - clip_box.pad(padding); - } - using vertex_converter_type = vertex_converter; - - vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_); - - if (clip) converter.set(); - converter.set(); //always transform - if (simplify_tolerance > 0.0) converter.set(); // optional simplify converter - if (std::fabs(offset) > 0.0) converter.set(); // parallel offset - converter.set(); // optional affine transform - if (smooth > 0.0) converter.set(); // optional smooth converter - - using apply_vertex_converter_type = detail::apply_vertex_converter; - using vertex_processor_type = geometry::vertex_processor; - apply_vertex_converter_type apply(converter, ras); - mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry()); + render(image, marker.width(), marker.height()); } void operator() (marker_rgba8 const& marker) const { - using color = agg::rgba8; + render(marker.get_data(), marker.width(), marker.height()); + } + +private: + void render(mapnik::image_rgba8 const& marker, double width, double height) const + { + using col = agg::rgba8; using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; + using blender_type = agg::comp_op_adaptor_rgba_pre; using pattern_filter_type = agg::pattern_filter_bilinear_rgba8; using pattern_type = agg::line_image_pattern; using pixfmt_type = agg::pixfmt_custom_blend_rgba; @@ -164,24 +105,22 @@ struct agg_renderer_process_visitor_l using rasterizer_type = agg::rasterizer_outline_aa; value_double opacity = get(sym_, feature_, common_.vars_); - mapnik::image_rgba8 const& image = marker.get_data(); - value_bool clip = get(sym_, feature_, common_.vars_); value_double offset = get(sym_, feature_, common_.vars_); value_double simplify_tolerance = get(sym_, feature_, common_.vars_); value_double smooth = get(sym_, feature_, common_.vars_); - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(), - current_buffer_->height(), current_buffer_->row_size()); + agg::rendering_buffer buf(current_buffer_.bytes(), current_buffer_.width(), + current_buffer_.height(), current_buffer_.row_size()); pixfmt_type pixf(buf); pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); renderer_base ren_base(pixf); agg::pattern_filter_bilinear_rgba8 filter; - pattern_source source(image, opacity); + pattern_source source(marker, opacity); pattern_type pattern (filter,source); renderer_type ren(ren_base, pattern); - double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0); + double half_stroke = std::max(width / 2.0, height / 2.0); int rast_clip_padding = static_cast(std::round(half_stroke)); ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding); rasterizer_type ras(ren); @@ -193,7 +132,7 @@ struct agg_renderer_process_visitor_l box2d clip_box = clipping_extent(common_); if (clip) { - double padding = (double)(common_.query_extent_.width()/pixmap_.width()); + double padding = (double)(common_.query_extent_.width() / common_.width_); if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) @@ -221,10 +160,8 @@ struct agg_renderer_process_visitor_l mapnik::util::apply_visitor(vertex_processor_type(apply), feature_.get_geometry()); } - private: renderer_common & common_; - buffer_type & pixmap_; - buffer_type * current_buffer_; + buffer_type & current_buffer_; std::unique_ptr const& ras_ptr_; line_pattern_symbolizer const& sym_; mapnik::feature_impl & feature_; @@ -249,8 +186,7 @@ void agg_renderer::process(line_pattern_symbolizer const& sym, } std::shared_ptr marker = marker_cache::instance().find(filename, true); agg_renderer_process_visitor_l visitor(common_, - pixmap_, - current_buffer_, + buffers_.top().get(), ras_ptr, sym, feature, diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index 9bace2539..5d8ebf073 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include @@ -112,7 +112,8 @@ void agg_renderer::process(line_symbolizer const& sym, gamma_ = gamma; } - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); using color_type = agg::rgba8; using order_type = agg::order_rgba; @@ -139,7 +140,7 @@ void agg_renderer::process(line_symbolizer const& sym, line_rasterizer_enum rasterizer_e = get(sym, feature, common_.vars_); if (clip) { - double padding = static_cast(common_.query_extent_.width()/pixmap_.width()); + double padding = static_cast(common_.query_extent_.width() / common_.width_); double half_stroke = 0.5 * width; if (half_stroke > 1) { diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 3fc122dcb..8546f042b 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -56,7 +56,6 @@ struct agg_markers_renderer_context : markers_renderer_context { using renderer_base = typename SvgRenderer::renderer_base; using vertex_source_type = typename SvgRenderer::vertex_source_type; - using attribute_source_type = typename SvgRenderer::attribute_source_type; using pixfmt_type = typename renderer_base::pixfmt_type; agg_markers_renderer_context(symbolizer_base const& sym, @@ -117,7 +116,6 @@ void agg_renderer::process(markers_symbolizer const& sym, using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; using renderer_type = agg::renderer_scanline_aa_solid; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg_renderer_agg::process(markers_symbolizer const& sym, gamma_ = gamma; } - buf_type render_buffer(current_buffer_->bytes(), current_buffer_->width(), current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + buf_type render_buffer(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); box2d clip_box = clipping_extent(common_); - using context_type = detail::agg_markers_renderer_context; - context_type renderer_context(sym, feature, common_.vars_, render_buffer, *ras_ptr); + renderer_context_type renderer_context(sym, feature, common_.vars_, render_buffer, *ras_ptr); render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, renderer_context); diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp index bb54db51c..2ed9675ab 100644 --- a/src/agg/process_point_symbolizer.cpp +++ b/src/agg/process_point_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index f2a0159d1..935e5294a 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -62,7 +62,7 @@ template struct agg_renderer_process_visitor_p { agg_renderer_process_visitor_p(renderer_common & common, - buffer_type * current_buffer, + buffer_type & current_buffer, std::unique_ptr const& ras_ptr, gamma_method_enum & gamma_method, double & gamma, @@ -88,125 +88,19 @@ struct agg_renderer_process_visitor_p mapnik::box2d const& bbox_image = marker.get_data()->bounding_box() * image_tr; mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern(*ras_ptr_, marker, image_tr, 1.0, image); - - agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(), - current_buffer_->height(), current_buffer_->row_size()); - ras_ptr_->reset(); - value_double gamma = get(sym_, feature_, common_.vars_); - gamma_method_enum gamma_method = get(sym_, feature_, common_.vars_); - if (gamma != gamma_ || gamma_method != gamma_method_) - { - set_gamma_method(ras_ptr_, gamma, gamma_method); - gamma_method_ = gamma_method; - gamma_ = gamma; - } - - value_bool clip = get(sym_, feature_, common_.vars_); - value_double opacity = get(sym_, feature_, common_.vars_); - value_double simplify_tolerance = get(sym_, feature_, common_.vars_); - value_double smooth = get(sym_, feature_, common_.vars_); - - box2d clip_box = clipping_extent(common_); - - using color = agg::rgba8; - using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; - using pixfmt_type = agg::pixfmt_custom_blend_rgba; - - using wrap_x_type = agg::wrap_mode_repeat; - using wrap_y_type = agg::wrap_mode_repeat; - using img_source_type = agg::image_accessor_wrap; - - using span_gen_type = agg::span_pattern_rgba; - using ren_base = agg::renderer_base; - - using renderer_type = agg::renderer_scanline_aa_alpha, - span_gen_type>; - - pixfmt_type pixf(buf); - pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); - ren_base renb(pixf); - - unsigned w = image.width(); - unsigned h = image.height(); - agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4); - agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf); - img_source_type img_src(pixf_pattern); - - pattern_alignment_enum alignment = get(sym_, feature_, common_.vars_); - unsigned offset_x=0; - unsigned offset_y=0; - - if (alignment == LOCAL_ALIGNMENT) - { - double x0 = 0; - double y0 = 0; - using apply_local_alignment = detail::apply_local_alignment; - apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0); - util::apply_visitor(geometry::vertex_processor(apply), feature_.get_geometry()); - offset_x = unsigned(current_buffer_->width() - x0); - offset_y = unsigned(current_buffer_->height() - y0); - } - - span_gen_type sg(img_src, offset_x, offset_y); - - agg::span_allocator sa; - renderer_type rp(renb,sa, sg, unsigned(opacity * 255)); - - agg::trans_affine tr; - auto transform = get_optional(sym_, keys::geometry_transform); - if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_); - using vertex_converter_type = vertex_converter; - - vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_); - - - if (prj_trans_.equal() && clip) converter.set(); - converter.set(); //always transform - converter.set(); // optional affine transform - if (simplify_tolerance > 0.0) converter.set(); // optional simplify converter - if (smooth > 0.0) converter.set(); // optional smooth converter - - using apply_vertex_converter_type = detail::apply_vertex_converter; - using vertex_processor_type = geometry::vertex_processor; - apply_vertex_converter_type apply(converter, *ras_ptr_); - mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry()); - agg::scanline_u8 sl; - ras_ptr_->filling_rule(agg::fill_even_odd); - agg::render_scanlines(*ras_ptr_, sl, rp); + render(image); } void operator() (marker_rgba8 const& marker) const { - using color = agg::rgba8; - using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; - using pixfmt_type = agg::pixfmt_custom_blend_rgba; + render(marker.get_data()); + } - using wrap_x_type = agg::wrap_mode_repeat; - using wrap_y_type = agg::wrap_mode_repeat; - using img_source_type = agg::image_accessor_wrap; - - using span_gen_type = agg::span_pattern_rgba; - using ren_base = agg::renderer_base; - - using renderer_type = agg::renderer_scanline_aa_alpha, - span_gen_type>; - mapnik::image_rgba8 const& image = marker.get_data(); - - - agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(), - current_buffer_->height(), current_buffer_->row_size()); +private: + void render(mapnik::image_rgba8 const& image) const + { + agg::rendering_buffer buf(current_buffer_.bytes(), current_buffer_.width(), + current_buffer_.height(), current_buffer_.row_size()); ras_ptr_->reset(); value_double gamma = get(sym_, feature_, common_.vars_); gamma_method_enum gamma_method = get(sym_, feature_, common_.vars_); @@ -224,6 +118,23 @@ struct agg_renderer_process_visitor_p box2d clip_box = clipping_extent(common_); + using col = agg::rgba8; + using order = agg::order_rgba; + using blender_type = agg::comp_op_adaptor_rgba_pre; + using pixfmt_type = agg::pixfmt_custom_blend_rgba; + + using wrap_x_type = agg::wrap_mode_repeat; + using wrap_y_type = agg::wrap_mode_repeat; + using img_source_type = agg::image_accessor_wrap; + + using span_gen_type = agg::span_pattern_rgba; + using ren_base = agg::renderer_base; + + using renderer_type = agg::renderer_scanline_aa_alpha, + span_gen_type>; pixfmt_type pixf(buf); pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); @@ -247,8 +158,8 @@ struct agg_renderer_process_visitor_p apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0); util::apply_visitor(geometry::vertex_processor(apply), feature_.get_geometry()); - offset_x = unsigned(current_buffer_->width() - x0); - offset_y = unsigned(current_buffer_->height() - y0); + offset_x = unsigned(current_buffer_.width() - x0); + offset_y = unsigned(current_buffer_.height() - y0); } span_gen_type sg(img_src, offset_x, offset_y); @@ -282,9 +193,8 @@ struct agg_renderer_process_visitor_p agg::render_scanlines(*ras_ptr_, sl, rp); } -private: renderer_common & common_; - buffer_type * current_buffer_; + buffer_type & current_buffer_; std::unique_ptr const& ras_ptr_; gamma_method_enum & gamma_method_; double & gamma_; @@ -302,7 +212,7 @@ void agg_renderer::process(polygon_pattern_symbolizer const& sym, if (filename.empty()) return; std::shared_ptr marker = marker_cache::instance().find(filename, true); agg_renderer_process_visitor_p visitor(common_, - current_buffer_, + buffers_.top().get(), ras_ptr, gamma_method_, gamma_, diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index bd2d2bc15..a3cf32fe0 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -63,9 +63,10 @@ void agg_renderer::process(polygon_symbolizer const& sym, gamma_ = gamma; } - box2d clip_box = clipping_extent(common_); - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); + box2d clip_box = clipping_extent(common_); render_polygon_symbolizer( sym, feature, prj_trans, common_, clip_box, *ras_ptr, [&](color const &fill, double opacity) { diff --git a/src/agg/process_raster_symbolizer.cpp b/src/agg/process_raster_symbolizer.cpp index 746a5cc2b..ad3581065 100644 --- a/src/agg/process_raster_symbolizer.cpp +++ b/src/agg/process_raster_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -55,7 +55,7 @@ void agg_renderer::process(raster_symbolizer const& sym, sym, feature, prj_trans, common_, [&](image_rgba8 const & target, composite_mode_e comp_op, double opacity, int start_x, int start_y) { - composite(*current_buffer_, target, + composite(buffers_.top().get(), target, comp_op, opacity, start_x, start_y); } ); diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp index 3d28eff60..e331121e9 100644 --- a/src/agg/process_shield_symbolizer.cpp +++ b/src/agg/process_shield_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,7 +51,7 @@ void agg_renderer::process(shield_symbolizer const& sym, halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer, feature, common_.vars_, HALO_RASTERIZER_FULL); composite_mode_e comp_op = get(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e halo_comp_op = get(sym, keys::halo_comp_op, feature, common_.vars_, src_over); - agg_text_renderer ren(*current_buffer_, + agg_text_renderer ren(buffers_.top().get(), halo_rasterizer, comp_op, halo_comp_op, diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index 685b66c95..afb6c85a3 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -52,7 +52,7 @@ void agg_renderer::process(text_symbolizer const& sym, halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer,feature, common_.vars_, HALO_RASTERIZER_FULL); composite_mode_e comp_op = get(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e halo_comp_op = get(sym, keys::halo_comp_op, feature, common_.vars_, src_over); - agg_text_renderer ren(*current_buffer_, + agg_text_renderer ren(buffers_.top().get(), halo_rasterizer, comp_op, halo_comp_op, diff --git a/src/build.py b/src/build.py index 6dd0f24a9..00c9134a4 100644 --- a/src/build.py +++ b/src/build.py @@ -152,27 +152,31 @@ else: # unix, non-macos source = Split( """ - expression_grammar.cpp + expression_grammar_x3.cpp fs.cpp request.cpp well_known_srs.cpp params.cpp - image_filter_types.cpp - image_filter_grammar.cpp + parse_image_filters.cpp + generate_image_filters.cpp + image_filter_grammar_x3.cpp color.cpp - conversions.cpp + conversions_numeric.cpp + conversions_string.cpp image_copy.cpp image_compositing.cpp image_scaling.cpp - box2d.cpp datasource_cache.cpp datasource_cache_static.cpp debug.cpp - geometry_reprojection.cpp + geometry/box2d.cpp + geometry/reprojection.cpp + geometry/envelope.cpp expression_node.cpp expression_string.cpp expression.cpp transform_expression.cpp + transform_expression_grammar_x3.cpp feature_kv_iterator.cpp feature_style_processor.cpp feature_type_style.cpp @@ -181,6 +185,7 @@ source = Split( font_set.cpp function_call.cpp gradient.cpp + path_expression_grammar_x3.cpp parse_path.cpp image_reader.cpp cairo_io.cpp @@ -199,8 +204,6 @@ source = Split( load_map.cpp palette.cpp marker_helpers.cpp - transform_expression_grammar.cpp - geometry_envelope.cpp plugin.cpp rule.cpp save_map.cpp @@ -223,8 +226,9 @@ source = Split( svg/svg_path_parser.cpp svg/svg_points_parser.cpp svg/svg_transform_parser.cpp + svg/svg_path_grammar_x3.cpp warp.cpp - css_color_grammar.cpp + css_color_grammar_x3.cpp vertex_cache.cpp vertex_adapters.cpp text/font_library.cpp diff --git a/src/cairo/cairo_context.cpp b/src/cairo/cairo_context.cpp index cb9216df4..3dae97105 100644 --- a/src/cairo/cairo_context.cpp +++ b/src/cairo/cairo_context.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/cairo/cairo_render_vector.cpp b/src/cairo/cairo_render_vector.cpp index 160002dd2..f1779d96e 100644 --- a/src/cairo/cairo_render_vector.cpp +++ b/src/cairo/cairo_render_vector.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,16 +33,16 @@ namespace mapnik { void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path, - agg::pod_bvector const & attributes, + agg::pod_bvector const & attrs, box2d const& bbox, agg::trans_affine const& tr, double opacity) { using namespace mapnik::svg; agg::trans_affine transform; - for(unsigned i = 0; i < attributes.size(); ++i) + for(unsigned i = 0; i < attrs.size(); ++i) { - mapnik::svg::path_attributes const& attr = attributes[i]; + mapnik::svg::path_attributes const& attr = attrs[i]; if (!attr.visibility_flag) continue; cairo_save_restore guard(context); diff --git a/src/cairo/cairo_renderer.cpp b/src/cairo/cairo_renderer.cpp index 2f845a53a..43c3ffef4 100644 --- a/src/cairo/cairo_renderer.cpp +++ b/src/cairo/cairo_renderer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -188,12 +188,25 @@ void cairo_renderer::start_layer_processing(layer const& lay, box2d c common_.detector_->clear(); } common_.query_extent_ = query_extent; + + if (lay.comp_op() || lay.get_opacity() < 1.0) + { + context_.push_group(); + } } template -void cairo_renderer::end_layer_processing(layer const&) +void cairo_renderer::end_layer_processing(layer const& lay) { MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer: End layer processing"; + + if (lay.comp_op() || lay.get_opacity() < 1.0) + { + context_.pop_group(); + composite_mode_e comp_op = lay.comp_op() ? *lay.comp_op() : src_over; + context_.set_operator(comp_op); + context_.paint(lay.get_opacity()); + } } template @@ -254,11 +267,11 @@ struct cairo_render_marker_visitor marker_tr *= tr_; } marker_tr *= agg::trans_affine_scaling(common_.scale_factor_); - agg::pod_bvector const & attributes = vmarker->attributes(); + agg::pod_bvector const & attrs = vmarker->attributes(); svg::vertex_stl_adapter stl_storage(vmarker->source()); svg::svg_path_adapter svg_path(stl_storage); marker_tr.translate(pos_.x, pos_.y); - render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity_); + render_vector_marker(context_, svg_path, attrs, bbox, marker_tr, opacity_); } } diff --git a/src/cairo/process_building_symbolizer.cpp b/src/cairo/process_building_symbolizer.cpp index 544414374..af305a2e6 100644 --- a/src/cairo/process_building_symbolizer.cpp +++ b/src/cairo/process_building_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,6 +34,7 @@ // stl #include +#include namespace mapnik { diff --git a/src/cairo/process_debug_symbolizer.cpp b/src/cairo/process_debug_symbolizer.cpp index 8c78a82b5..627c4586f 100644 --- a/src/cairo/process_debug_symbolizer.cpp +++ b/src/cairo/process_debug_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/cairo/process_group_symbolizer.cpp b/src/cairo/process_group_symbolizer.cpp index 0c35ba0ec..fa7b1e628 100644 --- a/src/cairo/process_group_symbolizer.cpp +++ b/src/cairo/process_group_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,6 +32,8 @@ // mapnik symbolizer generics #include +#include + namespace mapnik { diff --git a/src/cairo/process_line_pattern_symbolizer.cpp b/src/cairo/process_line_pattern_symbolizer.cpp index f53d850a6..65ec43500 100644 --- a/src/cairo/process_line_pattern_symbolizer.cpp +++ b/src/cairo/process_line_pattern_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +35,8 @@ #include #include +#include + namespace mapnik { diff --git a/src/cairo/process_line_symbolizer.cpp b/src/cairo/process_line_symbolizer.cpp index ed64d5c01..6a798582e 100644 --- a/src/cairo/process_line_symbolizer.cpp +++ b/src/cairo/process_line_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +29,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/src/cairo/process_markers_symbolizer.cpp b/src/cairo/process_markers_symbolizer.cpp index 73b84ecb7..e598b0cbd 100644 --- a/src/cairo/process_markers_symbolizer.cpp +++ b/src/cairo/process_markers_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -76,8 +76,8 @@ void cairo_renderer::process(markers_symbolizer const& sym, context_.set_operator(comp_op); box2d clip_box = common_.query_extent_; - using context_type = detail::cairo_markers_renderer_context; - context_type renderer_context(context_); + using renderer_context_type = detail::cairo_markers_renderer_context; + renderer_context_type renderer_context(context_); render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, diff --git a/src/cairo/process_point_symbolizer.cpp b/src/cairo/process_point_symbolizer.cpp index b0ffefb80..a9ee159d1 100644 --- a/src/cairo/process_point_symbolizer.cpp +++ b/src/cairo/process_point_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/cairo/process_polygon_pattern_symbolizer.cpp b/src/cairo/process_polygon_pattern_symbolizer.cpp index 4e21234b8..4578cac5a 100644 --- a/src/cairo/process_polygon_pattern_symbolizer.cpp +++ b/src/cairo/process_polygon_pattern_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/cairo/process_polygon_symbolizer.cpp b/src/cairo/process_polygon_symbolizer.cpp index b2558a46a..360b28d3f 100644 --- a/src/cairo/process_polygon_symbolizer.cpp +++ b/src/cairo/process_polygon_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/cairo/process_raster_symbolizer.cpp b/src/cairo/process_raster_symbolizer.cpp index 2b6fdc5c2..bd297ec6d 100644 --- a/src/cairo/process_raster_symbolizer.cpp +++ b/src/cairo/process_raster_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,6 +32,8 @@ // mapnik symbolizer generics #include +#include + namespace mapnik { diff --git a/src/cairo/process_text_symbolizer.cpp b/src/cairo/process_text_symbolizer.cpp index 2d34e213c..548c2bf94 100644 --- a/src/cairo/process_text_symbolizer.cpp +++ b/src/cairo/process_text_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/cairo_io.cpp b/src/cairo_io.cpp index 96152cc92..30f54d8f0 100644 --- a/src/cairo_io.cpp +++ b/src/cairo_io.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/color.cpp b/src/color.cpp index 1804d5107..325f690f5 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/color_factory.cpp b/src/color_factory.cpp index dc54e89e5..e3607fa26 100644 --- a/src/color_factory.cpp +++ b/src/color_factory.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,21 +24,20 @@ #include #include #include -#include +#include namespace mapnik { color parse_color(std::string const& str) { // TODO - early return for @color? - static const css_color_grammar g; + auto const& grammar = mapnik::color_grammar(); color c; std::string::const_iterator first = str.begin(); std::string::const_iterator last = str.end(); - boost::spirit::ascii::space_type space; - bool result = boost::spirit::qi::phrase_parse(first, last, g, - space, - c); + using namespace boost::spirit::x3::ascii; + + bool result = boost::spirit::x3::phrase_parse(first, last, grammar, space, c); if (result && (first == last)) { return c; diff --git a/src/config_error.cpp b/src/config_error.cpp index 8de797072..b5b069ffa 100644 --- a/src/config_error.cpp +++ b/src/config_error.cpp @@ -37,7 +37,7 @@ config_error::config_error(std::string const& what, { } -char const* config_error::what() const throw() +char const* config_error::what() const noexcept { msg_ = what_; if (!node_name_.empty()) diff --git a/src/conversions.cpp b/src/conversions.cpp deleted file mode 100644 index 04bfc5789..000000000 --- a/src/conversions.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include - -#include -#include - -// karma is used by default -#define MAPNIK_KARMA_TO_STRING - -#pragma GCC diagnostic push -#include -#include -#ifdef MAPNIK_KARMA_TO_STRING - #include -#endif -#pragma GCC diagnostic pop - -#if _MSC_VER -#define snprintf _snprintf -#endif - -namespace mapnik { - -namespace util { - -using namespace boost::spirit; - -auto INTEGER = qi::int_type(); -#ifdef BIGINT -auto LONGLONG = qi::long_long_type(); -#endif -auto FLOAT = qi::float_type(); -auto DOUBLE = qi::double_type(); - -bool string2bool(std::string const& value, bool & result) -{ - if (value.empty() || value.size() > 5) { - return false; - } else if (value == "true") { - return result = true; - } else if (value == "false") { - result = false; - return true; - } - std::string val(value); - std::transform(val.begin(), val.end(), val.begin(), ::tolower); - if (val == "true" || val == "yes" || val == "1" || val == "on") { - return result = true; - } else if (val == "false" || val == "no" || val == "0" || val == "off") { - result = false; - return true; - } - return false; -} - -bool string2bool(const char * iter, const char * end, bool & result) -{ - std::string val(iter,end); - return string2bool(val,result); -} - -bool string2int(const char * iter, const char * end, int & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,INTEGER,space,result); - return r && (iter == end); -} - -bool string2int(std::string const& value, int & result) -{ - ascii::space_type space; - 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,INTEGER,space,result); - return r && (str_beg == str_end); -} - -#ifdef BIGINT -bool string2int(const char * iter, const char * end, mapnik::value_integer & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,LONGLONG,space,result); - return r && (iter == end); -} - -bool string2int(std::string const& value, mapnik::value_integer & result) -{ - ascii::space_type space; - 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,LONGLONG,space,result); - return r && (str_beg == str_end); -} -#endif - -bool string2double(std::string const& value, double & result) -{ - ascii::space_type space; - 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,DOUBLE,space,result); - return r && (str_beg == str_end); -} - -bool string2double(const char * iter, const char * end, double & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,DOUBLE,space,result); - return r && (iter == end); -} - -bool string2float(std::string const& value, float & result) -{ - ascii::space_type space; - 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,FLOAT,space,result); - return r && (str_beg == str_end); -} - -bool string2float(const char * iter, const char * end, float & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,FLOAT,space,result); - return r && (iter == end); -} - -// double conversion - here we use sprintf over karma to work -// around https://github.com/mapnik/mapnik/issues/1741 -bool to_string(std::string & s, double val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%g", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -#ifdef MAPNIK_KARMA_TO_STRING - -bool to_string(std::string & str, int value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -#ifdef BIGINT -bool to_string(std::string & str, mapnik::value_integer value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} -#endif - -bool to_string(std::string & str, unsigned value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -bool to_string(std::string & str, bool value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -#else - -bool to_string(std::string & s, int val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%d", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -#ifdef BIGINT -bool to_string(std::string & s, mapnik::value_integer val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%lld", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} -#endif - -bool to_string(std::string & s, unsigned val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%u", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -bool to_string(std::string & s, bool val) -{ - if (val) s = "true"; - else s = "false"; - return true; -} - -#endif - -} // end namespace util - -} diff --git a/src/conversions_numeric.cpp b/src/conversions_numeric.cpp new file mode 100644 index 000000000..d209ea6b6 --- /dev/null +++ b/src/conversions_numeric.cpp @@ -0,0 +1,146 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace util { + +using namespace boost::spirit; + +auto INTEGER = x3::int_type(); +#ifdef BIGINT +//auto LONGLONG = x3::long_long_type(); +#endif +auto FLOAT = x3::float_type(); +auto DOUBLE = x3::double_type(); + +bool string2bool(std::string const& value, bool& result) +{ + if (value.empty() || value.size() > 5) + { + return false; + } + else if (value == "true") + { + return result = true; + } + else if (value == "false") + { + result = false; + return true; + } + std::string val(value); + std::transform(val.begin(), val.end(), val.begin(), ::tolower); + if (val == "true" || val == "yes" || val == "1" || val == "on") + { + return result = true; + } + else if (val == "false" || val == "no" || val == "0" || val == "off") + { + result = false; + return true; + } + return false; +} + +bool string2bool(const char* iter, const char* end, bool& result) +{ + std::string val(iter, end); + return string2bool(val, result); +} + +bool string2int(const char* iter, const char* end, int& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, INTEGER, space, result); + return r && (iter == end); +} + +bool string2int(std::string const& value, int& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, INTEGER, space, result); + return r && (str_beg == str_end); +} + +#ifdef BIGINT +bool string2int(const char* iter, const char* end, mapnik::value_integer& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, x3::long_long, space, result); + return r && (iter == end); +} + +bool string2int(std::string const& value, mapnik::value_integer& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, x3::long_long, space, result); + return r && (str_beg == str_end); +} +#endif + +bool string2double(std::string const& value, double& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, DOUBLE, space, result); + return r && (str_beg == str_end); +} + +bool string2double(const char* iter, const char* end, double& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, DOUBLE, space, result); + return r && (iter == end); +} + +bool string2float(std::string const& value, float& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, FLOAT, space, result); + return r && (str_beg == str_end); +} + +bool string2float(const char* iter, const char* end, float& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, FLOAT, space, result); + return r && (iter == end); +} +} // util +} // mapnik diff --git a/src/conversions_string.cpp b/src/conversions_string.cpp new file mode 100644 index 000000000..bd9e46df1 --- /dev/null +++ b/src/conversions_string.cpp @@ -0,0 +1,162 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +#include +#include + +// karma is used by default +#define MAPNIK_KARMA_TO_STRING + +#pragma GCC diagnostic push +#include +#ifdef MAPNIK_KARMA_TO_STRING +#include +#endif +#pragma GCC diagnostic pop + +#if _MSC_VER +#define snprintf _snprintf +#endif + +namespace mapnik { namespace util { + +using namespace boost::spirit; + +// double conversion - here we use sprintf over karma to work +// around https://github.com/mapnik/mapnik/issues/1741 +bool to_string(std::string& s, double val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%g", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +#ifdef MAPNIK_KARMA_TO_STRING + +bool to_string(std::string& str, int value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +#ifdef BIGINT +bool to_string(std::string& str, mapnik::value_integer value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} +#endif + +bool to_string(std::string& str, unsigned value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +bool to_string(std::string& str, bool value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +#else + +bool to_string(std::string& s, int val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%d", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +#ifdef BIGINT +bool to_string(std::string& s, mapnik::value_integer val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%lld", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} +#endif + +bool to_string(std::string& s, unsigned val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%u", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +bool to_string(std::string& s, bool val) +{ + if (val) + s = "true"; + else + s = "false"; + return true; +} + +#endif + +} // end namespace util +} diff --git a/src/css_color_grammar_x3.cpp b/src/css_color_grammar_x3.cpp new file mode 100644 index 000000000..a89505496 --- /dev/null +++ b/src/css_color_grammar_x3.cpp @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include + +namespace mapnik { namespace css_color_grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type); + +}} diff --git a/src/dasharray_parser.cpp b/src/dasharray_parser.cpp index 963a2905a..e42182c0c 100644 --- a/src/dasharray_parser.cpp +++ b/src/dasharray_parser.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,11 +25,7 @@ #pragma GCC diagnostic push #include -#include -#include -#include -#include -#include +#include #pragma GCC diagnostic pop namespace mapnik { @@ -58,15 +54,14 @@ inline bool setup_dashes(std::vector & buf, dash_array & dash) } } + bool parse_dasharray(std::string const& value, dash_array & dash) { using namespace boost::spirit; - qi::double_type double_; - qi::_1_type _1; - qi::lit_type lit; - qi::char_type char_; - qi::ascii::space_type space; - qi::no_skip_type no_skip; + using x3::no_skip; + using x3::double_; + using x3::char_; + boost::spirit::x3::ascii::space_type space; // SVG // dasharray ::= (length | percentage) (comma-wsp dasharray)? // no support for 'percentage' as viewport is unknown at load_map @@ -74,11 +69,9 @@ bool parse_dasharray(std::string const& value, dash_array & dash) std::vector buf; auto first = value.begin(); auto last = value.end(); - bool r = qi::phrase_parse(first, last, - (double_[boost::phoenix::push_back(boost::phoenix::ref(buf), _1)] % - no_skip[char_(", ")] - | lit("none")), - space); + bool r = x3::phrase_parse(first, last, + (double_ % no_skip[char_(", ")] | "none"), + space, buf); if (r && first == last) { return setup_dashes(buf, dash); diff --git a/src/datasource_cache.cpp b/src/datasource_cache.cpp index 3759a6ceb..ccb6a19c2 100644 --- a/src/datasource_cache.cpp +++ b/src/datasource_cache.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/datasource_cache_static.cpp b/src/datasource_cache_static.cpp index ba79d1d01..38d87f273 100644 --- a/src/datasource_cache_static.cpp +++ b/src/datasource_cache_static.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/debug.cpp b/src/debug.cpp index d1ae15fa4..affb39491 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/expression.cpp b/src/expression.cpp index f4bdeeb84..7c3726682 100644 --- a/src/expression.cpp +++ b/src/expression.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,27 +25,30 @@ #include #include #include -#include - -// boost -#include +#include namespace mapnik { expression_ptr parse_expression(std::string const& str) { - static const expression_grammar g; - boost::spirit::standard_wide::space_type space; auto node = std::make_shared(); - std::string::const_iterator itr = str.begin(); - std::string::const_iterator end = str.end(); + using boost::spirit::x3::ascii::space; + mapnik::transcoder const tr("utf8"); + auto parser = boost::spirit::x3::with(std::ref(tr)) + [ + mapnik::expression_grammar() + ]; + bool r = false; + std::string::const_iterator itr = str.begin(); + std::string::const_iterator const end = str.end(); + try { - r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node); + r = boost::spirit::x3::phrase_parse(itr, end, parser, space, *node); } - catch (boost::spirit::qi::expectation_failure const& ex) + catch (boost::spirit::x3::expectation_failure const& ex) { // no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error throw config_error("Failed to parse expression: \"" + str + "\""); diff --git a/src/wkt/mapnik_wkt_grammar.cpp b/src/expression_grammar_x3.cpp similarity index 79% rename from src/wkt/mapnik_wkt_grammar.cpp rename to src/expression_grammar_x3.cpp index aea52a917..07d4a8ece 100644 --- a/src/wkt/mapnik_wkt_grammar.cpp +++ b/src/expression_grammar_x3.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,12 +20,11 @@ * *****************************************************************************/ -#include -#include +#include +#include -namespace mapnik { namespace wkt { +namespace mapnik { namespace grammar { -using iterator_type = std::string::const_iterator; -template struct wkt_grammar; +BOOST_SPIRIT_INSTANTIATE(expression_grammar_type, iterator_type, context_type); }} diff --git a/src/expression_node.cpp b/src/expression_node.cpp index 549f4c891..62d19fd4f 100644 --- a/src/expression_node.cpp +++ b/src/expression_node.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ *****************************************************************************/ #include -#include +#include #include #include diff --git a/src/expression_string.cpp b/src/expression_string.cpp index 0f904ee68..471acc50e 100644 --- a/src/expression_string.cpp +++ b/src/expression_string.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include namespace mapnik diff --git a/src/feature_kv_iterator.cpp b/src/feature_kv_iterator.cpp index 4ae384254..6853bc503 100644 --- a/src/feature_kv_iterator.cpp +++ b/src/feature_kv_iterator.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index c041016d6..f923128da 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/feature_type_style.cpp b/src/feature_type_style.cpp index a2ddb33ba..0fdf67536 100644 --- a/src/feature_type_style.cpp +++ b/src/feature_type_style.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -148,9 +148,9 @@ std::vector const& feature_type_style::direct_image_filter return direct_filters_; } -void feature_type_style::set_comp_op(composite_mode_e comp_op) +void feature_type_style::set_comp_op(composite_mode_e _comp_op) { - comp_op_ = comp_op; + comp_op_ = _comp_op; } boost::optional feature_type_style::comp_op() const diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 9721d70bf..a325ada42 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -48,7 +48,6 @@ extern "C" #include #include - namespace mapnik { diff --git a/src/font_set.cpp b/src/font_set.cpp index 9236cac32..cb06be77f 100644 --- a/src/font_set.cpp +++ b/src/font_set.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/fs.cpp b/src/fs.cpp index 640345396..3ed841e1e 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/function_call.cpp b/src/function_call.cpp index e813deef7..6326becfa 100644 --- a/src/function_call.cpp +++ b/src/function_call.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_filter_types.cpp b/src/generate_image_filters.cpp similarity index 66% rename from src/image_filter_types.cpp rename to src/generate_image_filters.cpp index d30804378..03c55ab43 100644 --- a/src/image_filter_types.cpp +++ b/src/generate_image_filters.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,9 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ + // mapnik #include -#include #pragma GCC diagnostic push #include @@ -43,18 +43,4 @@ bool generate_image_filters(std::back_insert_iterator & sink, std:: return r; } -bool parse_image_filters(std::string const& filters, std::vector& image_filters) -{ - std::string::const_iterator itr = filters.begin(); - std::string::const_iterator end = filters.end(); - static const mapnik::image_filter_grammar > filter_grammar; - boost::spirit::qi::ascii::space_type space; - bool r = boost::spirit::qi::phrase_parse(itr,end, - filter_grammar, - space, - image_filters); - return r && itr==end; -} - }} diff --git a/src/box2d.cpp b/src/geometry/box2d.cpp similarity index 93% rename from src/box2d.cpp rename to src/geometry/box2d.cpp index 2a87553ce..07ceda0eb 100644 --- a/src/box2d.cpp +++ b/src/geometry/box2d.cpp @@ -21,12 +21,12 @@ *****************************************************************************/ // mapnik -#include +#include namespace mapnik { template class box2d; -template class box2d; +//template class box2d; template class box2d; template class box2d; diff --git a/src/geometry_envelope.cpp b/src/geometry/envelope.cpp similarity index 91% rename from src/geometry_envelope.cpp rename to src/geometry/envelope.cpp index bb79f59ad..cb4b61371 100644 --- a/src/geometry_envelope.cpp +++ b/src/geometry/envelope.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,8 @@ * *****************************************************************************/ -#include -#include -#include +#include +#include namespace mapnik { namespace geometry { diff --git a/src/geometry_reprojection.cpp b/src/geometry/reprojection.cpp similarity index 89% rename from src/geometry_reprojection.cpp rename to src/geometry/reprojection.cpp index fad2c5b6f..8f4ae742c 100644 --- a/src/geometry_reprojection.cpp +++ b/src/geometry/reprojection.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,15 +21,15 @@ *****************************************************************************/ // mapnik -#include -#include +#include +#include namespace mapnik { namespace geometry { template MAPNIK_DECL geometry reproject_copy(geometry const& geom, proj_transform const& proj_trans, unsigned int & n_err); -template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, proj_transform const& proj_trans, unsigned int & n_err); +template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL point reproject_copy(point const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL line_string reproject_copy(line_string const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL polygon reproject_copy(polygon const& geom, proj_transform const& proj_trans, unsigned int & n_err); @@ -39,7 +39,7 @@ template MAPNIK_DECL multi_polygon reproject_copy(multi_polygon template MAPNIK_DECL geometry_collection reproject_copy(geometry_collection const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL geometry reproject_copy(geometry const& geom, projection const& source, projection const& dest, unsigned int & n_err); -template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, projection const& source, projection const& dest, unsigned int & n_err); +template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL point reproject_copy(point const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL line_string reproject_copy(line_string const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL polygon reproject_copy(polygon const& geom, projection const& source, projection const& dest, unsigned int & n_err); @@ -49,7 +49,7 @@ template MAPNIK_DECL multi_polygon reproject_copy(multi_polygon template MAPNIK_DECL geometry_collection reproject_copy(geometry_collection const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL bool reproject(geometry & geom, proj_transform const& proj_trans); -template MAPNIK_DECL bool reproject(geometry_empty & geom, proj_transform const& proj_trans); +template MAPNIK_DECL bool reproject(geometry_empty & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(point & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(line_string & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(polygon & geom, proj_transform const& proj_trans); @@ -59,7 +59,7 @@ template MAPNIK_DECL bool reproject(multi_polygon & geom, proj_transform template MAPNIK_DECL bool reproject(geometry_collection & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(geometry & geom, projection const& source, projection const& dest); -template MAPNIK_DECL bool reproject(geometry_empty & geom, projection const& source, projection const& dest); +template MAPNIK_DECL bool reproject(geometry_empty & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(point & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(line_string & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(polygon & geom, projection const& source, projection const& dest); diff --git a/src/gradient.cpp b/src/gradient.cpp index 0c9c6b8fa..6e3ca355a 100644 --- a/src/gradient.cpp +++ b/src/gradient.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -121,7 +121,7 @@ stop_array const& gradient::get_stop_array() const return stops_; } -void gradient::swap(gradient& other) throw() +void gradient::swap(gradient& other) noexcept { std::swap(gradient_type_, other.gradient_type_); std::swap(stops_, other.stops_); diff --git a/src/grid/grid.cpp b/src/grid/grid.cpp index b0d3d598d..678584412 100644 --- a/src/grid/grid.cpp +++ b/src/grid/grid.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp index fd970f580..593a7ee21 100644 --- a/src/grid/grid_renderer.cpp +++ b/src/grid/grid_renderer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/process_building_symbolizer.cpp b/src/grid/process_building_symbolizer.cpp index 13ee8d442..14893ce0f 100644 --- a/src/grid/process_building_symbolizer.cpp +++ b/src/grid/process_building_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +38,7 @@ // stl #include +#include #pragma GCC diagnostic push #include diff --git a/src/grid/process_group_symbolizer.cpp b/src/grid/process_group_symbolizer.cpp index ba7f48ece..46f90bbc7 100644 --- a/src/grid/process_group_symbolizer.cpp +++ b/src/grid/process_group_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -74,7 +74,6 @@ struct thunk_renderer : render_thunk_list_dispatch using renderer_type = agg::renderer_scanline_bin_solid; using namespace mapnik::svg; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg_renderer_agg #include #include -#include +#include #pragma GCC diagnostic push #include diff --git a/src/grid/process_markers_symbolizer.cpp b/src/grid/process_markers_symbolizer.cpp index 380923211..7b8d7ed8a 100644 --- a/src/grid/process_markers_symbolizer.cpp +++ b/src/grid/process_markers_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -143,7 +143,6 @@ void grid_renderer::process(markers_symbolizer const& sym, using renderer_type = agg::renderer_scanline_bin_solid; using namespace mapnik::svg; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg_renderer_agg::process(markers_symbolizer const& sym, ras_ptr->reset(); box2d clip_box = common_.query_extent_; - using context_type = detail::grid_markers_renderer_context; - context_type renderer_context(feature, render_buf, *ras_ptr, pixmap_); + renderer_context_type renderer_context(feature, render_buf, *ras_ptr, pixmap_); render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, renderer_context); diff --git a/src/grid/process_point_symbolizer.cpp b/src/grid/process_point_symbolizer.cpp index 60328009d..e8c364965 100644 --- a/src/grid/process_point_symbolizer.cpp +++ b/src/grid/process_point_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/process_polygon_pattern_symbolizer.cpp b/src/grid/process_polygon_pattern_symbolizer.cpp index 03e27c65d..d0ff02107 100644 --- a/src/grid/process_polygon_pattern_symbolizer.cpp +++ b/src/grid/process_polygon_pattern_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/process_polygon_symbolizer.cpp b/src/grid/process_polygon_symbolizer.cpp index ab8526252..c951d1a81 100644 --- a/src/grid/process_polygon_symbolizer.cpp +++ b/src/grid/process_polygon_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/process_raster_symbolizer.cpp b/src/grid/process_raster_symbolizer.cpp index 9e392a720..413f6e1ff 100644 --- a/src/grid/process_raster_symbolizer.cpp +++ b/src/grid/process_raster_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/process_shield_symbolizer.cpp b/src/grid/process_shield_symbolizer.cpp index 0463bee8e..54c2dea12 100644 --- a/src/grid/process_shield_symbolizer.cpp +++ b/src/grid/process_shield_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/grid/process_text_symbolizer.cpp b/src/grid/process_text_symbolizer.cpp index d1b6a17b4..a28165f92 100644 --- a/src/grid/process_text_symbolizer.cpp +++ b/src/grid/process_text_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/group/group_layout_manager.cpp b/src/group/group_layout_manager.cpp index ad9aaad7c..dd5f2099a 100644 --- a/src/group/group_layout_manager.cpp +++ b/src/group/group_layout_manager.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -90,30 +90,26 @@ struct process_layout return; } - bound_box layout_box; - int middle_ifirst = safe_cast((member_boxes_.size() - 1) >> 1); - int top_i = 0; - int bottom_i = 0; - if (middle_ifirst % 2 == 0) + auto max_diff = layout.get_max_difference(); + auto layout_box = make_horiz_pair(0, 0.0, 0, x_margin, max_diff); + auto y_shift = 0.5 * layout_box.height(); + + for (size_t i = 2; i < member_boxes_.size(); i += 2) { - layout_box = make_horiz_pair(0, 0.0, 0, x_margin, layout.get_max_difference()); - top_i = middle_ifirst - 2; - bottom_i = middle_ifirst + 2; - } - else - { - top_i = middle_ifirst - 1; - bottom_i = middle_ifirst + 1; + auto y = layout_box.maxy() + y_margin; + auto pair_box = make_horiz_pair(i, y, 1, x_margin, max_diff); + layout_box.expand_to_include(pair_box); } - while (bottom_i >= 0 && top_i >= 0 && top_i < static_cast(member_offsets_.size())) - { - layout_box.expand_to_include(make_horiz_pair(static_cast(top_i), layout_box.miny() - y_margin, -1, x_margin, layout.get_max_difference())); - layout_box.expand_to_include(make_horiz_pair(static_cast(bottom_i), layout_box.maxy() + y_margin, 1, x_margin, layout.get_max_difference())); - top_i -= 2; - bottom_i += 2; - } + // layout_box.center corresponds to the center of the first row; + // shift offsets so that the whole group is centered vertically + y_shift -= 0.5 * layout_box.height(); + + for (auto & offset : member_offsets_) + { + offset.y += y_shift; + } } private: @@ -146,12 +142,12 @@ private: // stores corresponding offset, and returns modified bounding box bound_box box_offset_align(size_t i, double x, double y, int x_dir, int y_dir) const { - bound_box const& box = member_boxes_[i]; - pixel_position offset((x_dir == 0 ? x - input_origin_.x : x - (x_dir < 0 ? box.maxx() : box.minx())), - (y_dir == 0 ? y - input_origin_.y : y - (y_dir < 0 ? box.maxy() : box.miny()))); - - member_offsets_[i] = offset; - return bound_box(box.minx() + offset.x, box.miny() + offset.y, box.maxx() + offset.x, box.maxy() + offset.y); + auto box = member_boxes_[i]; + auto & offset = member_offsets_[i]; + offset.x = x - (x_dir == 0 ? input_origin_.x : (x_dir < 0 ? box.maxx() : box.minx())); + offset.y = y - (y_dir == 0 ? input_origin_.y : (y_dir < 0 ? box.maxy() : box.miny())); + box.move(offset.x, offset.y); + return box; } }; diff --git a/src/group/group_rule.cpp b/src/group/group_rule.cpp index a1a6bf940..56beb819b 100644 --- a/src/group/group_rule.cpp +++ b/src/group/group_rule.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/group/group_symbolizer_helper.cpp b/src/group/group_symbolizer_helper.cpp index 2ba70ff9b..4643595a4 100644 --- a/src/group/group_symbolizer_helper.cpp +++ b/src/group/group_symbolizer_helper.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,12 +23,11 @@ // mapnik #include #include -//#include #include #include #include #include -#include +#include #include #include #include diff --git a/src/image.cpp b/src/image.cpp index 5141860b7..086749cd0 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -88,7 +88,6 @@ template struct MAPNIK_DECL image_dimensions<65535>; } // end ns detail -template class MAPNIK_DECL image; template class MAPNIK_DECL image; template class MAPNIK_DECL image; template class MAPNIK_DECL image; diff --git a/src/image_any.cpp b/src/image_any.cpp index 5ba0c3947..4dfb39fa1 100644 --- a/src/image_any.cpp +++ b/src/image_any.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp index d6c8a3333..6fe319b52 100644 --- a/src/image_compositing.cpp +++ b/src/image_compositing.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_copy.cpp b/src/image_copy.cpp index 04fa75c32..8611e83e8 100644 --- a/src/image_copy.cpp +++ b/src/image_copy.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_filter_grammar_x3.cpp b/src/image_filter_grammar_x3.cpp new file mode 100644 index 000000000..8b1e84f8a --- /dev/null +++ b/src/image_filter_grammar_x3.cpp @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include + +namespace mapnik { namespace image_filter { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(image_filter_grammar_type, iterator_type, context_type); + +}} // image_filter //mapnik diff --git a/src/image_options.cpp b/src/image_options.cpp index bbcb6c909..fedf1f976 100644 --- a/src/image_options.cpp +++ b/src/image_options.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,54 +24,99 @@ #pragma GCC diagnostic push #include -#include +#include #include #pragma GCC diagnostic pop -namespace mapnik { namespace detail { - -namespace qi = boost::spirit::qi; - -template -struct image_options_grammar - : qi::grammar +#if defined(HAVE_PNG) +extern "C" { - using pair_type = std::pair>; - image_options_grammar() - : image_options_grammar::base_type(start) - { - qi::lit_type lit; - qi::char_type char_; - start = pair >> *(lit(':') >> pair) - ; - pair = key >> -('=' >> value) - ; - key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9\\.\\-") - ; - value = +char_("a-zA-Z_0-9\\.\\-") - ; - } +#include +} +#endif // HAVE_PNG - qi::rule start; - qi::rule pair; - qi::rule key, value; -}; +namespace mapnik { namespace grammar { -} // ns detail +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::ascii::char_; +using pair_type = std::pair>; + +x3::rule const image_options("image options"); +x3::rule const key_value("key_value"); +x3::rule const key("key"); +x3::rule const value("value"); + +auto const key_def = char_("a-zA-Z_") > *char_("a-zA-Z_0-9\\.\\-"); +auto const value_def = +char_("a-zA-Z_0-9\\.\\-|"); +auto const key_value_def = key > -('=' > value); +auto const image_options_def = key_value % lit(':'); + +BOOST_SPIRIT_DEFINE(key); +BOOST_SPIRIT_DEFINE(value); +BOOST_SPIRIT_DEFINE(key_value); +BOOST_SPIRIT_DEFINE(image_options); + +} // grammar image_options_map parse_image_options(std::string const& str) { - auto const begin = str.begin(); + auto begin = str.begin(); auto const end = str.end(); - boost::spirit::ascii::space_type space; - mapnik::detail::image_options_grammar g; + using boost::spirit::x3::space; + using mapnik::grammar::image_options; image_options_map options; - bool success = boost::spirit::qi::phrase_parse(begin, end, g, space, options); - if (!success) + try { - throw std::runtime_error("Can't parse image options: " + str); + bool success = boost::spirit::x3::phrase_parse(begin, end, image_options, space, options); + if (!success || begin != end) + { + throw std::runtime_error("Can't parse image options: " + str); + } + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw std::runtime_error("Can't parse image options: " + str + " " + ex.what()); } return options; // RVO } +#if defined(HAVE_PNG) + +int parse_png_filters(std::string const& str) +{ + auto begin = str.begin(); + auto const end = str.end(); + using boost::spirit::x3::space; + using boost::spirit::x3::symbols; + symbols filter; + filter.add + ("none", PNG_FILTER_NONE) + ("sub", PNG_FILTER_SUB) + ("up", PNG_FILTER_UP) + ("avg", PNG_FILTER_AVG) + ("paeth", PNG_FILTER_PAETH) + ; + + std::vector opts; + try + { + bool success = boost::spirit::x3::phrase_parse(begin, end, filter % "|" , space , opts); + if (!success || begin != end) + { + throw std::runtime_error("Can't parse PNG filters: " + str); + } + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw std::runtime_error("Can't parse PNG filters: " + str + " " + ex.what()); + } + int filters = 0; + std::for_each(opts.begin(), opts.end(), [&filters] (int f) { filters |= f;}); + return filters; +} + +#endif // HAVE_PNG + } // ns mapnik diff --git a/src/image_reader.cpp b/src/image_reader.cpp index d0ec815b9..b37ad06e1 100644 --- a/src/image_reader.cpp +++ b/src/image_reader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_scaling.cpp b/src/image_scaling.cpp index 413948c64..a2ed8ea53 100644 --- a/src/image_scaling.cpp +++ b/src/image_scaling.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_util.cpp b/src/image_util.cpp index 1fec8b130..954d5321c 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/image_util_jpeg.cpp b/src/image_util_jpeg.cpp index 13860fd4e..5abf8a21d 100644 --- a/src/image_util_jpeg.cpp +++ b/src/image_util_jpeg.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -119,7 +119,6 @@ void jpeg_saver::operator() (T const& image) const throw image_writer_exception("Mapnik does not support jpeg grayscale images"); } -template void jpeg_saver::operator() (image_rgba8 const& image) const; template void jpeg_saver::operator() (image_gray8 const& image) const; template void jpeg_saver::operator() (image_gray8s const& image) const; template void jpeg_saver::operator() (image_gray16 const& image) const; @@ -130,7 +129,6 @@ template void jpeg_saver::operator() (image_gray32f const& image) template void jpeg_saver::operator() (image_gray64 const& image) const; template void jpeg_saver::operator() (image_gray64s const& image) const; template void jpeg_saver::operator() (image_gray64f const& image) const; -template void jpeg_saver::operator() (image_view_rgba8 const& image) const; template void jpeg_saver::operator() (image_view_gray8 const& image) const; template void jpeg_saver::operator() (image_view_gray8s const& image) const; template void jpeg_saver::operator() (image_view_gray16 const& image) const; diff --git a/src/image_util_png.cpp b/src/image_util_png.cpp index f09d58019..0586ded06 100644 --- a/src/image_util_png.cpp +++ b/src/image_util_png.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,10 @@ extern "C" { #include } +#ifndef PNG_FAST_FILTERS // libpng < 1.6 +#define PNG_FAST_FILTERS ( PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP ) #endif +#endif // HAVE_PNG // mapnik #if defined(HAVE_PNG) @@ -154,6 +157,19 @@ void handle_png_options(std::string const& type, throw image_writer_exception("invalid compression strategy parameter: " + *val); } } + else if (key == "f") + { + // filters = PNG_NO_FILTERS; + // filters = PNG_ALL_FILTERS; + // filters = PNG_FAST_FILTERS; + // filters = PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | PNG_FILTER_PAETH; + + if (!val) throw image_writer_exception("invalid filters parameter: "); + if (*val == "no") opts.filters = PNG_NO_FILTERS; + else if (*val == "all") opts.filters = PNG_ALL_FILTERS; + else if (*val == "fast") opts.filters = PNG_FAST_FILTERS; + else opts.filters = parse_png_filters(*val); // none | sub | up | avg | paeth + } else { throw image_writer_exception("unhandled png option: " + key); @@ -316,7 +332,6 @@ void png_saver_pal::operator() (T const& image) const #endif } -template void png_saver::operator() (image_rgba8 const& image) const; template void png_saver::operator() (image_gray8 const& image) const; template void png_saver::operator() (image_gray8s const& image) const; template void png_saver::operator() (image_gray16 const& image) const; @@ -327,7 +342,6 @@ template void png_saver::operator() (image_gray32f const& image) template void png_saver::operator() (image_gray64 const& image) const; template void png_saver::operator() (image_gray64s const& image) const; template void png_saver::operator() (image_gray64f const& image) const; -template void png_saver::operator() (image_view_rgba8 const& image) const; template void png_saver::operator() (image_view_gray8 const& image) const; template void png_saver::operator() (image_view_gray8s const& image) const; template void png_saver::operator() (image_view_gray16 const& image) const; @@ -338,7 +352,6 @@ template void png_saver::operator() (image_view_gray32f cons template void png_saver::operator() (image_view_gray64 const& image) const; template void png_saver::operator() (image_view_gray64s const& image) const; template void png_saver::operator() (image_view_gray64f const& image) const; -template void png_saver_pal::operator() (image_rgba8 const& image) const; template void png_saver_pal::operator() (image_gray8 const& image) const; template void png_saver_pal::operator() (image_gray8s const& image) const; template void png_saver_pal::operator() (image_gray16 const& image) const; @@ -349,7 +362,6 @@ template void png_saver_pal::operator() (image_gray32f const& ima template void png_saver_pal::operator() (image_gray64 const& image) const; template void png_saver_pal::operator() (image_gray64s const& image) const; template void png_saver_pal::operator() (image_gray64f const& image) const; -template void png_saver_pal::operator() (image_view_rgba8 const& image) const; template void png_saver_pal::operator() (image_view_gray8 const& image) const; template void png_saver_pal::operator() (image_view_gray8s const& image) const; template void png_saver_pal::operator() (image_view_gray16 const& image) const; diff --git a/src/image_util_tiff.cpp b/src/image_util_tiff.cpp index 68ef9d9f8..1a0573cb8 100644 --- a/src/image_util_tiff.cpp +++ b/src/image_util_tiff.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/image_util_webp.cpp b/src/image_util_webp.cpp index c7b96aca5..86713ed85 100644 --- a/src/image_util_webp.cpp +++ b/src/image_util_webp.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -360,7 +360,6 @@ void webp_saver::operator() (T const& image) const throw image_writer_exception("Mapnik does not support webp grayscale images"); } -template void webp_saver::operator() (image_rgba8 const& image) const; template void webp_saver::operator() (image_gray8 const& image) const; template void webp_saver::operator() (image_gray8s const& image) const; template void webp_saver::operator() (image_gray16 const& image) const; @@ -371,7 +370,6 @@ template void webp_saver::operator() (image_gray32f const& image) template void webp_saver::operator() (image_gray64 const& image) const; template void webp_saver::operator() (image_gray64s const& image) const; template void webp_saver::operator() (image_gray64f const& image) const; -template void webp_saver::operator() (image_view_rgba8 const& image) const; template void webp_saver::operator() (image_view_gray8 const& image) const; template void webp_saver::operator() (image_view_gray8s const& image) const; template void webp_saver::operator() (image_view_gray16 const& image) const; diff --git a/src/image_view.cpp b/src/image_view.cpp index 44e4d7716..5e51327c7 100644 --- a/src/image_view.cpp +++ b/src/image_view.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,8 +28,6 @@ namespace mapnik { - -template class MAPNIK_DECL image_view; template class MAPNIK_DECL image_view; template class MAPNIK_DECL image_view; template class MAPNIK_DECL image_view; diff --git a/src/image_view_any.cpp b/src/image_view_any.cpp index 6fbbd7be4..80391e164 100644 --- a/src/image_view_any.cpp +++ b/src/image_view_any.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/jpeg_reader.cpp b/src/jpeg_reader.cpp index 6b6e1b127..57c358fb9 100644 --- a/src/jpeg_reader.cpp +++ b/src/jpeg_reader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/json/extract_bounding_boxes_x3.cpp b/src/json/extract_bounding_boxes_x3.cpp new file mode 100644 index 000000000..500bb8f68 --- /dev/null +++ b/src/json/extract_bounding_boxes_x3.cpp @@ -0,0 +1,203 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +namespace mapnik { namespace json { + +template +struct calculate_bounding_box +{ + calculate_bounding_box(Box & box) + : box_(box) {} + + void operator()(mapnik::json::point const& pt) const + { + box_.init(pt.x, pt.y); + } + + void operator()(mapnik::json::ring const& r) const + { + for (auto const& pt : r) + { + if (!box_.valid()) box_.init(pt.x, pt.y); + else box_.expand_to_include(pt.x, pt.y); + } + } + + void operator()(mapnik::json::rings const& rs) const + { + for (auto const& r : rs) + { + operator()(r); + break; // consider first ring only + } + } + + void operator()(mapnik::json::rings_array const& rings_ar) const + { + for (auto const& rs : rings_ar) + { + operator()(rs); + } + } + + template + void operator() (T const& ) const {} + + Box & box_; +}; + +namespace grammar { + +namespace x3 = boost::spirit::x3; + +using base_iterator_type = char const*; +using x3::lit; +using x3::omit; +using x3::raw; +using x3::char_; +using x3::eps; + +struct feature_callback_tag; + +auto on_feature_callback = [] (auto const& ctx) +{ + // call our callback + x3::get(ctx)(_attr(ctx)); +}; + +namespace { auto const& geojson_value = geojson_grammar();} +// import unicode string rule +namespace { auto const& geojson_string = unicode_string_grammar(); } +// import positions rule +namespace { auto const& positions_rule = positions_grammar(); } + +// extract bounding box from GeoJSON Feature + +struct bracket_tag ; + +auto check_brackets = [](auto const& ctx) +{ + _pass(ctx) = (x3::get(ctx) > 0); +}; + +auto open_bracket = [](auto const& ctx) +{ + ++x3::get(ctx); +}; + +auto close_bracket = [](auto const& ctx) +{ + --x3::get(ctx); +}; + +auto assign_range = [](auto const& ctx) +{ + std::get<0>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_bbox = [](auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto extract_bounding_box = [](auto const& ctx) +{ + using box_type = typename std::decay::type; + box_type bbox; + calculate_bounding_box visitor(bbox); + mapnik::util::apply_visitor(visitor, _attr(ctx)); + _val(ctx) = std::move(bbox); +}; + +x3::rule > const coordinates_rule = "Coordinates"; +x3::rule, mapnik::box2d>> const bounding_box = "Bounding Box"; +x3::rule const feature_collection = "Feature Collection"; + +auto const coordinates_rule_def = lit("\"coordinates\"") >> lit(':') >> positions_rule[extract_bounding_box]; + +auto const bounding_box_def = raw[lit('{')[open_bracket] + >> *(eps[check_brackets] >> + ((lit("\"FeatureCollection\"") > eps(false)) + | + lit('{')[open_bracket] + | + lit('}')[close_bracket] + | + coordinates_rule[assign_bbox] + | + omit[geojson_string] + | + omit[char_]))][assign_range]; + + +auto const feature = bounding_box[on_feature_callback]; + +auto const key_value_ = omit[geojson_string] > lit(':') > omit[geojson_value] ; + +auto const features = lit("\"features\"") + > lit(':') > lit('[') > -(omit[feature] % lit(',')) > lit(']'); + +auto const type = lit("\"type\"") > lit(':') > lit("\"FeatureCollection\""); + +auto const feature_collection_def = lit('{') > (( type | features | key_value_) % lit(',')) > lit('}'); + +BOOST_SPIRIT_DEFINE ( + coordinates_rule, + bounding_box, + feature_collection + ); +} + +template +void extract_bounding_boxes(Iterator& start, Iterator const& end, Boxes & boxes) +{ + using namespace boost::spirit; + using space_type = mapnik::json::grammar::space_type; + using iterator_type = Iterator; + + extract_positions callback(start, boxes); + auto keys = mapnik::json::get_keys(); + std::size_t bracket_counter = 0; + auto feature_collection_impl = x3::with(std::ref(bracket_counter)) + [x3::with(std::ref(callback)) + [x3::with(std::ref(keys)) + [mapnik::json::grammar::feature_collection] + ]]; + + if (!x3::phrase_parse(start, end, feature_collection_impl, space_type())) + { + throw std::runtime_error("Can't extract bounding boxes"); + } + +} +using base_iterator_type = char const*; +template void extract_bounding_boxes(base_iterator_type&, base_iterator_type const&, boxes_type&); +template void extract_bounding_boxes(base_iterator_type&, base_iterator_type const& , boxes_type_f&); +}} diff --git a/src/json/mapnik_json_geometry_parser.cpp b/src/json/feature_from_geojson.cpp similarity index 69% rename from src/json/mapnik_json_geometry_parser.cpp rename to src/json/feature_from_geojson.cpp index 278d2c4be..b4d0188c8 100644 --- a/src/json/mapnik_json_geometry_parser.cpp +++ b/src/json/feature_from_geojson.cpp @@ -21,23 +21,25 @@ *****************************************************************************/ +// mapnik #include -#include - -// boost -#include -#include +#include namespace mapnik { namespace json { -bool from_geojson(std::string const& json, mapnik::geometry::geometry & geom) +bool from_geojson(std::string const& json, feature_impl & feature) { - using namespace boost::spirit; - static const geometry_grammar g; - standard::space_type space; - char const* start = json.c_str(); - char const* end = start + json.length(); - return qi::phrase_parse(start, end, g, space, geom); + try + { + const char* start = json.c_str(); + const char* end = start + json.length(); + mapnik::json::parse_feature(start, end, feature); + } + catch (...) + { + return false; + } + return true; } }} diff --git a/src/json/feature_grammar_x3.cpp b/src/json/feature_grammar_x3.cpp new file mode 100644 index 000000000..a34474d49 --- /dev/null +++ b/src/json/feature_grammar_x3.cpp @@ -0,0 +1,34 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(feature_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(geometry_grammar_type, iterator_type, phrase_parse_context_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(feature_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(feature_grammar_type, iterator_type, feature_context_const_type); + +}}} diff --git a/src/json/generic_json.cpp b/src/json/generic_json.cpp deleted file mode 100644 index 7fb2e9fd3..000000000 --- a/src/json/generic_json.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include - -namespace mapnik { namespace json { - -template -generic_json::generic_json() - : generic_json::base_type(value) -{ - qi::lit_type lit; - qi::_val_type _val; - qi::_1_type _1; - using phoenix::construct; - // generic json types - value = object | array | string_ | number - ; - - key_value = string_ > lit(':') > value - ; - - object = lit('{') - > -(key_value % lit(',')) - > lit('}') - ; - - array = lit('[') - > -(value % lit(',')) - > lit(']') - ; - - number = strict_double[_val = double_converter(_1)] - | int__[_val = integer_converter(_1)] - | lit("true") [_val = true] - | lit ("false") [_val = false] - | lit("null")[_val = construct()] - ; -} - -}} - -using iterator_type = char const*; -template struct mapnik::json::generic_json; diff --git a/src/json/generic_json_grammar_x3.cpp b/src/json/generic_json_grammar_x3.cpp new file mode 100644 index 000000000..7c768e6cf --- /dev/null +++ b/src/json/generic_json_grammar_x3.cpp @@ -0,0 +1,37 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, feature_context_const_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(generic_json_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(generic_json_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(generic_json_grammar_type, iterator_type, feature_context_const_type); + +}}} diff --git a/include/mapnik/csv/csv_grammar_impl.hpp b/src/json/geojson_grammar_x3.cpp similarity index 50% rename from include/mapnik/csv/csv_grammar_impl.hpp rename to src/json/geojson_grammar_x3.cpp index 560835443..2d9b30bb9 100644 --- a/include/mapnik/csv/csv_grammar_impl.hpp +++ b/src/json/geojson_grammar_x3.cpp @@ -20,42 +20,22 @@ * *****************************************************************************/ -#include -namespace mapnik { +#include +#include +#include -namespace qi = boost::spirit::qi; +namespace mapnik { namespace json { namespace grammar { -template -csv_line_grammar::csv_line_grammar() - : csv_line_grammar::base_type(line) -{ - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::lit_type lit; - qi::char_type char_; - unesc_char.add - ("\\a", '\a') - ("\\b", '\b') - ("\\f", '\f') - ("\\n", '\n') - ("\\r", '\r') - ("\\t", '\t') - ("\\v", '\v') - ("\\\\",'\\') - ("\\\'", '\'') - ("\\\"", '\"') - ("\"\"", '\"') // double quote - ; - line = -lit("\r") > -lit("\n") > column(_r1, _r2) % lit(_r1) - ; - column = quoted(_r2) | *(char_ - lit(_r1)) - ; - quoted = lit(_r1) > text(_r1) > lit(_r1) // support unmatched quotes or not (??) - ; - text = *(unesc_char | (char_ - lit(_r1))) - ; - BOOST_SPIRIT_DEBUG_NODES((line)(column)(quoted)); -} +BOOST_SPIRIT_INSTANTIATE(geojson_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(key_value_type, iterator_type, context_type); -} // namespace mapnik +BOOST_SPIRIT_INSTANTIATE(geojson_grammar_type, iterator_type, extract_bounding_boxes_context_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +}}} diff --git a/src/json/geometry_from_geojson.cpp b/src/json/geometry_from_geojson.cpp new file mode 100644 index 000000000..c9a0659f4 --- /dev/null +++ b/src/json/geometry_from_geojson.cpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + + +// mapnik +#include +#include +#include + +namespace mapnik { namespace json { + +bool from_geojson(std::string const& json, mapnik::geometry::geometry & geom) +{ + namespace x3 = boost::spirit::x3; + using space_type = mapnik::json::grammar::space_type; + auto grammar = mapnik::json::geometry_grammar(); + try + { + const char* start = json.c_str(); + const char* end = start + json.length(); + if (!x3::phrase_parse(start, end, grammar, space_type(), geom)) + { + throw std::runtime_error("Can't parser GeoJSON Geometry"); + } + } + catch(...) { return false; } + + return true; +} + +}} diff --git a/include/mapnik/json/feature_generator.hpp b/src/json/mapnik_feature_to_geojson.cpp similarity index 81% rename from include/mapnik/json/feature_generator.hpp rename to src/json/mapnik_feature_to_geojson.cpp index f24df4ed8..3532fea97 100644 --- a/include/mapnik/json/feature_generator.hpp +++ b/src/json/mapnik_feature_to_geojson.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,19 +20,16 @@ * *****************************************************************************/ -#ifndef MAPNIK_JSON_FEATURE_GENERATOR_HPP -#define MAPNIK_JSON_FEATURE_GENERATOR_HPP - // mapnik -#include +#include #include // boost #include -namespace mapnik { namespace json { +namespace mapnik { namespace util { -inline bool to_geojson(std::string & json, mapnik::feature_impl const& feature) +bool to_geojson(std::string & json, mapnik::feature_impl const& feature) { using sink_type = std::back_insert_iterator; static const mapnik::json::feature_generator_grammar grammar; @@ -41,5 +38,3 @@ inline bool to_geojson(std::string & json, mapnik::feature_impl const& feature) } }} - -#endif // MAPNIK_JSON_FEATURE_GENERATOR_HPP diff --git a/src/json/mapnik_geometry_to_geojson.cpp b/src/json/mapnik_geometry_to_geojson.cpp index ab2618093..9b76b0648 100644 --- a/src/json/mapnik_geometry_to_geojson.cpp +++ b/src/json/mapnik_geometry_to_geojson.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/json/mapnik_json_generator_grammar.cpp b/src/json/mapnik_json_generator_grammar.cpp index 2b0171f98..5e5241fc5 100644 --- a/src/json/mapnik_json_generator_grammar.cpp +++ b/src/json/mapnik_json_generator_grammar.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,7 @@ * *****************************************************************************/ -#include - +#include #include #include #include @@ -31,5 +30,5 @@ using sink_type = std::back_insert_iterator; template struct mapnik::json::properties_generator_grammar; -template struct mapnik::json::feature_generator_grammar; template struct mapnik::json::geometry_generator_grammar >; +template struct mapnik::json::feature_generator_grammar; diff --git a/src/json/mapnik_topojson_grammar.cpp b/src/json/mapnik_topojson_grammar.cpp deleted file mode 100644 index e4b9dca32..000000000 --- a/src/json/mapnik_topojson_grammar.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include -#include -#include - -using iterator_type = char const*; -template struct mapnik::topojson::topojson_grammar ; diff --git a/src/json/parse_feature.cpp b/src/json/parse_feature.cpp new file mode 100644 index 000000000..d95343ccb --- /dev/null +++ b/src/json/parse_feature.cpp @@ -0,0 +1,59 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace json { + +template +void parse_feature(Iterator start, Iterator end, feature_impl& feature, mapnik::transcoder const& tr) +{ + namespace x3 = boost::spirit::x3; + using space_type = mapnik::json::grammar::space_type; + auto grammar = x3::with(std::ref(tr)) + [x3::with(std::ref(feature)) + [ mapnik::json::feature_grammar() ]]; + if (!x3::phrase_parse(start, end, grammar, space_type())) + { + throw std::runtime_error("Can't parser GeoJSON Feature"); + } +} + +template +void parse_geometry(Iterator start, Iterator end, feature_impl& feature) +{ + namespace x3 = boost::spirit::x3; + using space_type = mapnik::json::grammar::space_type; + auto grammar = mapnik::json::geometry_grammar(); + if (!x3::phrase_parse(start, end, grammar, space_type(), feature.get_geometry())) + { + throw std::runtime_error("Can't parser GeoJSON Geometry"); + } +} + +using iterator_type = mapnik::json::grammar::iterator_type; +template void parse_feature(iterator_type,iterator_type, feature_impl& feature, mapnik::transcoder const& tr); +template void parse_geometry(iterator_type,iterator_type, feature_impl& feature); + +}} diff --git a/src/json/positions_grammar_x3.cpp b/src/json/positions_grammar_x3.cpp new file mode 100644 index 000000000..339137ae2 --- /dev/null +++ b/src/json/positions_grammar_x3.cpp @@ -0,0 +1,44 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, feature_context_const_type); + +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +}}} diff --git a/src/json/mapnik_json_feature_grammar.cpp b/src/json/topojson_grammar_x3.cpp similarity index 76% rename from src/json/mapnik_json_feature_grammar.cpp rename to src/json/topojson_grammar_x3.cpp index 1aa6c7e9e..895b5e8cd 100644 --- a/src/json/mapnik_json_feature_grammar.cpp +++ b/src/json/topojson_grammar_x3.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,11 @@ * *****************************************************************************/ -#include -#include -#include +#include +#include -using iterator_type = char const*; -template struct mapnik::json::feature_grammar; +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(topojson_grammar_type, iterator_type, phrase_parse_context_type); + +}}} diff --git a/src/json/unicode_string_grammar_x3.cpp b/src/json/unicode_string_grammar_x3.cpp new file mode 100644 index 000000000..76c0e731e --- /dev/null +++ b/src/json/unicode_string_grammar_x3.cpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, feature_context_const_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, feature_context_const_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +}}} diff --git a/src/layer.cpp b/src/layer.cpp index 442026b4d..aa781860d 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,9 +31,9 @@ namespace mapnik { -layer::layer(std::string const& name, std::string const& srs) - : name_(name), - srs_(srs), +layer::layer(std::string const& _name, std::string const& _srs) + : name_(_name), + srs_(_srs), minimum_scale_denom_(0), maximum_scale_denom_(std::numeric_limits::max()), active_(true), @@ -42,9 +42,13 @@ layer::layer(std::string const& name, std::string const& srs) cache_features_(false), group_by_(), styles_(), + layers_(), ds_(), buffer_size_(), - maximum_extent_() {} + maximum_extent_(), + comp_op_(), + opacity_(1.0f) +{} layer::layer(layer const& rhs) : name_(rhs.name_), @@ -57,9 +61,13 @@ layer::layer(layer const& rhs) cache_features_(rhs.cache_features_), group_by_(rhs.group_by_), styles_(rhs.styles_), + layers_(rhs.layers_), ds_(rhs.ds_), buffer_size_(rhs.buffer_size_), - maximum_extent_(rhs.maximum_extent_) {} + maximum_extent_(rhs.maximum_extent_), + comp_op_(rhs.comp_op_), + opacity_(rhs.opacity_) +{} layer::layer(layer && rhs) : name_(std::move(rhs.name_)), @@ -72,9 +80,13 @@ layer::layer(layer && rhs) cache_features_(std::move(rhs.cache_features_)), group_by_(std::move(rhs.group_by_)), styles_(std::move(rhs.styles_)), + layers_(std::move(rhs.layers_)), ds_(std::move(rhs.ds_)), buffer_size_(std::move(rhs.buffer_size_)), - maximum_extent_(std::move(rhs.maximum_extent_)) {} + maximum_extent_(std::move(rhs.maximum_extent_)), + comp_op_(std::move(rhs.comp_op_)), + opacity_(std::move(rhs.opacity_)) +{} layer& layer::operator=(layer rhs) { @@ -92,6 +104,8 @@ layer& layer::operator=(layer rhs) std::swap(this->ds_, rhs.ds_); std::swap(this->buffer_size_, rhs.buffer_size_); std::swap(this->maximum_extent_, rhs.maximum_extent_); + std::swap(this->comp_op_, rhs.comp_op_); + std::swap(this->opacity_, rhs.opacity_); return *this; } @@ -109,14 +123,16 @@ bool layer::operator==(layer const& rhs) const (styles_ == rhs.styles_) && ((ds_ && rhs.ds_) ? *ds_ == *rhs.ds_ : ds_ == rhs.ds_) && (buffer_size_ == rhs.buffer_size_) && - (maximum_extent_ == rhs.maximum_extent_); + (maximum_extent_ == rhs.maximum_extent_) && + (comp_op_ == rhs.comp_op_) && + (opacity_ == rhs.opacity_); } layer::~layer() {} -void layer::set_name( std::string const& name) +void layer::set_name( std::string const& _name) { - name_ = name; + name_ = _name; } std::string const& layer::name() const @@ -124,9 +140,9 @@ std::string const& layer::name() const return name_; } -void layer::set_srs(std::string const& srs) +void layer::set_srs(std::string const& _srs) { - srs_ = srs; + srs_ = _srs; } std::string const& layer::srs() const @@ -149,6 +165,21 @@ std::vector & layer::styles() return styles_; } +void layer::add_layer(layer const& l) +{ + layers_.emplace_back(l); +} + +void layer::add_layer(layer && l) +{ + layers_.push_back(std::move(l)); +} + +std::vector const& layer::layers() const +{ + return layers_; +} + void layer::set_minimum_scale_denominator(double minimum_scale_denom) { minimum_scale_denom_=minimum_scale_denom; @@ -169,9 +200,9 @@ double layer::maximum_scale_denominator() const return maximum_scale_denom_; } -void layer::set_active(bool active) +void layer::set_active(bool _active) { - active_=active; + active_ = _active; } bool layer::active() const @@ -184,9 +215,9 @@ bool layer::visible(double scale_denom) const return active() && scale_denom >= minimum_scale_denom_ - 1e-6 && scale_denom < maximum_scale_denom_ + 1e-6; } -void layer::set_queryable(bool queryable) +void layer::set_queryable(bool _queryable) { - queryable_=queryable; + queryable_ = _queryable; } bool layer::queryable() const @@ -250,9 +281,9 @@ bool layer::clear_label_cache() const return clear_label_cache_; } -void layer::set_cache_features(bool cache_features) +void layer::set_cache_features(bool _cache_features) { - cache_features_ = cache_features; + cache_features_ = _cache_features; } bool layer::cache_features() const @@ -270,4 +301,24 @@ std::string const& layer::group_by() const return group_by_; } +void layer::set_comp_op(composite_mode_e comp_op) +{ + comp_op_ = comp_op; +} + +boost::optional layer::comp_op() const +{ + return comp_op_; +} + +void layer::set_opacity(double opacity) +{ + opacity_ = opacity; +} + +double layer::get_opacity() const +{ + return opacity_; +} + } diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index 3c904074c..b1216e6d4 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/load_map.cpp b/src/load_map.cpp index bf6324d20..767d32366 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include @@ -104,7 +104,10 @@ public: private: void parse_map_include(Map & map, xml_node const& node); void parse_style(Map & map, xml_node const& node); - void parse_layer(Map & map, xml_node const& node); + + template + void parse_layer(Parent & parent, xml_node const& node); + void parse_symbolizer_base(symbolizer_base &sym, xml_node const& node); void parse_fontset(Map & map, xml_node const & node); bool parse_font(font_set & fset, xml_node const& f); @@ -133,7 +136,7 @@ private: void find_unused_nodes_recursive(xml_node const& node, std::string & error_text); std::string ensure_relative_to_xml(boost::optional const& opt_path); void ensure_exists(std::string const& file_path); - void check_styles(Map const & map) const throw (config_error); + void check_styles(Map const & map); boost::optional get_opt_color_attr(boost::property_tree::ptree const& node, std::string const& name); @@ -559,7 +562,8 @@ bool map_parser::parse_font(font_set & fset, xml_node const& f) return false; } -void map_parser::parse_layer(Map & map, xml_node const& node) +template +void map_parser::parse_layer(Parent & parent, xml_node const& node) { std::string name; try @@ -575,7 +579,7 @@ void map_parser::parse_layer(Map & map, xml_node const& node) name = node.get_attr("name", std::string("Unnamed")); // If no projection is given inherit from map - std::string srs = node.get_attr("srs", map.srs()); + std::string srs = node.get_attr("srs", parent.srs()); try { // create throwaway projection object here to ensure it is valid @@ -679,6 +683,24 @@ void map_parser::parse_layer(Map & map, xml_node const& node) } } + // compositing + optional comp_op_name = node.get_opt_attr("comp-op"); + if (comp_op_name) + { + optional comp_op = comp_op_from_string(*comp_op_name); + if (comp_op) + { + lyr.set_comp_op(*comp_op); + } + else + { + throw config_error("failed to parse comp-op: '" + *comp_op_name + "'"); + } + } + + optional opacity = node.get_opt_attr("opacity"); + if (opacity) lyr.set_opacity(*opacity); + for (auto const& child: node) { @@ -758,8 +780,12 @@ void map_parser::parse_layer(Map & map, xml_node const& node) throw config_error("Unknown exception occurred attempting to create datasoure for layer '" + lyr.name() + "'"); } } + else if (child.is("Layer")) + { + parse_layer(lyr, child); + } } - map.add_layer(std::move(lyr)); + parent.add_layer(std::move(lyr)); } catch (config_error const& ex) { @@ -895,6 +921,7 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const& nod set_symbolizer_property(sym, keys::comp_op, node); set_symbolizer_property(sym, keys::geometry_transform, node); set_symbolizer_property(sym, keys::simplify_algorithm, node); + set_symbolizer_property(sym, keys::extend, node); } void map_parser::parse_point_symbolizer(rule & rule, xml_node const & node) @@ -1155,10 +1182,14 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& node) if (placement_type) { placements = placements::registry::instance().from_xml(*placement_type, node, fontsets_, true); - } else { - placements = std::make_shared(); + if (!placements) + return; + } + else + { + placements = std::make_shared(); + placements->defaults.from_xml(node, fontsets_, true); } - placements->defaults.from_xml(node, fontsets_, true); if (strict_ && !placements->defaults.format_defaults.fontset) { @@ -1483,32 +1514,32 @@ bool map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, colorizer_mode mode = n.get_attr("mode", COLORIZER_INHERIT); // value is required, and it must be bigger than the previous - optional value = n.get_opt_attr("value"); + optional val = n.get_opt_attr("value"); - if(!value) + if (!val) { throw config_error("stop tag missing value"); } - if(value < maximumValue) + if (val < maximumValue) { throw config_error("stop tag values must be in ascending order"); } - maximumValue = *value; + maximumValue = *val; optional label = n.get_opt_attr("label"); //append the stop - colorizer_stop tmpStop; - tmpStop.set_color(*stopcolor); - tmpStop.set_mode(mode); - tmpStop.set_value(*value); + colorizer_stop stop; + stop.set_color(*stopcolor); + stop.set_mode(mode); + stop.set_value(*val); if (label) { - tmpStop.set_label(*label); + stop.set_label(*label); } - rc->add_stop(tmpStop); + rc->add_stop(stop); } } } @@ -1691,7 +1722,7 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string & } } -void map_parser::check_styles(Map const & map) const throw (config_error) +void map_parser::check_styles(Map const & map) { for (auto const & layer : map.layers()) { diff --git a/src/map.cpp b/src/map.cpp index ec0d9f83e..23d6d92f1 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -375,39 +375,39 @@ unsigned Map::height() const return height_; } -void Map::set_width(unsigned width) +void Map::set_width(unsigned _width) { - if (width != width_ && - width >= MIN_MAPSIZE && - width <= MAX_MAPSIZE) + if (_width != width_ && + _width >= MIN_MAPSIZE && + _width <= MAX_MAPSIZE) { - width_=width; + width_=_width; fixAspectRatio(); } } -void Map::set_height(unsigned height) +void Map::set_height(unsigned _height) { - if (height != height_ && - height >= MIN_MAPSIZE && - height <= MAX_MAPSIZE) + if (_height != height_ && + _height >= MIN_MAPSIZE && + _height <= MAX_MAPSIZE) { - height_=height; + height_ = _height; fixAspectRatio(); } } -void Map::resize(unsigned width,unsigned height) +void Map::resize(unsigned _width, unsigned _height) { - if ((width != width_ || - height != height_) && - width >= MIN_MAPSIZE && - width <= MAX_MAPSIZE && - height >= MIN_MAPSIZE && - height <= MAX_MAPSIZE) + if ((_width != width_ || + _height != height_) && + _width >= MIN_MAPSIZE && + _width <= MAX_MAPSIZE && + _height >= MIN_MAPSIZE && + _height <= MAX_MAPSIZE) { - width_=width; - height_=height; + width_ = _width; + height_ = _height; fixAspectRatio(); } } @@ -417,14 +417,14 @@ std::string const& Map::srs() const return srs_; } -void Map::set_srs(std::string const& srs) +void Map::set_srs(std::string const& _srs) { - srs_ = srs; + srs_ = _srs; } -void Map::set_buffer_size( int buffer_size) +void Map::set_buffer_size(int _buffer_size) { - buffer_size_ = buffer_size; + buffer_size_ = _buffer_size; } int Map::buffer_size() const diff --git a/src/mapped_memory_cache.cpp b/src/mapped_memory_cache.cpp index f35a379af..03654a6d7 100644 --- a/src/mapped_memory_cache.cpp +++ b/src/mapped_memory_cache.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp index 059280c6b..74ccf642d 100644 --- a/src/marker_cache.cpp +++ b/src/marker_cache.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/marker_helpers.cpp b/src/marker_helpers.cpp index eb0202169..86dcc8795 100644 --- a/src/marker_helpers.cpp +++ b/src/marker_helpers.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/math.cpp b/src/math.cpp index 1fd2a4fff..b8d1950cb 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/memory_datasource.cpp b/src/memory_datasource.cpp index 1127f4b83..21acfd7f6 100644 --- a/src/memory_datasource.cpp +++ b/src/memory_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,11 +23,11 @@ // mapnik #include #include -#include +#include #include #include #include -#include +#include // stl #include @@ -68,12 +68,12 @@ const char * memory_datasource::name() return "memory"; } -memory_datasource::memory_datasource(parameters const& params) - : datasource(params), +memory_datasource::memory_datasource(parameters const& _params) + : datasource(_params), desc_(memory_datasource::name(), - *params.get("encoding","utf-8")), + *params_.get("encoding","utf-8")), type_(datasource::Vector), - bbox_check_(*params.get("bbox_check", true)), + bbox_check_(*params_.get("bbox_check", true)), type_set_(false) {} memory_datasource::~memory_datasource() {} @@ -95,7 +95,7 @@ void memory_datasource::push(feature_ptr feature) throw std::runtime_error("Can not add a raster feature to a memory datasource that contains vectors"); } } - else + else { if (!type_set_) { diff --git a/src/palette.cpp b/src/palette.cpp index 1fc5b8b21..e1b8cad9e 100644 --- a/src/palette.cpp +++ b/src/palette.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/params.cpp b/src/params.cpp index 8d3a2c859..61a2dc61a 100644 --- a/src/params.cpp +++ b/src/params.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/src/parse_image_filters.cpp b/src/parse_image_filters.cpp new file mode 100644 index 000000000..74c29261c --- /dev/null +++ b/src/parse_image_filters.cpp @@ -0,0 +1,53 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include +// stl +#include + +namespace mapnik { + +namespace filter { + +bool parse_image_filters(std::string const& str, std::vector & image_filters) +{ + auto const& grammar = mapnik::image_filter_grammar(); + auto itr = str.begin(); + auto end = str.end(); + + boost::spirit::x3::ascii::space_type space; + bool r = false; + try + { + r = boost::spirit::x3::phrase_parse(itr, end, grammar, space, image_filters); + } + catch (...) + { + image_filters.clear(); + r = false; + } + return r && itr==end; +} + +}} diff --git a/src/parse_path.cpp b/src/parse_path.cpp index a3d67c2cb..4a9751d13 100644 --- a/src/parse_path.cpp +++ b/src/parse_path.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,13 +21,13 @@ *****************************************************************************/ #include -#include -#include #include #include #include #include +#include + // stl #include @@ -35,12 +35,12 @@ namespace mapnik { path_expression_ptr parse_path(std::string const& str) { - static const path_expression_grammar g; + namespace x3 = boost::spirit::x3; auto path = std::make_shared(); - boost::spirit::standard_wide::space_type space; + using boost::spirit::x3::standard_wide::space; std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); - bool r = qi::phrase_parse(itr, end, g, space, *path); + bool r = x3::phrase_parse(itr, end, path_expression_grammar(), space, *path); if (r && itr == end) { return path; diff --git a/src/parse_transform.cpp b/src/parse_transform.cpp index e2daaf480..ae56560f2 100644 --- a/src/parse_transform.cpp +++ b/src/parse_transform.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,10 @@ * *****************************************************************************/ -#include -#include - +#include +#include +#include // transcoder_tag +#include // stl #include #include @@ -31,14 +32,28 @@ namespace mapnik { transform_list_ptr parse_transform(std::string const& str, std::string const& encoding) { - static const transform_expression_grammar g; - transform_list_ptr tl = std::make_shared(); + using boost::spirit::x3::ascii::space; + transform_list_ptr trans_list = std::make_shared(); std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); - bool r = qi::phrase_parse(itr, end, g, space_type(), *tl); - if (r && itr == end) + mapnik::transcoder const tr(encoding); + auto const parser = boost::spirit::x3::with(std::ref(tr)) + [ + mapnik::transform_expression_grammar() + ]; + bool status = false; + try { - return tl; + status = boost::spirit::x3::phrase_parse(itr, end, parser, space, *trans_list); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw config_error("Failed to parse transform expression: \"" + str + "\""); + } + + if (status && itr == end) + { + return trans_list; } else { diff --git a/src/path_expression_grammar_x3.cpp b/src/path_expression_grammar_x3.cpp new file mode 100644 index 000000000..fe3bf276d --- /dev/null +++ b/src/path_expression_grammar_x3.cpp @@ -0,0 +1,32 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; +BOOST_SPIRIT_INSTANTIATE(path_expression_grammar_type, iterator_type, context_type); + +}} diff --git a/src/plugin.cpp b/src/plugin.cpp index b2186304d..ee39a7727 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -58,8 +58,8 @@ PluginInfo::PluginInfo(std::string const& filename, if (module_) module_->dl = LoadLibraryA(filename.c_str()); if (module_ && module_->dl) { - callable_returning_string name = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); - if (name) name_ = name(); + callable_returning_string name_call = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); + if (name_call) name_ = name_call(); callable_returning_void init_once = reinterpret_cast(dlsym(module_->dl, "on_plugin_load")); if (init_once) { init_once(); @@ -70,8 +70,8 @@ PluginInfo::PluginInfo(std::string const& filename, if (module_) module_->dl = dlopen(filename.c_str(),RTLD_LAZY); if (module_ && module_->dl) { - callable_returning_string name = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); - if (name) name_ = name(); + callable_returning_string name_call = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); + if (name_call) name_ = name_call(); callable_returning_void init_once = reinterpret_cast(dlsym(module_->dl, "on_plugin_load")); if (init_once) { init_once(); diff --git a/src/png_reader.cpp b/src/png_reader.cpp index 8c58b2238..4f70dd928 100644 --- a/src/png_reader.cpp +++ b/src/png_reader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index 4761724de..c3b5aa098 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +22,7 @@ // mapnik #include -#include +#include #include #include #include diff --git a/src/projection.cpp b/src/projection.cpp index 07f78ba11..10e7fd12b 100644 --- a/src/projection.cpp +++ b/src/projection.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/rapidxml_loader.cpp b/src/rapidxml_loader.cpp index 94e829405..976e14f96 100644 --- a/src/rapidxml_loader.cpp +++ b/src/rapidxml_loader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/raster_colorizer.cpp b/src/raster_colorizer.cpp index 2c43df6b6..879da7fdb 100644 --- a/src/raster_colorizer.cpp +++ b/src/raster_colorizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +22,7 @@ // mapnik #include -#include +#include #include // for to_double #include #include @@ -48,10 +48,10 @@ static const char *colorizer_mode_strings[] = { IMPLEMENT_ENUM( colorizer_mode, colorizer_mode_strings ) -colorizer_stop::colorizer_stop(float value, colorizer_mode mode, +colorizer_stop::colorizer_stop(float val, colorizer_mode mode, color const& _color, std::string const& label) -: value_(value) +: value_(val) , mode_(mode) , color_(_color) , label_(label) @@ -135,14 +135,14 @@ void raster_colorizer::colorize(image_rgba8 & out, T const& in, int len = out.width() * out.height(); for (int i=0; i(fraction * (static_cast(end) - static_cast(start)) + static_cast(start)); } -unsigned raster_colorizer::get_color(float value) const +unsigned raster_colorizer::get_color(float val) const { int stopCount = stops_.size(); @@ -162,13 +162,13 @@ unsigned raster_colorizer::get_color(float value) const return default_color_.rgba(); } - //1 - Find the stop that the value is in + //1 - Find the stop that the val is in int stopIdx = -1; bool foundStopIdx = false; for(int i=0; i layout_thunks; + std::list layout_thunks; // layout manager to store and arrange bboxes of matched features group_layout_manager layout_manager(props->get_layout()); @@ -182,11 +182,13 @@ void render_group_symbolizer(group_symbolizer const& sym, pixel_position_list const& positions = helper.get(); for (pixel_position const& pos : positions) { - for (size_t layout_i = 0; layout_i < layout_thunks.size(); ++layout_i) + size_t layout_i = 0; + for (auto const& thunks : layout_thunks) { pixel_position const& offset = layout_manager.offset_at(layout_i); pixel_position render_offset = pos + offset; - render_thunks.render_list(layout_thunks[layout_i], render_offset); + render_thunks.render_list(thunks, render_offset); + ++layout_i; } } } diff --git a/src/renderer_common/render_markers_symbolizer.cpp b/src/renderer_common/render_markers_symbolizer.cpp index 6706cb1cd..c0c148b0a 100644 --- a/src/renderer_common/render_markers_symbolizer.cpp +++ b/src/renderer_common/render_markers_symbolizer.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -128,12 +128,12 @@ struct render_marker_symbolizer_visitor agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); - boost::optional const& stock_vector_marker = mark.get_data(); - svg_path_ptr marker_ptr = *stock_vector_marker; + svg_path_ptr stock_vector_marker = mark.get_data(); + svg_path_ptr marker_ptr = stock_vector_marker; bool is_ellipse = false; svg_attribute_type s_attributes; - auto const& r_attributes = get_marker_attributes(*stock_vector_marker, s_attributes); + auto const& r_attributes = get_marker_attributes(stock_vector_marker, s_attributes); // special case for simple ellipse markers // to allow for full control over rx/ry dimensions diff --git a/src/renderer_common/render_pattern.cpp b/src/renderer_common/render_pattern.cpp index 5e6f95820..f33645996 100644 --- a/src/renderer_common/render_pattern.cpp +++ b/src/renderer_common/render_pattern.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ *****************************************************************************/ // mapnik #include -#include +#include #include #include #include diff --git a/src/renderer_common/render_thunk_extractor.cpp b/src/renderer_common/render_thunk_extractor.cpp index c437262da..9307064eb 100644 --- a/src/renderer_common/render_thunk_extractor.cpp +++ b/src/renderer_common/render_thunk_extractor.cpp @@ -55,7 +55,7 @@ struct thunk_markers_renderer_context : markers_renderer_context { vector_marker_render_thunk thunk(src, attrs, marker_tr, params.opacity, comp_op_, params.snap_to_pixels); - thunks_.push_back(std::make_unique(std::move(thunk))); + thunks_.emplace_back(std::move(thunk)); } virtual void render_marker(image_rgba8 const& src, @@ -64,7 +64,7 @@ struct thunk_markers_renderer_context : markers_renderer_context { raster_marker_render_thunk thunk(src, marker_tr, params.opacity, comp_op_, params.snap_to_pixels); - thunks_.push_back(std::make_unique(std::move(thunk))); + thunks_.emplace_back(std::move(thunk)); } private: @@ -87,8 +87,8 @@ render_thunk_extractor::render_thunk_extractor(box2d & box, void render_thunk_extractor::operator()(markers_symbolizer const& sym) const { - using context_type = detail::thunk_markers_renderer_context; - context_type renderer_context(sym, feature_, vars_, thunks_); + using renderer_context_type = detail::thunk_markers_renderer_context; + renderer_context_type renderer_context(sym, feature_, vars_, thunks_); render_markers_symbolizer( sym, feature_, prj_trans_, common_, clipping_extent_, renderer_context); @@ -128,7 +128,7 @@ void render_thunk_extractor::extract_text_thunk(text_render_thunk::helper_ptr && halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL); text_render_thunk thunk(std::move(helper), opacity, comp_op, halo_rasterizer); - thunks_.push_back(std::make_unique(std::move(thunk))); + thunks_.emplace_back(std::move(thunk)); update_box(); } diff --git a/src/request.cpp b/src/request.cpp index f74f62c38..2f5e2eddc 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/rule.cpp b/src/rule.cpp index 2fec472a0..e6b2c0244 100644 --- a/src/rule.cpp +++ b/src/rule.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/save_map.cpp b/src/save_map.cpp index f3d89153c..f5825ce73 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include @@ -488,7 +488,8 @@ void serialize_datasource( ptree & layer_node, datasource_ptr datasource) void serialize_parameters( ptree & map_node, mapnik::parameters const& params) { - if (params.size()) { + if (params.size()) + { ptree & params_node = map_node.push_back( ptree::value_type("Parameters", ptree()))->second; @@ -513,6 +514,17 @@ void serialize_layer( ptree & map_node, layer const& lyr, bool explicit_defaults set_attr( layer_node, "name", lyr.name() ); } + auto const comp_op = lyr.comp_op(); + + if (comp_op) + { + set_attr(layer_node, "comp-op", *comp_op_to_string(*comp_op)); + } + else if (explicit_defaults) + { + set_attr(layer_node, "comp-op", "src-over"); + } + if ( lyr.srs() != "" ) { set_attr( layer_node, "srs", lyr.srs() ); @@ -582,6 +594,12 @@ void serialize_layer( ptree & map_node, layer const& lyr, bool explicit_defaults { serialize_datasource( layer_node, datasource ); } + + // serialize nested layers + for (auto const& child : lyr.layers()) + { + serialize_layer(layer_node, child, explicit_defaults ); + } } void serialize_map(ptree & pt, Map const& map, bool explicit_defaults) diff --git a/src/scale_denominator.cpp b/src/scale_denominator.cpp index 7e7b2f14d..fdd7fba7a 100644 --- a/src/scale_denominator.cpp +++ b/src/scale_denominator.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/output/process_line_symbolizer.cpp b/src/svg/output/process_line_symbolizer.cpp index 5db205eff..e2063a6ce 100644 --- a/src/svg/output/process_line_symbolizer.cpp +++ b/src/svg/output/process_line_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/output/process_polygon_symbolizer.cpp b/src/svg/output/process_polygon_symbolizer.cpp index c5a1f8709..be994ec1e 100644 --- a/src/svg/output/process_polygon_symbolizer.cpp +++ b/src/svg/output/process_polygon_symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/output/process_symbolizers.cpp b/src/svg/output/process_symbolizers.cpp index 6ff486f7f..c7f7ec9a7 100644 --- a/src/svg/output/process_symbolizers.cpp +++ b/src/svg/output/process_symbolizers.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,8 +32,8 @@ #include #include #include -#include -#include +#include +#include #include #include // boost diff --git a/src/svg/output/svg_generator.cpp b/src/svg/output/svg_generator.cpp index cb8eb79ec..9a353c087 100644 --- a/src/svg/output/svg_generator.cpp +++ b/src/svg/output/svg_generator.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/output/svg_output_attributes.cpp b/src/svg/output/svg_output_attributes.cpp index bf05d874b..2612a71a3 100644 --- a/src/svg/output/svg_output_attributes.cpp +++ b/src/svg/output/svg_output_attributes.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/output/svg_output_grammars.cpp b/src/svg/output/svg_output_grammars.cpp index 398c41a7e..b048968a1 100644 --- a/src/svg/output/svg_output_grammars.cpp +++ b/src/svg/output/svg_output_grammars.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/output/svg_renderer.cpp b/src/svg/output/svg_renderer.cpp index 569164645..2519d54fa 100644 --- a/src/svg/output/svg_renderer.cpp +++ b/src/svg/output/svg_renderer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/svg/svg_parser.cpp b/src/svg/svg_parser.cpp index 827f557fc..b4d90cda7 100644 --- a/src/svg/svg_parser.cpp +++ b/src/svg/svg_parser.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,9 +41,8 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include +#include #include #include #include @@ -55,6 +54,24 @@ #include #include +namespace mapnik { namespace svg { +struct viewbox +{ + double x0; + double y0; + double x1; + double y1; +}; +}} + +BOOST_FUSION_ADAPT_STRUCT ( + mapnik::svg::viewbox, + (double, x0) + (double, y0) + (double, x1) + (double, y1) + ) + namespace mapnik { namespace svg { namespace rapidxml = boost::property_tree::detail::rapidxml; @@ -77,29 +94,26 @@ void parse_attr(svg_parser & parser,rapidxml::xml_node const* node); void parse_attr(svg_parser & parser,char const * name, char const* value); +namespace { namespace grammar { + +namespace x3 = boost::spirit::x3; + using color_lookup_type = std::vector >; -namespace qi = boost::spirit::qi; using pairs_type = std::vector >; -template -struct key_value_sequence_ordered - : qi::grammar -{ - key_value_sequence_ordered() - : key_value_sequence_ordered::base_type(query) - { - qi::lit_type lit; - qi::char_type char_; - query = pair >> *( lit(';') >> pair); - pair = key >> -(':' >> value); - key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9-"); - value = +(char_ - lit(';')); - } +x3::rule const key_value_sequence_ordered("key_value_sequence_ordered"); +x3::rule > key_value("key_value"); +x3::rule key("key"); +x3::rule value("value"); - qi::rule query; - qi::rule(), SkipType> pair; - qi::rule key, value; -}; +auto const key_def = x3::char_("a-zA-Z_") > *x3::char_("a-zA-Z_0-9-"); +auto const value_def = +(x3::char_ - ';'); +auto const key_value_def = key > -(':' > value); +auto const key_value_sequence_ordered_def = key_value % ';'; + +BOOST_SPIRIT_DEFINE(key, value, key_value, key_value_sequence_ordered); + +}} template mapnik::color parse_color(T & error_messages, const char* str) @@ -126,10 +140,9 @@ agg::rgba8 parse_color_agg(T & error_messages, const char* str) template double parse_double(T & error_messages, const char* str) { - using namespace boost::spirit::qi; - double_type double_; + using namespace boost::spirit::x3; double val = 0.0; - if (!parse(str, str + std::strlen(str),double_,val)) + if (!parse(str, str + std::strlen(str), double_, val)) { error_messages.emplace_back("Failed to parse double: \"" + std::string(str) + "\""); } @@ -138,15 +151,11 @@ double parse_double(T & error_messages, const char* str) // https://www.w3.org/TR/SVG/coords.html#Units template -double parse_svg_value(T & error_messages, const char* str, bool & percent) +double parse_svg_value(T & error_messages, const char* str, bool & is_percent) { - using skip_type = boost::spirit::ascii::space_type; - using boost::phoenix::ref; - qi::double_type double_; - qi::lit_type lit; - qi::_1_type _1; + namespace x3 = boost::spirit::x3; double val = 0.0; - qi::symbols units; + x3::symbols units; units.add ("px", 1.0) ("pt", DPI/72.0) @@ -157,12 +166,17 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent) ; const char* cur = str; // phrase_parse modifies the first iterator const char* end = str + std::strlen(str); - if (!qi::phrase_parse(cur, end, - double_[ref(val) = _1][ref(percent) = false] - > - (units[ ref(val) *= _1] - | - lit('%')[ref(val) *= 0.01][ref(percent) = true]), - skip_type())) + + auto apply_value = [&](auto const& ctx) { val = _attr(ctx); is_percent = false; }; + auto apply_units = [&](auto const& ctx) { val *= _attr(ctx); }; + auto apply_percent = [&](auto const& ctx) { val *= 0.01; is_percent = true; }; + + if (!x3::phrase_parse(cur, end, + x3::double_[apply_value] + > - (units[apply_units] + | + x3::lit('%')[apply_percent]), + x3::space)) { error_messages.emplace_back("Failed to parse SVG value: '" + std::string(str) + "'"); } @@ -174,46 +188,35 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent) return val; } -template -bool parse_double_list(T & error_messages, const char* str, double* list) +template +bool parse_viewbox(T & error_messages, const char* str, V & viewbox) { - using namespace boost::spirit::qi; - using boost::phoenix::ref; - _1_type _1; - double_type double_; - lit_type lit; - using skip_type = boost::spirit::ascii::space_type; - - if (!phrase_parse(str, str + std::strlen(str), - double_[ref(list[0])=_1] >> -lit(',') >> - double_[ref(list[1])=_1] >> -lit(',') >> - double_[ref(list[2])=_1] >> -lit(',') >> - double_[ref(list[3])=_1], skip_type())) + namespace x3 = boost::spirit::x3; + if ( !x3::phrase_parse(str, str + std::strlen(str), + x3::double_ > -x3::lit(',') > + x3::double_ > -x3::lit(',') > + x3::double_ > -x3::lit(',') > + x3::double_, x3::space, viewbox)) { - error_messages.emplace_back("failed to parse list of doubles from " + std::string(str)); + error_messages.emplace_back("failed to parse SVG viewbox from " + std::string(str)); return false; } return true; } -bool parse_style (char const* str, pairs_type & v) +bool parse_style (char const* str, grammar::pairs_type & v) { - using namespace boost::spirit::qi; - using skip_type = boost::spirit::ascii::space_type; - key_value_sequence_ordered kv_parser; - return phrase_parse(str, str + std::strlen(str), kv_parser, skip_type(), v); + namespace x3 = boost::spirit::x3; + return x3::phrase_parse(str, str + std::strlen(str), grammar::key_value_sequence_ordered , x3::space, v); } bool parse_id_from_url (char const* str, std::string & id) { - using namespace boost::spirit::qi; - using skip_type = boost::spirit::ascii::space_type; - qi::_1_type _1; - qi::char_type char_; - qi::lit_type lit; - return phrase_parse(str, str + std::strlen(str), - lit("url") > "(" > "#" > *(char_ - lit(')'))[boost::phoenix::ref(id) += _1] > ")", - skip_type()); + namespace x3 = boost::spirit::x3; + auto extract_id = [&](auto const& ctx) { id += _attr(ctx); }; + return x3::phrase_parse(str, str + std::strlen(str), + x3::lit("url") > '(' > '#' > *(x3::char_ - ')')[extract_id] > ')', + x3::space); } bool traverse_tree(svg_parser & parser, rapidxml::xml_node const* node) @@ -517,7 +520,7 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node const* node) double width = 0; double height = 0; double aspect_ratio = 1; - double viewbox[4] = {0,0,0,0}; + viewbox vbox = {0,0,0,0}; bool has_viewbox = false; bool has_percent_height = true; bool has_percent_width = true; @@ -535,23 +538,23 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node const* node) auto const* viewbox_attr = node->first_attribute("viewBox"); if (viewbox_attr) { - has_viewbox = parse_double_list(parser.error_messages_, viewbox_attr->value(), viewbox); + has_viewbox = parse_viewbox(parser.error_messages_, viewbox_attr->value(), vbox); } if (has_percent_width && !has_percent_height && has_viewbox) { - aspect_ratio = viewbox[2] / viewbox[3]; + aspect_ratio = vbox.x1 / vbox.y1; width = aspect_ratio * height; } else if (!has_percent_width && has_percent_height && has_viewbox) { - aspect_ratio = viewbox[2] / viewbox[3]; + aspect_ratio = vbox.x1 / vbox.y1; height = height / aspect_ratio; } else if (has_percent_width && has_percent_height && has_viewbox) { - width = viewbox[2]; - height = viewbox[3]; + width = vbox.x1; + height = vbox.y1; } parser.path_.set_dimensions(width, height); diff --git a/src/json/mapnik_json_positions_grammar.cpp b/src/svg/svg_path_grammar_x3.cpp similarity index 58% rename from src/json/mapnik_json_positions_grammar.cpp rename to src/svg/svg_path_grammar_x3.cpp index a13f0e313..b1b04434d 100644 --- a/src/json/mapnik_json_positions_grammar.cpp +++ b/src/svg/svg_path_grammar_x3.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,18 @@ * *****************************************************************************/ -#include -#include +#include -using iterator_type = char const*; -template struct mapnik::json::positions_grammar; +namespace mapnik { namespace svg { namespace grammar { + +#define BOOST_SPIRIT_INSTANTIATE_UNUSED(rule_type, Iterator, Context) \ + template bool parse_rule( \ + rule_type rule_ \ + , Iterator& first, Iterator const& last \ + , Context const& context, boost::spirit::x3::unused_type const& ); \ + /***/ + +BOOST_SPIRIT_INSTANTIATE_UNUSED(svg_path_grammar_type, iterator_type, svg_parse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(svg_points_grammar_type, iterator_type, svg_parse_context_type); + +}}} diff --git a/src/svg/svg_path_parser.cpp b/src/svg/svg_path_parser.cpp index 52f95ef6e..53c3a94ee 100644 --- a/src/svg/svg_path_parser.cpp +++ b/src/svg/svg_path_parser.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ // mapnik #include -#include +#include // stl #include #include @@ -35,14 +35,30 @@ template bool parse_path(const char* wkt, PathType& p) { using namespace boost::spirit; - using iterator_type = const char*; - using skip_type = ascii::space_type; - static const svg_path_grammar g; + using iterator_type = char const*; iterator_type first = wkt; iterator_type last = wkt + std::strlen(wkt); - bool status = qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type()); - return (status && (first == last)); + bool relative = false; + using space_type = mapnik::svg::grammar::space_type; + auto const grammar = x3::with(std::ref(p)) + [ x3::with(std::ref(relative)) + [mapnik::svg::svg_path_grammar()]]; + + try + { + if (!x3::phrase_parse(first, last, grammar, space_type()) + || first != last) + { + throw std::runtime_error("Failed to parse svg-path"); + } + } + catch (...) + { + return false; + } + return true; } + template bool MAPNIK_DECL parse_path(const char*, svg_converter_type&); } // namespace svg diff --git a/src/svg/svg_points_parser.cpp b/src/svg/svg_points_parser.cpp index 3e292ba70..9ede3b7de 100644 --- a/src/svg/svg_points_parser.cpp +++ b/src/svg/svg_points_parser.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // stl #include #include @@ -34,12 +34,29 @@ template bool parse_points(const char* wkt, PathType& p) { using namespace boost::spirit; - using iterator_type = const char*; - using skip_type = ascii::space_type; - static const svg_points_grammar g; + using iterator_type = char const*; + using space_type = mapnik::svg::grammar::space_type; iterator_type first = wkt; iterator_type last = wkt + std::strlen(wkt); - return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type()); + bool relative = false; + + auto const grammar = x3::with(std::ref(p)) + [ x3::with(std::ref(relative)) + [mapnik::svg::svg_points_grammar()]]; + + try + { + if (!x3::phrase_parse(first, last, grammar, space_type()) + || first != last) + { + throw std::runtime_error("Failed to parse svg-path"); + } + } + catch (...) + { + return false; + } + return true; } template bool parse_points(const char*, svg_converter_type&); diff --git a/src/svg/svg_transform_parser.cpp b/src/svg/svg_transform_parser.cpp index 7b90ca4cb..46aca7fd6 100644 --- a/src/svg/svg_transform_parser.cpp +++ b/src/svg/svg_transform_parser.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,24 +22,37 @@ // mapnik #include -#include +#include // stl #include #include -namespace mapnik { -namespace svg { +namespace mapnik { namespace svg { -template -bool parse_svg_transform(const char* wkt, TransformType& tr) +template +bool parse_svg_transform(const char* wkt, Transform& tr) { using namespace boost::spirit; - using iterator_type = const char*; - using skip_type = ascii::space_type; - static const svg_transform_grammar g; + using iterator_type = char const*; iterator_type first = wkt; iterator_type last = wkt + std::strlen(wkt); - return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(tr)), skip_type()); + using space_type = mapnik::svg::grammar::space_type; + auto const grammar = x3::with(std::ref(tr)) + [mapnik::svg::svg_transform_grammar()]; + + try + { + if (!x3::phrase_parse(first, last, grammar, space_type()) + || first != last) + { + throw std::runtime_error("Failed to parse svg-transform"); + } + } + catch (...) + { + return false; + } + return true; } template bool MAPNIK_DECL parse_svg_transform(const char*, agg::trans_affine&); diff --git a/src/symbolizer.cpp b/src/symbolizer.cpp index 6d3109f8e..7833663b5 100644 --- a/src/symbolizer.cpp +++ b/src/symbolizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/src/symbolizer_enumerations.cpp b/src/symbolizer_enumerations.cpp index 94227dfd2..1c8098271 100644 --- a/src/symbolizer_enumerations.cpp +++ b/src/symbolizer_enumerations.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/symbolizer_keys.cpp b/src/symbolizer_keys.cpp index fa5c73d32..db04a296a 100644 --- a/src/symbolizer_keys.cpp +++ b/src/symbolizer_keys.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -158,6 +158,7 @@ static const property_meta_type key_meta[const_max_key] = property_types::target_direction}, property_meta_type{ "avoid-edges",nullptr, property_types::target_bool }, property_meta_type{ "font-feature-settings", nullptr, property_types::target_font_feature_settings }, + property_meta_type{ "extend", nullptr, property_types::target_double}, }; diff --git a/src/text/face.cpp b/src/text/face.cpp index 1d3ad7820..1c3a4ba25 100644 --- a/src/text/face.cpp +++ b/src/text/face.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,7 @@ extern "C" { #include FT_GLYPH_H +#include FT_TRUETYPE_TABLES_H } #pragma GCC diagnostic pop @@ -37,16 +38,23 @@ namespace mapnik { font_face::font_face(FT_Face face) - : face_(face) {} + : face_(face) +{ + static const uint32_t tag = FT_MAKE_TAG('C', 'B', 'D', 'T'); + unsigned long length = 0; + FT_Load_Sfnt_Table(face_, tag, 0, nullptr, &length); + if (length) color_font_ = true; +} bool font_face::set_character_sizes(double size) { - return (FT_Set_Char_Size(face_,0,static_cast(size * (1<<6)),0,0) == 0); + return (FT_Set_Char_Size(face_, 0, static_cast(size * (1 << 6)), 0, 0) == 0); } bool font_face::set_unscaled_character_sizes() { - return (FT_Set_Char_Size(face_,0,face_->units_per_EM,0,0) == 0); + FT_F26Dot6 char_height = face_->units_per_EM > 0 ? face_->units_per_EM : 2048.0; + return (FT_Set_Char_Size(face_, 0, char_height, 0, 0) == 0); } bool font_face::glyph_dimensions(glyph_info & glyph) const @@ -54,11 +62,14 @@ bool font_face::glyph_dimensions(glyph_info & glyph) const FT_Vector pen; pen.x = 0; pen.y = 0; + if (color_font_) FT_Select_Size(face_, 0); FT_Set_Transform(face_, 0, &pen); - - if (FT_Load_Glyph(face_, glyph.glyph_index, FT_LOAD_NO_HINTING)) + FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; + if (color_font_) load_flags |= FT_LOAD_COLOR ; + if (FT_Load_Glyph(face_, glyph.glyph_index, load_flags)) { - MAPNIK_LOG_ERROR(font_face) << "FT_Load_Glyph failed"; + MAPNIK_LOG_ERROR(font_face) << "FT_Load_Glyph failed :( index=" << glyph.glyph_index << " " << load_flags + << " " << face_->family_name << " " << face_->style_name ; return false; } FT_Glyph image; @@ -93,11 +104,11 @@ void font_face_set::add(face_ptr face) faces_.push_back(face); } -void font_face_set::set_character_sizes(double size) +void font_face_set::set_character_sizes(double _size) { for (face_ptr const& face : faces_) { - face->set_character_sizes(size); + face->set_character_sizes(_size); } } diff --git a/src/text/font_feature_settings.cpp b/src/text/font_feature_settings.cpp index 81a62f9dd..8a9b32b17 100644 --- a/src/text/font_feature_settings.cpp +++ b/src/text/font_feature_settings.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,11 +26,10 @@ #pragma GCC diagnostic push #include -#include +#include #include #pragma GCC diagnostic pop - // stl #include #include @@ -52,23 +51,14 @@ font_feature_settings::font_feature_settings() void font_feature_settings::from_string(std::string const& features) { features_.clear(); - if (std::all_of(features.begin(), features.end(), isspace)) return; - namespace qi = boost::spirit::qi; - qi::char_type char_; - qi::as_string_type as_string; - -#if BOOST_VERSION <= 104800 - // Call correct overload. - using std::placeholders::_1; - void (font_feature_settings::*append)(std::string const&) = &font_feature_settings::append; - if (!qi::parse(features.begin(), features.end(), as_string[+(char_ - ',')][std::bind(append, this, _1)] % ',')) -#else - auto app = [&](std::string const& s) { append(s); }; - if (!qi::parse(features.begin(), features.end(), as_string[+(char_ - ',')][app] % ',')) -#endif - + namespace x3 = boost::spirit::x3; + auto appender = [&](auto const& ctx) + { + this->append(_attr(ctx)); + }; + if (!x3::parse(features.begin(), features.end(), (+(x3::char_ - ','))[appender] % ',')) { throw config_error("failed to parse font-feature-settings: '" + features + "'"); } diff --git a/src/text/font_library.cpp b/src/text/font_library.cpp index 37fd6a43b..2dca13fe6 100644 --- a/src/text/font_library.cpp +++ b/src/text/font_library.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/formatting/base.cpp b/src/text/formatting/base.cpp index 8d8f0a1bb..c4e59fcc5 100644 --- a/src/text/formatting/base.cpp +++ b/src/text/formatting/base.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/formatting/format.cpp b/src/text/formatting/format.cpp index 8a6a8cc9d..4f054af5f 100644 --- a/src/text/formatting/format.cpp +++ b/src/text/formatting/format.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/formatting/layout.cpp b/src/text/formatting/layout.cpp index 9a5ca10aa..711422b8e 100644 --- a/src/text/formatting/layout.cpp +++ b/src/text/formatting/layout.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/formatting/list.cpp b/src/text/formatting/list.cpp index 4bf7c4d2d..686e5424c 100644 --- a/src/text/formatting/list.cpp +++ b/src/text/formatting/list.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,27 +37,27 @@ namespace formatting { void list_node::to_xml(boost::property_tree::ptree & xml) const { - for (node_ptr const& node : children_) + for (node_ptr const& n : children_) { - node->to_xml(xml); + n->to_xml(xml); } } void list_node::apply(evaluated_format_properties_ptr const& p, feature_impl const& feature, attributes const& vars, text_layout & output) const { - for (node_ptr const& node : children_) + for (node_ptr const& n : children_) { - node->apply(p, feature, vars, output); + n->apply(p, feature, vars, output); } } void list_node::add_expressions(expression_set &output) const { - for (node_ptr const& node : children_) + for (node_ptr const& n : children_) { - node->add_expressions(output); + n->add_expressions(output); } } diff --git a/src/text/formatting/registry.cpp b/src/text/formatting/registry.cpp index 6114f97e5..09c1ee89a 100644 --- a/src/text/formatting/registry.cpp +++ b/src/text/formatting/registry.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/formatting/text.cpp b/src/text/formatting/text.cpp index 3158f20e2..6cc70b09d 100644 --- a/src/text/formatting/text.cpp +++ b/src/text/formatting/text.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/glyph_positions.cpp b/src/text/glyph_positions.cpp index fdcb3a811..e56393c7c 100644 --- a/src/text/glyph_positions.cpp +++ b/src/text/glyph_positions.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/itemizer.cpp b/src/text/itemizer.cpp index 9f01035f1..bf8d4b725 100644 --- a/src/text/itemizer.cpp +++ b/src/text/itemizer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp index e4adddf3e..a580ac297 100644 --- a/src/text/placement_finder.cpp +++ b/src/text/placement_finder.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +35,7 @@ // stl #include +#include namespace mapnik { diff --git a/src/text/placements/base.cpp b/src/text/placements/base.cpp index 861c5664a..b01adee66 100644 --- a/src/text/placements/base.cpp +++ b/src/text/placements/base.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/placements/dummy.cpp b/src/text/placements/dummy.cpp index dd51db8b8..76b8537cf 100644 --- a/src/text/placements/dummy.cpp +++ b/src/text/placements/dummy.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/placements/list.cpp b/src/text/placements/list.cpp index 7d609f2c4..ca3cda4b4 100644 --- a/src/text/placements/list.cpp +++ b/src/text/placements/list.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/placements/registry.cpp b/src/text/placements/registry.cpp index e24131d03..cd5f44d1a 100644 --- a/src/text/placements/registry.cpp +++ b/src/text/placements/registry.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/placements/simple.cpp b/src/text/placements/simple.cpp index 800a3d3e3..0bec3423d 100644 --- a/src/text/placements/simple.cpp +++ b/src/text/placements/simple.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,9 +32,7 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include #include #pragma GCC diagnostic pop @@ -43,12 +41,9 @@ namespace mapnik { -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -using phoenix::push_back; -using phoenix::ref; +namespace x3 = boost::spirit::x3; -struct direction_name : qi::symbols +struct direction_name : x3::symbols { direction_name() { @@ -62,10 +57,10 @@ struct direction_name : qi::symbols ("NW", NORTHWEST) ("SW", SOUTHWEST) ("X" , EXACT_POSITION) + ("C" , CENTER) ; } - -}; +} names; // Position string: [POS][SIZE] // [POS] is any combination of @@ -82,28 +77,22 @@ bool parse_positions(std::string const& evaluated_positions, std::vector & direction, std::vector & text_sizes) { - direction_name names; - boost::spirit::ascii::space_type space; - qi::_1_type _1; - qi::float_type float_; - std::string::const_iterator first = evaluated_positions.begin(); - std::string::const_iterator last = evaluated_positions.end(); - bool r = qi::phrase_parse(first, last, - (names[push_back(phoenix::ref(direction), _1)] % ',') - >> *(',' >> float_[push_back(phoenix::ref(text_sizes), _1)]), - space); - if (first != last) - { - return false; - } - return r; + auto push_back_direction = [&](auto const& ctx) { direction.push_back(_attr(ctx));}; + auto push_back_size = [&](auto const& ctx) { text_sizes.push_back(_attr(ctx));}; + auto const first = evaluated_positions.begin(); + auto const last = evaluated_positions.end(); + bool r = x3::phrase_parse(first, last, + (names[push_back_direction] % ',') + >> *(',' >> x3::float_[push_back_size]), + x3::space); + return (r && first != last); } text_placement_info_simple::text_placement_info_simple(text_placements_simple const* parent, std::string const& evaluated_positions, - double scale_factor) -: text_placement_info(parent, scale_factor), + double scale_factor_) +: text_placement_info(parent, scale_factor_), state(0), position_state(0), direction_(parent->direction_), @@ -147,10 +136,10 @@ bool text_placement_info_simple::next_position_only() const return true; } -text_placement_info_ptr text_placements_simple::get_placement_info(double scale_factor, feature_impl const& feature, attributes const& vars) const +text_placement_info_ptr text_placements_simple::get_placement_info(double scale_factor_, feature_impl const& feature, attributes const& vars) const { std::string evaluated_positions = util::apply_visitor(extract_value(feature,vars), positions_); - return std::make_shared(this, evaluated_positions, scale_factor); + return std::make_shared(this, evaluated_positions, scale_factor_); } text_placements_simple::text_placements_simple(symbolizer_base::value_type const& positions) diff --git a/src/text/properties_util.cpp b/src/text/properties_util.cpp index e08d4fd55..fa3e60d08 100644 --- a/src/text/properties_util.cpp +++ b/src/text/properties_util.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/text/renderer.cpp b/src/text/renderer.cpp index 163d11c6f..32e57f3ba 100644 --- a/src/text/renderer.cpp +++ b/src/text/renderer.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -66,8 +68,35 @@ void text_renderer::prepare_glyphs(glyph_positions const& positions) for (auto const& glyph_pos : positions) { glyph_info const& glyph = glyph_pos.glyph; - glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); //TODO: Optimize this? + FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; + FT_Face face = glyph.face->get_face(); + if (glyph.face->is_color()) + { + load_flags |= FT_LOAD_COLOR ; + if (face->num_fixed_sizes > 0) + { + int scaled_size = static_cast(glyph.format->text_size * scale_factor_); + int best_match = 0; + int diff = std::abs(scaled_size - face->available_sizes[0].width); + for (int i = 1; i < face->num_fixed_sizes; ++i) + { + int ndiff = std::abs(scaled_size - face->available_sizes[i].height); + if (ndiff < diff) + { + best_match = i; + diff = ndiff; + } + } + error = FT_Select_Size(face, best_match); + } + } + else + { + glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); + } + + double size = glyph.format->text_size * scale_factor_; matrix.xx = static_cast( glyph_pos.rot.cos * 0x10000L); matrix.xy = static_cast(-glyph_pos.rot.sin * 0x10000L); matrix.yx = static_cast( glyph_pos.rot.sin * 0x10000L); @@ -77,17 +106,13 @@ void text_renderer::prepare_glyphs(glyph_positions const& positions) pen.x = static_cast(pos.x * 64); pen.y = static_cast(pos.y * 64); - FT_Face face = glyph.face->get_face(); FT_Set_Transform(face, &matrix, &pen); - - error = FT_Load_Glyph(face, glyph.glyph_index, FT_LOAD_NO_HINTING); + error = FT_Load_Glyph(face, glyph.glyph_index, load_flags); if (error) continue; - FT_Glyph image; error = FT_Get_Glyph(face->glyph, &image); if (error) continue; - - glyphs_.emplace_back(image, *glyph.format); + glyphs_.emplace_back(image, *glyph.format, pos, size); } } @@ -101,7 +126,7 @@ void composite_bitmap(T & pixmap, FT_Bitmap *bitmap, unsigned rgba, int x, int y { for (int j = y, q = 0; j < y_max; ++j, ++q) { - unsigned gray=bitmap->buffer[q*bitmap->width+p]; + unsigned gray = bitmap->buffer[q * bitmap->width + p]; if (gray) { mapnik::composite_pixel(pixmap, comp_op, i, j, rgba, gray, opacity); @@ -110,6 +135,31 @@ void composite_bitmap(T & pixmap, FT_Bitmap *bitmap, unsigned rgba, int x, int y } } +template +void composite_color_bitmap(T & pixmap, FT_Bitmap *bitmap, int x, int y, double size, double opacity, composite_mode_e comp_op) +{ + image_rgba8 image(bitmap->width, bitmap->rows); + + for (unsigned i = 0, p = 0; i < bitmap->width; ++i, p += 4) + { + for (unsigned j = 0, q = 0; j < bitmap->rows; ++j, ++q) + { + std::uint8_t b = bitmap->buffer[q * bitmap->width * 4 + p]; + std::uint8_t g = bitmap->buffer[q * bitmap->width * 4 + p + 1]; + std::uint8_t r = bitmap->buffer[q * bitmap->width * 4 + p + 2]; + std::uint8_t a = bitmap->buffer[q * bitmap->width * 4 + p + 3]; + unsigned c = static_cast((a << 24) | (b << 16) | (g << 8) | (r)); + image(i, j) = c; + } + } + double scale = size/image.height(); + int scaled_width = bitmap->width * scale; + int scaled_height = bitmap->rows * scale; + image_rgba8 scaled_image(scaled_width, scaled_height); + scale_image_agg(scaled_image, image , SCALING_BILINEAR , scale, scale, 0.0, 0.0, 1.0, 0); + composite(pixmap, scaled_image, comp_op, opacity, x, y); +} + template agg_text_renderer::agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer, @@ -211,18 +261,38 @@ void agg_text_renderer::render(glyph_positions const& pos) { fill = glyph.properties.fill.rgba(); text_opacity = glyph.properties.text_opacity; + FT_Glyph_Transform(glyph.image, &matrix, &start); - error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1); - if (!error) + error = 0; + if ( glyph.image->format != FT_GLYPH_FORMAT_BITMAP ) + { + + error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1); + } + if (error == 0) { FT_BitmapGlyph bit = reinterpret_cast(glyph.image); - composite_bitmap(pixmap_, - &bit->bitmap, - fill, - bit->left, - height - bit->top, - text_opacity, - comp_op_); + int pixel_mode = bit->bitmap.pixel_mode; + if (pixel_mode == 7) + { + int x = (start.x >> 6) + glyph.pos.x; + int y = height - (start.y >> 6) + glyph.pos.y; + composite_color_bitmap(pixmap_, + &bit->bitmap, + x,y, glyph.size, + text_opacity, + comp_op_); + } + else + { + composite_bitmap(pixmap_, + &bit->bitmap, + fill, + bit->left, + height - bit->top, + text_opacity, + comp_op_); + } } FT_Done_Glyph(glyph.image); } @@ -257,7 +327,6 @@ void grid_text_renderer::render(glyph_positions const& pos, value_integer fea error = FT_Glyph_To_Bitmap(&glyph.image, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { - FT_BitmapGlyph bit = reinterpret_cast(glyph.image); render_halo_id(&bit->bitmap, feature_id, diff --git a/src/text/scrptrun.cpp b/src/text/scrptrun.cpp index 0cbb2c839..750998764 100644 --- a/src/text/scrptrun.cpp +++ b/src/text/scrptrun.cpp @@ -22,7 +22,7 @@ #include -#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) const char ScriptRun::fgClassID=0; @@ -124,7 +124,7 @@ UBool ScriptRun::next() if (scriptEnd >= charLimit) { return false; } - + scriptCode = USCRIPT_COMMON; for (scriptStart = scriptEnd; scriptEnd < charLimit; scriptEnd += 1) { @@ -178,7 +178,6 @@ UBool ScriptRun::next() if (sameScript(scriptCode, sc)) { if (scriptCode <= USCRIPT_INHERITED && sc > USCRIPT_INHERITED) { scriptCode = sc; - // now that we have a final script code, fix any open // characters we pushed before we knew the script code. while (startSP < parenSP) { @@ -205,4 +204,3 @@ UBool ScriptRun::next() return true; } - diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp index 9eae83cfa..17b4cec08 100644 --- a/src/text/symbolizer_helpers.cpp +++ b/src/text/symbolizer_helpers.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,14 +29,14 @@ #include #include #include -#include -#include +#include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -110,7 +110,7 @@ struct split_multi_geometries split_multi_geometries(container_type & cont) : cont_(cont) { } - void operator() (geometry::geometry_empty const&) const {} + void operator() (geometry::geometry_empty const&) const {} void operator() (geometry::multi_point const& multi_pt) const { for ( auto const& pt : multi_pt ) @@ -187,23 +187,26 @@ base_symbolizer_helper::base_symbolizer_helper( initialize_points(); } -struct largest_bbox_first +template +static It largest_bbox(It begin, It end) { - bool operator() (geometry::geometry const* g0, geometry::geometry const* g1) const + if (begin == end) { - box2d b0 = geometry::envelope(*g0); - box2d b1 = geometry::envelope(*g1); - return b0.width() * b0.height() > b1.width() * b1.height(); + return end; } - bool operator() (base_symbolizer_helper::geometry_cref const& g0, - base_symbolizer_helper::geometry_cref const& g1) const + It largest_geom = begin; + double largest_bbox = geometry::envelope(*largest_geom).area(); + for (++begin; begin != end; ++begin) { - // TODO - this has got to be expensive! Can we cache bbox's if there are repeated calls to same geom? - box2d b0 = geometry::envelope(g0); - box2d b1 = geometry::envelope(g1); - return b0.width() * b0.height() > b1.width() * b1.height(); + double bbox = geometry::envelope(*begin).area(); + if (bbox > largest_bbox) + { + largest_bbox = bbox; + largest_geom = begin; + } } -}; + return largest_geom; +} void base_symbolizer_helper::initialize_geometries() const { @@ -216,10 +219,16 @@ void base_symbolizer_helper::initialize_geometries() const type == geometry::geometry_types::MultiPolygon) { bool largest_box_only = text_props_->largest_bbox_only; - if (largest_box_only) + if (largest_box_only && geometries_to_process_.size() > 1) { - geometries_to_process_.sort(largest_bbox_first()); + auto largest_geom = largest_bbox( + geometries_to_process_.begin(), + geometries_to_process_.end()); geo_itr_ = geometries_to_process_.begin(); + if (geo_itr_ != largest_geom) + { + std::swap(*geo_itr_, *largest_geom); + } geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end()); } } @@ -318,10 +327,12 @@ text_symbolizer_helper::text_symbolizer_helper( value_bool clip = mapnik::get(sym_, feature_, vars_); value_double simplify_tolerance = mapnik::get(sym_, feature_, vars_); value_double smooth = mapnik::get(sym_, feature_, vars_); + value_double extend = mapnik::get(sym_, feature_, vars_); if (clip) converter_.template set(); converter_.template set(); //always transform converter_.template set(); + if (extend > 0.0) converter_.template set(); if (simplify_tolerance > 0.0) converter_.template set(); // optional simplify converter if (smooth > 0.0) converter_.template set(); // optional smooth converter @@ -443,12 +454,15 @@ text_symbolizer_helper::text_symbolizer_helper( value_bool clip = mapnik::get(sym_, feature_, vars_); value_double simplify_tolerance = mapnik::get(sym_, feature_, vars_); value_double smooth = mapnik::get(sym_, feature_, vars_); + value_double extend = mapnik::get(sym_, feature_, vars_); if (clip) converter_.template set(); converter_.template set(); //always transform converter_.template set(); + if (extend > 0.0) converter_.template set(); if (simplify_tolerance > 0.0) converter_.template set(); // optional simplify converter if (smooth > 0.0) converter_.template set(); // optional smooth converter + if (geometries_to_process_.size()) { init_marker(); diff --git a/src/text/text_layout.cpp b/src/text/text_layout.cpp index 3a3818c1f..9de48d44f 100644 --- a/src/text/text_layout.cpp +++ b/src/text/text_layout.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +35,7 @@ #pragma GCC diagnostic pop #include +#include namespace mapnik { @@ -62,31 +63,24 @@ pixel_position evaluate_displacement(double dx, double dy, directions_e dir) { case EXACT_POSITION: return pixel_position(dx,dy); - break; case NORTH: return pixel_position(0,-std::abs(dy)); - break; case EAST: return pixel_position(std::abs(dx),0); - break; case SOUTH: return pixel_position(0,std::abs(dy)); - break; case WEST: return pixel_position(-std::abs(dx),0); - break; case NORTHEAST: return pixel_position(std::abs(dx),-std::abs(dy)); - break; case SOUTHEAST: return pixel_position(std::abs(dx),std::abs(dy)); - break; case NORTHWEST: return pixel_position(-std::abs(dx),-std::abs(dy)); - break; case SOUTHWEST: return pixel_position(-std::abs(dx),std::abs(dy)); - break; + case CENTER: + return pixel_position(0, 0); default: return pixel_position(dx,dy); } diff --git a/src/text/text_line.cpp b/src/text/text_line.cpp index 2d0516731..77300aaf5 100644 --- a/src/text/text_line.cpp +++ b/src/text/text_line.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -64,7 +64,7 @@ void text_line::add_glyph(glyph_info && glyph, double scale_factor_) // Only add character spacing if the character is not a zero-width part of a cluster. width_ += advance + glyphs_.back().format->character_spacing * scale_factor_; glyphs_width_ += advance; - space_count_++; + ++space_count_; } glyphs_.emplace_back(std::move(glyph)); } diff --git a/src/text/text_properties.cpp b/src/text/text_properties.cpp index 73210d109..b25478db8 100644 --- a/src/text/text_properties.cpp +++ b/src/text/text_properties.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,6 +39,8 @@ #include #pragma GCC diagnostic pop +#include + namespace mapnik { using boost::optional; diff --git a/src/tiff_reader.cpp b/src/tiff_reader.cpp index 157e4d0cb..b6ccef80e 100644 --- a/src/tiff_reader.cpp +++ b/src/tiff_reader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/transform_expression.cpp b/src/transform_expression.cpp index 34c704866..996ba8873 100644 --- a/src/transform_expression.cpp +++ b/src/transform_expression.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // stl #include diff --git a/src/transform_expression_grammar.cpp b/src/transform_expression_grammar.cpp deleted file mode 100644 index 170b0a823..000000000 --- a/src/transform_expression_grammar.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include -#include - -template struct mapnik::transform_expression_grammar; diff --git a/src/json/mapnik_json_geometry_grammar.cpp b/src/transform_expression_grammar_x3.cpp similarity index 76% rename from src/json/mapnik_json_geometry_grammar.cpp rename to src/transform_expression_grammar_x3.cpp index f2b96f230..cc0839613 100644 --- a/src/json/mapnik_json_geometry_grammar.cpp +++ b/src/transform_expression_grammar_x3.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +20,11 @@ * *****************************************************************************/ -#include -#include +#include +#include -using iterator_type = char const*; -template struct mapnik::json::geometry_grammar; +namespace mapnik { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(transform_expression_grammar_type, iterator_type, context_type); + +}} diff --git a/src/twkb.cpp b/src/twkb.cpp index 64ef6aa34..099a1b098 100644 --- a/src/twkb.cpp +++ b/src/twkb.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include namespace mapnik { namespace detail { @@ -82,7 +82,7 @@ public: mapnik::geometry::geometry read() { - mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); + mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); // Read the metadata bytes, populating all the // information about optional fields, extended (z/m) dimensions // expansion factors and so on diff --git a/src/unicode.cpp b/src/unicode.cpp index c96c58914..0c0d4a1ef 100644 --- a/src/unicode.cpp +++ b/src/unicode.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // std #include diff --git a/src/util/utf_conv_win.cpp b/src/util/utf_conv_win.cpp index 7bfcbc29f..f3a41ec55 100644 --- a/src/util/utf_conv_win.cpp +++ b/src/util/utf_conv_win.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/value.cpp b/src/value.cpp index b5ad606c7..7dfb9f4ed 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -22,7 +22,7 @@ // mapnik #include -#include +#include #include // stl diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp index dd7b0202f..3cd1745fc 100644 --- a/src/vertex_adapters.cpp +++ b/src/vertex_adapters.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace mapnik { namespace geometry { diff --git a/src/vertex_cache.cpp b/src/vertex_cache.cpp index c0d575892..b6516953b 100644 --- a/src/vertex_cache.cpp +++ b/src/vertex_cache.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/warp.cpp b/src/warp.cpp index 29cfa44cc..f4ecc22fe 100644 --- a/src/warp.cpp +++ b/src/warp.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/webp_reader.cpp b/src/webp_reader.cpp index ca611aeef..a1077bb5f 100644 --- a/src/webp_reader.cpp +++ b/src/webp_reader.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +37,7 @@ extern "C" // stl #include +#include namespace mapnik { diff --git a/src/well_known_srs.cpp b/src/well_known_srs.cpp index 445d84aee..7f8dec2a8 100644 --- a/src/well_known_srs.cpp +++ b/src/well_known_srs.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/wkb.cpp b/src/wkb.cpp index 21a07fd97..8966afe3b 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,9 @@ #include #include #include -#include +#include + +#include namespace mapnik { @@ -119,7 +121,7 @@ public: mapnik::geometry::geometry read() { - mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); + mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); int type = read_integer(); switch (type) { diff --git a/src/wkt/geometry_to_wkt.cpp b/src/wkt/geometry_to_wkt.cpp new file mode 100644 index 000000000..3460dfec4 --- /dev/null +++ b/src/wkt/geometry_to_wkt.cpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include +// boost +#include + +namespace mapnik { namespace util { + +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) +{ + using sink_type = std::back_insert_iterator; + static const mapnik::wkt::wkt_generator_grammar> generator; + sink_type sink(wkt); + return boost::spirit::karma::generate(sink, generator, geom); +} + +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) +{ + using sink_type = std::back_insert_iterator; + static const mapnik::wkt::wkt_generator_grammar> generator; + sink_type sink(wkt); + return boost::spirit::karma::generate(sink, generator, geom); +} + +}} diff --git a/src/wkt/mapnik_wkt_generator_grammar.cpp b/src/wkt/mapnik_wkt_generator_grammar.cpp index 07813fcc8..a7267b71f 100644 --- a/src/wkt/mapnik_wkt_generator_grammar.cpp +++ b/src/wkt/mapnik_wkt_generator_grammar.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,10 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ - -#include -#include #include +#include +#include namespace mapnik { namespace wkt { diff --git a/src/wkt/wkt_factory.cpp b/src/wkt/wkt_factory.cpp new file mode 100644 index 000000000..acb388434 --- /dev/null +++ b/src/wkt/wkt_factory.cpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +namespace mapnik { + +bool from_wkt(std::string const& wkt, mapnik::geometry::geometry & geom) +{ + using namespace boost::spirit; + x3::ascii::space_type space; + std::string::const_iterator itr = wkt.begin(); + std::string::const_iterator end = wkt.end(); + bool result; + try + { + result = x3::phrase_parse(itr, end, wkt_grammar(), space, geom); + } + catch (x3::expectation_failure const& ex) + { + return false; + } + return result && itr==end; +} + +} diff --git a/src/expression_grammar.cpp b/src/wkt/wkt_grammar_x3.cpp similarity index 72% rename from src/expression_grammar.cpp rename to src/wkt/wkt_grammar_x3.cpp index 09234a07f..eeb602e7d 100644 --- a/src/expression_grammar.cpp +++ b/src/wkt/wkt_grammar_x3.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,13 @@ * *****************************************************************************/ -// NOTE: we define this here in a cpp because def is needed twice: -// once by src/expression.cpp and once by mapnik/transform_expression_grammar_impl.hpp -#include -#include +#include -template struct mapnik::expression_grammar; +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; +BOOST_SPIRIT_INSTANTIATE(wkt_grammar_type, iterator_type, context_type); + +}} diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 2e2a7df8e..84e1f0d4d 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +38,7 @@ // stl #include +#include namespace mapnik { @@ -133,13 +134,13 @@ node_not_found::node_not_found(std::string const& node_name) : node_name_(node_name), msg_() {} -const char* node_not_found::what() const throw() +const char* node_not_found::what() const noexcept { msg_ = std::string("Node "+node_name_+ "not found"); return msg_.c_str(); } -node_not_found::~node_not_found() throw() {} +node_not_found::~node_not_found() {} attribute_not_found::attribute_not_found(std::string const& node_name, @@ -148,25 +149,25 @@ attribute_not_found::attribute_not_found(std::string const& node_name, attribute_name_(attribute_name), msg_() {} -const char* attribute_not_found::what() const throw() +const char* attribute_not_found::what() const noexcept { msg_ = std::string("Attribute '" + attribute_name_ +"' not found in node '"+node_name_+ "'"); return msg_.c_str(); } -attribute_not_found::~attribute_not_found() throw() {} +attribute_not_found::~attribute_not_found() {} more_than_one_child::more_than_one_child(std::string const& node_name) : node_name_(node_name), msg_() {} -const char* more_than_one_child::what() const throw() +const char* more_than_one_child::what() const noexcept { msg_ = std::string("More than one child node in node '" + node_name_ +"'"); return msg_.c_str(); } -more_than_one_child::~more_than_one_child() throw() {} +more_than_one_child::~more_than_one_child() {} xml_node::xml_node(xml_tree &tree, std::string && name, unsigned line, bool is_text) : tree_(tree), @@ -229,9 +230,9 @@ xml_node & xml_node::add_child(const char * name, unsigned line, bool is_text) return children_.back(); } -void xml_node::add_attribute(const char * name, const char * value) +void xml_node::add_attribute(const char * name, const char * value_) { - auto result = attributes_.emplace(name,xml_attribute(value)); + auto result = attributes_.emplace(name,xml_attribute(value_)); if (!result.second) { MAPNIK_LOG_ERROR(xml_tree) << "ignoring duplicate attribute '" << name << "'"; @@ -345,16 +346,16 @@ boost::optional xml_node::get_opt_attr(std::string const& name) const template T xml_node::get_attr(std::string const& name, T const& default_opt_value) const { - boost::optional value = get_opt_attr(name); - if (value) return *value; + boost::optional val = get_opt_attr(name); + if (val) return *val; return default_opt_value; } template T xml_node::get_attr(std::string const& name) const { - boost::optional value = get_opt_attr(name); - if (value) return *value; + boost::optional val = get_opt_attr(name); + if (val) return *val; throw attribute_not_found(name_, name); } diff --git a/test/build.py b/test/build.py index 78fd9342a..8a9a44523 100644 --- a/test/build.py +++ b/test/build.py @@ -54,6 +54,7 @@ else: visual/report.cpp visual/runner.cpp visual/run.cpp + visual/parse_map_sizes.cpp """ ) test_program3 = test_env_local.Program('visual/run', source=source) diff --git a/test/data b/test/data index 6ce59adfc..dac50a321 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 6ce59adfc4f11b16a5dc0e2020c36dc614850989 +Subproject commit dac50a321bdcc92c6183ded08200eb8fa117532c diff --git a/test/data-visual b/test/data-visual index 941db3d00..b399ad677 160000 --- a/test/data-visual +++ b/test/data-visual @@ -1 +1 @@ -Subproject commit 941db3d00920dc7aceaa6797096a7228bc7bac14 +Subproject commit b399ad677146c9d7b1c11470691b7a332d95b156 diff --git a/test/standalone/font_registration_test.cpp b/test/standalone/font_registration_test.cpp index a5ba0b271..765406443 100644 --- a/test/standalone/font_registration_test.cpp +++ b/test/standalone/font_registration_test.cpp @@ -57,7 +57,7 @@ SECTION("registration") { mapnik::load_map_string(m3,""); REQUIRE( m3.get_font_memory_cache().size() == 0 ); REQUIRE( m3.load_fonts() ); - REQUIRE( m3.get_font_memory_cache().size() == 1 ); + REQUIRE( m3.get_font_memory_cache().size() == 2 ); std::vector face_names; std::string foo("foo"); diff --git a/test/unit/color/css_color.cpp b/test/unit/color/css_color.cpp index f1bc17196..a532cb1cf 100644 --- a/test/unit/color/css_color.cpp +++ b/test/unit/color/css_color.cpp @@ -1,63 +1,113 @@ #include "catch.hpp" -#include -#include + #include +#include +#include +#include + #include -TEST_CASE("css color") { +TEST_CASE("CSS color") { SECTION("conversions") { - mapnik::percent_conv_impl conv; - CHECK( conv(1.0) == 3 ); - CHECK( conv(60.0) == 153 ); + using namespace mapnik::css_color_grammar; + CHECK( percent_converter::call(1.0) == 3 ); + CHECK( percent_converter::call(60.0) == 153 ); // should not overflow on invalid input - CHECK( conv(100000.0) == 255 ); - CHECK( conv(-100000.0) == 0 ); - - mapnik::alpha_conv_impl conv2; - CHECK( conv2(0.5) == 128 ); - CHECK( conv2(1.0) == 255 ); - // should not overflow on invalid input - CHECK( conv2(60.0) == 255 ); - CHECK( conv2(100000.0) == 255 ); - CHECK( conv2(-100000.0) == 0 ); - - mapnik::hsl_conv_impl conv3; - mapnik::color c; - conv3(c, 1.0, 1.0, 1.0); - CHECK( c.alpha() == 255 ); - CHECK( c.red() == 3 ); - CHECK( c.green() == 3 ); - CHECK( c.blue() == 3 ); - // invalid - conv3(c, -1, -1, -1); - CHECK( c.alpha() == 255 ); // should not be touched by hsl converter - CHECK( c.red() == 0 ); - CHECK( c.green() == 0 ); - CHECK( c.blue() == 0 ); + CHECK( percent_converter::call(100000.0) == 255 ); + CHECK( percent_converter::call(-100000.0) == 0 ); } - SECTION("hex colors") + SECTION("CSS colors") { - mapnik::css_color_grammar color_grammar; - boost::spirit::qi::ascii::space_type space; - + auto const& color_grammar = mapnik::color_grammar(); + boost::spirit::x3::ascii::space_type space; + { + // rgb + std::string s("rgb(128,0,255)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0xff ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgb (percent) + std::string s("rgb(50%,0%,100%)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0xff ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgba + std::string s("rgba(128,0,255,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0x80 ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgba (percent) + std::string s("rgba(50%,0%,100%,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0x80 ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // named colours + std::string s("darksalmon"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 255 ); + CHECK( c.red() == 233 ); + CHECK( c.green() == 150 ); + CHECK( c.blue() == 122 ); + } + // hsl + { + std::string s("hsl(240,50%,50%)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 255 ); + CHECK( c.red() == 64 ); + CHECK( c.green() == 64 ); + CHECK( c.blue() == 191 ); + } + // hsla + { + std::string s("hsla(240,50%,50%,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 128 ); + CHECK( c.red() == 64 ); + CHECK( c.green() == 64 ); + CHECK( c.blue() == 191 ); + } + // hex colours { std::string s("#abcdef"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); CHECK( c.blue() == 0xef ); } - { std::string s("#abcdef12"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0x12 ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -67,7 +117,7 @@ TEST_CASE("css color") { { std::string s(" #abcdef"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -77,7 +127,7 @@ TEST_CASE("css color") { { std::string s(" #abcdef12"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0x12 ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -86,22 +136,26 @@ TEST_CASE("css color") { { std::string s("# abcdef"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("# abcdef12"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#ab cdef"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#ab cdef12"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } // hex_color_small @@ -109,7 +163,7 @@ TEST_CASE("css color") { { std::string s("#abc"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -119,7 +173,7 @@ TEST_CASE("css color") { { std::string s("#abcd"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xdd ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -129,7 +183,7 @@ TEST_CASE("css color") { { std::string s(" #abc"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -139,7 +193,7 @@ TEST_CASE("css color") { { std::string s(" #abcd"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xdd ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -148,22 +202,26 @@ TEST_CASE("css color") { { std::string s("# abc"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("# abcd"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#a bc"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#a bcd"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } } SECTION("operator<< / to_string()") diff --git a/test/unit/core/box2d_test.cpp b/test/unit/core/box2d_test.cpp index 8385bba7c..1db9a0a93 100644 --- a/test/unit/core/box2d_test.cpp +++ b/test/unit/core/box2d_test.cpp @@ -1,8 +1,7 @@ - #include "catch.hpp" #include -#include +#include #include "agg_trans_affine.h" TEST_CASE("box2d") { diff --git a/test/unit/core/comparison_test.cpp b/test/unit/core/comparison_test.cpp index 7e8e8e414..886b52960 100644 --- a/test/unit/core/comparison_test.cpp +++ b/test/unit/core/comparison_test.cpp @@ -1,7 +1,6 @@ - #include "catch.hpp" -#include +#include #include TEST_CASE("comparison") diff --git a/test/unit/core/conversions_test.cpp b/test/unit/core/conversions_test.cpp index 43592af01..98d2bacf4 100644 --- a/test/unit/core/conversions_test.cpp +++ b/test/unit/core/conversions_test.cpp @@ -1,7 +1,6 @@ - #include "catch.hpp" -#include +#include #include #include #include @@ -284,16 +283,19 @@ SECTION("to string") { REQUIRE( string2bool("true",val) ); REQUIRE( val == true ); - // mapnik::value hashability - using values_container = std::unordered_map; + // mapnik::value hash() and operator== works for all T in value + mapnik::transcoder tr("utf8"); + using values_container = std::unordered_map; values_container vc; - mapnik::value val2(1); - vc[val2] = 1; - REQUIRE( vc[1] == static_cast(1) ); + mapnik::value keys[5] = {true, 123456789, 3.14159f, tr.transcode("Мапник"), mapnik::value_null()} ; + for (auto const& k : keys) + { + vc.insert({k, k}); + REQUIRE( vc[k] == k ); + } // mapnik::value << to ostream std::stringstream s; - mapnik::transcoder tr("utf-8"); mapnik::value_unicode_string ustr = tr.transcode("hello world!"); mapnik::value streamable(ustr); s << streamable; diff --git a/test/unit/core/expressions_test.cpp b/test/unit/core/expressions_test.cpp index 22ba3c00d..a01c5bdea 100644 --- a/test/unit/core/expressions_test.cpp +++ b/test/unit/core/expressions_test.cpp @@ -125,9 +125,9 @@ TEST_CASE("expressions") // geometry types TRY_CHECK(eval(" [mapnik::geometry_type] = point ") == true); - TRY_CHECK(eval(" [mapnik::geometry_type] <> linestring ") == true); - TRY_CHECK(eval(" [mapnik::geometry_type] != polygon ") == true); - TRY_CHECK(eval(" [mapnik::geometry_type] neq collection ") == true); + TRY_CHECK(eval(" [ mapnik::geometry_type] <> linestring ") == true); + TRY_CHECK(eval(" [mapnik::geometry_type ] != polygon ") == true); + TRY_CHECK(eval(" [ mapnik::geometry_type ] neq collection ") == true); TRY_CHECK(eval(" [mapnik::geometry_type] eq collection ") == false); //unary expression @@ -183,7 +183,16 @@ TEST_CASE("expressions") auto val1 = eval("'♜♞♝♛♚♝♞♜'.replace('♞','♘')"); // ==> expected ♜♘♝♛♚♝♘♜ TRY_CHECK(val0 == val1); TRY_CHECK(val0.to_string() == val1.to_string()); // UTF-8 - TRY_CHECK(val0.to_unicode() == val1.to_unicode()); // Unicode (UTF-16) + TRY_CHECK(val0.to_unicode() == val1.to_unicode()); // Unicode + // \u+NNNN \U+NNNNNNNN \xNN\xNN + auto val3 = eval(u8"'\u262f\xF0\x9F\x8D\xB7'"); + auto val4 = eval(u8"'\U0000262f\U0001F377'"); + // UTF16 surrogate pairs work also ;) + // \ud83d\udd7a\ud83c\udffc => \U0001F57A\U0001F3FC works also + // TODO: find a way to enter UTF16 pairs + TRY_CHECK(val3 == val4); + TRY_CHECK(val3.to_string() == val4.to_string()); // UTF-8 + TRY_CHECK(val3.to_unicode() == val4.to_unicode()); // Unicode // following test will fail if boost_regex is built without ICU support (unpaired surrogates in output) TRY_CHECK(eval("[name].replace('(\\B)|( )',' ') ") == tr.transcode("Q u é b e c")); diff --git a/test/unit/core/params_test.cpp b/test/unit/core/params_test.cpp index 3131f0cbc..0363d24a4 100644 --- a/test/unit/core/params_test.cpp +++ b/test/unit/core/params_test.cpp @@ -1,8 +1,7 @@ - #include "catch.hpp" #include -#include +#include #include #include diff --git a/test/unit/core/transform_expressions_test.cpp b/test/unit/core/transform_expressions_test.cpp new file mode 100644 index 000000000..b2195fb50 --- /dev/null +++ b/test/unit/core/transform_expressions_test.cpp @@ -0,0 +1,60 @@ +#include "catch.hpp" + +#include +#include + +namespace { + + +bool test_transform_expressions(std::string const& in, std::string const& out) +{ + auto tr_list = mapnik::parse_transform(in); + return mapnik::to_expression_string(*tr_list) == out; +} + +} + +TEST_CASE("transform-expressions") +{ + // matrix + CHECK(test_transform_expressions("matrix( 1,2,3,4,5, 6)", "matrix(1, 2, 3, 4, 5, 6)")); + CHECK(test_transform_expressions("matrix(1 2 3 4 5 6)", "matrix(1, 2, 3, 4, 5, 6)")); + CHECK(test_transform_expressions("matrix(1,2,3,4,5,4*2-1)", "matrix(1, 2, 3, 4, 5, (4*2-1))")); + CHECK(test_transform_expressions("matrix(1,2,3,4,5,[value])", "matrix(1, 2, 3, 4, 5, [value])")); + CHECK(test_transform_expressions("matrix(1,2,@value,4,5,6)", "matrix(1, 2, @value, 4, 5, 6)")); + CHECK(test_transform_expressions("matrix(1,2,3,4,5,@value)", "matrix(1, 2, 3, 4, 5, @value)")); + + // translate + CHECK(test_transform_expressions("translate(100)", "translate(100)")); + CHECK(test_transform_expressions("translate([tx])", "translate([tx])")); + CHECK(test_transform_expressions("translate(100 200)", "translate(100, 200)")); + CHECK(test_transform_expressions("translate([tx],[ty])", "translate([tx], [ty])")); + CHECK(test_transform_expressions("translate([tx],200)", "translate([tx], 200)")); + CHECK(test_transform_expressions("translate(100,[ty])", "translate(100, [ty])")); + + // scale + CHECK(test_transform_expressions("scale(1.5)", "scale(1.5)")); + CHECK(test_transform_expressions("scale([sx])", "scale([sx])")); + CHECK(test_transform_expressions("scale([sx],1.5)", "scale([sx], 1.5)")); + CHECK(test_transform_expressions("scale(1.5,[sy])", "scale(1.5, [sy])")); + CHECK(test_transform_expressions("scale([sx],[sy]/2)", "scale([sx], [sy]/2)")); + + // rotate + CHECK(test_transform_expressions("rotate([a] -2)", "rotate(([a]-2))")); + CHECK(test_transform_expressions("rotate([a] -2 -3)", "rotate((([a]-2)-3))")); + CHECK(test_transform_expressions("rotate([a],-2,-3)", "rotate([a], -2, -3)")); + CHECK(test_transform_expressions("rotate([a] -2 -3 -4)", "rotate(((([a]-2)-3)-4))")); + CHECK(test_transform_expressions("rotate([a] -2, 3, 4)", "rotate(([a]-2), 3, 4)")); + + // skewX + CHECK(test_transform_expressions("skewX(2)", "skewX(2)")); + CHECK(test_transform_expressions("skewX(2*[x]+[y])", "skewX((2*[x]+[y]))")); + + // skewY + CHECK(test_transform_expressions("skewY(2)", "skewY(2)")); + CHECK(test_transform_expressions("skewY(2*[x]+[y])", "skewY((2*[x]+[y]))")); + + // compound + CHECK(test_transform_expressions("translate([tx]) rotate([a])", "translate([tx]) rotate([a])")); + CHECK(test_transform_expressions("rotate(30+@global_value) scale(2*[sx],[sy])", "rotate((30+@global_value)) scale(2*[sx], [sy])")); +} diff --git a/test/unit/core/value_test.cpp b/test/unit/core/value_test.cpp index cdb64dbbe..a76910a26 100644 --- a/test/unit/core/value_test.cpp +++ b/test/unit/core/value_test.cpp @@ -1,7 +1,6 @@ - #include "catch.hpp" -#include +#include #include TEST_CASE("mapnik::value") diff --git a/test/unit/datasource/csv.cpp b/test/unit/datasource/csv.cpp index 6142185ca..18c337702 100644 --- a/test/unit/datasource/csv.cpp +++ b/test/unit/datasource/csv.cpp @@ -28,8 +28,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/test/unit/datasource/ds_test_util.hpp b/test/unit/datasource/ds_test_util.hpp index dd2e4a242..cbdbe4921 100644 --- a/test/unit/datasource/ds_test_util.hpp +++ b/test/unit/datasource/ds_test_util.hpp @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include namespace { @@ -131,7 +131,7 @@ struct feature_count return mapnik::util::apply_visitor(*this, geom); } - std::size_t operator()(mapnik::geometry::geometry_empty const &) const + std::size_t operator()(mapnik::geometry::geometry_empty const &) const { return 0; } diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp index c4951860b..2311c5273 100644 --- a/test/unit/datasource/geojson.cpp +++ b/test/unit/datasource/geojson.cpp @@ -27,10 +27,12 @@ #include #include #include -#include +#include +#include +#include #include #include - +#include #include /* @@ -115,6 +117,50 @@ TEST_CASE("geojson") { } } + SECTION("GeoJSON empty Geometries handling") + { + auto valid_empty_geometries = + { + "null", // Point can't be empty + "{ \"type\": \"LineString\", \"coordinates\": [] }", + "{ \"type\": \"Polygon\", \"coordinates\": [ [ ] ] } ", + "{ \"type\": \"MultiPoint\", \"coordinates\": [ ] }", + "{ \"type\": \"MultiLineString\", \"coordinates\": [ [] ] }", + "{ \"type\": \"MultiPolygon\", \"coordinates\": [[ []] ] }" + }; + + for (auto const& in : valid_empty_geometries) + { + std::string json(in); + mapnik::geometry::geometry geom; + CHECK(mapnik::json::from_geojson(json, geom)); + // round trip + std::string json_out; + CHECK(mapnik::util::to_geojson(json_out, geom)); + json.erase(std::remove_if( + std::begin(json), std::end(json), + [l = std::locale{}](auto ch) { return std::isspace(ch, l); } + ), std::end(json)); + REQUIRE(json == json_out); + } + + auto invalid_empty_geometries = + { + "{ \"type\": \"Point\", \"coordinates\": [] }", + "{ \"type\": \"LineString\", \"coordinates\": [[]] }" + "{ \"type\": \"Polygon\", \"coordinates\": [[[]]] }", + "{ \"type\": \"MultiPoint\", \"coordinates\": [[]] }", + "{ \"type\": \"MultiLineString\", \"coordinates\": [[[]]] }", + "{ \"type\": \"MultiPolygon\", \"coordinates\": [[[[]]]] }" + }; + + for (auto const& json : invalid_empty_geometries) + { + mapnik::geometry::geometry geom; + CHECK(!mapnik::json::from_geojson(json, geom)); + } + } + SECTION("GeoJSON num_features_to_query") { std::string filename = "./test/data/json/featurecollection-multipleprops.geojson"; diff --git a/test/unit/datasource/postgis.cpp b/test/unit/datasource/postgis.cpp index 95ee65851..f74ee1548 100644 --- a/test/unit/datasource/postgis.cpp +++ b/test/unit/datasource/postgis.cpp @@ -25,7 +25,8 @@ #include #include -#include +#include +#include #include /* @@ -185,6 +186,24 @@ TEST_CASE("postgis") { CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); } + SECTION("Postgis properly escapes names with single quotes") + { + mapnik::parameters params(base_params); + params["table"] = "\"test'single'quotes\""; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); + } + + SECTION("Postgis properly escapes names with double quotes") + { + mapnik::parameters params(base_params); + params["table"] = "\"test\"\"double\"\"quotes\""; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); + } + SECTION("Postgis query field names") { mapnik::parameters params(base_params); @@ -270,6 +289,55 @@ TEST_CASE("postgis") { REQUIRE(ext.maxy() == 4); } + SECTION("Postgis doesn't interpret @domain in email address as @variable") + { + mapnik::parameters params(base_params); + params["table"] = "(SELECT gid, geom, 'fake@mail.ru' as email" + " FROM public.test LIMIT 1) AS data"; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + auto featureset = all_features(ds); + auto feature = featureset->next(); + CHECKED_IF(feature != nullptr) + { + CHECK(feature->get("email").to_string() == "fake@mail.ru"); + } + } + + SECTION("Postgis interpolates !@uservar! tokens in query") + { + mapnik::parameters params(base_params); + params["table"] = "(SELECT * FROM public.test" + " WHERE GeometryType(geom) = !@wantedGeomType!" + " LIMIT 1) AS data"; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + + mapnik::transcoder tr("utf8"); + mapnik::query qry(ds->envelope()); + qry.set_variables({{"wantedGeomType", tr.transcode("POINT")}}); + CHECK(qry.variables().count("wantedGeomType") == 1); + + auto featureset = ds->features(qry); + auto feature = featureset->next(); + CHECKED_IF(feature != nullptr) + { + auto const& geom = feature->get_geometry(); + CHECK(mapnik::geometry::geometry_type(geom) == mapnik::geometry::Point); + } + + qry.set_variables({{"wantedGeomType", tr.transcode("POLYGON")}}); + CHECK(qry.variables().count("wantedGeomType") == 1); + + featureset = ds->features(qry); + feature = featureset->next(); + CHECKED_IF(feature != nullptr) + { + auto const& geom = feature->get_geometry(); + CHECK(mapnik::geometry::geometry_type(geom) == mapnik::geometry::Polygon); + } + } + SECTION("Postgis query extent: full dataset") { //include schema to increase coverage diff --git a/test/unit/datasource/topojson.cpp b/test/unit/datasource/topojson.cpp index 7bf155e33..229e7d9b1 100644 --- a/test/unit/datasource/topojson.cpp +++ b/test/unit/datasource/topojson.cpp @@ -26,14 +26,11 @@ #include #include #include -#include +#include #include namespace { -using iterator_type = char const*; -const mapnik::topojson::topojson_grammar grammar; - bool parse_topology(std::string const& filename, mapnik::topojson::topology & topo) { mapnik::util::file file(filename); @@ -41,11 +38,22 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to buffer.resize(file.size()); std::fread(&buffer[0], buffer.size(), 1, file.get()); if (!file) return false; - boost::spirit::standard::space_type space; - iterator_type itr = buffer.c_str(); - iterator_type end = itr + buffer.length(); - bool result = boost::spirit::qi::phrase_parse(itr, end, grammar, space, topo); - return (result && (itr == end)); + using space_type = boost::spirit::x3::standard::space_type; + char const* itr = buffer.c_str(); + char const* end = itr + buffer.length(); + try + { + boost::spirit::x3::phrase_parse(itr, end, mapnik::json::topojson_grammar(), space_type() , topo); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + std::cerr << "failed to parse TopoJSON..." << std::endl; + std::cerr << ex.what() << std::endl; + std::cerr << "Expected: " << ex.which(); + std::cerr << " Got: \"" << std::string(ex.where(), ex.where() + 200) << "...\"" << std::endl; + return false; + } + return (itr == end); } } diff --git a/test/unit/font/fontset_runtime_test.cpp b/test/unit/font/fontset_runtime_test.cpp index bfbae2786..1182807cd 100644 --- a/test/unit/font/fontset_runtime_test.cpp +++ b/test/unit/font/fontset_runtime_test.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -12,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -69,4 +68,4 @@ SECTION("error") { REQUIRE(std::string(ex.what()) == std::string("Unable to find specified font face 'DejaVu Sans Book' in font set: 'fontset'")); } } -} \ No newline at end of file +} diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index 4549bec9b..c4b3619ac 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry centroid") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; mapnik::geometry::point centroid; REQUIRE(!mapnik::geometry::centroid(geom, centroid)); } diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp index 10551d363..2b26f91df 100644 --- a/test/unit/geometry/geometry_envelope_test.cpp +++ b/test/unit/geometry/geometry_envelope_test.cpp @@ -1,7 +1,7 @@ #include "catch.hpp" #include -#include +#include namespace { @@ -21,7 +21,7 @@ void envelope_test() } { // Test empty geom - geometry geom = mapnik::geometry::geometry_empty(); + geometry geom = mapnik::geometry::geometry_empty(); mapnik::box2d bbox = mapnik::geometry::envelope(geom); REQUIRE_FALSE( bbox.valid() ); } diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp index 97e0bf26a..65c2bfbc7 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -107,7 +107,7 @@ struct geometry_equal_visitor } template - void operator() (geometry_empty const&, geometry_empty const&) const + void operator() (geometry_empty const&, geometry_empty const&) const { REQUIRE(true); } diff --git a/test/unit/geometry/geometry_hit_test.cpp b/test/unit/geometry/geometry_hit_test.cpp index afc7dfa9c..0f5196a7c 100644 --- a/test/unit/geometry/geometry_hit_test.cpp +++ b/test/unit/geometry/geometry_hit_test.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include TEST_CASE("geometry ops") { diff --git a/test/unit/geometry/geometry_is_simple.cpp b/test/unit/geometry/geometry_is_simple.cpp index 936c3caae..cb8421582 100644 --- a/test/unit/geometry/geometry_is_simple.cpp +++ b/test/unit/geometry/geometry_is_simple.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include TEST_CASE("geometry is_simple") { @@ -10,7 +10,7 @@ TEST_CASE("geometry is_simple") { #if BOOST_VERSION >= 105800 SECTION("point") { - mapnik::geometry::geometry_empty empty; + mapnik::geometry::geometry_empty empty; CHECK( mapnik::geometry::is_simple(empty) ); } @@ -280,6 +280,7 @@ SECTION("multi polygon") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; + ring.emplace_back(0,0); ring.emplace_back(1,0); ring.emplace_back(1,1); diff --git a/test/unit/geometry/geometry_is_valid.cpp b/test/unit/geometry/geometry_is_valid.cpp index f8227b050..734cf5a3c 100644 --- a/test/unit/geometry/geometry_is_valid.cpp +++ b/test/unit/geometry/geometry_is_valid.cpp @@ -1,7 +1,7 @@ #include "catch.hpp" #include -#include +#include TEST_CASE("geometry is_valid") { @@ -10,7 +10,7 @@ TEST_CASE("geometry is_valid") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty empty; + mapnik::geometry::geometry_empty empty; CHECK( mapnik::geometry::is_valid(empty) ); std::string message; CHECK( mapnik::geometry::is_valid(empty, message) ); diff --git a/test/unit/geometry/geometry_reprojection.cpp b/test/unit/geometry/geometry_reprojection.cpp index 95bfdb099..cf64a41e8 100644 --- a/test/unit/geometry/geometry_reprojection.cpp +++ b/test/unit/geometry/geometry_reprojection.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include TEST_CASE("geometry reprojection") { @@ -15,10 +15,10 @@ SECTION("test_projection_4326_3857 - Empty Geometry Object") { mapnik::projection dest("+init=epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { - geometry_empty geom; + geometry_empty geom; unsigned int err = 0; // Test Standard Transform - geometry_empty new_geom = reproject_copy(geom, proj_trans, err); + geometry_empty new_geom = reproject_copy(geom, proj_trans, err); REQUIRE(err == 0); // Transform providing projections not transfrom new_geom = reproject_copy(geom, source, dest, err); @@ -41,20 +41,20 @@ SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") { mapnik::projection dest("+init=epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { - geometry geom = geometry_empty(); + geometry geom = geometry_empty(); unsigned int err = 0; // Test Standard Transform geometry new_geom = reproject_copy(geom, proj_trans, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); // Transform providing projections not transfrom new_geom = reproject_copy(geom, source, dest, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); // Transform providing projections in reverse new_geom = reproject_copy(geom, dest, source, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); // Transform in place REQUIRE(reproject(new_geom, proj_trans)); // Transform in place providing projections @@ -268,7 +268,7 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") { // Reprojecting empty line string will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -455,7 +455,7 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -595,7 +595,7 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") { // Reprojecting empty multi point will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -751,7 +751,7 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") // Reprojecting empty line string will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -945,7 +945,7 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -1139,7 +1139,7 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index cb20cb74a..2e63cc9d4 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -5,11 +5,12 @@ #include #include #include -#include -#include +#include +#include #include #include +#if 0 TEST_CASE("geometry strategy tests") { SECTION("proj and view strategy") { using namespace mapnik::geometry; @@ -183,3 +184,4 @@ SECTION("scaling strategies - double to int64") { } } // END SECTION } // END TEST CASE +#endif diff --git a/test/unit/geometry/geometry_test_helper.cpp b/test/unit/geometry/geometry_test_helper.cpp index 44bcce596..98c254b55 100644 --- a/test/unit/geometry/geometry_test_helper.cpp +++ b/test/unit/geometry/geometry_test_helper.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include namespace mapnik { namespace geometry { diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index ff2e40f23..79159d173 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry has_empty") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; REQUIRE(!mapnik::geometry::has_empty(geom)); } @@ -18,7 +18,7 @@ SECTION("geometry collection") { } { mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; + mapnik::geometry::geometry_empty geom1; geom.emplace_back(std::move(geom1)); REQUIRE(mapnik::geometry::has_empty(geom)); } diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 25ed8a487..6f6ed2ed2 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry is_empty") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; REQUIRE(mapnik::geometry::is_empty(geom)); } @@ -18,7 +18,7 @@ SECTION("geometry collection") { } { mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; + mapnik::geometry::geometry_empty geom1; geom.emplace_back(std::move(geom1)); REQUIRE(!mapnik::geometry::is_empty(geom)); } diff --git a/test/unit/geometry/remove_empty.cpp b/test/unit/geometry/remove_empty.cpp index 36a6955c5..b51d0c8e2 100644 --- a/test/unit/geometry/remove_empty.cpp +++ b/test/unit/geometry/remove_empty.cpp @@ -1,6 +1,6 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry remove_empty") { diff --git a/test/unit/projection/proj_transform.cpp b/test/unit/projection/proj_transform.cpp index 95c959587..bb56b888c 100644 --- a/test/unit/projection/proj_transform.cpp +++ b/test/unit/projection/proj_transform.cpp @@ -1,9 +1,8 @@ - #include "catch.hpp" #include #include -#include +#include #ifdef MAPNIK_USE_PROJ4 // proj4 diff --git a/test/unit/serialization/parse_hex.hpp b/test/unit/serialization/parse_hex.hpp index 48c70a5d4..4475bc946 100644 --- a/test/unit/serialization/parse_hex.hpp +++ b/test/unit/serialization/parse_hex.hpp @@ -23,19 +23,21 @@ #ifndef MAPNIK_PARSE_HEX_HPP #define MAPNIK_PARSE_HEX_HPP -#include -#include +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop namespace mapnik { namespace util { template bool parse_hex(std::string const& input, Out & output) { - boost::spirit::qi::lit_type lit; + using boost::spirit::x3::lit; auto itr = input.begin(); auto end = input.end(); - using hex2 = boost::spirit::qi::uint_parser< unsigned, 16, 2, 2 >; - return boost::spirit::qi::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output); + using hex2 = boost::spirit::x3::uint_parser< unsigned, 16, 2, 2 >; + return boost::spirit::x3::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output); } }} diff --git a/test/unit/serialization/wkb_formats_test.cpp b/test/unit/serialization/wkb_formats_test.cpp index 6d1a0ea2c..d74c7ed63 100644 --- a/test/unit/serialization/wkb_formats_test.cpp +++ b/test/unit/serialization/wkb_formats_test.cpp @@ -2,9 +2,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include TEST_CASE("geometry formats") { @@ -79,7 +79,7 @@ SECTION("wkb") { geom = mapnik::geometry_utils::from_wkb((const char*)sp_invalid_blob, sizeof(sp_invalid_blob) / sizeof(sp_invalid_blob[0]), mapnik::wkbAuto); - REQUIRE(geom.is>()); // returns geometry_empty + REQUIRE(geom.is()); // returns geometry_empty // sqlite generic wkb blob @@ -103,7 +103,7 @@ SECTION("wkb") { geom = mapnik::geometry_utils::from_wkb((const char*)sq_invalid_blob, sizeof(sq_invalid_blob) / sizeof(sq_invalid_blob[0]), mapnik::wkbGeneric); - REQUIRE(geom.is>()); // returns geometry_empty + REQUIRE(geom.is()); // returns geometry_empty } catch (std::exception const& ex) diff --git a/test/unit/serialization/wkb_test.cpp b/test/unit/serialization/wkb_test.cpp index 2dbb49cca..97c292486 100644 --- a/test/unit/serialization/wkb_test.cpp +++ b/test/unit/serialization/wkb_test.cpp @@ -2,8 +2,8 @@ // mapnik #include #include -#include -#include +#include +#include #include // bool #include @@ -23,7 +23,7 @@ struct spatially_equal_visitor { using result_type = bool; - result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const + result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const { return true; } @@ -100,7 +100,7 @@ TEST_CASE("Well-known-geometries") REQUIRE(mapnik::util::parse_hex(columns[2], twkb)); mapnik::geometry::geometry geom_0 = mapnik::geometry_utils::from_wkb(wkb.data(), wkb.size(), mapnik::wkbAuto); mapnik::geometry::geometry geom_1 = mapnik::geometry_utils::from_twkb(twkb.data(), twkb.size()); - // compare WKTs + // compare WKTs as doubles std::string wkt0, wkt1; REQUIRE(mapnik::util::to_wkt(wkt0, geom_0)); REQUIRE(mapnik::util::to_wkt(wkt1, geom_1)); @@ -112,6 +112,25 @@ TEST_CASE("Well-known-geometries") REQUIRE(spatially_equal(geom_0, geom_1)); #endif } + + // compare WKTS as ints + // note: mapnik::util::to_wkt used in mapnik-vt + std::string wkt2, wkt3; + mapnik::geometry::line_string geom_2; + geom_2.emplace_back(0,0); + geom_2.emplace_back(1,1); + geom_2.emplace_back(2,2); + mapnik::geometry::line_string geom_3; + geom_3.emplace_back(0,0); + geom_3.emplace_back(1,1); + geom_3.emplace_back(2,2); + REQUIRE(mapnik::util::to_wkt(wkt0, geom_2)); + REQUIRE(mapnik::util::to_wkt(wkt1, geom_3)); + if (!mapnik::geometry::is_empty(geom_2) && !mapnik::geometry::is_empty(geom_3)) + { + REQUIRE(wkt2 == wkt3); + // compare spatially (NOTE: GeometryCollection comparison also enforces strict order) + } } } } diff --git a/test/unit/text/shaping.cpp b/test/unit/text/shaping.cpp index d9da17efb..ea1fbd44a 100644 --- a/test/unit/text/shaping.cpp +++ b/test/unit/text/shaping.cpp @@ -1,25 +1,101 @@ - #include "catch.hpp" #include #include #include +#include -TEST_CASE("shapers compile") { +namespace { - mapnik::text_line line(0,0); - mapnik::text_itemizer itemizer; +void test_shaping( mapnik::font_set const& fontset, mapnik::face_manager& fm, + std::vector> const& expected, char const* str, bool debug = false) +{ + mapnik::transcoder tr("utf8"); std::map width_map; + mapnik::text_itemizer itemizer; + auto props = std::make_unique(); + props->fontset = fontset; + props->text_size = 32; + double scale_factor = 1; + auto ustr = tr.transcode(str); + auto length = ustr.length(); + itemizer.add_text(ustr, props); + + mapnik::text_line line(0, length); + mapnik::harfbuzz_shaper::shape_text(line, itemizer, + width_map, + fm, + scale_factor); + + std::size_t index = 0; + for (auto const& g : line) + { + if (debug) + { + if (index++ > 0) std::cerr << ","; + std::cerr << "{" << g.glyph_index << ", " << g.char_index + //<< ", " << g.face->family_name() << ":" << g.face->style_name() + << "}"; + } + else + { + unsigned glyph_index, char_index; + CHECK(index < expected.size()); + std::tie(glyph_index, char_index) = expected[index++]; + REQUIRE(glyph_index == g.glyph_index); + REQUIRE(char_index == g.char_index); + } + } +} +} + +TEST_CASE("shaping") +{ + mapnik::freetype_engine::register_font("test/data/fonts/NotoSans-Regular.ttc"); + mapnik::freetype_engine::register_fonts("test/data/fonts/Noto"); + mapnik::font_set fontset("fontset"); + for (auto const& name : mapnik::freetype_engine::face_names()) + { + fontset.add_face_name(name); + } + mapnik::font_library fl; mapnik::freetype_engine::font_file_mapping_type font_file_mapping; mapnik::freetype_engine::font_memory_cache_type font_memory_cache; - mapnik::face_manager fm(fl,font_file_mapping,font_memory_cache); - mapnik::harfbuzz_shaper::shape_text(line,itemizer, - width_map, - fm, - scale_factor); - mapnik::icu_shaper::shape_text(line,itemizer, - width_map, - fm, - scale_factor); -} \ No newline at end of file + mapnik::face_manager fm(fl, font_file_mapping, font_memory_cache); + + { + std::vector> expected = + {{977, 0}, {1094, 3}, {1038, 4}, {1168, 4}, {9, 7}, {3, 8}, {11, 9}, {68, 10}, {69, 11}, {70, 12}, {12, 13}}; + test_shaping(fontset, fm, expected, u8"སྤུ་ཧྲེང (abc)"); + } + + { + std::vector> expected = + {{977, 0}, {1094, 3}, {1038, 4}, {1168, 4}, {9, 7}, {3, 8}, {11, 9}, {0, 10}, {0, 11}, {0, 12}, {12, 13}}; + test_shaping(fontset, fm, expected, u8"སྤུ་ཧྲེང (普兰镇)"); + } + + { + std::vector> expected = + {{68, 0}, {69, 1}, {70, 2}, {3, 3}, {11, 4}, {0, 5}, {0, 6}, {0, 7}, {12, 8}}; + test_shaping(fontset, fm, expected, u8"abc (普兰镇)"); + } + + { + std::vector> expected = + {{68, 0}, {69, 1}, {70, 2}, {3, 3}, {11, 4}, {68, 5}, {69, 6}, {70, 7}, {12, 8}}; + test_shaping(fontset, fm, expected, "abc (abc)"); + } + + { + // "ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي" + std::vector> expected = + {{0, 0}, {0, 1}, {0, 2}, {3, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, + {0, 8}, {0, 9}, {3, 10}, {509, 22}, {481, 21}, {438, 20}, {503, 19}, + {470, 18}, {496, 17}, {43, 16}, {3, 15}, {509, 14}, {454, 13}, {496, 12}, {43, 11}}; + test_shaping(fontset, fm, expected, u8"ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي"); + } + + +} diff --git a/test/unit/vertex_adapter/extend_converter.cpp b/test/unit/vertex_adapter/extend_converter.cpp new file mode 100644 index 000000000..a8b0f080d --- /dev/null +++ b/test/unit/vertex_adapter/extend_converter.cpp @@ -0,0 +1,128 @@ +#include "catch.hpp" +#include "fake_path.hpp" + +// mapnik +#include + +// stl +#include + +namespace offset_test { + +TEST_CASE("extend converter") { + +SECTION("empty") { + try + { + fake_path path = {}; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("one point") { + try + { + fake_path path = { 0, 0 }; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == 0); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("two points") { + try + { + fake_path path = { 0, 0 , 1, 0}; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == -1000); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1001); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("three points") { + try + { + fake_path path = { 0, 0, 1, 0, 2, 0 }; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == -1000); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1002); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("more points") { + try + { + fake_path path = { 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0 }; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == -1000); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 2); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 3); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 4); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1005); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +} + +} diff --git a/test/unit/vertex_adapter/fake_path.hpp b/test/unit/vertex_adapter/fake_path.hpp new file mode 100644 index 000000000..dc1b4aed2 --- /dev/null +++ b/test/unit/vertex_adapter/fake_path.hpp @@ -0,0 +1,93 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2015 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include + +// stl +#include +#include + +namespace detail +{ + +template +struct fake_path +{ + using coord_type = std::tuple; + using cont_type = std::vector; + cont_type vertices_; + typename cont_type::iterator itr_; + + fake_path(std::initializer_list l) + : fake_path(l.begin(), l.size()) + { + } + + fake_path(std::vector const &v, bool make_invalid = false) + : fake_path(v.begin(), v.size(), make_invalid) + { + } + + template + fake_path(Itr itr, size_t sz, bool make_invalid = false) + { + size_t num_coords = sz >> 1; + vertices_.reserve(num_coords + (make_invalid ? 1 : 0)); + if (make_invalid) + { + vertices_.push_back(std::make_tuple(0,0,mapnik::SEG_END)); + } + + for (size_t i = 0; i < num_coords; ++i) + { + T x = *itr++; + T y = *itr++; + unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO; + vertices_.push_back(std::make_tuple(x, y, cmd)); + } + itr_ = vertices_.begin(); + } + + unsigned vertex(T *x, T *y) + { + if (itr_ == vertices_.end()) + { + return mapnik::SEG_END; + } + *x = std::get<0>(*itr_); + *y = std::get<1>(*itr_); + unsigned cmd = std::get<2>(*itr_); + ++itr_; + return cmd; + } + + void rewind(unsigned) + { + itr_ = vertices_.begin(); + } +}; + +} + +using fake_path = detail::fake_path; + diff --git a/test/unit/vertex_adapter/line_offset_test.cpp b/test/unit/vertex_adapter/line_offset_test.cpp index dcb8dc68b..75bfb0799 100644 --- a/test/unit/vertex_adapter/line_offset_test.cpp +++ b/test/unit/vertex_adapter/line_offset_test.cpp @@ -1,5 +1,6 @@ #include "catch.hpp" +#include "fake_path.hpp" // mapnik #include @@ -7,53 +8,6 @@ // stl #include -#include -#include - -struct fake_path -{ - using coord_type = std::tuple; - using cont_type = std::vector; - cont_type vertices_; - cont_type::iterator itr_; - - fake_path(std::initializer_list l) - : fake_path(l.begin(), l.size()) { - } - - fake_path(std::vector const &v) - : fake_path(v.begin(), v.size()) { - } - - template - fake_path(Itr itr, size_t sz) { - size_t num_coords = sz >> 1; - vertices_.reserve(num_coords); - - for (size_t i = 0; i < num_coords; ++i) { - double x = *itr++; - double y = *itr++; - unsigned cmd = (i == 0) ? agg::path_cmd_move_to : agg::path_cmd_line_to; - vertices_.push_back(std::make_tuple(x, y, cmd)); - } - itr_ = vertices_.begin(); - } - - unsigned vertex(double *x, double *y) { - if (itr_ == vertices_.end()) { - return agg::path_cmd_stop; - } - *x = std::get<0>(*itr_); - *y = std::get<1>(*itr_); - unsigned cmd = std::get<2>(*itr_); - ++itr_; - return cmd; - } - - void rewind(unsigned) { - itr_ = vertices_.begin(); - } -}; double dist(mapnik::pixel_position const &a, mapnik::pixel_position const &b) diff --git a/test/unit/vertex_adapter/offset_converter.cpp b/test/unit/vertex_adapter/offset_converter.cpp index 9255f7d97..96c796d06 100644 --- a/test/unit/vertex_adapter/offset_converter.cpp +++ b/test/unit/vertex_adapter/offset_converter.cpp @@ -1,66 +1,15 @@ #include "catch.hpp" +#include "fake_path.hpp" // mapnik -#include #include // stl #include -#include -#include namespace offset_test { -struct fake_path -{ - using coord_type = std::tuple; - using cont_type = std::vector; - cont_type vertices_; - cont_type::iterator itr_; - - fake_path(std::initializer_list l) - : fake_path(l.begin(), l.size()) { - } - - fake_path(std::vector const &v, bool make_invalid = false) - : fake_path(v.begin(), v.size(), make_invalid) { - } - - template - fake_path(Itr itr, size_t sz, bool make_invalid = false) { - size_t num_coords = sz >> 1; - vertices_.reserve(num_coords + (make_invalid ? 1 : 0)); - if (make_invalid) - { - vertices_.push_back(std::make_tuple(0,0,mapnik::SEG_END)); - } - - for (size_t i = 0; i < num_coords; ++i) { - double x = *itr++; - double y = *itr++; - unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO; - vertices_.push_back(std::make_tuple(x, y, cmd)); - } - itr_ = vertices_.begin(); - } - - unsigned vertex(double *x, double *y) { - if (itr_ == vertices_.end()) { - return mapnik::SEG_END; - } - *x = std::get<0>(*itr_); - *y = std::get<1>(*itr_); - unsigned cmd = std::get<2>(*itr_); - ++itr_; - return cmd; - } - - void rewind(unsigned) { - itr_ = vertices_.begin(); - } -}; - static double DELTA_BUFF = 0.5; double dist(double x0, double y0, double x1, double y1) diff --git a/test/unit/vertex_adapter/vertex_adapter.cpp b/test/unit/vertex_adapter/vertex_adapter.cpp index d6c1ed592..6fe6dda44 100644 --- a/test/unit/vertex_adapter/vertex_adapter.cpp +++ b/test/unit/vertex_adapter/vertex_adapter.cpp @@ -1,7 +1,7 @@ #include "catch.hpp" #include -#include +#include TEST_CASE("vertex_adapters") { diff --git a/test/visual/map_sizes_grammar.hpp b/test/visual/parse_map_sizes.cpp similarity index 55% rename from test/visual/map_sizes_grammar.hpp rename to test/visual/parse_map_sizes.cpp index 2c79d90d8..7cea5df4a 100644 --- a/test/visual/map_sizes_grammar.hpp +++ b/test/visual/parse_map_sizes.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,40 +20,36 @@ * *****************************************************************************/ -#ifndef MAP_SIZES_GRAMMAR_HPP -#define MAP_SIZES_GRAMMAR_HPP +#include "parse_map_sizes.hpp" #pragma GCC diagnostic push #include -#include -#include +#include +#include #pragma GCC diagnostic pop -namespace visual_tests -{ +BOOST_FUSION_ADAPT_STRUCT ( + visual_tests::map_size, + (std::size_t, width) + (std::size_t, height) + ) -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; +namespace visual_tests { -template -struct map_sizes_grammar : qi::grammar(), ascii::space_type> +namespace x3 = boost::spirit::x3; +using x3::ulong_; +auto const map_sizes_grammar = x3::rule >{} = + (ulong_ >> ',' >> ulong_) % ';' ; + +void parse_map_sizes(std::string const & str, std::vector & sizes) { - map_sizes_grammar() : map_sizes_grammar::base_type(start) + boost::spirit::x3::ascii::space_type space; + std::string::const_iterator iter = str.begin(); + std::string::const_iterator end = str.end(); + if (!boost::spirit::x3::phrase_parse(iter, end, map_sizes_grammar, space, sizes)) { - using namespace boost::spirit::qi; - using namespace boost::phoenix; - - int_type int_; - _1_type _1; - _2_type _2; - _val_type _val; - - start = (int_ >> ',' >> int_)[push_back(_val, construct(_1, _2))] % ';'; + throw std::runtime_error("Failed to parse list of sizes: '" + str + "'"); } - - qi::rule(), ascii::space_type> start; -}; - } -#endif +} diff --git a/src/image_filter_grammar.cpp b/test/visual/parse_map_sizes.hpp similarity index 80% rename from src/image_filter_grammar.cpp rename to test/visual/parse_map_sizes.hpp index 9a4bea35a..5d0f0125b 100644 --- a/src/image_filter_grammar.cpp +++ b/test/visual/parse_map_sizes.hpp @@ -20,10 +20,17 @@ * *****************************************************************************/ -#include -#include -#include -#include -#include +#ifndef VISUAL_TESTS_PARSE_MAP_SIZES_HPP +#define VISUAL_TESTS_PARSE_MAP_SIZES_HPP -template struct mapnik::image_filter_grammar>; +#include "config.hpp" +#include +#include + +namespace visual_tests { + +void parse_map_sizes(std::string const & str, std::vector & sizes); + +} + +#endif //VISUAL_TESTS_PARSE_MAP_SIZES_HPP diff --git a/test/visual/runner.cpp b/test/visual/runner.cpp index d0c7222fb..18e6506ec 100644 --- a/test/visual/runner.cpp +++ b/test/visual/runner.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,9 +25,11 @@ #include #include + #include #include "runner.hpp" +#include "parse_map_sizes.hpp" namespace visual_tests { @@ -348,19 +350,7 @@ result_list runner::test_one(runner::path_type const& style_path, } } } - return results; } -void runner::parse_map_sizes(std::string const & str, std::vector & sizes) const -{ - boost::spirit::ascii::space_type space; - std::string::const_iterator iter = str.begin(); - std::string::const_iterator end = str.end(); - if (!boost::spirit::qi::phrase_parse(iter, end, map_sizes_parser_, space, sizes)) - { - throw std::runtime_error("Failed to parse list of sizes: '" + str + "'"); - } -} - } diff --git a/test/visual/runner.hpp b/test/visual/runner.hpp index e38e39422..b5c031627 100644 --- a/test/visual/runner.hpp +++ b/test/visual/runner.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,7 +26,6 @@ #include "config.hpp" #include "report.hpp" #include "renderer.hpp" -#include "map_sizes_grammar.hpp" namespace visual_tests { @@ -58,9 +57,7 @@ private: result_list test_one(path_type const & style_path, report_type & report, std::atomic & fail_limit) const; - void parse_map_sizes(std::string const & str, std::vector & sizes) const; - const map_sizes_grammar map_sizes_parser_; const path_type styles_dir_; const config defaults_; const std::size_t jobs_; @@ -71,4 +68,4 @@ private: } -#endif +#endif //VISUAL_TEST_RUNNER_HPP diff --git a/utils/mapnik-index/build.py b/utils/mapnik-index/build.py index 358ce5f88..9bddaf196 100644 --- a/utils/mapnik-index/build.py +++ b/utils/mapnik-index/build.py @@ -32,8 +32,8 @@ source = Split( """ mapnik-index.cpp process_csv_file.cpp - process_geojson_file.cpp - ../../plugins/input/csv/csv_utils.cpp + process_geojson_file_x3.cpp + ../../plugins/input/csv/csv_utils.os """ ) diff --git a/utils/mapnik-index/mapnik-index.cpp b/utils/mapnik-index/mapnik-index.cpp index 9b1859bf2..1de90b6c4 100644 --- a/utils/mapnik-index/mapnik-index.cpp +++ b/utils/mapnik-index/mapnik-index.cpp @@ -24,12 +24,12 @@ #include #include #include - +#include #include #include #include "process_csv_file.hpp" -#include "process_geojson_file.hpp" +#include "process_geojson_file_x3.hpp" #pragma GCC diagnostic push #include @@ -87,12 +87,16 @@ int main (int argc, char** argv) po::positional_options_description p; p.add("files",-1); po::variables_map vm; - po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); + po::store(po::command_line_parser(argc, argv) + .options(desc) + .style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise) + .positional(p) + .run(), vm); po::notify(vm); if (vm.count("version")) { - std::clog << "version 1.0.0" << std::endl; + std::clog << "version " << MAPNIK_VERSION_STRING << std::endl; return 1; } if (vm.count("help")) @@ -190,7 +194,8 @@ int main (int argc, char** argv) else if (mapnik::detail::is_geojson(filename)) { std::clog << "processing '" << filename << "' as GeoJSON\n"; - auto result = mapnik::detail::process_geojson_file(boxes, filename, validate_features, verbose); + std::pair> result; + result = mapnik::detail::process_geojson_file_x3(boxes, filename, validate_features, verbose); if (!result.first) { std::clog << "Error: failed to process " << filename << std::endl; diff --git a/utils/mapnik-index/process_csv_file.cpp b/utils/mapnik-index/process_csv_file.cpp index a0342cff5..79802392c 100644 --- a/utils/mapnik-index/process_csv_file.cpp +++ b/utils/mapnik-index/process_csv_file.cpp @@ -24,7 +24,7 @@ #include "../../plugins/input/csv/csv_getline.hpp" #include "../../plugins/input/csv/csv_utils.hpp" #include -#include +#include #include #if defined(MAPNIK_MEMORY_MAPPED_FILE) diff --git a/utils/mapnik-index/process_csv_file.hpp b/utils/mapnik-index/process_csv_file.hpp index 395bf55c7..24cb71509 100644 --- a/utils/mapnik-index/process_csv_file.hpp +++ b/utils/mapnik-index/process_csv_file.hpp @@ -24,7 +24,7 @@ #define MAPNIK_UTILS_PROCESS_CSV_FILE_HPP #include -#include +#include namespace mapnik { namespace detail { diff --git a/utils/mapnik-index/process_geojson_file.cpp b/utils/mapnik-index/process_geojson_file.cpp deleted file mode 100644 index 44553185f..000000000 --- a/utils/mapnik-index/process_geojson_file.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2015 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include "process_geojson_file.hpp" - -#if defined(MAPNIK_MEMORY_MAPPED_FILE) -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop -#include -#else -#include -#endif - -#include -#include - -namespace { - -template -struct feature_validate_callback -{ - feature_validate_callback(mapnik::box2d const& box) - : box_(box) {} - - void operator() (mapnik::feature_ptr const& f) const - { - if (box_ != box_) - { - throw std::runtime_error("Bounding boxes mismatch validation feature"); - } - } - mapnik::box2d const& box_; -}; - -using box_type = mapnik::box2d; -using boxes_type = std::vector>>; -using base_iterator_type = char const*; -const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; -const mapnik::transcoder tr("utf8"); -const mapnik::json::feature_grammar_callback> fc_grammar(tr); -} - -namespace mapnik { namespace detail { - -template -std::pair process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose) -{ - using box_type = typename T::value_type::first_type; - box_type extent; -#if defined(MAPNIK_MEMORY_MAPPED_FILE) - mapnik::mapped_region_ptr mapped_region; - boost::optional memory = - mapnik::mapped_memory_cache::instance().find(filename, true); - if (!memory) - { - std::clog << "Error : cannot memory map " << filename << std::endl; - return std::make_pair(false, extent); - } - else - { - mapped_region = *memory; - } - char const* start = reinterpret_cast(mapped_region->get_address()); - char const* end = start + mapped_region->get_size(); -#else - mapnik::util::file file(filename); - if (!file) - { - std::clog << "Error : cannot open " << filename << std::endl; - return std::make_pair(false, extent); - } - std::string file_buffer; - file_buffer.resize(file.size()); - std::fread(&file_buffer[0], file.size(), 1, file.get()); - char const* start = file_buffer.c_str(); - char const* end = start + file_buffer.length(); -#endif - - boost::spirit::standard::space_type space; - auto const* itr = start; - try - { - if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) - { - std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'" << std::endl; - return std::make_pair(false, extent); - } - } - catch (std::exception const& ex) - { - std::clog << "mapnik-index (GeoJSON): " << ex.what() << std::endl; - } - mapnik::context_ptr ctx = std::make_shared(); - std::size_t start_id = 1; - for (auto const& item : boxes) - { - if (item.first.valid()) - { - if (!extent.valid()) extent = item.first; - else extent.expand_to_include(item.first); - - if (validate_features) - { - base_iterator_type feat_itr = start + item.second.first; - base_iterator_type feat_end = feat_itr + item.second.second; - feature_validate_callback callback(item.first); - bool result = boost::spirit::qi::phrase_parse(feat_itr, feat_end, (fc_grammar) - (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || feat_itr != feat_end) - { - if (verbose) std::clog << std::string(start + item.second.first, feat_end ) << std::endl; - return std::make_pair(false, extent); - } - } - } - } - return std::make_pair(true, extent); -} - -template std::pair process_geojson_file(boxes_type&, std::string const&, bool, bool); - -}} diff --git a/utils/mapnik-index/process_geojson_file_x3.cpp b/utils/mapnik-index/process_geojson_file_x3.cpp new file mode 100644 index 000000000..c55989bc7 --- /dev/null +++ b/utils/mapnik-index/process_geojson_file_x3.cpp @@ -0,0 +1,330 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include "process_geojson_file_x3.hpp" + +#if defined(MAPNIK_MEMORY_MAPPED_FILE) +#pragma GCC diagnostic push +#include +#include +#include +#include +#pragma GCC diagnostic pop +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +namespace { + +constexpr mapnik::json::well_known_names feature_properties[] = { + mapnik::json::well_known_names::type, + mapnik::json::well_known_names::geometry, + mapnik::json::well_known_names::properties}; // sorted + +constexpr mapnik::json::well_known_names geometry_properties[] = { + mapnik::json::well_known_names::type, + mapnik::json::well_known_names::coordinates}; // sorted + +template +std::string join(Keys const& keys) +{ + std::string result; + bool first = true; + for (auto const& key : keys) + { + if (!first) result += ","; + result += "\"" + std::string(mapnik::json::wkn_to_string(key)) + "\""; + first = false; + } + return result; +} + +template +bool has_keys(Iterator first1, Iterator last1, Keys const& keys) +{ + auto first2 = std::begin(keys); + auto last2 = std::end(keys); + for (; first2 != last2; ++first1) + { + if (first1 == last1 || *first2 < std::get<0>(*first1)) + return false; + if (!(std::get<0>(*first1) < *first2)) + ++first2; + } + return true; +} + +template +bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& keys, bool verbose) +{ + if (!value.is()) + { + if (verbose) std::clog << "Expecting an GeoJSON object" << std::endl; + return false; + } + mapnik::json::geojson_object & feature = mapnik::util::get(value); + std::sort(feature.begin(), feature.end(), [](auto const& e0, auto const& e1) + { + return std::get<0>(e0) < std::get<0>(e1); + }); + + if (!has_keys(feature.begin(), feature.end(), feature_properties)) + { + if (verbose) std::clog << "Expecting one of " << join(feature_properties) << std::endl; + return false; + } + + for (auto & elem : feature) + { + auto const key = std::get<0>(elem); + if (key == mapnik::json::well_known_names::geometry) + { + auto & geom_value = std::get<1>(elem); + if (!geom_value.is()) + { + if (verbose) std::clog << "\"geometry\": xxx <-- expecting an JSON object here" << std::endl; + return false; + } + auto & geometry = mapnik::util::get(geom_value); + // sort by property name + std::sort(geometry.begin(), geometry.end(), [](auto const& e0, auto const& e1) + { + return std::get<0>(e0) < std::get<0>(e1); + }); + if (!has_keys(geometry.begin(), geometry.end(), geometry_properties)) + { + if (verbose) std::clog << "Expecting one of " << join(geometry_properties) << std::endl; + return false; + } + + mapnik::geometry::geometry_types geom_type; + mapnik::json::positions const* coordinates = nullptr; + for (auto & elem2 : geometry) + { + auto const key2 = std::get<0>(elem2); + if (key2 == mapnik::json::well_known_names::type) + { + auto const& geom_type_value = std::get<1>(elem2); + if (!geom_type_value.is()) + { + if (verbose) std::clog << "\"type\": xxx <-- expecting an GeoJSON geometry type here" << std::endl; + return false; + } + geom_type = mapnik::util::get(geom_type_value); + if (geom_type == mapnik::geometry::geometry_types::GeometryCollection) + { + if (verbose) std::clog << "GeometryCollections are not allowed" << std::endl;; + return false; + } + } + else if (key2 == mapnik::json::well_known_names::coordinates) + { + auto const& coordinates_value = std::get<1>(elem2); + if (!coordinates_value.is()) + { + if (verbose) std::clog << "\"coordinates\": xxx <-- expecting an GeoJSON positions here" << std::endl; + return false; + } + coordinates = &mapnik::util::get(coordinates_value); + } + } + if (geom_type == mapnik::geometry::geometry_types::Point) + { + // expecting single position + if (!coordinates->is()) + { + if (verbose) std::clog << "Expecting single position in Point" << std::endl; + return false; + } + } + else if (geom_type == mapnik::geometry::geometry_types::LineString) + { + // expecting + if (!coordinates->is()) + { + if (verbose) std::clog << "Expecting sequence of positions (ring) in LineString" << std::endl; + return false; + } + else + { + auto const& ring = mapnik::util::get(*coordinates); + if (ring.size() < 2) + { + if (verbose) std::clog << "Expecting at least two coordinates in LineString" << std::endl; + return false; + } + } + } + else if (geom_type == mapnik::geometry::geometry_types::Polygon) + { + // expecting + if (!coordinates->is()) + { + if (verbose) std::clog << "Expecting an array of rings in Polygon" << std::endl; + return false; + } + else + { + auto const& rings = mapnik::util::get(*coordinates); + if (rings.size() < 1) + { + if (verbose) std::clog << "Expecting at least one ring in Polygon" << std::endl; + return false; + } + for (auto const& ring : rings) + { + if (ring.size() < 4) + { + if (verbose) std::clog << "Expecting at least four coordinates in Polygon ring" << std::endl; + return false; + } + } + } + } + } + } + return true; +}; + +using box_type = mapnik::box2d; +using boxes_type = std::vector>>; +using base_iterator_type = char const*; + +auto const& geojson_value = mapnik::json::geojson_grammar(); + +} + +namespace mapnik { namespace detail { + + +template +std::pair process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose) +{ + using box_type = typename T::value_type::first_type; + box_type extent; +#if defined(MAPNIK_MEMORY_MAPPED_FILE) + mapnik::mapped_region_ptr mapped_region; + boost::optional memory = + mapnik::mapped_memory_cache::instance().find(filename, true); + if (!memory) + { + std::clog << "Error : cannot memory map " << filename << std::endl; + return std::make_pair(false, extent); + } + else + { + mapped_region = *memory; + } + base_iterator_type start = reinterpret_cast(mapped_region->get_address()); + base_iterator_type end = start + mapped_region->get_size(); +#else + mapnik::util::file file(filename); + if (!file) + { + std::clog << "Error : cannot open " << filename << std::endl; + return std::make_pair(false, extent); + } + std::string file_buffer; + file_buffer.resize(file.size()); + auto count = std::fread(&file_buffer[0], file.size(), 1, file.get()); + base_iterator_type start = file_buffer.c_str(); + base_iterator_type end = (count == 1) ? start + file_buffer.length() : start; +#endif + base_iterator_type itr = start; // make a copy to preserve `start` iterator state + try + { + mapnik::json::extract_bounding_boxes(itr, end, boxes); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + std::clog << ex.what() << std::endl; + std::clog << "Expected: " << ex.which(); + std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << '"' << std::endl; + return std::make_pair(false, extent); + } + catch (std::exception const& ex) + { + std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'" << std::endl; + return std::make_pair(false, extent); + } + + using namespace boost::spirit; + using space_type = mapnik::json::grammar::space_type; + auto keys = mapnik::json::get_keys(); + auto feature_grammar = x3::with(std::ref(keys)) + [ geojson_value ]; + for (auto const& item : boxes) + { + if (item.first.valid()) + { + if (!extent.valid()) extent = item.first; + else extent.expand_to_include(item.first); + if (validate_features) + { + base_iterator_type feat_itr = start + item.second.first; + base_iterator_type feat_end = feat_itr + item.second.second; + mapnik::json::geojson_value feature_value; + try + { + bool result = x3::phrase_parse(feat_itr, feat_end, feature_grammar, space_type(), feature_value); + if (!result || feat_itr != feat_end) + { + if (verbose) std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second << std::endl; + return std::make_pair(false, extent); + } + } + catch (x3::expectation_failure const& ex) + { + if (verbose) std::clog << ex.what() << std::endl; + return std::make_pair(false, extent); + } + catch (...) + { + if (verbose) std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second << std::endl; + return std::make_pair(false, extent); + } + if (!validate_geojson_feature(feature_value, keys, verbose)) + { + if (verbose) std::clog << "Failed to validate: [" << std::string(start + item.second.first, feat_end ) << "]" << std::endl; + return std::make_pair(false, extent); + } + } + } + else if (validate_features) + { + if (verbose) std::clog << "Invalid bbox encountered " << item.first << std::endl; + return std::make_pair(false, extent); + } + } + return std::make_pair(true, extent); +} + +template std::pair process_geojson_file_x3(boxes_type&, std::string const&, bool, bool); + +}} diff --git a/utils/mapnik-index/process_geojson_file.hpp b/utils/mapnik-index/process_geojson_file_x3.hpp similarity index 81% rename from utils/mapnik-index/process_geojson_file.hpp rename to utils/mapnik-index/process_geojson_file_x3.hpp index a377d23e3..17545db66 100644 --- a/utils/mapnik-index/process_geojson_file.hpp +++ b/utils/mapnik-index/process_geojson_file_x3.hpp @@ -20,17 +20,17 @@ * *****************************************************************************/ -#ifndef MAPNIK_UTILS_PROCESS_GEOJSON_FILE_HPP -#define MAPNIK_UTILS_PROCESS_GEOJSON_FILE_HPP +#ifndef MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP +#define MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP #include -#include +#include namespace mapnik { namespace detail { template -std::pair process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose); +std::pair process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose); }} -#endif // MAPNIK_UTILS_PROCESS_GEOJSON_FILE_HPP +#endif // MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP diff --git a/utils/ogrindex/ogrindex.cpp b/utils/ogrindex/ogrindex.cpp index 3e7fd503c..4aa685abe 100644 --- a/utils/ogrindex/ogrindex.cpp +++ b/utils/ogrindex/ogrindex.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/utils/pgsql2sqlite/pgsql2sqlite.hpp b/utils/pgsql2sqlite/pgsql2sqlite.hpp index 9de886732..8e702a2fa 100644 --- a/utils/pgsql2sqlite/pgsql2sqlite.hpp +++ b/utils/pgsql2sqlite/pgsql2sqlite.hpp @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include #include "connection_manager.hpp" #include "cursorresultset.hpp" diff --git a/utils/shapeindex/shapeindex.cpp b/utils/shapeindex/shapeindex.cpp index 9dcff1189..b8fef4a1a 100644 --- a/utils/shapeindex/shapeindex.cpp +++ b/utils/shapeindex/shapeindex.cpp @@ -20,13 +20,13 @@ * *****************************************************************************/ - #include #include #include +#include #include #include -#include +#include #include "shapefile.hpp" #include "shape_io.hpp" #include "shape_index_featureset.hpp" @@ -71,7 +71,7 @@ int main (int argc,char** argv) if (vm.count("version")) { - std::clog << "version 0.3.0" <