This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository mapnik.
commit a9cd3996f51bca7a07c8f1289eedb228a2d8d25e Author: Bas Couwenberg <[email protected]> Date: Mon Feb 6 18:55:44 2017 +0100 Imported Upstream version 3.0.13~rc2+ds --- .travis.yml | 10 ++-- CHANGELOG.md | 5 +- bootstrap.sh | 4 +- circle.yml | 12 ++-- include/mapnik/box2d.hpp | 1 + include/mapnik/box2d_impl.hpp | 7 ++- .../mapnik/json/extract_bounding_box_grammar.hpp | 2 +- .../json/extract_bounding_box_grammar_impl.hpp | 35 +++++------ include/mapnik/json/positions_grammar.hpp | 2 +- include/mapnik/json/positions_grammar_impl.hpp | 12 ++-- include/mapnik/version.hpp | 2 +- src/text/symbolizer_helpers.cpp | 37 +++++++----- test/unit/datasource/geojson.cpp | 68 ++++++++++++---------- utils/mapnik-index/process_geojson_file.cpp | 5 ++ 14 files changed, 110 insertions(+), 92 deletions(-) diff --git a/.travis.yml b/.travis.yml index 387e677..814325d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,12 +86,12 @@ before_script: - source bootstrap.sh - | if [[ $(uname -s) == 'Linux' ]]; then - mason install clang++ 3.9.0 - export PATH=$(mason prefix clang++ 3.9.0)/bin:${PATH} - mason install llvm-cov 3.9.0 - export PATH=$(mason prefix llvm-cov 3.9.0)/bin:${PATH} + 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.0)/bin/llvm-cov" + export LLVM_COV="$(mason prefix llvm-cov 3.9.1)/bin/llvm-cov" fi - ccache --version - ccache -p || true diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a48f3..e8751c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ For a complete change history, see the git log. ## 3.0.13 -Released: January xx, 2017 +Released: February xx, 2017 (Packaged from xxxxxxx) @@ -26,7 +26,8 @@ Released: January xx, 2017 - Changed `render_thunk_list` to `std::list<render_thunk>` (PR #3585) - Upgraded to variant `v1.1.5` - CSV.input - fixed `blank` line test (8a3a380b3b5c64681f2478b4f0d06f6a907f5eed) - +- GeoJSON - handle empty elements in position grammar (ref #3609) +- mapnik-index - return failure on invalid bounding box (ref #3611) ## 3.0.12 diff --git a/bootstrap.sh b/bootstrap.sh index f7d0ce3..7f369ac 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -11,7 +11,7 @@ todo - shrink icu data ' -MASON_VERSION="3e2944322" +MASON_VERSION="v0.5.0" 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++} diff --git a/circle.yml b/circle.yml index d9d4bad..5624c66 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/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp index 2671201..6165283 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/box2d.hpp @@ -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/box2d_impl.hpp index 7f3e9d1..ec3d3b4 100644 --- a/include/mapnik/box2d_impl.hpp +++ b/include/mapnik/box2d_impl.hpp @@ -393,6 +393,11 @@ std::string box2d<T>::to_string() const return s.str(); } +template <typename T> +T box2d<T>::area() const +{ + return width() * height(); +} template <typename T> box2d<T>& box2d<T>::operator+=(box2d<T> const& other) @@ -466,7 +471,7 @@ T box2d<T>::operator[] (int index) const case -1: return maxy_; default: - throw std::out_of_range("index out of range, max value is 3, min value is -4 "); + throw std::out_of_range(std::string("index out of range, max value is 3, min value is -4 ")); } } diff --git a/include/mapnik/json/extract_bounding_box_grammar.hpp b/include/mapnik/json/extract_bounding_box_grammar.hpp index 906e712..601511e 100644 --- a/include/mapnik/json/extract_bounding_box_grammar.hpp +++ b/include/mapnik/json/extract_bounding_box_grammar.hpp @@ -51,7 +51,7 @@ struct extract_bounding_box_grammar : qi::rule<Iterator, qi::locals<Iterator>, void(boxes_type&), space_type> features; qi::rule<Iterator, qi::locals<int, box_type>, void(boxes_type&, Iterator const&), space_type> feature; qi::rule<Iterator, qi::locals<box_type>, box_type(), space_type> coords; - qi::rule<Iterator, boost::optional<position_type>(), space_type> pos; + qi::rule<Iterator, position_type(), space_type> pos; qi::rule<Iterator, void(box_type&), space_type> ring; qi::rule<Iterator, void(box_type&), space_type> rings; qi::rule<Iterator, void(box_type&), space_type> rings_array; diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp index bdc1b98..4d81de7 100644 --- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp +++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp @@ -42,18 +42,15 @@ struct calculate_bounding_box_impl template <typename T0, typename T1> 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()) { - 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); - } + bbox.init(x, y); + } + else + { + bbox.expand_to_include(x, y); } } }; @@ -64,10 +61,10 @@ struct push_box_impl template <typename T0, typename T1, typename T2, typename T3> 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()))); + boxes.emplace_back(box, + std::make_pair(std::distance(begin, + range.begin()), + std::distance(range.begin(), range.end()))); } }; @@ -132,16 +129,16 @@ extract_bounding_box_grammar<Iterator, Boxes, ErrorHandler>::extract_bounding_bo >> 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(']') + pos = lit('[') > double_ > lit(',') > double_ > omit[*(lit(',') > double_)] > lit(']') ; - ring = lit('[') >> pos[calculate_bounding_box(_r1,_1)] % lit(',') > lit(']') + ring = lit('[') >> -(pos[calculate_bounding_box(_r1,_1)] % lit(',')) >> lit(']') ; - rings = lit('[') >> ring(_r1) % lit(',') > lit(']') + rings = lit('[') >> (ring(_r1) % lit(',') > lit(']')) ; - rings_array = lit('[') >> rings(_r1) % lit(',') > lit(']') + rings_array = lit('[') >> (rings(_r1) % lit(',') > lit(']')) ; coords.name("Coordinates"); diff --git a/include/mapnik/json/positions_grammar.hpp b/include/mapnik/json/positions_grammar.hpp index 6984300..a09f4e2 100644 --- a/include/mapnik/json/positions_grammar.hpp +++ b/include/mapnik/json/positions_grammar.hpp @@ -44,7 +44,7 @@ struct positions_grammar : { positions_grammar(ErrorHandler & error_handler); qi::rule<Iterator, coordinates(),space_type> coords; - qi::rule<Iterator, boost::optional<position>(), space_type> pos; + qi::rule<Iterator, position(), space_type> pos; qi::rule<Iterator, positions(), space_type> ring; qi::rule<Iterator, std::vector<positions>(), space_type> rings; qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array; diff --git a/include/mapnik/json/positions_grammar_impl.hpp b/include/mapnik/json/positions_grammar_impl.hpp index 65f2a93..94bfe6a 100644 --- a/include/mapnik/json/positions_grammar_impl.hpp +++ b/include/mapnik/json/positions_grammar_impl.hpp @@ -41,7 +41,7 @@ struct set_position_impl template <typename T0,typename T1> result_type operator() (T0 & coords, T1 const& pos) const { - if (pos) coords = *pos; + coords = pos; } }; @@ -51,7 +51,7 @@ struct push_position_impl template <typename T0, typename T1> result_type operator() (T0 & coords, T1 const& pos) const { - if (pos) coords.emplace_back(*pos); + coords.emplace_back(pos); } }; @@ -75,13 +75,13 @@ positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & erro 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(']') + pos = lit('[') > double_ > lit(',') > double_ > omit[*(lit(',') > double_)] > lit(']') ; - ring = lit('[') >> pos[push_position(_val,_1)] % lit(',') > lit(']') + ring = lit('[') >> -(pos[push_position(_val,_1)] % lit(',')) >> lit(']') ; - rings = lit('[') >> ring % lit(',') > lit(']') + rings = lit('[') >> (ring % lit(',') > lit(']')) ; - rings_array = lit('[') >> rings % lit(',') > lit(']') + rings_array = lit('[') >> (rings % lit(',') > lit(']')) ; coords.name("Coordinates"); pos.name("Position"); diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp index deba428..5f19a43 100644 --- a/include/mapnik/version.hpp +++ b/include/mapnik/version.hpp @@ -27,7 +27,7 @@ #define MAPNIK_MAJOR_VERSION 3 #define MAPNIK_MINOR_VERSION 0 -#define MAPNIK_PATCH_VERSION 12 +#define MAPNIK_PATCH_VERSION 13 #define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION) diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp index fe5568a..8064e6c 100644 --- a/src/text/symbolizer_helpers.cpp +++ b/src/text/symbolizer_helpers.cpp @@ -187,23 +187,26 @@ base_symbolizer_helper::base_symbolizer_helper( initialize_points(); } -struct largest_bbox_first +template <typename It> +static It largest_bbox(It begin, It end) { - bool operator() (geometry::geometry<double> const* g0, geometry::geometry<double> const* g1) const + if (begin == end) { - box2d<double> b0 = geometry::envelope(*g0); - box2d<double> 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<double> b0 = geometry::envelope(g0); - box2d<double> 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()); } } diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp index b036684..337f809 100644 --- a/test/unit/datasource/geojson.cpp +++ b/test/unit/datasource/geojson.cpp @@ -514,7 +514,8 @@ TEST_CASE("geojson") { for (auto const& c_str : {"./test/data/json/feature-malformed-1.geojson", "./test/data/json/feature-malformed-2.geojson", - "./test/data/json/feature-malformed-3.geojson"}) + "./test/data/json/feature-malformed-3.geojson", + "./test/data/json/feature-malformed-4.geojson"}) { std::string filename(c_str); params["file"] = filename; @@ -554,43 +555,46 @@ TEST_CASE("geojson") { SECTION("GeoJSON ensure mapnik::featureset::next() throws on malformed input") { - std::string filename{"./test/data/json/featurecollection-malformed.json"}; mapnik::parameters params; params["type"] = "geojson"; - params["file"] = filename; - - // cleanup in the case of a failed previous run - if (mapnik::util::exists(filename + ".index")) + for (auto const& c_str : {"./test/data/json/featurecollection-malformed.json", + "./test/data/json/featurecollection-malformed-2.json"}) { - mapnik::util::remove(filename + ".index"); - } + std::string filename(c_str); + params["file"] = filename; + // cleanup in the case of a failed previous run + if (mapnik::util::exists(filename + ".index")) + { + mapnik::util::remove(filename + ".index"); + } - CHECK(!mapnik::util::exists(filename + ".index")); - int ret = create_disk_index(filename); - int ret_posix = (ret >> 8) & 0x000000ff; - INFO(ret); - INFO(ret_posix); - CHECK(mapnik::util::exists(filename + ".index")); + CHECK(!mapnik::util::exists(filename + ".index")); + int ret = create_disk_index(filename); + int ret_posix = (ret >> 8) & 0x000000ff; + INFO(ret); + INFO(ret_posix); + CHECK(mapnik::util::exists(filename + ".index")); - for (auto cache_features : {true,false}) - { - params["cache_features"] = cache_features; - auto ds = mapnik::datasource_cache::instance().create(params); - auto fields = ds->get_descriptor().get_descriptors(); - mapnik::query query(ds->envelope()); - auto features = ds->features(query); - REQUIRE_THROWS( - auto feature = features->next(); - while (feature != nullptr) - { - feature = features->next(); - }); - } + for (auto cache_features : {true,false}) + { + params["cache_features"] = cache_features; + auto ds = mapnik::datasource_cache::instance().create(params); + auto fields = ds->get_descriptor().get_descriptors(); + mapnik::query query(ds->envelope()); + auto features = ds->features(query); + REQUIRE_THROWS( + auto feature = features->next(); + while (feature != nullptr) + { + feature = features->next(); + }); + } - // cleanup - if (mapnik::util::exists(filename + ".index")) - { - mapnik::util::remove(filename + ".index"); + // cleanup + if (mapnik::util::exists(filename + ".index")) + { + mapnik::util::remove(filename + ".index"); + } } } diff --git a/utils/mapnik-index/process_geojson_file.cpp b/utils/mapnik-index/process_geojson_file.cpp index 4455318..c00c554 100644 --- a/utils/mapnik-index/process_geojson_file.cpp +++ b/utils/mapnik-index/process_geojson_file.cpp @@ -137,6 +137,11 @@ std::pair<bool,typename T::value_type::first_type> process_geojson_file(T & boxe } } } + 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); } -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

