Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid GeoJSON Polygons passed to map step #76

Closed
jamesbursa opened this issue Feb 5, 2016 · 2 comments
Closed

Invalid GeoJSON Polygons passed to map step #76

jamesbursa opened this issue Feb 5, 2016 · 2 comments

Comments

@jamesbursa
Copy link

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 ] ] ] ] } };
---------------------------------------------------------------
@e-n-f
Copy link
Contributor

e-n-f commented Feb 5, 2016

Thanks! It is great to have a solid test case for polygon problems. I'll take a close look at this in the morning.

@mourner
Copy link
Member

mourner commented Mar 10, 2016

This is an upstream issue in vector-tile-js, see mapbox/vector-tile-js#33. It was not possible to fix in earlier vector spec, but will be ready to land once vector-tile-spec version 2 becomes the production version at Mapbox (which is happening any time these days).

@mourner mourner closed this as completed Mar 10, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants