From b404cf282f2bc4b1fc994f1b0a6344a17f104eed Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 9 Aug 2019 09:33:04 +0100 Subject: [PATCH 1/4] assemble polygons before intersecting with bounding box (ref #100) --- src/feature_builder.hpp | 55 +++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/feature_builder.hpp b/src/feature_builder.hpp index 8c8f7d4..7259e21 100644 --- a/src/feature_builder.hpp +++ b/src/feature_builder.hpp @@ -220,43 +220,40 @@ struct overzoomed_feature_builder { std::vector> rings; vtzero::decode_polygon_geometry(feature.geometry(), detail::polygon_handler(rings, dx_, dy_, zoom_factor_)); - if (!rings.empty()) + std::vector> polygons; + bool process = false; + for (auto& r : rings) + { + if (r.second == vtzero::ring_type::outer) + { + auto extent = mapbox::geometry::envelope(r.first); + process = boost::geometry::intersects(extent, bbox_); + if (process) polygons.emplace_back(); // start new polygon + } + if (process && r.first.size() > 3) + { + polygons.back().emplace_back(std::move(r.first)); + } + } + if (!polygons.empty()) { vtzero::polygon_feature_builder feature_builder{layer_builder_}; feature_builder.copy_id(feature); bool valid = false; - bool process = false; - for (auto& r : rings) + for (auto const& poly : polygons) { - if (r.second == vtzero::ring_type::outer) - { - auto extent = mapbox::geometry::envelope(r.first); - process = boost::geometry::intersects(extent, bbox_); - } - if (process) + std::vector> result; + boost::geometry::intersection(poly, bbox_, result); + for (auto const& p : result) { - std::vector> result; - if (r.second == vtzero::ring_type::inner) boost::geometry::reverse(r.first); - // ^^ reverse inner rings before clipping as we're dealing with a disassembled polygon - boost::geometry::intersection(r.first, bbox_, result); - for (auto const& p : result) + for (auto const& ring : p) { - for (auto const& ring : p) + if (ring.size() > 3) { - if (ring.size() > 3) - { - valid = true; - feature_builder.add_ring(static_cast(ring.size())); - if (r.second == vtzero::ring_type::outer) - { - std::for_each(ring.begin(), ring.end(), [&feature_builder](auto const& pt) { feature_builder.set_point(static_cast(pt.x), static_cast(pt.y)); }); - } - else - { - // apply points in reverse to preserve original winding order of inner rings - std::for_each(ring.rbegin(), ring.rend(), [&feature_builder](auto const& pt) { feature_builder.set_point(static_cast(pt.x), static_cast(pt.y)); }); - } - } + valid = true; + feature_builder.add_ring(static_cast(ring.size())); + std::for_each(ring.begin(), ring.end(), + [&feature_builder](auto const& pt) { feature_builder.set_point(static_cast(pt.x), static_cast(pt.y)); }); } } } From f0c0d5bd65e8ed761e605111f8c8e9db1d595a1c Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 9 Aug 2019 11:08:29 +0100 Subject: [PATCH 2/4] use push_back(std::move(ring)) --- src/feature_builder.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/feature_builder.hpp b/src/feature_builder.hpp index 7259e21..200c5ee 100644 --- a/src/feature_builder.hpp +++ b/src/feature_builder.hpp @@ -222,7 +222,7 @@ struct overzoomed_feature_builder vtzero::decode_polygon_geometry(feature.geometry(), detail::polygon_handler(rings, dx_, dy_, zoom_factor_)); std::vector> polygons; bool process = false; - for (auto& r : rings) + for (auto const& r : rings) { if (r.second == vtzero::ring_type::outer) { @@ -232,7 +232,7 @@ struct overzoomed_feature_builder } if (process && r.first.size() > 3) { - polygons.back().emplace_back(std::move(r.first)); + polygons.back().push_back(std::move(r.first)); } } if (!polygons.empty()) From 21bc38ce29b9caa3c782f259b3c90b384cde475d Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 9 Aug 2019 14:45:25 +0100 Subject: [PATCH 3/4] fix travis --- .travis.yml | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index e29fc0f..01b2d7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,18 +35,10 @@ matrix: ## ** Builds that are published ** - # linux cfi build node v6/release + # linux cfi build node v10/release - os: linux env: BUILDTYPE=release TOOLSET=cfi CXXFLAGS="-flto -fsanitize=cfi -fvisibility=hidden" LDFLAGS="-flto -fsanitize=cfi" - node_js: 6 - # linux publishable node v6/release - - os: linux - env: BUILDTYPE=release - node_js: 6 - # linux publishable node v6/debug - - os: linux - env: BUILDTYPE=debug - node_js: 6 + node_js: 10 # linux publishable node v8/release - os: linux env: BUILDTYPE=release @@ -63,16 +55,6 @@ matrix: - os: linux env: BUILDTYPE=debug node_js: 10 - # osx publishable node v6/release - - os: osx - osx_image: xcode9.2 - env: BUILDTYPE=release - node_js: 6 - # osx publishable node v6/debug - - os: osx - osx_image: xcode9.2 - env: BUILDTYPE=debug - node_js: 6 # osx publishable node v8/release - os: osx osx_image: xcode9.2 @@ -85,7 +67,7 @@ matrix: node_js: 10 - os: linux env: BUILDTYPE=debug TOOLSET=asan - node_js: 6 + node_js: 10 sudo: required # Overrides `install` to set up custom asan flags install: @@ -107,8 +89,8 @@ matrix: # g++ build (default builds all use clang++) - os: linux - env: BUILDTYPE=debug CXX="g++-6" CC="gcc-6" LINK="g++-6" AR="ar" NM="nm" - node_js: 6 + env: BUILDTYPE=debug CXX="g++-6" CC="gcc-6" LINK="g++-6" AR="ar" NM="nm" CXXFLAGS="-fext-numeric-literals" + node_js: 10 addons: apt: sources: @@ -124,7 +106,7 @@ matrix: # Coverage build - os: linux env: BUILDTYPE=debug CXXFLAGS="--coverage" LDFLAGS="--coverage" - node_js: 6 + node_js: 10 # Overrides `script` to publish coverage data to codecov script: - export PATH=$(pwd)/mason_packages/.link/bin/:${PATH} @@ -151,7 +133,7 @@ matrix: # Clang tidy build - os: linux env: CLANG_TIDY - node_js: 6 + node_js: 10 # Overrides `install` to avoid initializing clang toolchain install: # First run the clang-tidy target From fce6a9c5294f982d54c45226f4dd33b79ffd88ef Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 9 Aug 2019 15:40:15 +0100 Subject: [PATCH 4/4] add test (ref #100) --- test/fixtures/polygons-with-holes-4-13-6.mvt | Bin 0 -> 2723 bytes test/vtcomposite-polygons.test.js | 36 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/fixtures/polygons-with-holes-4-13-6.mvt diff --git a/test/fixtures/polygons-with-holes-4-13-6.mvt b/test/fixtures/polygons-with-holes-4-13-6.mvt new file mode 100644 index 0000000000000000000000000000000000000000..ff09be7f5fcd90693c8c1dd0e6be108ac0d95f9f GIT binary patch literal 2723 zcmWlbNr+`v9mdZ*PxqcXz2UyG-g{N`UUgM>r+Tbv(y@n_?l$QRm`>=VX$*-(6N#e6 zs5F@r2Xvt#E+n9!WMOb2MmJ(MaiJg*kcdMJu5=^fLIR4XRu3Nc{ogs?|NDO5?Y>fe z8Y%Iyr$6%S<4-^J@%3Ay{LiAnledL@7{a7bGiFi&+>6r zLXCK^A_EJ|r9NJ#J3h8?6Ba5NUQW^G)?*{D-7p$HBseOgxM-<{dQQ2&lLz zgAF{u90lQw38Fv(o;kZJ4_$9saJQG=$G;^%haN@4tFk`~HR1&3q)_4D*@x_1o!mN4 zBCRpy`28R`&wKeceht0~rz|RKWKMHji5DRYj49+`WmSews&X=88e}-iPCC7Ok9>tZ z4?QWJ4swDDA|6>QP!1hcmer7F@o-(XUjCJSmA(NpGz^fbfD|^-#EP$hDqSJ1%OI0} zlf2@ImM6Pf4RJb}m;Xe!()^Otrq}2uxi|!uivkqXNTylFrl5Bq*WdM<@)^*S=jb{~ z0}GW)Q;V@U4|~{Rs*@dl7GCE!GlLoJ<25!Cs!~CV4jSU2ti7Dio=KYvC}%-AXB=}# zQD&j1S!`|ki+ACl$h}z~>uv|Mo>5Mv+AH|8UehELx z!MIEk+x9xMo4tPT1F*}JLt0_G^0r}ryt$jco%wv4_%f95Z2WKMCPT>8x3#NUlt4?s znanv@Tv+)0izYqwf{||(KRojt+>qRL2f$?$enJR^1YR2pV2CNq`~Uz>1QcN4Odv)N zQPs;)u0&ub(ngabyT9OoXfP&OUkl&uxrI1P@P+nySX|}_B#l)ufK$66UH$9y-{^OX z=Ro%*2rbo8TDqmM%wL1b3P=dPJ&cSIsDX+TiLCr7B;H`bm{aEzsSYgMAsO`JtI3o) zOu_LmQ?nouhNbudM0|2uUCL#(6=EfG^27~AHl;&@{DM5R*W?qkViPd;ef%<1^SYqt zxWN5sVP8#(XI(1rnd4n;;AN9A>(@G?VKHNPM>3o*PHY#`)#3iO;{%*?BiFYN%@{|L z%4w@3Z$H?(mZ*?cKcZoO9y#BRNISf)^W8LxtDd2T?m;D0heovQkEKLyH9X>7iMGon z+BUVyj1D-UuBR<{_Kwcr%WyA4J~0oLW*c%%Bm5e49g3Em*YpZ1MX8rtSOdD6?ZpSL zOti41WmKTiAgzt4q$?XgLJaO^rY5w($6%kWg^Cn1kE^6HD+M?BcBrtxw_ggKl!S{+ z3Vv{m3xkG@u%V-&D^;1ABhxl&4GDGp3EJg?rvx7*eBKVmhVH;bSSb=K>IJr@W>H*o z)6ai&1*+`EG;t>D?gE?LN8} zP^FGC^vDCOB}>E&zw8`r{Q7nxV2{Q)A8K2U3L6z&0YZfJ=8dT`O$y_h^8v9(e{iD*dM z$yBF^x8PNl%%vVBK5$e93F7*gaCJUJuyNvaBGFMscgj$rj=sXmVybGmpN_CkkCPbM zwb(rxq=9!9cdXV{LG($3?-&}GwhI%kS+kRfkg6ncm4_wM3MXLTd?WAC9@kqf=a2)< zVo~P2;mtvl3+BxI=_3_{gF-g@N*CJr8|of^VU}kuvJ#gVQ@jfhP0=#*k;GD^+;?fF0EAem}WzfVLIVXE-uX}lr12j18&?Sej=Cv2%E6bG*n zs+JOD$qiT$*X((DtN(lZnO1Suu44yMO(fD1hYc?}!m1W#2etLh@E(1}8*V@#p%^$7 zh=Wd}3`QAks#-7q#=hroF4B7>uRzK*VL1uZ`BbtIW?sG{-my1J5)CbwbD|(QPAK;{ I { + assert.notOk(err); + assert.equal(vtBuffer.length, 848); + const outputInfo = vtinfo(vtBuffer); + // one feature + assert.equal(outputInfo.layers.polygons.feature.length, 1); + var feature = outputInfo.layers.polygons.feature(0); + var geojson = feature.toGeoJSON(zxy.x,zxy.y,zxy.z); + var coords = geojson.geometry.coordinates; + // two polygons + assert.equal(coords.length,2); + // first polygons 8 rings + assert.equal(coords[0].length, 8); + assert.equal(coords[0][0].length, 95); + assert.equal(coords[0][1].length, 25); + assert.equal(coords[0][2].length, 23); + assert.equal(coords[0][3].length, 18); + assert.equal(coords[0][4].length, 26); + assert.equal(coords[0][5].length, 18); + assert.equal(coords[0][6].length, 14); + assert.equal(coords[0][7].length, 16); + // second polygon 1 ring + assert.equal(coords[1].length,1); + assert.equal(coords[1][0].length, 6); + assert.end(); + }); +});