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

Consider implementing logic to reverse northing-easting to easting-northing axis ordering if required for eWKT->GeoJSON #108

Open
ashleysommer opened this issue Aug 19, 2024 · 5 comments

Comments

@ashleysommer
Copy link

ashleysommer commented Aug 19, 2024

The default CRS for WKT geometry strings (if a CRS/SRID is not specified) is specified to be"OGC::CRS84" that is like WGS84 except with latitude-longitude reversed (it uses easting-northing, aka longitude-latitude).
Similarly, GeoJSON spec states coordinates in GeoJSON geometries are always defined in WGS84 but with the first two coordinates" components being "longitude, latitude" regardless of CRS.

So the result is functionally the same, they both by default use WGS84 but with axis-ordering of Longitude,Latitude. This allows for easy WKT->GeoJSON conversion.

The hard part: when WKT specifies an alternate CRS/SRID (eg, with eWKT).
Eg WKT string: "SRID=4326; POINT (40.7128 -74.0060)"
This string now uses "real" WGS84 (epsg:4326) with the axis ordering of latitude-longitude as specified by the ESPG code.

However, even if we add geometry["meta"]["srid"]=4326 to the GeoJSON output, the geojson spec states that all geometries with a "longitude" and "latitude" component will always be in "longitude, latitude" order, so geomet emits an INVALID GeoJSON chunk:

      {
          "type": "Feature",
          "geometry": {
              "type": "Point",
              "meta": {
                  "srid": 4326
              },
              "coordinates": [
                  40.7128,
                  -74.0060
              ]
          },
          "properties": {
          }
      }

Geomet should have the ability to swap latitude-longitude ordering when required, a more correct output would be:

      {
          "type": "Feature",
          "geometry": {
              "type": "Point",
              "meta": {
                  "srid": 4326
              },
              "coordinates": [
                  -74.0060
                  40.7128
              ]
          },
          "properties": {
          }
      }

However that is misleading because it is going against the EPSG:4326 specification, that means technically all EPSG CRS standards that use latitude-longitude axis-ordering are not compatible with GeoJSON output, that is also mentioned in this W3C document on GeoJSON: https://www.w3.org/2015/spatial/wiki/Coordinate_Reference_Systems.html#GeoJSON

Meanwhile,
I wonder if for simple common cases of WKT strings with "SRID=4326" like shown above, Geomet should reverse the coordinates and omit the meta.srid property, so the point ordering is not ambiguous.

      {
          "type": "Feature",
          "geometry": {
              "type": "Point",
              "coordinates": [
                  -74.0060
                  40.7128
              ]
          },
          "properties": {
          }
      }
@ashleysommer ashleysommer changed the title Consider implementing logic to reverse easting-northing latitude-longtiude axis ordering if required Consider implementing logic to reverse northing-easting to easting-northing axis ordering if required for GeoJSON Aug 19, 2024
@achapkowski
Copy link
Contributor

GeoJSON says that all coordinates must be longitude/latitude or X/Y. This means the GeoJSON spec takes precedence over the crs.

see: https://www.rfc-editor.org/rfc/rfc7946.html#appendix-A.1

@ashleysommer
Copy link
Author

ashleysommer commented Aug 19, 2024

GeoJSON says that all coordinates must be longitude/latitude or X/Y. This means the GeoJSON spec takes precedence over the crs.

Yep, that"s correct, I wrote that in the original post. That is why I am suggesting when the WKT string specifies coordinates in latitude/longitude order, they should be swapped when writing out to GeoJSON.

@ashleysommer ashleysommer changed the title Consider implementing logic to reverse northing-easting to easting-northing axis ordering if required for GeoJSON Consider implementing logic to reverse northing-easting to easting-northing axis ordering if required for eWKT->GeoJSON Aug 19, 2024
@ashleysommer
Copy link
Author

I was checking the spec for eWKB, to see if the logic of swapping the Latitude/Longitude order based on SRID is the same as for WKT.

Its not completely clear, but it looks like WKB is like GeoJSON, the first two coordinates are always specified to be X-Y (Longitude-Latitude), so unlike WKT, they never need swapping when writing to GeoJSON.

@larsbutler
Copy link
Member

@ashleysommer Could you provide some context about your use case? This discussion so far is about data and specifications, and I think it would be helpful to understand your use case more concretely.

However, even if we add geometry["meta"]["srid"]=4326 to the GeoJSON output, the geojson spec states that all geometries with a "longitude" and "latitude" component will always be in "longitude, latitude" order, so geomet emits an INVALID GeoJSON chunk:

I see your point, but I wouldn"t agree that"s invalid GeoJSON. There"s a discussion about why we introduced the "meta" extension to the GeoJSON output: #28. The big challenge with converting between different data types is the fact that not all specifications (WKT/WKB/EWKT/EWKB/GeoJSON, etc.) are completely "lossless". GeoJSON doesn"t have any aware of SRIDs. Even the various the WK specs are ambiguous in places. We figured the least we could do is add some hints to the output.

