diff --git a/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PGGeometryTypeDescriptor.java b/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PGGeometryTypeDescriptor.java index 7d3d96876e..34602eb884 100644 --- a/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PGGeometryTypeDescriptor.java +++ b/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PGGeometryTypeDescriptor.java @@ -35,7 +35,6 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; * Type Descriptor for the Postgis Geometry type * * @author Karel Maesen, Geovise BVBA - * */ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor { @@ -101,23 +100,31 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor { }; } - public static Geometry toGeometry(Object object) { + public static Geometry toGeometry(Object object) { if ( object == null ) { return null; } ByteBuffer buffer = null; if ( object instanceof PGobject ) { - String pgValue = ((PGobject) object ).getValue(); - if (pgValue.charAt( 0 ) == 'S') { // /we have a Wkt value - final WktDecoder decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 ); - return decoder.decode(pgValue); - } - else { + String pgValue = ((PGobject) object).getValue(); + + if ( pgValue.startsWith( "00" ) || pgValue.startsWith( "01" ) ) { + //we have a WKB because this pgValue starts with the bit-order byte buffer = ByteBuffer.from( pgValue ); final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 ); return decoder.decode( buffer ); + } + else { + return parseWkt( pgValue ); + } + } throw new IllegalStateException( "Received object of type " + object.getClass().getCanonicalName() ); } + + private static Geometry parseWkt(String pgValue) { + final WktDecoder decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 ); + return decoder.decode( pgValue ); + } } diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/dialect/postgis/PostgisUnmarshalTest.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/dialect/postgis/PostgisUnmarshalTest.java new file mode 100644 index 0000000000..28d493b241 --- /dev/null +++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/dialect/postgis/PostgisUnmarshalTest.java @@ -0,0 +1,70 @@ +package org.hibernate.spatial.dialect.postgis; + +import java.sql.SQLException; + +import org.geolatte.geom.ByteOrder; +import org.geolatte.geom.C2D; +import org.geolatte.geom.G2D; +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.Wkb; +import org.geolatte.geom.codec.Wkt; +import org.geolatte.geom.crs.CoordinateReferenceSystem; +import org.geolatte.geom.crs.CoordinateReferenceSystems; +import org.postgresql.util.PGobject; + +import org.junit.Test; + +import static org.geolatte.geom.builder.DSL.*; +import static org.junit.Assert.assertEquals; + +/** + * Tests the different ways Postgis seraialises Geometries + *

+ * Created by Karel Maesen, Geovise BVBA on 29/10/16. + */ +public class PostgisUnmarshalTest { + + private CoordinateReferenceSystem crs = CoordinateReferenceSystems.WGS84; + private Geometry geom = linestring( crs, g( 6.123, 53.234 ), g( 6.133, 53.244 ) ); + private Geometry geomNoSrid = linestring( + CoordinateReferenceSystems.PROJECTED_2D_METER, + c( 6.123, 53.234 ), + c( 6.133, 53.244 ) + ); + + + @Test + public void testWktWithSrid() throws SQLException { + String ewkt = Wkt.toWkt( geom ); + testCase( ewkt, geom ); + } + + @Test + public void testWktWithoutSrid() throws SQLException { + String wkt = Wkt.toWkt( geom ).split( ";" )[1]; + testCase( wkt, geomNoSrid ); + } + + @Test + public void testWkbXDR() throws SQLException { + String wkb = Wkb.toWkb( geom, ByteOrder.XDR ).toString(); + testCase( wkb, geom ); + } + + @Test + public void testWkbNDR() throws SQLException { + String wkb = Wkb.toWkb( geom, ByteOrder.NDR ).toString(); + testCase( wkb, geom ); + } + + + public void testCase(String pgValue, Geometry expected) throws SQLException { + PGobject pgo = new PGobject(); + System.out.println( "pgValue " + pgValue ); + pgo.setValue( pgValue ); + Geometry received = PGGeometryTypeDescriptor.toGeometry( pgo ); + assertEquals( String.format( "Failure on %s", pgValue ), expected, received ); + } + + +}