GeoPackage WKB and contents min/max axis order issue
Description
Environment
Issue independent from Environment
relates to
Activity
Jody Garnett January 18, 2022 at 10:57 PM
Okay so the GeoPackage module is … complicated:
GeoTools low-level API FeatureReader / FeatureWriter via JDBCDataStore
GeoTools high-level API FeatureSource / FeatureCollection / FeatureIterator
GeoPackage class “direct” API
The pull request https://github.com/geotools/geotools/pull/3740 provides a fix for the “direct” API primarily used by GeoPackage extensions and the GeoServer WPS process
The pull request https://github.com/geotools/geotools/pull/3741 makes a note in the geotools documentation that care must be taken when using the GeoTools high-level and low-level api to be careful about axis order.
The next step is to discuss what changes are needed to GeoPkgDataStore / JDBCDataStore / JDBCDialect to prevent the datastore from writing out data in YX order?
Jody Garnett January 6, 2022 at 7:07 PM
For now care must be taken by client code to construct using correct axis order.
Recommend making a factory parameter
GEOMETRY_XY_ORDER
with a default of true (allowing clients an option to load previously created data).
How to handle geometry_xy_order:
When creating a table datastore API the provided schema is used as a template, this is an opportunity to either throw an error (when the wrong axis order is provided), or correct the axis order with a warning. This is consistent with how shapefile shortens attribute names (with a warning).
When adding features it is the client’s responsibility to provide data using the same coordinate reference system as the datastore; as long as we advertise that correct XYZM order clients can use ReprojectingFeatureCollection to add content.
If we were nice we could make a utility method to only retroject a feature collection if needed, similar to how retype for Shapefile
Jody Garnett November 4, 2021 at 3:49 AM
Locating geometry reading/writing code:
Expect to see the geometry read as WKB:
protected Geometry read() throws IOException { // header must be read!
// read the geometry
try {
WKBReader wkbReader = new WKBReader(factory);
Geometry g = wkbReader.read(input);
g.setSRID(header.getSrid());
return g;
} catch (ParseException e) {
throw new IOException(e);
}
}
This is awkward as the code is setup to trust the srid provided, you can detect if 4326 is passed in and is nice and general purpose. What a terrible decision on the part of the geopackage specification.
You can create a CoordianteReferenceSystem that matches your EASTING/NORTHING standard:
The geometry should be assigned the correct coordinate reference system as it is being read, see https://docs.geotools.org/latest/userguide/library/referencing/order.html
Rather than looking up definition using geoserver results the datastore should specifically create the CoordianteReferenceSystem matching the stored content:
CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory("EPSG", new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE));CoordinateReferenceSystem crs = factory.createCoordinateReferenceSystem("EPSG:4326");
gt-wms client has to perform similar steps to construct coordinate reference systems that match the remote systems.You may also be able to get by with the constant DefaultGeographicCRS.WGS84 which has axis order define in EASTING/NORTHING order.
The specification you quote actually goes into more detail with (x,y{,z}{,m}) all of which is now supported by the JTS Geometry library, so if you have capacity you should be able to make some decent improvements.
The GeoServer Community Plugin GeoPackage produces flipped axis when created for data encoded in EPSG:4326. The plugin leverages code from GoeTools GeoPackage. That's why the issue targets GeoTools.
Axis ordering per GeoPackage standard
https://docs.ogc.org/is/12-128r17/12-128r17.html
Requirement 13, Table 4 defines the *_x to be EAST or LONGITUDE and *_y to be NORTH or LATITUDE
Issue min/max: GeoPackage contains LATITUDE/LONGITUDE
Requirement 19, Note alerts that WKB is using LON/LAT axis order. The GeoPackage standard leverages the OGC Policy directive () 'case four' - the legacy case - that informs that the WKB axis order to be followed. WKB as OGC 06-104r4 defines the axis order to be (x,y{,z}{,m}) where x is easting or longitude, y is northing or latitude, z is optional elevation.
Issue WKB: GeoPackage geometry encoded in WKB has LATITUDE/LONGITUDE
Verification
Download GeoPackage for Giant Polygon
https://ogc.secure-dimensions.com/geoserver-dp/tiger/ows?service=WFS&version=2.0.0&request=GetFeature&typeName=tiger%3Agiant_polygon&outputFormat=application%2Fx-gpkg
Issue WKB
giant_polygon.the_geom=47500002000010E6C0568000000000004056800000000000C066800000000000406680000000000000000000060000000100000000030000000100000005C056800000000000C0668000000000004056800000000000C06680000000000040568000000000004066800000000000C0568000000000004066800000000000C056800000000000C066800000000000
=> MULTIPOLYGON (((-90 -180, 90 -180, 90 180, -90 180, -90 -180)))
Issue min/max
gpkg_contents.min_x=-90.0
gpkg_contents.min_y=-180.0
gpkg_contents.max_x=90.0
gpkg_contents.mx_y=180.0