-
Notifications
You must be signed in to change notification settings - Fork 32
Description
In some cases I'm seeing invalid GeoJSON Polygons passed to the map step. It looks like features that consist of multiple exterior polygons are being converted from vector tiles to a GeoJSON Polygon instead of a GeoJSON MultiPolygon.
Then, when these Polygons are used with turf.intersect(), it throws an "TopologyError: side location conflict" exception.
Here's a test case that shows the problem.
Input file: dc.json https://gist.github.com/jamesbursa/2026d7338b7a3d227732#file-dc-json
Convert to MBTiles using Tippecanoe:
$ tippecanoe -f -o dc.mbtiles -Z 15 -z 15 -b 0 -ps dc.json
Decode one tile with tippecanoe-decode:
$ tippecanoe-decode dc.mbtiles 15 9378 12535
{ "type": "FeatureCollection", "features": [
{ "type": "Feature", "properties": { "STFIPS": "11", "CTFIPS": "11001", "STATE": "District of Columbia", "COUNTY": "District of Columbia" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -76.965699, 38.897320 ], [ -76.968470, 38.893357 ], [ -76.968760, 38.892036 ], [ -76.968237, 38.891032 ], [ -76.970214, 38.891032 ], [ -76.970214, 38.899582 ], [ -76.965852, 38.899582 ], [ -76.965699, 38.897320 ] ] ], [ [ [ -76.965710, 38.891032 ], [ -76.966973, 38.891032 ], [ -76.966501, 38.892122 ], [ -76.966000, 38.894021 ], [ -76.965710, 38.891032 ] ] ], [ [ [ -76.962199, 38.897320 ], [ -76.962100, 38.896821 ], [ -76.963985, 38.891032 ], [ -76.965222, 38.891032 ], [ -76.965699, 38.897320 ], [ -76.964200, 38.899582 ], [ -76.962481, 38.899582 ], [ -76.962199, 38.897320 ] ] ], [ [ [ -76.959227, 38.891032 ], [ -76.962204, 38.891032 ], [ -76.961099, 38.896618 ], [ -76.961132, 38.896812 ], [ -76.961199, 38.897217 ], [ -76.961703, 38.898319 ], [ -76.961169, 38.899509 ], [ -76.961137, 38.899582 ], [ -76.959227, 38.899582 ], [ -76.959227, 38.891032 ] ] ] ] } }
] }
Note that the output is correctly a MultiPolygon (containing 4 Polygons). See https://gist.github.com/jamesbursa/2026d7338b7a3d227732#file-tile-json
Run through a test TileReduce:
https://gist.github.com/jamesbursa/2026d7338b7a3d227732#file-tilereduce_test-js
https://gist.github.com/jamesbursa/2026d7338b7a3d227732#file-tilereduce_test_map-js
This simply processes the one tile of interest (15 9378 12535), outputs the feature in the tile, and attempts a turf.intersect() which throws an exception. Note that the feature as passed to the map function is a Polygon, not a MultiPolygon as tippecanoe-decode produces for the same tile.
Converting the Polygon to a MultiPolygon manually allows the turf.intersect() to work.
$ ./tilereduce_test.js
Starting up 8 workers... Job started.
Processing 1 tiles.
1 tiles processed in 0s.
map tile [9378,12535,15]
---------------------------------------------------------------
feature = { type: 'Feature',
geometry:
{ type: 'Polygon',
coordinates:
[ [ [ -76.96570068597794, 38.89732062336043 ],
[ -76.96847140789032, 38.89335845766496 ],
[ -76.96876108646393, 38.89203699076319 ],
[ -76.96823805570602, 38.89103282648847 ],
[ -76.97021484375, 38.89103282648847 ],
[ -76.97021484375, 38.89958342598271 ],
[ -76.96585357189178, 38.89958342598271 ],
[ -76.96570068597794, 38.89732062336043 ] ],
[ [ -76.965711414814, 38.89103282648847 ],
[ -76.96697473526001, 38.89103282648847 ],
[ -76.96650266647339, 38.8921225841508 ],
[ -76.9660010933876, 38.89402231327574 ],
[ -76.965711414814, 38.89103282648847 ] ],
[ [ -76.9622004032135, 38.89732062336043 ],
[ -76.96210116147995, 38.89682171160487 ],
[ -76.96398675441742, 38.89103282648847 ],
[ -76.96522325277328, 38.89103282648847 ],
[ -76.96570068597794, 38.89732062336043 ],
[ -76.96420133113861, 38.89958342598271 ],
[ -76.96248203516006, 38.89958342598271 ],
[ -76.9622004032135, 38.89732062336043 ] ],
[ [ -76.959228515625, 38.89103282648847 ],
[ -76.96220576763153, 38.89103282648847 ],
[ -76.9611006975174, 38.89661922340707 ],
[ -76.96113288402557, 38.89681336158753 ],
[ -76.96119993925095, 38.89721833629872 ],
[ -76.96170419454575, 38.89832052381641 ],
[ -76.96117043495178, 38.89951036613891 ],
[ -76.9611382484436, 38.89958342598271 ],
[ -76.959228515625, 38.89958342598271 ],
[ -76.959228515625, 38.89103282648847 ] ] ] },
properties:
{ STFIPS: '11',
CTFIPS: '11001',
STATE: 'District of Columbia',
COUNTY: 'District of Columbia' } };
square = { type: 'Feature',
geometry:
{ type: 'Polygon',
coordinates:
[ [ [ -76.965, 38 ],
[ -76, 38 ],
[ -76, 38.895 ],
[ -76.965, 38.895 ],
[ -76.965, 38 ] ] ] },
properties: {} };
*** turf.intersect exception: TopologyError: side location conflict [ (-76.96570068597794, 38.89732062336043) ]
---------------------------------------------------------------
converting to MultiPolygon
feature = { type: 'Feature',
geometry:
{ type: 'MultiPolygon',
coordinates:
[ [ [ [ -76.96570068597794, 38.89732062336043 ],
[ -76.96847140789032, 38.89335845766496 ],
[ -76.96876108646393, 38.89203699076319 ],
[ -76.96823805570602, 38.89103282648847 ],
[ -76.97021484375, 38.89103282648847 ],
[ -76.97021484375, 38.89958342598271 ],
[ -76.96585357189178, 38.89958342598271 ],
[ -76.96570068597794, 38.89732062336043 ] ] ],
[ [ [ -76.965711414814, 38.89103282648847 ],
[ -76.96697473526001, 38.89103282648847 ],
[ -76.96650266647339, 38.8921225841508 ],
[ -76.9660010933876, 38.89402231327574 ],
[ -76.965711414814, 38.89103282648847 ] ] ],
[ [ [ -76.9622004032135, 38.89732062336043 ],
[ -76.96210116147995, 38.89682171160487 ],
[ -76.96398675441742, 38.89103282648847 ],
[ -76.96522325277328, 38.89103282648847 ],
[ -76.96570068597794, 38.89732062336043 ],
[ -76.96420133113861, 38.89958342598271 ],
[ -76.96248203516006, 38.89958342598271 ],
[ -76.9622004032135, 38.89732062336043 ] ] ],
[ [ [ -76.959228515625, 38.89103282648847 ],
[ -76.96220576763153, 38.89103282648847 ],
[ -76.9611006975174, 38.89661922340707 ],
[ -76.96113288402557, 38.89681336158753 ],
[ -76.96119993925095, 38.89721833629872 ],
[ -76.96170419454575, 38.89832052381641 ],
[ -76.96117043495178, 38.89951036613891 ],
[ -76.9611382484436, 38.89958342598271 ],
[ -76.959228515625, 38.89958342598271 ],
[ -76.959228515625, 38.89103282648847 ] ] ] ] },
properties:
{ STFIPS: '11',
CTFIPS: '11001',
STATE: 'District of Columbia',
COUNTY: 'District of Columbia' } };
intersect = { type: 'Feature',
properties: {},
geometry:
{ type: 'MultiPolygon',
coordinates:
[ [ [ [ -76.96142100332834, 38.895 ],
[ -76.959228515625, 38.895 ],
[ -76.959228515625, 38.89103282648847 ],
[ -76.96220576763153, 38.89103282648847 ],
[ -76.96142100332834, 38.895 ] ] ],
[ [ [ -76.965, 38.89103282648847 ],
[ -76.965, 38.895 ],
[ -76.96269454111474, 38.895 ],
[ -76.96398675441742, 38.89103282648847 ],
[ -76.965, 38.89103282648847 ] ] ] ] } };
---------------------------------------------------------------