CrunchyData / pg_featureserv

Lightweight RESTful Geospatial Feature Server for PostGIS in Go
Apache License 2.0
450 stars 89 forks source link

Add crs on top-level object #161

Open sebakerckhof opened 6 months ago

sebakerckhof commented 6 months ago

While the obsolete geojson spec specifies that a crs property can be on each object, most servers (geoserver/mapserver) specify a crs property only on the root object of the geojson output. This makes sense since the crs in the request should be applied to all features. Hence, tools like openlayers only look at this top-level crs to read the geometry projection of the geojson and not the individual features.

Would it therefore be possible for pg_featureserv to do the same?

dr-jts commented 6 months ago

Seems reasonable. Can you provide a link to a spec or canonical example?

sebakerckhof commented 6 months ago

Well, in the 2016 GeoJSON spec ( https://datatracker.ietf.org/doc/html/rfc7946 ), they have removed CRS altogether and defaulted to WGS84. In the original 2008 spec, CRS could be applied to any geojson object. Most implentations I've encountered will still support the CRS for convenience. So it's not that featureserv is not compliant, but in my experience many tools only do it on the top level, since typically a request will specify the CRS for all features. So it would aid interopability if featureserv could do this as well.

E.g. geoserver only writes it on the top-level: https://github.com/geoserver/geoserver/blob/main/src/wfs/src/main/java/org/geoserver/wfs/json/GeoJSONGetFeatureResponse.java#L160

Openlayers only tries to read it at the top-level as well: https://github.com/openlayers/openlayers/blob/main/src/ol/format/Feature.js#L156-L158

fredmorin commented 6 months ago

From OGC API Part 2. GeoJSON normatively supports WGS 84 (without height: CRS84; with ellipsoidal height: CRS84h), but the "prior arrangement" provision allows other coordinate systems to be used.

Requirement 14

/req/crs/geojson

Servers that implement this extension plus the GeoJSON requirements class and clients that use this extension SHALL be subject to the prior arrangement provisionin the second paragraph of section 4 of the GeoJSON standard.

A GeoJSON object may have an optional "crs"member,

The coordinate reference system (CRS) of a GeoJSON object is determined by its "crs" member (referred to as the CRS object below). If an object has no crs member, then its parent or grandparent object’s crs member may be acquired. If no crs member can be so acquired, the default CRS shall apply to the GeoJSON object.

The default CRS is a geographic coordinate reference system, using the WGS84 datum, and with longitude and latitude units of decimal degrees.

The value of a member named "crs" must be a JSON object (referred to as the CRS object below) or JSON null. If the value of CRS is null, no CRS can be assumed.

The crs member should be on the top-level GeoJSON object in a hierarchy (in feature collection, feature, geometry order) and should not be repeated or overridden on children or grandchildren of the object.

A non-null CRS object has two mandatory members: "type" and "properties".

The value of the type member must be a string, indicating the type of CRS object.

The value of the properties member must be an object.

CRS shall not change coordinate ordering (see 2.1.1. Positions).

dr-jts commented 6 months ago

@fredmorin thanks for the quotes from the old GeoJSON spec (link here for reference).

sebakerckhof commented 6 months ago

Thanks, I had interpreted

If an object has no crs member, then its parent or grandparent object’s crs member may be acquired.

As allowing the implementation to choose where the define the crs, but I missed:

The crs member should be on the top-level GeoJSON object in a hierarchy (in feature collection, feature, geometry order) and should not be repeated or overridden on children or grandchildren of the object.

So it seems that it should indeed be at the top-level instead of the current behavior of defining it on each feature.

fredmorin commented 6 months ago

https://datatracker.ietf.org/doc/html/rfc2119

SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

It is weird that a spec like OGC API relies on an obsolete specification and that the specification had been made obsolete because there were incompatibilities issues because of the crs field.