diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f1bf0164..ec736c8a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.8.1 + +* Improve precision of polygon ring area calculations + ## 2.8.0 * Add the option to use a different simplification level at maxzoom diff --git a/decode.cpp b/decode.cpp index 04593e701..9a7869b22 100644 --- a/decode.cpp +++ b/decode.cpp @@ -207,9 +207,9 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::set= max_exact_double) { + again = true; + break; + } + area -= (double) ((geom[k].y - by) / scale) * (double) ((geom[i + ((k - i + 1) % (j - i))].x - bx) / scale); + if (std::fabs(area) >= max_exact_double) { + again = true; + break; + } + } + + if (again) { + continue; + } else { + area /= 2; + return area * scale * scale; + } + } + + fprintf(stderr, "get_area_scaled: can't happen\n"); + exit(EXIT_IMPOSSIBLE); +} + +double get_area(const drawvec &geom, size_t i, size_t j) { + const double max_exact_double = (double) ((1LL << 53) - 1); + + // Coordinates in `geom` are 40-bit integers, so there is no good way + // to multiply them without possible precision loss. Since they probably + // do not use the full precision, shift them nearer to the origin so + // their product is more likely to be exactly representable as a double. + // + // (In practice they are actually 34-bit integers: 32 bits for the + // Mercator world plane, plus another two bits so features can stick + // off either the left or right side. But that is still too many bits + // for the product to fit either in a 64-bit long long or in a + // double where the largest exact integer is 2^53.) + // + // If the intermediate calculation still exceeds 2^53, start trying to + // recalculate the area by scaling down the geometry. This will not + // produce as precise an area, but it will still be close, and the + // sign will be correct, which is more important, since the sign + // determines the winding order of the rings. We can then use that + // sign with this generally more precise area calculation. + + long long bx = geom[i].x; + long long by = geom[i].y; + + // https://en.wikipedia.org/wiki/Shoelace_formula double area = 0; + bool overflow = false; for (size_t k = i; k < j; k++) { - area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y; - area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x; + area += (double) (geom[k].x - bx) * (double) (geom[i + ((k - i + 1) % (j - i))].y - by); + if (std::fabs(area) >= max_exact_double) { + overflow = true; + } + area -= (double) (geom[k].y - by) * (double) (geom[i + ((k - i + 1) % (j - i))].x - bx); + if (std::fabs(area) >= max_exact_double) { + overflow = true; + } } area /= 2; + + if (overflow) { + double scaled_area = get_area_scaled(geom, i, j); + if ((area < 0 && scaled_area > 0) || (area > 0 && scaled_area < 0)) { + area = -area; + } + } + return area; } @@ -518,7 +593,7 @@ drawvec simple_clip_poly(drawvec &geom, int z, int buffer) { drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area) { drawvec out; - const long long pixel = (1 << (32 - detail - z)) * tiny_polygon_size; + const double pixel = (1LL << (32 - detail - z)) * (double) tiny_polygon_size; *reduced = true; bool included_last_outer = false; diff --git a/geometry.hpp b/geometry.hpp index 8a388cca0..cfcb29594 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -74,7 +74,7 @@ drawvec reorder_lines(drawvec &geom); drawvec fix_polygon(drawvec &geom); std::vector chop_polygon(std::vector &geoms); void check_polygon(drawvec &geom); -double get_area(drawvec &geom, size_t i, size_t j); +double get_area(const drawvec &geom, size_t i, size_t j); double get_mp_area(drawvec &geom); drawvec simple_clip_poly(drawvec &geom, long long x1, long long y1, long long x2, long long y2); diff --git a/main.cpp b/main.cpp index e20eaf7a9..6c87639a9 100644 --- a/main.cpp +++ b/main.cpp @@ -2289,7 +2289,7 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo if (maxzoom == 0) { droprate = 2.5; } else { - droprate = exp(log((long double) max[0].count / max[maxzoom].count) / (maxzoom)); + droprate = exp(log((double) max[0].count / max[maxzoom].count) / (maxzoom)); if (!quiet) { fprintf(stderr, "Choosing a drop rate of -r%f to get from %lld to %lld in %d zooms\n", droprate, max[maxzoom].count, max[0].count, maxzoom); } @@ -2298,7 +2298,7 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo basezoom = 0; for (z = 0; z <= maxzoom; z++) { - double zoomdiff = log((long double) max[z].count / max_features) / log(droprate); + double zoomdiff = log((double) max[z].count / max_features) / log(droprate); if (zoomdiff + z > basezoom) { basezoom = ceil(zoomdiff + z); } @@ -2314,7 +2314,7 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo double interval = exp(log(droprate) * (basezoom - z)); if (max[z].count / interval >= max_features) { - interval = (long double) max[z].count / max_features; + interval = (double) max[z].count / max_features; droprate = exp(log(interval) / (basezoom - z)); interval = exp(log(droprate) * (basezoom - z)); diff --git a/tests/single-polygons/in.json b/tests/single-polygons/in.json new file mode 100644 index 000000000..685b259de --- /dev/null +++ b/tests/single-polygons/in.json @@ -0,0 +1,30 @@ +{"type":"Feature","properties":{"seq":6},"geometry":{"type":"Polygon","coordinates":[[[174.72151704933612,-37.16620984485238],[174.721517058737,-37.16620953185807],[174.7215172151761,-37.16620953486748],[174.72151720953557,-37.16620972266407],[174.72151705121628,-37.166209782253527],[174.72151704933612,-37.16620984485238]]]}} +{"type":"Feature","properties":{"seq":7},"geometry":{"type":"Polygon","coordinates":[[[174.7215178334118,-37.16620979730054],[174.72151760063333,-37.16620973018757],[174.72151760627387,-37.16620954239099],[174.72151784093254,-37.16620954690509],[174.72151791351156,-37.166209736206379],[174.7215178334118,-37.16620979730054]]]}} +{"type":"Feature","properties":{"seq":8},"geometry":{"type":"Polygon","coordinates":[[[174.72151861936775,-37.16620968714982],[174.7215183064895,-37.166209681131018],[174.72151823203033,-37.16620955442859],[174.7215186231281,-37.1662095619521],[174.72151861936775,-37.16620968714982]]]}} +{"type":"Feature","properties":{"seq":9},"geometry":{"type":"Polygon","coordinates":[[[174.72151955424205,-37.16620983040395],[174.72151932710407,-37.1662095754944],[174.7215196399823,-37.16620958151319],[174.72151963434178,-37.16620976930978],[174.72151955424205,-37.16620983040395]]]}} +{"type":"Feature","properties":{"seq":10},"geometry":{"type":"Polygon","coordinates":[[[174.7215202600982,-37.166209781347379],[174.7215201036591,-37.16620977833798],[174.72151995286053,-37.166209587532],[174.7215203439583,-37.16620959505549],[174.72152034019795,-37.166209720253217],[174.7215202600982,-37.166209781347379]]]}} +{"type":"Feature","properties":{"seq":11},"geometry":{"type":"Polygon","coordinates":[[[174.72152111863316,-37.16620986049794],[174.7215208076351,-37.16620979188027],[174.72152081327563,-37.16620960408368],[174.72152112615385,-37.16620961010249],[174.72152111863316,-37.16620986049794]]]}} +{"type":"Feature","properties":{"seq":12},"geometry":{"type":"Polygon","coordinates":[[[174.72152182448932,-37.16620981144135],[174.72152151349128,-37.166209742823699],[174.7215215172516,-37.166209617625977],[174.7215219083494,-37.16620962514947],[174.72152190458906,-37.16620975034719],[174.72152182448932,-37.16620981144135]]]}} +{"type":"Feature","properties":{"seq":13},"geometry":{"type":"Polygon","coordinates":[[[174.7215236235391,-37.1662098460494],[174.72152331630142,-37.16620965223402],[174.72152370739918,-37.166209659757509],[174.7215237036388,-37.16620978495524],[174.7215236235391,-37.1662098460494]]]}} +{"type":"Feature","properties":{"seq":14},"geometry":{"type":"Polygon","coordinates":[[[174.72152440761483,-37.16620979849751],[174.72152409849697,-37.16620966728101],[174.7215244895947,-37.16620967480448],[174.721524409495,-37.166209735898657],[174.72152440761483,-37.16620979849751]]]}} +{"type":"Feature","properties":{"seq":15},"geometry":{"type":"Polygon","coordinates":[[[174.72152526802993,-37.16620981504918],[174.72152495703188,-37.166209746431537],[174.72152527179029,-37.16620968985145],[174.72152526802993,-37.16620981504918]]]}} +{"type":"Feature","properties":{"seq":16},"geometry":{"type":"Polygon","coordinates":[[[174.72152581180647,-37.16620995077977],[174.72152565536738,-37.16620994777038],[174.72152558466849,-37.166209695870239],[174.7215258975467,-37.16620970188902],[174.7215258919062,-37.1662098896856],[174.72152581180647,-37.16620995077977]]]}} +{"type":"Feature","properties":{"seq":17},"geometry":{"type":"Polygon","coordinates":[[[174.72152690876045,-37.16620990924664],[174.72152659776237,-37.166209840629],[174.72152660152273,-37.16620971543128],[174.72152691440093,-37.16620972145006],[174.72152690876045,-37.16620990924664]]]}} +{"type":"Feature","properties":{"seq":18},"geometry":{"type":"Polygon","coordinates":[[[174.72153363564224,-37.16621003865021],[174.72153324642464,-37.1662099685279],[174.72153325018497,-37.166209843330168],[174.72153364128273,-37.16620985085363],[174.72153363564224,-37.16621003865021]]]}} +{"type":"Feature","properties":{"seq":19},"geometry":{"type":"Polygon","coordinates":[[[174.72153504359427,-37.166210065734649],[174.72153488715515,-37.16621006272526],[174.72153473635653,-37.166209871919289],[174.72153520567387,-37.166209880947437],[174.72153512369398,-37.16621000464046],[174.72153504359427,-37.166210065734649]]]}} +{"type":"Feature","properties":{"seq":20},"geometry":{"type":"Polygon","coordinates":[[[174.7215366079854,-37.166210095828429],[174.72153621876778,-37.16621002570611],[174.7215362225281,-37.16620990050839],[174.72153661362587,-37.166209908031827],[174.7215366079854,-37.166210095828429]]]}} +{"type":"Feature","properties":{"seq":21},"geometry":{"type":"Polygon","coordinates":[[[174.72153817425667,-37.16621006332332],[174.72153786137847,-37.16621005730457],[174.7215377869192,-37.16620993060216],[174.721538178017,-37.16620993812559],[174.72153817425667,-37.16621006332332]]]}} +{"type":"Feature","properties":{"seq":22},"geometry":{"type":"Polygon","coordinates":[[[174.72154004964589,-37.166210162034669],[174.7215398149872,-37.1662101575206],[174.7215397424081,-37.16620996821933],[174.7215401335059,-37.16620997574277],[174.72154012974557,-37.16621010094049],[174.72154004964589,-37.166210162034669]]]}} +{"type":"Feature","properties":{"seq":23},"geometry":{"type":"Polygon","coordinates":[[[174.72154153581747,-37.166210190623697],[174.7215412248194,-37.16621012200609],[174.7215412285797,-37.16620999680837],[174.72154154145793,-37.16621000282711],[174.72154153581747,-37.166210190623697]]]}} +{"type":"Feature","properties":{"seq":24},"geometry":{"type":"Polygon","coordinates":[[[174.72154231801304,-37.16621020567055],[174.7215421615739,-37.16621020266118],[174.72154201077528,-37.16621001185522],[174.7215424800926,-37.16621002088333],[174.72154239811273,-37.16621014457637],[174.72154231801304,-37.16621020567055]]]}} +{"type":"Feature","properties":{"seq":25},"geometry":{"type":"Polygon","coordinates":[[[174.7215440332028,-37.1662104265702],[174.7215438041846,-37.16621023425956],[174.72154349130637,-37.16621022824081],[174.72154341872727,-37.16621003893954],[174.72154380982509,-37.16621004646295],[174.72154380606475,-37.16621017166068],[174.72154404072342,-37.16621017617474],[174.7215441133025,-37.166210365476008],[174.7215440332028,-37.1662104265702]]]}} +{"type":"Feature","properties":{"seq":26},"geometry":{"type":"Polygon","coordinates":[[[174.72154474093913,-37.16621031491462],[174.7215445845,-37.16621031190526],[174.7215445138011,-37.166210060005109],[174.7215448266793,-37.166210066023847],[174.72154482103884,-37.16621025382044],[174.72154474093913,-37.16621031491462]]]}} +{"type":"Feature","properties":{"seq":27},"geometry":{"type":"Polygon","coordinates":[[[174.7215463760292,-37.1662105969084],[174.72154606503114,-37.16621052829082],[174.7215461564118,-37.16621009160346],[174.72154639107047,-37.166210096117499],[174.72154637978952,-37.16621047171068],[174.7215463760292,-37.1662105969084]]]}} +{"type":"Feature","properties":{"seq":28},"geometry":{"type":"Polygon","coordinates":[[[174.7215470093063,-37.166210358550419],[174.72154677652777,-37.1662102914375],[174.72154678216823,-37.166210103640917],[174.72154709504648,-37.166210109659647],[174.721547089406,-37.16621029745623],[174.7215470093063,-37.166210358550419]]]}} +{"type":"Feature","properties":{"seq":29},"geometry":{"type":"Polygon","coordinates":[[[174.72154865379714,-37.16621032754985],[174.7215484191385,-37.16621032303581],[174.7215482683398,-37.16621013222985],[174.72154873765718,-37.16621014125794],[174.72154873389688,-37.16621026645566],[174.72154865379714,-37.16621032754985]]]}} +{"type":"Feature","properties":{"seq":30},"geometry":{"type":"Polygon","coordinates":[[[174.7215495123321,-37.1662104067002],[174.72154920321419,-37.16621027548374],[174.7215492069745,-37.16621015028602],[174.72154951985272,-37.166210156304739],[174.7215495123321,-37.1662104067002]]]}} +{"type":"Feature","properties":{"seq":31},"geometry":{"type":"Polygon","coordinates":[[[174.7215563193138,-37.166210475008309],[174.7215560846551,-37.166210470494288],[174.72155609029557,-37.16621028269769],[174.7215563249542,-37.166210287211708],[174.7215563193138,-37.166210475008309]]]}} +{"type":"Feature","properties":{"seq":32},"geometry":{"type":"Polygon","coordinates":[[[174.72155686497056,-37.1662105481399],[174.72155671041157,-37.16621048253168],[174.72155671417188,-37.16621035733396],[174.72155702893026,-37.1662103007538],[174.72155694507024,-37.1662104870457],[174.72155686497056,-37.1662105481399]]]}} +{"type":"Feature","properties":{"seq":33},"geometry":{"type":"Polygon","coordinates":[[[174.72155858768097,-37.166210518643868],[174.7215583530223,-37.16621051412985],[174.7215582804432,-37.16621032482858],[174.72155867154096,-37.166210332351969],[174.7215585895611,-37.16621045604501],[174.72155858768097,-37.166210518643868]]]}} +{"type":"Feature","properties":{"seq":34},"geometry":{"type":"Polygon","coordinates":[[[174.72155944057554,-37.166210785590759],[174.72155920591687,-37.16621078107673],[174.7215592153176,-37.16621046808239],[174.72155906263874,-37.16621033987532],[174.721559375517,-37.16621034589402],[174.72155944621597,-37.16621059779416],[174.72155944057554,-37.166210785590759]]]}} +{"type":"Feature","properties":{"seq":35},"geometry":{"type":"Polygon","coordinates":[[[174.72156406305005,-37.16621062397093],[174.7215637501718,-37.166210617952248],[174.72156375581225,-37.16621043015566],[174.72156406869048,-37.16621043617434],[174.72156406305005,-37.16621062397093]]]}} diff --git a/tests/single-polygons/out/-Z21_-zg_-D10_-d10.json b/tests/single-polygons/out/-Z21_-zg_-D10_-d10.json new file mode 100644 index 000000000..941fddc14 --- /dev/null +++ b/tests/single-polygons/out/-Z21_-zg_-D10_-d10.json @@ -0,0 +1,116 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "174.721517,-37.166211,174.721564,-37.166209", +"center": "174.721541,-37.166211,22", +"description": "tests/single-polygons/out/-Z21_-zg_-D10_-d10.json.check.mbtiles", +"format": "pbf", +"generator_options": "./tippecanoe -q -a@ -f -o tests/single-polygons/out/-Z21_-zg_-D10_-d10.json.check.mbtiles -Z21 -zg -D10 -d10 tests/single-polygons/in.json", +"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 21, \"maxzoom\": 22, \"fields\": {\"seq\": \"Number\"} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"in\",\"count\": 30,\"geometry\": \"Polygon\",\"attributeCount\": 1,\"attributes\": [{\"attribute\": \"seq\",\"count\": 30,\"type\": \"number\",\"values\": [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,6,7,8,9],\"min\": 6,\"max\": 35}]}]}}", +"maxzoom": "22", +"minzoom": "21", +"name": "tests/single-polygons/out/-Z21_-zg_-D10_-d10.json.check.mbtiles", +"strategies": "[ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { \"tiny_polygons\": 27 }, { \"tiny_polygons\": 1 } ]", +"type": "overlay", +"version": "2" +}, "features": [ +{ "type": "FeatureCollection", "properties": { "zoom": 21, "x": 2066402, "y": 1282091 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 1024 }, "features": [ +{ "type": "Feature", "properties": { "seq": 8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721518, -37.166209 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166209 ], [ 174.721518, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721519, -37.166209 ], [ 174.721519, -37.166210 ], [ 174.721519, -37.166210 ], [ 174.721519, -37.166209 ], [ 174.721519, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 10 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721520, -37.166209 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166209 ], [ 174.721520, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 12 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721522, -37.166209 ], [ 174.721522, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166209 ], [ 174.721522, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 15 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721525, -37.166209 ], [ 174.721525, -37.166210 ], [ 174.721525, -37.166210 ], [ 174.721525, -37.166209 ], [ 174.721525, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 17 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721527, -37.166209 ], [ 174.721527, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166209 ], [ 174.721527, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 18 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 20 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 22 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 24 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721543, -37.166210 ], [ 174.721544, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 26 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721545, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 27 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721546, -37.166210 ], [ 174.721546, -37.166211 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 29 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 30 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 32 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721557, -37.166210 ], [ 174.721557, -37.166211 ], [ 174.721556, -37.166211 ], [ 174.721556, -37.166210 ], [ 174.721557, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 34 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721559, -37.166210 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 35 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 22, "x": 4132805, "y": 2564182 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 1024 }, "features": [ +{ "type": "Feature", "properties": { "seq": 6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721517, -37.166209 ], [ 174.721517, -37.166210 ], [ 174.721517, -37.166210 ], [ 174.721517, -37.166209 ], [ 174.721517, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721518, -37.166209 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166209 ], [ 174.721518, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721519, -37.166209 ], [ 174.721519, -37.166210 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166209 ], [ 174.721519, -37.166209 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721519, -37.166210 ], [ 174.721520, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 11 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 10 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 12 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721522, -37.166210 ], [ 174.721522, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721522, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 13 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721523, -37.166210 ], [ 174.721524, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 14 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 16 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 17 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 18 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721534, -37.166210 ], [ 174.721534, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721534, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 19 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 20 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721537, -37.166210 ], [ 174.721537, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721537, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 21 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 22 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 23 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 24 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721543, -37.166210 ], [ 174.721543, -37.166210 ], [ 174.721544, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 26 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 27 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721546, -37.166210 ], [ 174.721546, -37.166211 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 28 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 29 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 30 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 31 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 32 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 33 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ], [ 174.721558, -37.166210 ], [ 174.721558, -37.166210 ], [ 174.721559, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 34 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721559, -37.166210 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ] ] ] } } +, +{ "type": "Feature", "properties": { "seq": 35 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166211 ], [ 174.721564, -37.166211 ], [ 174.721564, -37.166210 ] ] ] } } +] } +] } +] } diff --git a/version.hpp b/version.hpp index 7aedadb96..5709b4a09 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "v2.8.0" +#define VERSION "v2.8.1" #endif diff --git a/write_json.cpp b/write_json.cpp index 545e726b2..5a3e18705 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -505,11 +505,11 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y int outer = 0; for (size_t i = 0; i < rings.size(); i++) { - long double area = 0; + double area = 0; for (size_t k = 0; k < rings[i].size(); k++) { if (rings[i][k].op != VT_CLOSEPATH) { - area += (long double) rings[i][k].x * (long double) rings[i][(k + 1) % rings[i].size()].y; - area -= (long double) rings[i][k].y * (long double) rings[i][(k + 1) % rings[i].size()].x; + area += (double) rings[i][k].x * (double) rings[i][(k + 1) % rings[i].size()].y; + area -= (double) rings[i][k].y * (double) rings[i][(k + 1) % rings[i].size()].x; } } area /= 2;