[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;
+ }
+ }
}