Esri / terraformer-wkt-parser

Well-Known Text parser for Terraformer
MIT License
77 stars 30 forks source link

Counter clockwise polygons #15

Closed TheCycoONE closed 6 years ago

TheCycoONE commented 8 years ago

When converting from ArcGIS JSON to WKT my polygon always ends up with a clockwise orientation (regardless of whether ring[0] in the ArcGIS JSON is clockwise or counter clockwise.

This is particularly undesirable because the OGC specification requires that the polygon be specified counter-clockwise, and tools like SQL Server require that orientation.

I am using: terraformer 1.0.4 terraformer-wkt-parser 1.1.0 terraformer-arcgis-parser 1.0.4

{"rings":[[[-9466845.160610136,6659598.392804854],[551909.0107818246,6659598.392804854],[551909.0107818246,1591517.6693858737],[-9466845.160610136,1591517.6693858737],[-9466845.160610136,6659598.392804854]]],"spatialReference":{"wkid":102100}}

and

{"rings":[[[-9466845.160610136,6659598.392804854],[-9466845.160610136,1591517.6693858737],[551909.0107818246,1591517.6693858737],[551909.0107818246,6659598.392804854],[-9466845.160610136,6659598.392804854]]],"spatialReference":{"wkid":102100}}

both become

{"type":"Polygon","coordinates":[[[-85.04211700169012,51.21604200714901],[4.957882998285988,51.21604200714901],[4.957882998285988,14.150752375669544],[-85.04211700169012,14.150752375669544],[-85.04211700169012,51.21604200714901]]],"bbox":[-85.04211700169012,14.150752375669544,4.957882998285988,51.21604200714901]}

which becomes:

POLYGON ((-85.04211700169012 51.21604200714901, 4.957882998285988 51.21604200714901, 4.957882998285988 14.150752375669544, -85.04211700169012 14.150752375669544, -85.04211700169012 51.21604200714901))
TheCycoONE commented 8 years ago

As a workaround I can use: geoJson.coordinates[0].reverse(); before converting to WKT.

TheCycoONE commented 8 years ago

I just read the latest draft spec for GeoJSON, which says "A linear ring SHOULD follow right-hand rule with respect to the area it bounds (i.e., exterior rings are counter-clockwise, holes are clockwise)"

Given that, the bug is probably in the arcgis-parser rather than the wkt-parser.

Awaiting feedback before I open the issue on that project.

jgravois commented 8 years ago

i'll check into it in both projects. thanks for the report.

JerrySievert commented 8 years ago

i would think that the issue is in the arcgis-parser. the wkt parser doesn't do anything special, it just accepts whatever input it is given, and does a quick conversion without validation.

jgravois commented 8 years ago

i did quite a bit of research and testing today, and this is what i found.

while the GeoJSON spec does not dictate winding order for polygons, most folks agree that its appropriate to reverse the winding order of interior rings, hence the SHOULD language in the draft specification which has settled on adopting counter-clockwise outer, clockwise inner as an informal recommendation. This is apparently consistent with the OGC/ISO spec.

In contrast, PostGIS and both Esri's Shapefile spec and Geoservices Geometry specification prefer clockwise outer, counter-clockwise inner.

In our current implementation in terraformer-arcgis-parser, we simply pass through without re-winding. Given that the intent of declaring an established practice is largely based on a universal agreement that its preferable to ensure that interior rings are oriented differently than outer rings, i'm kind of happy to just let sleeping dogs lie in Terraformer.

That said, I have already created a branch that spits out ring orders that align with the recommendation of the draft spec so it'd would be very easy to PR the change if anyone can explain to me why it'd be helpful to them for Terraformer to ensure that exterior rings are oriented counter-clockwise and interior rings clockwise.

more discussion here: https://github.com/mapbox/tilemill/issues/2110#issuecomment-30674206

cc/ @patrickarlt

TheCycoONE commented 8 years ago

Well the reason I ran into an issue was that SQL Server 2008 R2's Spatial engine errors out if clockwise outer is used. In SQL Server 2012 if you use clockwise outer then the engine assumes you are selecting the entire world except what is within the polygon.

jgravois commented 8 years ago

i see three options.

  1. ensure that ring orders are reversed when converting ArcGIS geometries to WKT or GeoJSON in existing methods.
  2. add new methods which force a left handed rule in output (and leave the existing methods be)
  3. do nothing (and just document the fact that folks are on their own).

since PostGIS/JTS/GEOS/OGC/WKT/WKB don't make any internal assumptions about ring order, restricting the surface area of the change has some appeal.

since the current behavior causes problems in SQL Server, and produces output which is out of sync with both the GeoJSON draft spec recommendation, as well as what is outlined in version 2.1 of the vector-tile-spec, the first option doesn't seem bad either.

more feedback, especially from the folks that wrote the bulk of Terraformer, would be sincerely appreciated.

pinging @ajturner too.

jgravois commented 6 years ago

RFC 7946 is more opinionated than the previous draft of the spec with regard to ring-winding order.

in arcgis-to-geojson-utils (another standalone parser) we have ensured that we are compliant.

i've logged https://github.com/Esri/terraformer-arcgis-parser/issues/50 to track progress of the same for that lib.