Skip to content

SRID not preserved in Geometry types (Point) since it is encoded as text using the WKTWriter #542

@jurriaan

Description

@jurriaan

Bug Report

I'm trying to store JTS Points in a geometry(Point,4326) type column. This fails since the SRID is not encoded in the encoded representation.

Versions

  • Driver: 0.9.1
  • Database: PostgreSQL 13.6 (PostGIS 3.0 USE_GEOS=1 USE_PROJ=1 USE_STATS=1)
  • Java: OpenJDK 64-Bit Server VM (build 18.0.2+0, mixed mode)
  • OS: Linux 5.19.5

Current Behavior

Inserting a Point with SRID into a geometry(Point,4326) column results in the following error.

io.r2dbc.postgresql.ExceptionFactory$PostgresqlBadGrammarException: [22023] Geometry SRID (0) does not match column SRID (4326)

Steps to reproduce

This is how Geometries are currently encoded in PostgisGeometryCodec:

@Override
public EncodedParameter encode(Object value) {
    Assert.requireType(value, Geometry.class, "value must be Geometry type");
    Geometry geometry = (Geometry) value;

    return new EncodedParameter(Format.FORMAT_TEXT, this.oid, Mono.fromSupplier(
        () -> ByteBufUtils.encode(this.byteBufAllocator, geometry.toText())
    ));
}

This drops the SRID from the geometry as shown with this example:

val factory = GeometryFactory(PrecisionModel(), 4326)

val point = factory.createPoint(Coordinate(10.0, 5.0))
println(point.srid) // -> 4326
println(point.toText()) // -> POINT (10 5)

Expected behavior/workaround

Either EWKT or (E)WKB representations should be used when encoding Geometries, these can encode the SRID properly.

For our purposes a workaround that seems to help is encoding the geometries as WKB before inserting (we use Spring Data, so this is easy using Converters):

/**
 * Alternative encoder of geometries that encodes the geometry in WKB (well known binary) format and includes the SRID.
 */
@WritingConverter
object GeometryToWKBConverter : Converter<Geometry, ByteArray> {
    private val encoder = WKBWriter(/* outputDimension = */ 2, /* includeSRID = */ true)

    override fun convert(source: Geometry): ByteArray = encoder.write(source)
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions