[postgis-devel] [JDBC] Patch for JtsBinaryWriter

Thomas Marti (HSR) tmarti at hsr.ch
Sun Dec 17 14:56:05 PST 2006


Ok, this time it should actually work. We tested it with our JPOX-Spatial 
mappings...but we need change JtsTestParser as well, because right now the third 
ordinate just gets stripped before the BinaryWriter gets called...

JTS seems to have a really strange way to handle dimensions. Do any of the JTS 
gurus know an easier way (than the one I applied in the patch) to get that 
information out of a Geometry object?


Greetings, Thomas
-------------- next part --------------
Index: examples/JtsTestParser.java
===================================================================
--- examples/JtsTestParser.java	(revision 2531)
+++ examples/JtsTestParser.java	(working copy)
@@ -480,8 +480,14 @@
         System.out.println("***");
 
         for (int i = 0; i < testset.length; i++) {
-            test(testset[i][1], conns, testset[i][0]);
-            test(SRIDPREFIX + testset[i][1], conns, testset[i][0]);
+            try {
+				test(testset[i][1], conns, testset[i][0]);
+				test(SRIDPREFIX + testset[i][1], conns, testset[i][0]);
+			} catch ( Throwable t ) {
+				String msg = "Exception with Testset-Nr: " + i;
+				System.out.println(msg);
+				throw new RuntimeException(msg, t);
+			}
         }
 
         System.out.print("cleaning up...");
Index: org/postgis/jts/JtsBinaryWriter.java
===================================================================
--- org/postgis/jts/JtsBinaryWriter.java	(revision 2531)
+++ org/postgis/jts/JtsBinaryWriter.java	(working copy)
@@ -108,7 +108,7 @@
     /** Parse a geometry starting at offset. */
     protected void writeGeometry(Geometry geom, ValueSetter dest) {
         final int dimension = getCoordDim(geom);
-        if (dimension < 2 || dimension > 4) {
+        if (dimension != 0 && (dimension < 2 || dimension > 4)) {
             throw new IllegalArgumentException("Unsupported geometry dimensionality: " + dimension);
         }
         // write endian flag
@@ -362,12 +362,31 @@
     }
 
     public static final int getCoordDim(Geometry geom) {
-        // TODO: Fix geometries with more dimensions
-        // geom.getFactory().getCoordinateSequenceFactory()
-        if (geom == null) {
-            return 0;
-        } else {
-            return 2;
-        }
+        if (geom == null || geom.isEmpty()) return 0;
+        
+        if (geom instanceof Point) {
+    		return getCoordSequenceDim(((Point)geom).getCoordinateSequence());
+    	} else if (geom instanceof LineString) {
+    		return getCoordSequenceDim(((LineString)geom).getCoordinateSequence());
+    	} else if (geom instanceof Polygon) {
+    		return getCoordSequenceDim(((Polygon)geom).getExteriorRing().getCoordinateSequence());
+    	} else {
+    		return getCoordDim(geom.getGeometryN(0));
+    	}
     }
+
+    public static final int getCoordSequenceDim(CoordinateSequence coords) {
+    	if ( coords == null || coords.size() == 0 ) return 0;
+    	// JTS has a really strange way to handle dimensions!
+    	// Just have a look at PackedCoordinateSequence and 
+    	// CoordinateArraySequence
+    	int dimensions = coords.getDimension();
+    	if ( dimensions == 3 ) {
+    		// CoordinateArraySequence will always return 3, so we have to check, if 
+    		// the third ordinate contains NaN, then the geom is actually 2-dimensional
+    		return Double.isNaN( coords.getOrdinate( 0, CoordinateSequence.Z ) ) ? 2 : 3;
+    	} else {
+    		return dimensions;
+    	}
+    }
 }