Yep, that"s correct, I wrote that in the original post. That is why I am suggesting when the WKT string specifies coordinates in latitude/longitude order, they should be swapped when writing out to GeoJSON.

This is an interesting idea. I do theoretically like the idea of intelligently reading the SRID and ordering coordinates of converted output accordingly. I think the main challenge there is finding good specs for all the different reference systems and adding special handling for all of them. That would be the thorough way to do it, but it"s a lot of work. I am, however, wary of introducing something which could cause problems.

I was checking the spec for eWKB, to see if the logic of swapping the Latitude/Longitude order based on SRID is the same as for WKT.
Its not completely clear, but it looks like WKB is like GeoJSON, the first two coordinates are always specified to be X-Y (Longitude-Latitude), so unlike WKT, they never need swapping when writing to GeoJSON.

It makes sense that a binary protocol would standard the order of coordinate components.

@ashleysommer Do you have a references to the WGS84 specification where the coordinate ordering is defined? Just so I can deep-dive on this a bit more.

In any case, I would be cautious to implement this change, because from what I can see, all of the WK specs standardize on XY(Z) ordering. GeoJSON is the same. In my view, this is about encoding values in 2d/3d space, which different from how those coordinates are represented or displayed in a given spatial reference system.

@ashleysommer
Copy link
Author

ashleysommer commented Oct 15, 2024

@larsbutler
Our use case is for the RDFLib project, we are implementing a GeoSPARQL to GeoJSON converter.
Serialized GeoSPARQL geometries are similar to eWKT, they are a wkt string with a CRS identifier attached.
Similarly, GeoSPARQL operates in the same manner to eWKT with regard to the axis ordering; if no CRS is provided, it assumes CRS84 and it uses lon-lat ordering. If a EPSG code is given, it uses the axis ordering from the EPSG spec (lat-lon).

That means when we convert a GeoSPARQL string with an EPSG crs and lat-lon axis-ordering to a GeoJSON document, we need to add the meta.srid string and reverse the axis ordering to maintain a standard compliant GeoJSON document.

I see your point, but I wouldn"t agree that"s invalid GeoJSON.

I"ve taken a look at a variety of industry-standard open-source GeoJSON parsers (in QGIS, in Postgres, in GDAL, in Shapely, and others) and all parse the coordinates in lon-lat order as-per the GeoJSON spec, regardless of any crs property or meta.srid property.

Subsequently, when taking a GeoJSON document produced by GeoMet with the meta.srid field populated and coordinates in lat-lon order, the document fails to load, or loads bogus geometry, in all applications I tested.

Therefore, GeoJSON documents with lat-lon ordering are invalid for all intents and purposes.

Do you have a references to the WGS84 specification where the coordinate ordering is defined? Just so I can deep-dive on this a bit more.

The official WGS84 spec is here: https://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf
But it is a bit hard to parse, and it doesn"t actually specify the order which the axes are serialized, because that is the reference spec, not a concrete implementation.

The best way I"ve found to lookup concrete specs with axis-order is on the espg.io website, eg https://epsg.io/4326
scroll down to "export" and choose "OGC WKT 2", this will give you everything you need to know how to implement that CRS in WKT, notably it includes axis ordering.

I do theoretically like the idea of intelligently reading the SRID and ordering coordinates of converted output accordingly. I think the main challenge there is finding good specs for all the different reference systems and adding special handling for all of them.

Thats what I thought too, until I dug a bit deeper and found that the EPSG organisation has a standard of following Y-X ordering on all of their CRS definitions, so that means on latitude/longitude axis CRS"s the order is always latitude-longitude.

I have a fork of geomet with a quick-and-dirty attempt at implementing conditionally reversing axis order for all geometries based on the CRS. In my code the logic is to flip the coordinates if the incoming geometry is in any EPSG-defined CRS, and don"t flip it if CRS is OGC:CRS84 or CRS is not given. I don"t know if there are any other CRS defined in the OGC namespace (but if there are, I bet they are all lon-lat order), and I don"t know if there are any other agencies that publish CRSs that a user would be referencing.

In any case, I would be cautious to implement this change, because from what I can see, all of the WK specs standardize on XY(Z) ordering. GeoJSON is the same. In my view, this is about encoding values in 2d/3d space, which different from how those coordinates are represented or displayed in a given spatial reference system.

I agree, WKT, WKB, eWKB, and GeoJSON all follow the same axis ordering, that makes it easy to simply declare that is the standard. However we cannot ignore eWKT and GeoSPARQL that are the two outliers. Both of these include in their respective spec documents the instruction to reverse the axis order when declaring a EPSG code that uses lat-lon ordering (all of them), and it is specifically the case of converting those formats into valid GeoJSON that we"re trying to achieve.

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