GeoLatte / geolatte-geom

A geometry model that conforms to the OGC Simple Features for SQL specification.
Other
134 stars 63 forks source link

Geometry.setSrid() #110

Closed stevanpa closed 3 years ago

stevanpa commented 4 years ago

In my applications I have a Geopackage that I want to read in. It consists of simple geometries, nothing but point geometries. For each Geometry that I read in, I have to do the following:

WkbDecoder wkbDecoder = Wkb.newDecoder();
GeoPackageGeometryData geometry = resultSet.getGeometry();
Point<C2D> point = (Point<C2D>) wkbDecoder.decode( ByteBuffer.from( geometry.getWkbBytes() ) );
int srsId = geometry.getSrsId();
double x = point.getPosition().getX();
double y = point.getPosition().getY();
CoordinateReferenceSystem<C2D> c = (CoordinateReferenceSystem<C2D>) CrsRegistry.getCoordinateReferenceSystemForEPSG( srsId, CoordinateReferenceSystems.WGS84 );
point = new Point<C2D>(new C2D(x, y), c);

I read the Point Geometry in but the SRID info inside the Geopackage Geometry is not read in by the WkbDecoder, which is expected. The WKB format is similar to the WKT format, it holds no SRID information about the geometry.

If there was a method like Geometry.setSrid(int srid). I could do the following:

WkbDecoder wkbDecoder = Wkb.newDecoder();
GeoPackageGeometryData geometry = resultSet.getGeometry();
Point<C2D> point = (Point<C2D>) wkbDecoder.decode( ByteBuffer.from( geometry.getWkbBytes() ) );
point.setSrid(geometry.getSrsId());

What I also would expect from the WkbDecoder or the WktDecoder is to read in a geometry and set its SRID to -1. The reason for that is that both WKT and WKB formats, contain no SRID information as defined by the OGC standards.

An even shorter alternative could be a method like wkbDecoder.decode(ByteBuffer bytes, int srid):

WkbDecoder wkbDecoder = Wkb.newDecoder();
GeoPackageGeometryData geometry = resultSet.getGeometry();
Point<C2D> point = (Point<C2D>) wkbDecoder.decode( ByteBuffer.from( geometry.getWkbBytes() ), geometry.getSrsId() );

Where the SRID parameter is optional in wkbDecoder.decode(ByteBuffer bytes, int srid). Then the SRID defaults to -1.

I specifically say -1 as default SRID, because for example in PostGIS it is possible to store a geometry with an unknown SRID, it just sets the SRID value to -1 or the user sets it to -1.

Giving support to both these methods Geometry.setSrid(int srid) and wkbDecoder.decode(ByteBuffer bytes, int srid) would prevent a lot of clunky code.

maesenka commented 3 years ago

Geometrys are immutable objects, so there won't be a setSrid() method.

The WktDecoder and WkbDecoder do set the SRID to -1 on absence of CRS information in the Wkb/Wkt.

There is a static method Geometry.forceToCrs(geometry, crs) that creates a new Geometry with the specified CRS. and you can use the CrsRegistry to find the CRS corresponding to a SRID.

Also the WkbDecoder and the WktDecoder have a method decode( <String or ByteBuffer>, crs) that does what you want.