]> granicus.if.org Git - postgis/commitdiff
Imported new jdbc driver source by Markus Schaber
authorSandro Santilli <strk@keybit.net>
Wed, 19 Jan 2005 08:54:44 +0000 (08:54 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 19 Jan 2005 08:54:44 +0000 (08:54 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1316 b70326c6-7e19-0410-871a-916f4a2858ee

27 files changed:
jdbc2/Makefile [new file with mode: 0644]
jdbc2/README [new file with mode: 0644]
jdbc2/build.xml [new file with mode: 0644]
jdbc2/regression.txt [new file with mode: 0644]
jdbc2/src/examples/BitTest.java [new file with mode: 0644]
jdbc2/src/examples/Test.java [new file with mode: 0644]
jdbc2/src/examples/TestParser.java [new file with mode: 0644]
jdbc2/src/examples/TestServer.java [new file with mode: 0644]
jdbc2/src/org/postgis/ComposedGeom.java [new file with mode: 0644]
jdbc2/src/org/postgis/DriverWrapper.java [new file with mode: 0644]
jdbc2/src/org/postgis/Geometry.java [new file with mode: 0644]
jdbc2/src/org/postgis/GeometryCollection.java [new file with mode: 0644]
jdbc2/src/org/postgis/LineString.java [new file with mode: 0644]
jdbc2/src/org/postgis/LinearRing.java [new file with mode: 0644]
jdbc2/src/org/postgis/MultiLineString.java [new file with mode: 0644]
jdbc2/src/org/postgis/MultiPoint.java [new file with mode: 0644]
jdbc2/src/org/postgis/MultiPolygon.java [new file with mode: 0644]
jdbc2/src/org/postgis/PGbox.java [new file with mode: 0644]
jdbc2/src/org/postgis/PGbox3d.java [new file with mode: 0644]
jdbc2/src/org/postgis/PGgeometry.java [new file with mode: 0644]
jdbc2/src/org/postgis/Point.java [new file with mode: 0644]
jdbc2/src/org/postgis/PointComposedGeom.java [new file with mode: 0644]
jdbc2/src/org/postgis/Polygon.java [new file with mode: 0644]
jdbc2/src/org/postgis/binary/BinaryParser.java [new file with mode: 0644]
jdbc2/src/org/postgis/binary/ByteGetter.java [new file with mode: 0644]
jdbc2/src/org/postgis/binary/ValueGetter.java [new file with mode: 0644]
jdbc2/todo.txt [new file with mode: 0644]

diff --git a/jdbc2/Makefile b/jdbc2/Makefile
new file mode 100644 (file)
index 0000000..7907e87
--- /dev/null
@@ -0,0 +1,64 @@
+JAVAC = javac
+JAVA = java
+JAR = jar
+MKDIR = mkdir -p
+DELETE = rm -rvf
+
+# configure your postgresql.jar here
+
+#CLASSPATH=src/:../../../src/interfaces/jdbc/jars/postgresql.jar
+#CLASSPATH=src/:/usr/share/java/postgresql.jar
+#CLASSPATH=src/:/usr/share/java/postgresql.jar
+CLASSPATH=src/:lib/postgresql-8.0.309.jdbc3.jar
+
+SRC=src
+EXAMPLES=examples
+BUILD=bin/make
+
+all:   jar \
+       test
+
+jar:   compile
+       $(JAR) -cf postgis.jar -C $(BUILD) . -C $(SRC) org/postgresql/ postgresql.properties README     
+       $(JAR) -cf postgis_debug.jar -C $(BUILD) . -C $(SRC) . README   
+
+prepare:
+       $(MKDIR) $(BUILD)
+
+
+compile:       prepare
+       $(JAVAC) -classpath $(CLASSPATH) -d $(BUILD)\
+               $(SRC)/examples/Test.java \
+               $(SRC)/examples/TestParser.java \
+               $(SRC)/examples/TestServer.java \
+               $(SRC)/org/postgis/ComposedGeom.java \
+               $(SRC)/org/postgis/DriverWrapper.java \
+               $(SRC)/org/postgis/GeometryCollection.java \
+               $(SRC)/org/postgis/Geometry.java \
+               $(SRC)/org/postgis/LinearRing.java \
+               $(SRC)/org/postgis/LineString.java \
+               $(SRC)/org/postgis/MultiLineString.java \
+               $(SRC)/org/postgis/MultiPoint.java \
+               $(SRC)/org/postgis/MultiPolygon.java \
+               $(SRC)/org/postgis/PGbox3d.java \
+               $(SRC)/org/postgis/PGbox.java \
+               $(SRC)/org/postgis/PGgeometry.java \
+               $(SRC)/org/postgis/PointComposedGeom.java \
+               $(SRC)/org/postgis/Point.java \
+               $(SRC)/org/postgis/Polygon.java 
+
+test:  compile
+       $(JAVA) -classpath $(BUILD):$(CLASSPATH) $(EXAMPLES)/Test
+        
+jtest: compile
+       $(JAVA) -classpath $(BUILD):$(CLASSPATH) $(EXAMPLES)/TestServer
+
+ptestoffline: compile  
+       $(JAVA) -classpath $(BUILD):$(CLASSPATH) $(EXAMPLES)/TestParser offline
+
+ptest:  compile
+       $(JAVA) -classpath $(BUILD):$(CLASSPATH) $(EXAMPLES)/TestParser
+
+clean:  
+       $(DELETE) $(BUILD) postgis.jar postgis_debug.jar
+     
diff --git a/jdbc2/README b/jdbc2/README
new file mode 100644 (file)
index 0000000..426e204
--- /dev/null
@@ -0,0 +1,17 @@
+** This has to be reviewed! **
+
+To use the PostGIS types, you must:
+- have the postgis.jar in your CLASSPATH
+- have a PostgreSQL JDBC Connection instance
+
+  Connection conn = new Connection();
+  ((org.postgresql.Connection)conn).addDataType("geometry","org.postgis.PGgeometry");
+  ((org.postgresql.Connection)conn).addDataType("box3d","org.postgis.PGbox3d");
+
+To build the examples:
+- put the jar file containing the PostgreSQL JDBC under 
+  postgis/original/jars/postgresql.jar
+  The file might be named jdbc7.1-1.2.jar originally
+
+- edit the file TestServer.java to adjust the connection information, run
+  the test with 'make jtest'
diff --git a/jdbc2/build.xml b/jdbc2/build.xml
new file mode 100644 (file)
index 0000000..3febbc2
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" ?>
+<!-- ================================================================
+     postgis ant build.xml
+     (C) 2004 Markus.Schaber@logi-track.com, logi-track ag, Zürich
+     This file is licensed under the GNU GPL.
+     
+     $Id$
+     ============================================================ -->
+<project name="postgis" default="jar" basedir=".">
+
+       <path id="classpath.base">
+               <pathelement location="lib/postgresql-8.0.309.jdbc3.jar" />
+       </path>
+
+       <target name="compile">        
+        <mkdir dir="bin/ant" />
+               <javac srcdir="src" destdir="bin/ant">
+                       <classpath refid="classpath.base" />
+               </javac>
+       </target>
+
+       <target name="jar" depends="compile">
+               <jar destfile="postgis.jar" index="true">
+                       <fileset dir="bin/ant" includes="**/*.class" />
+                       <fileset dir="src" excludes="**/*.java" />
+            <fileset file="README"/>
+               </jar>
+        <!-- And a source including version for debugging purposes -->      
+               <jar destfile="postgis_debug.jar" index="true">
+                       <fileset dir="bin/ant" includes="**/*.class" />
+                       <fileset dir="src" />
+            <fileset file="README"/>
+               </jar>
+       </target>
+
+    <target name="clean">
+        <delete dir="bin/ant" />
+        <delete file="postgis.jar" />
+        <delete file="postgis_debug.jar" />
+    </target>
+</project>
diff --git a/jdbc2/regression.txt b/jdbc2/regression.txt
new file mode 100644 (file)
index 0000000..057de95
--- /dev/null
@@ -0,0 +1,667 @@
+Creating JDBC connection to jdbc:postgresql_postGIS://localhost:5432/hwgeom
+Creating JDBC connection to jdbc:postgresql_postGIS://localhost:5432/lwgeom
+Performing tests...
+***
+Original:  POINT(10 10 20)
+Parsed:    POINT(10.0 10.0 20.0)
+Re-Parsed: POINT(10.0 10.0 20.0)
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : POINT(10.0 10.0 20.0)
+Eq SQL in: yes
+SQLout  :  POINT(10.0 10.0 20.0)
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : POINT(10.0 10.0 20.0)
+Eq SQL in: yes
+SQLout  :  POINT(10.0 10.0 20.0)
+Eq SQLout: yes
+***
+Original:  SRID=4326;POINT(10 10 20)
+Parsed:    SRID=4326;POINT(10.0 10.0 20.0)
+Re-Parsed: SRID=4326;POINT(10.0 10.0 20.0)
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;POINT(10.0 10.0 20.0)
+Eq SQL in: yes
+SQLout  :  SRID=4326;POINT(10.0 10.0 20.0)
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;POINT(10.0 10.0 20.0)
+Eq SQL in: yes
+SQLout  :  SRID=4326;POINT(10.0 10.0 20.0)
+Eq SQLout: yes
+***
+Original:  MULTIPOINT(10 10 10, 20 20 20)
+Parsed:    MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Re-Parsed: MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQL in: yes
+SQLout  :  MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQL in: yes
+SQLout  :  MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQLout: yes
+***
+Original:  SRID=4326;MULTIPOINT(10 10 10, 20 20 20)
+Parsed:    SRID=4326;MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Re-Parsed: SRID=4326;MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQL in: yes
+SQLout  :  SRID=4326;MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQL in: yes
+SQLout  :  SRID=4326;MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0)
+Eq SQLout: yes
+***
+Original:  LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34)
+Parsed:    LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Re-Parsed: LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQL in: yes
+SQLout  :  LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQL in: yes
+SQLout  :  LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQLout: yes
+***
+Original:  SRID=4326;LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34)
+Parsed:    SRID=4326;LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Re-Parsed: SRID=4326;LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQL in: yes
+SQLout  :  SRID=4326;LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQL in: yes
+SQLout  :  SRID=4326;LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0)
+Eq SQLout: yes
+***
+Original:  POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))
+Parsed:    POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Re-Parsed: POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+***
+Original:  SRID=4326;POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))
+Parsed:    SRID=4326;POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Re-Parsed: SRID=4326;POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+***
+Original:  MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  SRID=4326;MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    SRID=4326;MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: SRID=4326;MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))
+Parsed:    MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Re-Parsed: MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+***
+Original:  SRID=4326;MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))
+Parsed:    SRID=4326;MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Re-Parsed: SRID=4326;MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(POINT(10 10 20),POINT(20 20 20))
+Parsed:    GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Re-Parsed: GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(POINT(10 10 20),POINT(20 20 20))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),POINT(20.0 20.0 20.0))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34))
+Parsed:    GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Re-Parsed: GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(MULTIPOINT(10 10 10, 20 20 20),MULTIPOINT(10 10 10, 20 20 20))
+Parsed:    GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Re-Parsed: GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(MULTIPOINT(10 10 10, 20 20 20),MULTIPOINT(10 10 10, 20 20 20))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),LINESTRING(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+--- Geometries after SQL are not equal!
+SQLout  :  GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),LINESTRING(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+--- reparsed Geometries after SQL are not equal!
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),LINESTRING(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+--- Geometries after SQL are not equal!
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(LINESTRING(10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),LINESTRING(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))
+--- reparsed Geometries after SQL are not equal!
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))),MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))))
+Parsed:    GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Re-Parsed: GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+--- Geometries after SQL are not equal!
+SQLout  :  GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+--- reparsed Geometries after SQL are not equal!
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))),MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+--- Geometries after SQL are not equal!
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+--- reparsed Geometries after SQL are not equal!
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(POINT(10 10 20),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(POINT(10 10 20),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(POINT(10 10 20),MULTIPOINT(10 10 10, 20 20 20),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))),MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(POINT(10 10 20),MULTIPOINT(10 10 10, 20 20 20),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))),MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))
+Parsed:    SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+--- Server side error: org.postgresql.util.PSQLException: ERROR: couldnt parse objects in GEOMETRY
+
+
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION(POINT(10.0 10.0 20.0),MULTIPOINT(10.0 10.0 10.0,20.0 20.0 20.0),LINESTRING(10.0 10.0 20.0,20.0 20.0 20.0,50.0 50.0 50.0,34.0 34.0 34.0),POLYGON((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),MULTIPOLYGON(((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)),((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0))),MULTILINESTRING((10.0 10.0 0.0,20.0 10.0 0.0,20.0 20.0 0.0,20.0 10.0 0.0,10.0 10.0 0.0),(5.0 5.0 0.0,5.0 6.0 0.0,6.0 6.0 0.0,6.0 5.0 0.0,5.0 5.0 0.0)))
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION(EMPTY)
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION(EMPTY)
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  GEOMETRYCOLLECTION EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  POINT EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;POINT EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  LINESTRING EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;LINESTRING EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  POLYGON EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;POLYGON EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  MULTIPOINT EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: java.sql.SQLException: postgis.Pointjava.lang.NumberFormatException: For input string: "EMPTY"
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;MULTIPOINT EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: java.sql.SQLException: postgis.Pointjava.lang.NumberFormatException: For input string: "EMPTY"
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  MULTILINESTRING EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: java.sql.SQLException: postgis.multipointgeometry
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;MULTILINESTRING EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: java.sql.SQLException: postgis.multipointgeometry
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  MULTIPOLYGON EMPTY
+Parsed:    GEOMETRYCOLLECTION EMPTY
+Re-Parsed: GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: java.sql.SQLException: postgis.Pointjava.lang.NumberFormatException: For input string: "EMPTY"
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+Original:  SRID=4326;MULTIPOLYGON EMPTY
+Parsed:    SRID=4326;GEOMETRYCOLLECTION EMPTY
+Re-Parsed: SRID=4326;GEOMETRYCOLLECTION EMPTY
+Equals:    yes
+Testing on connection 0: hwgeom
+--- Server side error: java.sql.SQLException: postgis.Pointjava.lang.NumberFormatException: For input string: "EMPTY"
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+Testing on connection 1: lwgeom
+SQLin    : SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQL in: yes
+SQLout  :  SRID=4326;GEOMETRYCOLLECTION EMPTY
+Eq SQLout: yes
+***
+cleaning up...Finished.
diff --git a/jdbc2/src/examples/BitTest.java b/jdbc2/src/examples/BitTest.java
new file mode 100644 (file)
index 0000000..e737be3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * BitTest.java
+ * 
+ * (C) 17.01.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
+ * 
+ * $Id$
+ */
+package examples;
+
+import org.postgis.binary.ByteGetter;
+import org.postgis.binary.ValueGetter;
+
+/**
+ * BitTest
+ * 
+ * 
+ * @author schabi
+ * 
+ *  
+ */
+public class BitTest {
+
+    public static void main(String[] args) {
+        long doubleToLongBits = Double.doubleToLongBits(10.0);
+        System.out.println(doubleToLongBits);
+        String toHexString = Long.toHexString(doubleToLongBits);
+        System.out.println(toHexString);
+        long parseLong = Long.parseLong(toHexString, 16);
+        System.out.println(parseLong);
+        System.out.println(Double.longBitsToDouble(parseLong));
+
+        ValueGetter vg = new ValueGetter.NDR((new ByteGetter.StringByteGetter(toHexString)));
+        System.out.println(Long.toHexString(vg.getLong()));
+        vg = new ValueGetter.XDR((new ByteGetter.StringByteGetter(toHexString)));
+        System.out.println(Long.toHexString(vg.getLong()));
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/examples/Test.java b/jdbc2/src/examples/Test.java
new file mode 100644 (file)
index 0000000..5df2e9a
--- /dev/null
@@ -0,0 +1,61 @@
+package examples;
+
+import org.postgis.LineString;
+import org.postgis.LinearRing;
+import org.postgis.MultiLineString;
+import org.postgis.MultiPolygon;
+import org.postgis.PGgeometry;
+import org.postgis.Point;
+import org.postgis.Polygon;
+
+import java.sql.SQLException;
+
+public class Test {
+
+    public static void main(String[] args) throws SQLException {
+        String mlng_str = "MULTILINESTRING ((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))";
+        String mplg_str = "MULTIPOLYGON (((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))";
+        String plg_str = "POLYGON ((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))";
+        String lng_str = "LINESTRING  (10 10 20,20 20 20, 50 50 50, 34 34 34)";
+        String ptg_str = "POINT(10 10 20)";
+        String lr_str = "(10 10 20,34 34 34, 23 19 23 , 10 10 11)";
+
+        System.out.println("LinearRing Test:");
+        System.out.println(lr_str);
+        LinearRing lr = new LinearRing(lr_str);
+        System.out.println(lr.toString());
+
+        System.out.println("Point Test:");
+        System.out.println(ptg_str);
+        Point ptg = new Point(ptg_str);
+        System.out.println(ptg.toString());
+
+        System.out.println("LineString Test:");
+        System.out.println(lng_str);
+        LineString lng = new LineString(lng_str);
+        System.out.println(lng.toString());
+
+        System.out.println("Polygon Test:");
+        System.out.println(plg_str);
+        Polygon plg = new Polygon(plg_str);
+        System.out.println(plg.toString());
+
+        System.out.println("MultiPolygon Test:");
+        System.out.println(mplg_str);
+        MultiPolygon mplg = new MultiPolygon(mplg_str);
+        System.out.println(mplg.toString());
+
+        System.out.println("MultiLineString Test:");
+        System.out.println(mlng_str);
+        MultiLineString mlng = new MultiLineString(mlng_str);
+        System.out.println(mlng.toString());
+
+        System.out.println("PG Test:");
+        System.out.println(mlng_str);
+        PGgeometry pgf = new PGgeometry(mlng_str);
+        System.out.println(pgf.toString());
+
+        System.out.println("finished");
+    }
+}
+
diff --git a/jdbc2/src/examples/TestParser.java b/jdbc2/src/examples/TestParser.java
new file mode 100644 (file)
index 0000000..80f3b6f
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Test client and server side Parsing of canonical text representations, as
+ * well as the PostGisWrapper jdbc extension.
+ * 
+ * (C) 2005 Markus Schaber, logi-track ag, Zürich, Switzerland
+ * 
+ * This file is licensed under the GNU GPL. *** put full notice here ***
+ * 
+ * $Id$
+ */
+
+package examples;
+
+import org.postgis.Geometry;
+import org.postgis.PGgeometry;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class TestParser {
+
+    public static final String[] testset = new String[]{
+        "POINT(10 10 20)",
+        "MULTIPOINT(10 10 10, 20 20 20)",
+        "LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34)",
+        "POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))",
+        "MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))",
+        "MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))",
+        "GEOMETRYCOLLECTION(POINT(10 10 20),POINT(20 20 20))",
+        "GEOMETRYCOLLECTION(LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34))",
+        "GEOMETRYCOLLECTION(POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))",
+        "GEOMETRYCOLLECTION(MULTIPOINT(10 10 10, 20 20 20),MULTIPOINT(10 10 10, 20 20 20))",
+        "GEOMETRYCOLLECTION(MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))",
+        "GEOMETRYCOLLECTION(MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))),MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))))",
+        "GEOMETRYCOLLECTION(POINT(10 10 20),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))",
+        "GEOMETRYCOLLECTION(POINT(10 10 20),MULTIPOINT(10 10 10, 20 20 20),LINESTRING(10 10 20,20 20 20, 50 50 50, 34 34 34),POLYGON((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),MULTIPOLYGON(((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)),((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))),MULTILINESTRING((10 10 0,20 10 0,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0)))",
+        "GEOMETRYCOLLECTION(EMPTY)", // Old (bad) PostGIS 0.8 Representation
+        "GEOMETRYCOLLECTION EMPTY", // new (correct) representation
+        "POINT EMPTY", // new (correct) representation
+        "LINESTRING EMPTY", // new (correct) representation
+        "POLYGON EMPTY", // new (correct) representation
+        "MULTIPOINT EMPTY", // new (correct) representation
+        "MULTILINESTRING EMPTY", // new (correct) representation
+        "MULTIPOLYGON EMPTY", // new (correct) representation
+    };
+
+    public static final String[] testsridset = new String[testset.length];
+    public static final int SRID = 4326;
+
+    static {
+        String prefix = "SRID=" + SRID + ";";
+        for (int i = 0; i < testset.length; i++) {
+            testsridset[i] = prefix + testset[i];
+        }
+    }
+
+    public static void test(String WKT, Connection[] conns) throws SQLException {
+        System.out.println("Original:  " + WKT);
+        Geometry geom = PGgeometry.geomFromString(WKT);
+        String parsed = geom.toString();
+        System.out.println("Parsed:    " + parsed);
+        Geometry regeom = PGgeometry.geomFromString(parsed);
+        String reparsed = regeom.toString();
+        System.out.println("Re-Parsed: " + reparsed);
+        if (!geom.equals(regeom)) {
+            System.out.println("--- Geometries are not equal!");
+        } else if (!reparsed.equals(parsed)) {
+            System.out.println("--- Text Reps are not equal!");
+        } else {
+            System.out.println("Equals:    yes");
+        }
+        for (int i = 0; i < conns.length; i++) {
+            System.out.println("Testing on connection " + i + ": "+ conns[i].getCatalog());
+            Statement statement = conns[i].createStatement();
+
+            try {
+                Geometry sqlGeom = viaSQL(WKT, statement);
+                System.out.println("SQLin    : " + sqlGeom.toString());
+                if (!geom.equals(sqlGeom)) {
+                    System.out.println("--- Geometries after SQL are not equal!");
+                } else {
+                    System.out.println("Eq SQL in: yes");
+                }
+            } catch (SQLException e) {
+                System.out.println("--- Server side error: " + e.toString());
+            }
+
+            try {
+                Geometry sqlreGeom = viaSQL(parsed, statement);
+                System.out.println("SQLout  :  " + sqlreGeom.toString());
+                if (!geom.equals(sqlreGeom)) {
+                    System.out.println("--- reparsed Geometries after SQL are not equal!");
+                } else {
+                    System.out.println("Eq SQLout: yes");
+                }
+            } catch (SQLException e) {
+                System.out.println("--- Server side error: " + e.toString());
+            }
+
+            statement.close();
+        }
+        System.out.println("***");
+    }
+
+    private static Geometry viaSQL(String rep, Statement stat) throws SQLException {
+        ResultSet rs = stat.executeQuery("SELECT geometry_in('" + rep + "')");
+        rs.next();
+        return ((PGgeometry) rs.getObject(1)).getGeometry();
+    }
+
+    /**
+     * The list of databases to test (can be multiple to test against different
+     * postGIS releases.
+     * 
+     * Currently, all of them need the same username and password
+     */
+
+    public static final String[] databases = new String[]{
+        "jdbc:postgresql_postGIS://localhost:5432/hwgeom",
+        "jdbc:postgresql_postGIS://localhost:5432/lwgeom"};
+
+    public final static String dbuser = "postgistest";
+    public final static String dbpass = "testpostgis";
+
+    /**
+     * Connect to the databases
+     * 
+     * We use DriverWrapper here. For alternatives, see the DriverWrapper
+     * Javadoc
+     * 
+     * @throws ClassNotFoundException
+     * 
+     * @see org.postgis.DriverWrapper
+     *  
+     */
+    public static Connection connect(String url) throws SQLException, ClassNotFoundException {
+        Connection conn;
+        Class.forName("org.postgis.DriverWrapper");
+        conn = DriverManager.getConnection(url, dbuser, dbpass);
+        return conn;
+    }
+
+    public static void main(String[] args) throws SQLException, ClassNotFoundException {
+        String[] URLs = databases;
+
+        // allow to run offline tests...
+        if (args.length == 1 && args[0].equalsIgnoreCase("offline")) {
+            System.out.println("Performing only offline tests");
+            URLs = new String[0];
+        } else if (args.length!=0) {
+            System.err.println("usage: java [offline]");
+            System.exit(1);
+        }
+        Connection[] conns;
+        conns = new Connection[URLs.length];
+        for (int i = 0; i < URLs.length; i++) {
+            System.out.println("Creating JDBC connection to " + URLs[i]);
+            conns[i] = connect(URLs[i]);
+        }
+
+        System.out.println("Performing tests...");
+        System.out.println("***");
+
+        for (int i = 0; i < testset.length; i++) {
+            test(testset[i], conns);
+            test(testsridset[i], conns);
+        }
+
+        System.out.print("cleaning up...");
+        for (int i = 0; i < conns.length; i++) {
+            conns[i].close();
+
+        }
+        System.out.println("Finished.");
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/examples/TestServer.java b/jdbc2/src/examples/TestServer.java
new file mode 100644 (file)
index 0000000..bdf46ba
--- /dev/null
@@ -0,0 +1,67 @@
+package examples;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class TestServer {
+
+    public static void main(String[] args) {
+        Connection conn;
+
+        String dbname = "tb";
+        String dbuser = "dblasby";
+        String dbpass = "";
+        String dbhost = "ox";
+        String dbport = "5555";
+
+        String dbtable = "jdbc_test";
+
+        String dropSQL = "drop table " + dbtable;
+        String createSQL = "create table " + dbtable + " (geom geometry, id int4)";
+        String insertPointSQL = "insert into " + dbtable + " values ('POINT (10 10 10)',1)";
+        String insertPolygonSQL = "insert into " + dbtable
+                + " values ('POLYGON ((0 0 0,0 10 0,10 10 0,10 0 0,0 0 0))',2)";
+
+        try {
+
+            System.out.println("Creating JDBC connection...");
+            Class.forName("org.postgresql.Driver");
+            String url = "jdbc:postgresql://" + dbhost + ":" + dbport + "/" + dbname;
+            conn = DriverManager.getConnection(url, dbuser, dbpass);
+            System.out.println("Adding geometric type entries...");
+            ((org.postgresql.PGConnection) conn).addDataType("geometry", "org.postgis.PGgeometry");
+            ((org.postgresql.PGConnection) conn).addDataType("box3d", "org.postgis.PGbox3d");
+            Statement s = conn.createStatement();
+            System.out.println("Creating table with geometric types...");
+            //table might not yet exist
+            try {
+                s.execute(dropSQL);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            s.execute(createSQL);
+            System.out.println("Inserting point...");
+            s.execute(insertPointSQL);
+            System.out.println("Inserting polygon...");
+            s.execute(insertPolygonSQL);
+            System.out.println("Done.");
+            s = conn.createStatement();
+            System.out.println("Querying table...");
+            ResultSet r = s.executeQuery("select asText(geom),id from " + dbtable);
+            while (r.next()) {
+                Object obj = r.getObject(1);
+                int id = r.getInt(2);
+                System.out.println("Row " + id + ":");
+                System.out.println(obj.toString());
+            }
+            s.close();
+            conn.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/ComposedGeom.java b/jdbc2/src/org/postgis/ComposedGeom.java
new file mode 100644 (file)
index 0000000..d85b312
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * ComposedGeom.java
+ * 
+ * (C) 15.01.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
+ * 
+ * This file is licensed under GNU GPL.
+ * 
+ * $Id$
+ */
+package org.postgis;
+
+import java.util.Iterator;
+
+/**
+ * ComposedGeom - Abstract base class for all Geometries that are composed out
+ * of other Geometries.
+ * 
+ * In fact, this currently are all Geometry subclasses except Point.
+ * 
+ * @author schabi
+ * 
+ *  
+ */
+public abstract class ComposedGeom extends Geometry {
+    public static final Geometry[] EMPTY = new Geometry[0];
+
+    /**
+     * The Array containing the geometries
+     * 
+     * This is only to be exposed by concrete subclasses, to retain type safety.
+     */
+    protected Geometry[] subgeoms = EMPTY;
+
+    /**
+     * @param type
+     */
+    public ComposedGeom(int type) {
+        super(type);
+    }
+
+    public Geometry getSubGeometry(int index) {
+        return subgeoms[index];
+    }
+
+    protected ComposedGeom(int type, Geometry[] geoms) {
+        this(type);
+        this.subgeoms = geoms;
+        if (geoms.length>0) {
+        dimension = geoms[0].dimension;
+        } else {
+            dimension=0;
+        }
+    }
+
+    protected boolean equalsintern(Geometry other) {
+        // Can be assumed to be the same subclass of Geometry, so it must be a
+        // ComposedGeom, too.
+        ComposedGeom cother = (ComposedGeom) other;
+
+        if (cother.subgeoms == null && subgeoms == null) {
+            return true;
+        } else if (cother.subgeoms == null || subgeoms == null) {
+            return false;
+        } else if (cother.subgeoms.length != subgeoms.length) {
+            return false;
+        } else if (subgeoms.length == 0) {
+            return true;
+        } else {
+            for (int i = 0; i < subgeoms.length; i++) {
+                if (!cother.subgeoms[i].equalsintern(this.subgeoms[i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public int numPoints() {
+        if ((subgeoms == null) || (subgeoms.length == 0)) {
+            return 0;
+        } else {
+            int result = 0;
+            for (int i = 0; i < subgeoms.length; i++) {
+                result += subgeoms[i].numPoints();
+            }
+            return result;
+        }
+    }
+
+    public Point getPoint(int n) {
+        if (n < 0) {
+            throw new ArrayIndexOutOfBoundsException("Negative index not allowed");
+        } else if ((subgeoms == null) || (subgeoms.length == 0)) {
+            throw new ArrayIndexOutOfBoundsException("Empty Geometry has no Points!");
+        } else {
+            for (int i = 0; i < subgeoms.length; i++) {
+
+                Geometry current = subgeoms[i];
+                int np = current.numPoints();
+                if (n < np) {
+                    return current.getPoint(n);
+                } else {
+                    n -= np;
+                }
+            }
+            throw new ArrayIndexOutOfBoundsException("Index too large!");
+        }
+    }
+
+    /**
+     * Optimized version
+     */
+    public Point getLastPoint() {
+        if ((subgeoms == null) || (subgeoms.length == 0)) {
+            throw new ArrayIndexOutOfBoundsException("Empty Geometry has no Points!");
+        } else {
+            return subgeoms[subgeoms.length - 1].getLastPoint();
+        }
+    }
+
+    /**
+     * Optimized version
+     */
+    public Point getFirstPoint() {
+        if ((subgeoms == null) || (subgeoms.length == 0)) {
+            throw new ArrayIndexOutOfBoundsException("Empty Geometry has no Points!");
+        } else {
+            return subgeoms[0].getFirstPoint();
+        }
+    }
+
+    public Iterator iterator() {
+        return java.util.Arrays.asList(subgeoms).iterator();
+    }
+
+    public boolean isEmpty() {
+        return (subgeoms == null) || (subgeoms.length == 0);
+    }
+
+    protected void mediumWKT(StringBuffer sb) {
+        if ((subgeoms == null) || (subgeoms.length == 0)) {
+            sb.append(" EMPTY");
+        } else {
+            sb.append('(');
+            innerWKT(sb);
+            sb.append(')');
+        }
+   }
+
+    protected void innerWKT(StringBuffer sb) {
+        subgeoms[0].mediumWKT(sb);
+        for (int i = 1; i < subgeoms.length; i++) {
+            sb.append(',');
+            subgeoms[i].mediumWKT(sb);
+        }
+    }
+
+    // Hashing - still buggy!
+    boolean nohash = true;
+    int hashcode = 0;
+
+    public int hashCode() {
+        if (nohash) {
+            hashcode = super.hashCode() ^ subgeoms.hashCode();
+            nohash = false;
+        }
+        return hashcode;
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/DriverWrapper.java b/jdbc2/src/org/postgis/DriverWrapper.java
new file mode 100644 (file)
index 0000000..d50e721
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * PostGisWrapper.java
+ * 
+ * $Id$
+ * 
+ * (C) 2004 Markus Schaber, logi-track ag, Zürich, Switzerland
+ * 
+ * This file currently is beta test code and licensed under the GNU LGPL.
+ */
+package org.postgis;
+
+import org.postgresql.Driver;
+import org.postgresql.PGConnection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/**
+ * DriverWrapper
+ * 
+ * Wraps the PostGreSQL Driver to transparently add the PostGIS Object Classes.
+ * This avoids the need of explicit addDataType() calls from the driver users
+ * side.
+ * 
+ * This method currently works with J2EE DataSource implementations, and with
+ * DriverManager framework.
+ * 
+ * Simply replace the "jdbc:postgresql:" with a "jdbc:postgresql_postGIS" in the
+ * jdbc URL.
+ * 
+ * When using the drivermanager, you need to initialize DriverWrapper instead of
+ * (or in addition to) org.postgresql.Driver. When using a J2EE DataSource
+ * implementation, set the driver class property in the datasource config, the
+ * following works for jboss:
+ * 
+ * <code>
+ * &lt;driver-class&gt;com.logitrack.gis.util.DriverWrapper&lt;/driver-class&gt;
+ * </code>
+ * If you don't like or want to use the DriverWrapper, you have two
+ * alternatives:
+ * 
+ * A) If you use a pgjdbc driver newer than 8 Nov 2004, the
+ * postgresql.properties file in the org.postgresql directory delivered with
+ * this source should auto-register the PostGIS extension.
+ * 
+ * B) Add the datatypes manually to your connection:
+ * 
+ * <code>
+ * ((org.postgresql.PGConnection) conn).addDataType("geometry", "org.postgis.PGgeometry");
+ * ((org.postgresql.PGConnection) conn).addDataType("box3d", "org.postgis.PGbox3d");
+ * </code>
+ * 
+ * (You may need to dig through some wrappers when running in an appserver. E.
+ * G. for JBoss, you get a org.jboss.resource.adapter.jdbc.WrappedConnection and
+ * have to call getUnderlyingConnection() on it.)
+ * 
+ * Also note that the addDataType() methods known from earlier pgjdbc versions
+ * are deprecated in pgjdbc 8.0, see the commented code variants in the
+ * addGisTypes() method for an alternative.
+ * 
+ * @author Markus Schaber <schabios@logi-track.com>
+ *  
+ */
+public class DriverWrapper extends Driver {
+
+    private static final String POSTGRES_PROTOCOL = "jdbc:postgresql:";
+    private static final String POSTGIS_PROTOCOL = "jdbc:postgresql_postGIS:";
+    public static final String REVISION = "$Revision$";
+
+    public DriverWrapper() {
+        super();
+    }
+
+    static {
+        try {
+            // Try to register ourself to the DriverManager
+            java.sql.DriverManager.registerDriver(new DriverWrapper());
+        } catch (SQLException e) {
+            Driver.info("Error registering PostGIS Wrapper Driver", e);
+        }
+    }
+
+    /**
+     * Creates a postgresql connection, and then adds the PostGIS data types to
+     * it calling addpgtypes()
+     * 
+     * @param url the URL of the database to connect to
+     * @param info a list of arbitrary tag/value pairs as connection arguments
+     * @return a connection to the URL or null if it isnt us
+     * @exception SQLException if a database access error occurs
+     * 
+     * @see java.sql.Driver#connect
+     * @see org.postgresql.Driver
+     */
+    public java.sql.Connection connect(String url, Properties info) throws SQLException {
+        url = mangleURL(url);
+        Connection result = super.connect(url, info);
+        addGISTypes((PGConnection) result);
+        return result;
+    }
+
+    /**
+     * adds the JTS/PostGIS Data types to a PG Connection.
+     */
+    public static void addGISTypes(PGConnection pgconn) {
+        // This is correct for PostgreSQL jdbc drivers up to V7.4
+        pgconn.addDataType("geometry", "org.postgis.PGgeometry");
+        pgconn.addDataType("box3d", "org.postgis.PGbox3d");
+        pgconn.addDataType("box3d", "org.postgis.PGbox");
+        // If you use PostgreSQL jdbc drivers V8.0 or newer, the above
+        // methods are deprecated (but still work for now), and you
+        // may want to use the two lines below instead.
+        //pgconn.addDataType("geometry", org.postgis.PGgeometry.class);
+        //pgconn.addDataType("box3d", org.postgis.PGbox3d.class);
+        //pgconn.addDataType("box3d", org.postgis.PGBox.class);
+    }
+
+    /**
+     * Mangles the PostGIS URL to return the original PostGreSQL URL
+     */
+    public static String mangleURL(String url) throws SQLException {
+        if (url.startsWith(POSTGIS_PROTOCOL)) {
+            return POSTGRES_PROTOCOL + url.substring(POSTGIS_PROTOCOL.length());
+        } else {
+            throw new SQLException("Unknown protocol or subprotocol in url " + url);
+        }
+    }
+
+    /**
+     * Check whether the driver thinks he can handle the given URL.
+     * 
+     * @see java.sql.Driver#acceptsURL
+     * @param url the URL of the driver
+     * @return true if this driver accepts the given URL
+     * @exception SQLException Passed through from the underlying PostgreSQL
+     *                driver, should not happen.
+     */
+    public boolean acceptsURL(String url) throws SQLException {
+        try {
+            url = mangleURL(url);
+        } catch (SQLException e) {
+            return false;
+        }
+        return super.acceptsURL(url);
+    }
+
+    /**
+     * Gets the underlying drivers major version number
+     * 
+     * @return the drivers major version number
+     */
+
+    public int getMajorVersion() {
+        return super.getMajorVersion();
+    }
+
+    /**
+     * Get the underlying drivers minor version number
+     * 
+     * @return the drivers minor version number
+     */
+    public int getMinorVersion() {
+        return super.getMinorVersion();
+    }
+
+    /**
+     * Returns our own CVS version plus postgres Version
+     */
+    public static String getVersion() {
+        return "PostGisWrapper " + REVISION + ", wrapping " + Driver.getVersion();
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/Geometry.java b/jdbc2/src/org/postgis/Geometry.java
new file mode 100644 (file)
index 0000000..3e559de
--- /dev/null
@@ -0,0 +1,244 @@
+package org.postgis;
+
+import java.io.Serializable;
+
+/** The base class of all geometries */
+public abstract class Geometry implements Serializable {
+
+    // OpenGIS Geometry types as defined in the OGC WKB Spec
+    // (May we replace this with an ENUM as soon as JDK 1.5
+    //  has gained widespread usage?)
+
+    /** Fake type for linear ring */
+    public static final int LINEARRING = 0;
+    /**
+     * The OGIS geometry type number for points.
+     */
+    public static final int POINT = 1;
+
+    /**
+     * The OGIS geometry type number for lines.
+     */
+    public static final int LINESTRING = 2;
+
+    /**
+     * The OGIS geometry type number for polygons.
+     */
+    public static final int POLYGON = 3;
+
+    /**
+     * The OGIS geometry type number for aggregate points.
+     */
+    public static final int MULTIPOINT = 4;
+
+    /**
+     * The OGIS geometry type number for aggregate lines.
+     */
+    public static final int MULTILINESTRING = 5;
+
+    /**
+     * The OGIS geometry type number for aggregate polygons.
+     */
+    public static final int MULTIPOLYGON = 6;
+
+    /**
+     * The OGIS geometry type number for feature collections.
+     */
+    public static final int GEOMETRYCOLLECTION = 7;
+
+    public static final String[] ALLTYPES = new String[]{
+        "", // internally used LinearRing does not have any text in front of it
+        "POINT",
+        "LINESTRING",
+        "POLYGON",
+        "MULTIPOINT",
+        "MULTILINESTRING",
+        "MULTIPOLYGON",
+        "GEOMETRYCOLLECTION"};
+
+    /**
+     * The Text representations of the geometry types
+     */
+    public static String getTypeString(int type) {
+        if (type >= 0 && type <= 7) {
+            return ALLTYPES[type];
+        } else {
+            throw new IllegalArgumentException("Unknown Geometry type" + type);
+        }
+    }
+
+    // Properties common to all geometries
+    /**
+     * The dimensionality of this feature (2,3)
+     */
+    public int dimension;
+
+    /**
+     * Do we have a measure (4th dimension)
+     */
+    public boolean haveMeasure = false;
+
+    /**
+     * The OGIS geometry type of this feature. this is final as it never
+     * changes, it is bound to the subclass of the instance.
+     */
+    public final int type;
+
+    /**
+     * The string rep of the current type
+     */
+    public final String typestring;
+
+    /**
+     * The spacial reference system id of this geometry, default (no srid) is -1
+     */
+    public int srid = -1;
+
+    /**
+     * Constructor for subclasses
+     * 
+     * @param type has to be given by all subclasses.
+     */
+    protected Geometry(int type) {
+        this.type = type;
+        this.typestring = getTypeString(type);
+    }
+
+    /**
+     * java.lang.Object hashCode implementation
+     */
+    public int hashCode() {
+        return dimension | (type * 4) | (srid * 32);
+    }
+
+    /**
+     * java.lang.Object equals implementation
+     */
+    public boolean equals(Object other) {
+        return (other instanceof Geometry) && equals((Geometry) other);
+    }
+
+    /**
+     * geometry specific equals implementation
+     */
+    public boolean equals(Geometry other) {
+        return ((other != null) && (this.dimension == other.dimension) && (this.type == other.type)
+                && (this.srid == other.srid) && (this.haveMeasure == other.haveMeasure)
+                && other.getClass().equals(this.getClass()) && this.equalsintern(other));
+    }
+
+    /**
+     * Whether test coordinates for geometry - subclass specific code
+     * 
+     * Implementors can assume that dimensin, type, srid and haveMeasure are
+     * equal, other != null and other is the same subclass.
+     */
+    protected abstract boolean equalsintern(Geometry other);
+
+    /**
+     * Return the number of Points of the geometry
+     */
+    public abstract int numPoints();
+
+    /**
+     * Get the nth Point of the geometry
+     * 
+     * @param n the index of the point, from 0 to numPoints()-1;
+     * @throws ArrayIndexOutOfBoundsException in case of an emtpy geometry or
+     *             bad index.
+     */
+    public abstract Point getPoint(int n);
+
+    /**
+     * Same as getPoint(0);
+     */
+    public abstract Point getFirstPoint();
+
+    /**
+     * Same as getPoint(numPoints()-1);
+     */
+    public abstract Point getLastPoint();
+
+    /**
+     * The OGIS geometry type number of this geometry.
+     */
+    public int getType() {
+        return this.type;
+    }
+
+    /**
+     * Return the Type as String
+     */
+    public String getTypeString() {
+        return getTypeString(this.type);
+    }
+
+    /**
+     * @return The dimensionality (eg, 2D or 3D) of this geometry.
+     */
+    public int getDimension() {
+        return this.dimension;
+    }
+
+    /**
+     * The OGIS geometry type number of this geometry.
+     */
+    public int getSrid() {
+        return this.srid;
+    }
+
+    /**
+     * Recursively sets the srid on this geometry and all contained
+     * subgeometries
+     */
+    public void setSrid(int srid) {
+        this.srid = srid;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        if (srid != -1) {
+            sb.append("SRID=");
+            sb.append(srid);
+            sb.append(';');
+        }
+        outerWKT(sb);
+        return sb.toString();
+    }
+
+    /**
+     * Render the WKT version of this Geometry (without SRID) into the given
+     * StringBuffer.
+     */
+    public void outerWKT(StringBuffer sb) {
+        sb.append(typestring);
+        if (haveMeasure && dimension == 2) {
+            sb.append('M');
+        }
+        mediumWKT(sb);
+    }
+
+    /** Render the WKT without the type name, but including the brackets into the StringBuffer*/
+    protected void mediumWKT(StringBuffer sb) {
+        sb.append('(');
+        innerWKT(sb);
+        sb.append(')');
+    }
+    
+    /**
+     * Render the "inner" part of the WKT (inside the brackets) into the
+     * StringBuffer.
+     */
+    protected abstract void innerWKT(StringBuffer SB);
+
+    /**
+     * backwards compatibility method
+     */
+    public String getValue() {
+        StringBuffer sb = new StringBuffer();
+        mediumWKT(sb);
+        return sb.toString();
+    }
+
+
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/GeometryCollection.java b/jdbc2/src/org/postgis/GeometryCollection.java
new file mode 100644 (file)
index 0000000..7073dd2
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * GeometryCollection.java
+ * 
+ * $Id$
+ * 
+ * (C) 2004 Markus Schaber, logi-track ag, Zürich, Switzerland
+ * 
+ * This file currently is beta test code and licensed under the GNU GPL.
+ */package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+/**
+ * Geometry Collection class WARNING: Currently only implements empty
+ * collections
+ * 
+ * @author schabi
+ * 
+ * $Id$
+ */
+
+public class GeometryCollection extends ComposedGeom {
+    public static final String GeoCollID = "GEOMETRYCOLLECTION";
+    public static final String EmptyColl = GeoCollID + "(EMPTY)";
+
+    public GeometryCollection() {
+        super(GEOMETRYCOLLECTION);
+    }
+
+    public GeometryCollection(Geometry[] geoms) {
+        super(GEOMETRYCOLLECTION, geoms);
+    }
+
+    public GeometryCollection(String value) throws SQLException {
+        this();
+        value = value.trim();
+        if (value.equals(EmptyColl)) {
+            //Do nothing
+        } else if (value.startsWith(GeoCollID)) {
+            PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.substring(GeoCollID.length()).trim()), ',');
+            int ngeoms = t.getSize();
+            subgeoms = new Geometry[ngeoms];
+            for (int p = 0; p < ngeoms; p++) {
+                subgeoms[p] = PGgeometry.geomFromString(t.getToken(p));
+            }
+            dimension = subgeoms[0].dimension;
+        } else {
+            throw new SQLException("postgis.geocollection");
+        }
+    }
+
+    protected void innerWKT(StringBuffer SB) {
+        subgeoms[0].outerWKT(SB);
+        for (int i = 1; i < subgeoms.length; i++) {
+            SB.append(',');
+            subgeoms[i].outerWKT(SB);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/LineString.java b/jdbc2/src/org/postgis/LineString.java
new file mode 100644 (file)
index 0000000..fff8ff0
--- /dev/null
@@ -0,0 +1,69 @@
+package org.postgis;
+
+import java.sql.SQLException;
+
+public class LineString extends PointComposedGeom {
+
+    double len = -1.;
+
+    public LineString() {
+        super(LINESTRING);
+    }
+
+    public LineString(Point[] points) {
+        super(LINESTRING, points);
+    }
+
+    public LineString(String value) throws SQLException {
+        super(LINESTRING, value);
+    }
+
+    public LineString reverse() {
+        Point[] points = this.getPoints();
+        int l = points.length;
+        int i, j;
+        Point[] p = new Point[l];
+        for (i = 0, j = l - 1; i < l; i++, j--) {
+            p[i] = points[j];
+        }
+        return new LineString(p);
+    }
+
+    public LineString concat(LineString other) {
+        Point[] points = this.getPoints();
+        Point[] opoints = other.getPoints();
+
+        boolean cutPoint = this.getLastPoint() == null || this.getLastPoint().equals(other.getFirstPoint());
+        int count = points.length + points.length - (cutPoint ? 1 : 0);
+        Point[] p = new Point[count];
+
+        // Maybe we should use System.arrayCopy here?
+        int i, j;
+        for (i = 0; i < points.length; i++) {
+            p[i] = points[i];
+        }
+        if (!cutPoint) {
+            p[i++] = other.getFirstPoint();
+        }
+        for (j = 1; j < opoints.length; j++, i++) {
+            p[i] = opoints[j];
+        }
+        return new LineString(p);
+    }
+
+    public double length() {
+        if (len < 0) {
+            Point[] points = this.getPoints();
+            if ((points == null) || (points.length < 2)) {
+                len = 0;
+            } else {
+                double sum = 0;
+                for (int i = 1; i < points.length; i++) {
+                    sum += points[i - 1].distance(points[i]);
+                }
+                len = sum;
+            }
+        }
+        return len;
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/LinearRing.java b/jdbc2/src/org/postgis/LinearRing.java
new file mode 100644 (file)
index 0000000..b0fde39
--- /dev/null
@@ -0,0 +1,34 @@
+package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+/**
+ * This represents the LinearRing GIS datatype. This type is used to construct
+ * the polygon types, but is not stored or retrieved directly from the database.
+ */
+public class LinearRing extends PointComposedGeom {
+
+    public LinearRing(Point[] points) {
+        super(LINEARRING, points);
+    }
+
+    /**
+     * This is called to construct a LinearRing from the PostGIS string
+     * representation of a ring.
+     * 
+     * @param value Definition of this ring in the PostGIS string format.
+     */
+    public LinearRing(String value) throws SQLException {
+        super(LINEARRING);
+        PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.trim()), ',');
+        int npoints = t.getSize();
+        Point[] points = new Point[npoints];
+        for (int p = 0; p < npoints; p++) {
+            points[p] = new Point(t.getToken(p));
+        }
+        dimension = points[0].dimension;
+        this.subgeoms = points;
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/MultiLineString.java b/jdbc2/src/org/postgis/MultiLineString.java
new file mode 100644 (file)
index 0000000..ca1caef
--- /dev/null
@@ -0,0 +1,70 @@
+package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+public class MultiLineString extends ComposedGeom {
+
+    double len = -1;
+
+    public int hashCode() {
+        return super.hashCode() ^ (int) this.length();
+    }
+
+    public MultiLineString() {
+        super(MULTILINESTRING);
+    }
+
+    public MultiLineString(LineString[] lines) {
+        super(MULTILINESTRING, lines);
+    }
+
+    public MultiLineString(String value) throws SQLException {
+        this();
+        value = value.trim();
+        if (value.indexOf("MULTILINESTRING") == 0) {
+            PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.substring(15).trim()), ',');
+            int nlines = t.getSize();
+            subgeoms = new LineString[nlines];
+            for (int p = 0; p < nlines; p++) {
+                subgeoms[p] = new LineString(t.getToken(p));
+            }
+            dimension = subgeoms[0].dimension;
+        } else {
+            throw new SQLException("postgis.multilinestringgeometry");
+        }
+    }
+
+    public int numLines() {
+        return subgeoms.length;
+    }
+
+    public LineString[] getLines() {
+        return (LineString[]) subgeoms.clone();
+    }
+
+    public LineString getLine(int idx) {
+        if (idx >= 0 & idx < subgeoms.length) {
+            return (LineString) subgeoms[idx];
+        } else {
+            return null;
+        }
+    }
+
+    public double length() {
+        if (len < 0) {
+            LineString[] lines = (LineString[]) subgeoms;
+            if (lines.length < 1) {
+                len = 0;
+            } else {
+                double sum = 0;
+                for (int i = 0; i < lines.length; i++) {
+                    sum += lines[i].length();
+                }
+                len = sum;
+            }
+        }
+        return len;
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/MultiPoint.java b/jdbc2/src/org/postgis/MultiPoint.java
new file mode 100644 (file)
index 0000000..51ea26f
--- /dev/null
@@ -0,0 +1,18 @@
+package org.postgis;
+
+import java.sql.SQLException;
+
+public class MultiPoint extends PointComposedGeom {
+
+    public MultiPoint() {
+        super(MULTIPOINT);
+    }
+
+    public MultiPoint(Point[] points) {
+        super(MULTIPOINT, points);
+    }
+
+    public MultiPoint(String value) throws SQLException {
+        super(MULTIPOINT, value);
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/MultiPolygon.java b/jdbc2/src/org/postgis/MultiPolygon.java
new file mode 100644 (file)
index 0000000..f7cb40e
--- /dev/null
@@ -0,0 +1,45 @@
+package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+public class MultiPolygon extends ComposedGeom {
+
+    public MultiPolygon() {
+        super(MULTIPOLYGON);
+    }
+
+    public MultiPolygon(Polygon[] polygons) {
+        super(MULTIPOLYGON, polygons);
+    }
+
+    public MultiPolygon(String value) throws SQLException {
+        this();
+        value = value.trim();
+        if (value.indexOf("MULTIPOLYGON") == 0) {
+            PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.substring(12).trim()), ',');
+            int npolygons = t.getSize();
+            subgeoms = new Polygon[npolygons];
+            for (int p = 0; p < npolygons; p++) {
+                subgeoms[p] = new Polygon(t.getToken(p));
+            }
+            dimension = subgeoms[0].dimension;
+        } else {
+            throw new SQLException("postgis.multipolygongeometry");
+        }
+    }
+
+    public int numPolygons() {
+        return subgeoms.length;
+    }
+
+    public Polygon getPolygon(int idx) {
+        if (idx >= 0 & idx < subgeoms.length) {
+            return (Polygon) subgeoms[idx];
+        } else {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/PGbox.java b/jdbc2/src/org/postgis/PGbox.java
new file mode 100644 (file)
index 0000000..920e75a
--- /dev/null
@@ -0,0 +1,72 @@
+package org.postgis;
+
+import org.postgresql.util.PGobject;
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+/*
+ * Updates Oct 2002 - data members made private - getLLB() and getURT() methods
+ * added
+ */
+
+public class PGbox extends PGobject {
+
+    /**
+     * The lower left bottom corner of the box.
+     */
+    private Point llb;
+
+    /**
+     * The upper right top corner of the box.
+     */
+    private Point urt;
+
+    public PGbox() {
+        // do nothing.
+    }
+
+    public PGbox(Point llb, Point urt) {
+        this.llb = llb;
+        this.urt = urt;
+    }
+
+    public PGbox(String value) throws SQLException {
+        setValue(value);
+    }
+
+    public void setValue(String value) throws SQLException {
+        value = value.trim();
+        if (value.startsWith("BOX")) {
+            value = value.substring(5);
+        }
+        PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.trim()), ',');
+        llb = new Point(t.getToken(0));
+        urt = new Point(t.getToken(1));
+    }
+
+    public String getValue() {
+        return "BOX(" + llb.getValue() + "," + urt.getValue() + ")";
+    }
+
+    public String toString() {
+        return getValue();
+    }
+
+    public Object clone() {
+        PGbox obj = new PGbox(llb, urt);
+        obj.setType(type);
+        return obj;
+    }
+
+    /** Returns the lower left bottom corner of the box as a Point object */
+    public Point getLLB() {
+        return llb;
+    }
+
+    /** Returns the upper right top corner of the box as a Point object */
+    public Point getURT() {
+        return urt;
+    }
+
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/PGbox3d.java b/jdbc2/src/org/postgis/PGbox3d.java
new file mode 100644 (file)
index 0000000..8d3d5d2
--- /dev/null
@@ -0,0 +1,72 @@
+package org.postgis;
+
+import org.postgresql.util.PGobject;
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+/*
+ * Updates Oct 2002 - data members made private - getLLB() and getURT() methods
+ * added
+ */
+
+public class PGbox3d extends PGobject {
+
+    /**
+     * The lower left bottom corner of the box.
+     */
+    private Point llb;
+
+    /**
+     * The upper right top corner of the box.
+     */
+    private Point urt;
+
+    public PGbox3d() {
+        // do nothing.
+    }
+
+    public PGbox3d(Point llb, Point urt) {
+        this.llb = llb;
+        this.urt = urt;
+    }
+
+    public PGbox3d(String value) throws SQLException {
+        setValue(value);
+    }
+
+    public void setValue(String value) throws SQLException {
+        value = value.trim();
+        if (value.startsWith("BOX3D")) {
+            value = value.substring(5);
+        }
+        PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.trim()), ',');
+        llb = new Point(t.getToken(0));
+        urt = new Point(t.getToken(1));
+    }
+
+    public String getValue() {
+        return "BOX3D (" + llb.getValue() + "," + urt.getValue() + ")";
+    }
+
+    public String toString() {
+        return getValue();
+    }
+
+    public Object clone() {
+        PGbox3d obj = new PGbox3d(llb, urt);
+        obj.setType(type);
+        return obj;
+    }
+
+    /** Returns the lower left bottom corner of the box as a Point object */
+    public Point getLLB() {
+        return llb;
+    }
+
+    /** Returns the upper right top corner of the box as a Point object */
+    public Point getURT() {
+        return urt;
+    }
+
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/PGgeometry.java b/jdbc2/src/org/postgis/PGgeometry.java
new file mode 100644 (file)
index 0000000..bd1bd5c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * PG Geometry
+ * 
+ * Updates Oct 2002 - setValue() method now cheaks if the geometry has a SRID.
+ * If present, it is removed and only the wkt is used to create the new geometry
+ * 
+ * Jan 2005 Add parsing of new canonical text representation which basically is
+ * a hex-encoded extended OGC WKB
+ */
+
+package org.postgis;
+
+import org.postgis.binary.BinaryParser;
+import org.postgresql.util.PGobject;
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+public class PGgeometry extends PGobject {
+
+    Geometry geom;
+    BinaryParser bp = new BinaryParser();
+
+    public PGgeometry() {
+        // Do nothing
+    }
+
+    public PGgeometry(Geometry geom) {
+        this.geom = geom;
+    }
+
+    public PGgeometry(String value) throws SQLException {
+        setValue(value);
+    }
+
+    public void setValue(String value) throws SQLException {
+        geom = geomFromString(value, bp);
+    }
+
+    public static Geometry geomFromString(String value) throws SQLException {
+        BinaryParser bp = new BinaryParser();
+
+        return geomFromString(value, bp);
+    }
+
+    /**
+     * Maybe we could add more error checking here?
+     */
+    public static Geometry geomFromString(String value, BinaryParser bp) throws SQLException {
+        value = value.trim();
+
+        int srid = -1;
+        if (value.startsWith("SRID")) {
+            //break up geometry into srid and wkt
+            PGtokenizer t = new PGtokenizer(value, ';');
+            value = t.getToken(1).trim();
+
+            srid = Integer.parseInt(t.getToken(0).split("=")[1]);
+        }
+
+        Geometry result;
+        if (value.endsWith("EMPTY")) {
+            // We have a standard conforming representation for an empty
+            // geometry which is to be parsed as an empty GeometryCollection.
+            result = new GeometryCollection();
+        } else if (value.startsWith("MULTIPOLYGON")) {
+            result = new MultiPolygon(value);
+        } else if (value.startsWith("MULTILINESTRING")) {
+            result = new MultiLineString(value);
+        } else if (value.startsWith("MULTIPOINT")) {
+            result = new MultiPoint(value);
+        } else if (value.startsWith("POLYGON")) {
+            result = new Polygon(value);
+        } else if (value.startsWith("LINESTRING")) {
+            result = new LineString(value);
+        } else if (value.startsWith("POINT")) {
+            result = new Point(value);
+        } else if (value.startsWith("GEOMETRYCOLLECTION")) {
+            result = new GeometryCollection(value);
+        } else if (value.startsWith("00") || value.startsWith("01")) {
+            result = bp.parse(value);
+        } else {
+            throw new SQLException("Unknown type: " + value);
+        }
+
+        if (srid != -1) {
+            result.srid = srid;
+        }
+
+        return result;
+    }
+
+    public Geometry getGeometry() {
+        return geom;
+    }
+
+    public int getGeoType() {
+        return geom.type;
+    }
+
+    public String toString() {
+        return geom.toString();
+    }
+
+    public String getValue() {
+        return geom.toString();
+    }
+
+    public Object clone() {
+        PGgeometry obj = new PGgeometry(geom);
+        obj.setType(type);
+        return obj;
+    }
+
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/Point.java b/jdbc2/src/org/postgis/Point.java
new file mode 100644 (file)
index 0000000..801dc34
--- /dev/null
@@ -0,0 +1,189 @@
+package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+public class Point extends Geometry {
+
+    public int hashCode() {
+        return super.hashCode() ^ hashCode(x) ^ hashCode(y) ^ hashCode(z) ^ hashCode(m);
+    }
+
+    public static int hashCode(double value) {
+        long v = Double.doubleToLongBits(value);
+        return (int) (v ^ (v >>> 32));
+    }
+
+    protected boolean equalsintern(Geometry otherg) {
+        Point other = (Point) otherg;
+        return x == other.x && y == other.y && ((dimension == 2) || (z == other.z))
+                && ((haveMeasure == false) || (m == other.m));
+    }
+
+    public Point getPoint(int index) {
+        if (index == 0) {
+            return this;
+        } else {
+            throw new ArrayIndexOutOfBoundsException("Point only has a single Point! " + index);
+        }
+    }
+
+    /** Optimized versions for this special case */
+    public Point getFirstPoint() {
+        return this;
+    }
+
+    /** Optimized versions for this special case */
+    public Point getLastPoint() {
+        return this;
+    }
+
+    public int numPoints() {
+        return 1;
+    }
+
+    /**
+     * The X coordinate of the point.
+     */
+    public double x;
+
+    /**
+     * The Y coordinate of the point.
+     */
+    public double y;
+
+    /**
+     * The Z coordinate of the point.
+     */
+    public double z;
+
+    /**
+     * The measure of the point.
+     */
+    public double m = 0.0;
+
+    public Point() {
+        super(POINT);
+    }
+
+    public Point(double x, double y, double z) {
+        this();
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        dimension = 3;
+    }
+
+    public Point(double x, double y) {
+        this();
+        this.x = x;
+        this.y = y;
+        this.z = 0.0;
+        dimension = 2;
+    }
+
+    public Point(String value) throws SQLException {
+        this();
+        value = value.trim();
+        if (value.indexOf("POINT") == 0) {
+            value = value.substring(5).trim();
+        }
+        PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value), ' ');
+        try {
+            if (t.getSize() == 3) {
+                x = Double.valueOf(t.getToken(0)).doubleValue();
+                y = Double.valueOf(t.getToken(1)).doubleValue();
+                z = Double.valueOf(t.getToken(2)).doubleValue();
+                dimension = 3;
+            } else {
+                x = Double.valueOf(t.getToken(0)).doubleValue();
+                y = Double.valueOf(t.getToken(1)).doubleValue();
+                z = 0.0;
+                dimension = 2;
+            }
+        } catch (NumberFormatException e) {
+            throw new SQLException("postgis.Point" + e.toString());
+        }
+    }
+
+    public void innerWKT(StringBuffer sb) {
+        sb.append(x);
+        sb.append(' ');
+        sb.append(y);
+        if (dimension == 3) {
+            sb.append(' ');
+            sb.append(z);
+        }
+        if (haveMeasure) {
+            sb.append(' ');
+            sb.append(m);
+        }
+    }
+
+    public double getX() {
+        return x;
+    }
+
+    public double getY() {
+        return y;
+    }
+
+    public double getZ() {
+        return z;
+    }
+
+    public double getM() {
+        return m;
+    }
+
+    public void setX(double x) {
+        this.x = x;
+    }
+
+    public void setY(double y) {
+        this.y = y;
+    }
+
+    public void setZ(double z) {
+        this.z = z;
+    }
+
+    public void setM(double m) {
+        haveMeasure = true;
+        this.m = m;
+    }
+
+    public void setX(int x) {
+        this.x = x;
+    }
+
+    public void setY(int y) {
+        this.y = y;
+    }
+
+    public void setZ(int z) {
+        this.z = z;
+    }
+
+    public double distance(Point other) {
+        double tx, ty, tz;
+        if (this.dimension != other.dimension) {
+            throw new IllegalArgumentException("Points have different dimensions!");
+        }
+        tx = this.x - other.x;
+        switch (this.dimension) {
+        case 1 :
+            return Math.sqrt(tx * tx);
+        case 2 :
+            ty = this.y - other.y;
+            return Math.sqrt(tx * tx + ty * ty);
+        case 3 :
+            ty = this.y - other.y;
+            tz = this.z - other.z;
+            return Math.sqrt(tx * tx + ty * ty + tz * tz);
+        default :
+            throw new AssertionError("Illegal dimension of Point" + this.dimension);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/PointComposedGeom.java b/jdbc2/src/org/postgis/PointComposedGeom.java
new file mode 100644 (file)
index 0000000..d89d4e9
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * ComposedGeom.java
+ * 
+ * (C) 15.01.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
+ * 
+ * This file is licensed under GNU GPL.
+ * 
+ * $Id$
+ */
+package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+/**
+ * PointComposedGeom - base class for all composed geoms that contain only
+ * points.
+ * 
+ * @author schabi
+ *  
+ */
+
+public abstract class PointComposedGeom extends ComposedGeom {
+
+    protected PointComposedGeom(int type) {
+        super(type);
+    }
+
+    protected PointComposedGeom(int type, Point[] points) {
+        super(type, points);
+    }
+
+    public PointComposedGeom(int type, String value) throws SQLException {
+        this(type);
+        value = value.trim();
+        if (value.indexOf(typestring) == 0) {
+            value = value.substring(typestring.length()).trim();
+        }
+        if (value.charAt(0) == '(') {
+            PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value), ',');
+            int npoints = t.getSize();
+            subgeoms = new Point[npoints];
+            for (int p = 0; p < npoints; p++) {
+                subgeoms[p] = new Point(t.getToken(p));
+            }
+            dimension = subgeoms[0].dimension;
+        } else {
+            throw new SQLException("postgis.multipointgeometry");
+        }
+    }
+
+    protected void innerWKT(StringBuffer sb) {
+        subgeoms[0].innerWKT(sb);
+        for (int i = 1; i < subgeoms.length; i++) {
+            sb.append(',');
+            subgeoms[i].innerWKT(sb);
+        }
+    }
+
+    /**
+     * optimized version
+     */
+    public int numPoints() {
+        return subgeoms.length;
+    }
+
+    /**
+     * optimized version
+     */
+    public Point getPoint(int idx) {
+        if (idx >= 0 & idx < subgeoms.length) {
+            return (Point) subgeoms[idx];
+        } else {
+            return null;
+        }
+    }
+
+    /** Get the underlying Point array */
+    public Point[] getPoints() {
+        return (Point[]) subgeoms;
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/Polygon.java b/jdbc2/src/org/postgis/Polygon.java
new file mode 100644 (file)
index 0000000..ce3ab79
--- /dev/null
@@ -0,0 +1,43 @@
+package org.postgis;
+
+import org.postgresql.util.PGtokenizer;
+
+import java.sql.SQLException;
+
+public class Polygon extends ComposedGeom {
+
+    public Polygon() {
+        super(POLYGON);
+    }
+
+    public Polygon(LinearRing[] rings) {
+        super(POLYGON, rings);
+    }
+
+    public Polygon(String value) throws SQLException {
+        this();
+        value = value.trim();
+        if (value.indexOf("POLYGON") == 0) {
+            value = value.substring(7).trim();
+        }
+        PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value), ',');
+        int nrings = t.getSize();
+        subgeoms = new LinearRing[nrings];
+        for (int r = 0; r < nrings; r++) {
+            subgeoms[r] = new LinearRing(t.getToken(r));
+        }
+        dimension = subgeoms[0].dimension;
+    }
+
+    public int numRings() {
+        return subgeoms.length;
+    }
+
+    public LinearRing getRing(int idx) {
+        if (idx >= 0 & idx < subgeoms.length) {
+            return (LinearRing) subgeoms[idx];
+        } else {
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/binary/BinaryParser.java b/jdbc2/src/org/postgis/binary/BinaryParser.java
new file mode 100644 (file)
index 0000000..3d78a7c
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * BinReader.java
+ * 
+ * (C) 14.01.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
+ * 
+ * This File is Licensed under the GNU GPL.
+ * 
+ * $Id$
+ */
+package org.postgis.binary;
+
+import org.postgis.Geometry;
+import org.postgis.GeometryCollection;
+import org.postgis.LineString;
+import org.postgis.LinearRing;
+import org.postgis.MultiLineString;
+import org.postgis.MultiPoint;
+import org.postgis.MultiPolygon;
+import org.postgis.Point;
+import org.postgis.Polygon;
+import org.postgis.binary.ByteGetter.BinaryByteGetter;
+import org.postgis.binary.ByteGetter.StringByteGetter;
+
+/**
+ * Parse binary representation of geometries. Currently, only text rep (hexed)
+ * implementation is tested.
+ * 
+ * It should be easy to add char[] and CharSequence ByteGetter instances,
+ * although the latter one is not compatible with older jdks.
+ * 
+ * I did not implement real unsigned 32-bit integers or emulate them with long,
+ * as both java Arrays and Strings currently can have only 2^31-1 elements
+ * (bytes), so we cannot even get or build Geometries with more than approx.
+ * 2^28 coordinates (8 bytes each).
+ * 
+ * @author markus.schaber@logi-track.com
+ *  
+ */
+public class BinaryParser {
+
+    /**
+     * Get the appropriate ValueGetter for my endianness
+     * 
+     * @param bytes The appropriate Byte Getter
+     * 
+     * @return the ValueGetter
+     */
+    public static ValueGetter valueGetterForEndian(ByteGetter bytes) {
+        if (bytes.get(0) == ValueGetter.XDR.NUMBER) { // XDR
+            return new ValueGetter.XDR(bytes);
+        } else if (bytes.get(0) == ValueGetter.NDR.NUMBER) {
+            return new ValueGetter.NDR(bytes);
+        } else {
+            throw new IllegalArgumentException("Unknown Endian type:" + bytes.get(0));
+        }
+    }
+
+    /**
+     * Parse a hex encoded geometry
+     * 
+     * Is synchronized to protect offset counter. (Unfortunately, Java does not
+     * have neither call by reference nor multiple return values.)
+     */
+    public synchronized Geometry parse(String value) {
+        StringByteGetter bytes = new ByteGetter.StringByteGetter(value);
+        return parseGeometry(valueGetterForEndian(bytes));
+    }
+
+    /**
+     * Parse a binary encoded geometry.
+     * 
+     * Is synchronized to protect offset counter. (Unfortunately, Java does not
+     * have neither call by reference nor multiple return values.)
+     */
+    public synchronized Geometry parse(byte[] value) {
+        BinaryByteGetter bytes = new ByteGetter.BinaryByteGetter(value);
+        return parseGeometry(valueGetterForEndian(bytes));
+    }
+
+    /** Parse a geometry starting at offset. */
+    protected Geometry parseGeometry(ValueGetter data) {
+        byte endian = data.getByte(); //skip and test endian flag
+        if (endian != data.endian) {
+            throw new IllegalArgumentException("Endian inconsistency!");
+        }
+        int typeword = data.getInt();
+
+        int realtype = typeword & 0x1FFFFFFF; //cut off high flag bits
+
+        boolean haveZ = (typeword & 0x80000000) != 0;
+        boolean haveM = (typeword & 0x40000000) != 0;
+        boolean haveS = (typeword & 0x20000000) != 0;
+
+        int srid = -1;
+
+        if (haveS) {
+            srid = data.getInt();
+        }
+        Geometry result1;
+        switch (realtype) {
+        case Geometry.POINT :
+            result1 = parsePoint(data, haveZ, haveM);
+            break;
+        case Geometry.LINESTRING :
+            result1 = parseLineString(data, haveZ, haveM);
+            break;
+        case Geometry.POLYGON :
+            result1 = parsePolygon(data, haveZ, haveM);
+            break;
+        case Geometry.MULTIPOINT :
+            result1 = parseMultiPoint(data);
+            break;
+        case Geometry.MULTILINESTRING :
+            result1 = parseMultiLineString(data);
+            break;
+        case Geometry.MULTIPOLYGON :
+            result1 = parseMultiPolygon(data);
+            break;
+        case Geometry.GEOMETRYCOLLECTION :
+            result1 = parseCollection(data);
+            break;
+        default :
+            throw new IllegalArgumentException("Unknown Geometry Type!");
+        }
+
+        Geometry result = result1;
+
+        if (haveS) {
+            result.setSrid(srid);
+        }
+        return result;
+    }
+
+    private Point parsePoint(ValueGetter data, boolean haveZ, boolean haveM) {
+        double X = data.getDouble();
+        double Y = data.getDouble();
+        Point result;
+        if (haveZ) {
+            double Z = data.getDouble();
+            result = new Point(X, Y, Z);
+        } else {
+            result = new Point(X, Y);
+        }
+
+        if (haveM) {
+            result.setM(data.getDouble());
+        }
+
+        return result;
+    }
+
+    /** Parse an Array of "full" Geometries */
+    private void parseGeometryArray(ValueGetter data, Geometry[] container) {
+        for (int i = 0; i < container.length; i++) {
+            container[i] = parseGeometry(data);
+        }
+    }
+
+    /**
+     * Parse an Array of "slim" Points (without endianness and type, part of
+     * LinearRing and Linestring, but not MultiPoint!
+     * 
+     * @param haveZ
+     * @param haveM
+     */
+    private Point[] parsePointArray(ValueGetter data, boolean haveZ, boolean haveM) {
+        int count = data.getInt();
+        Point[] result = new Point[count];
+        for (int i = 0; i < count; i++) {
+            result[i] = parsePoint(data, haveZ, haveM);
+        }
+        return result;
+    }
+
+    private MultiPoint parseMultiPoint(ValueGetter data) {
+        Point[] points = new Point[data.getInt()];
+        parseGeometryArray(data, points);
+        return new MultiPoint(points);
+    }
+
+    private LineString parseLineString(ValueGetter data, boolean haveZ, boolean haveM) {
+        Point[] points = parsePointArray(data, haveZ, haveM);
+        return new LineString(points);
+    }
+
+    private LinearRing parseLinearRing(ValueGetter data, boolean haveZ, boolean haveM) {
+        Point[] points = parsePointArray(data, haveZ, haveM);
+        return new LinearRing(points);
+    }
+
+    private Polygon parsePolygon(ValueGetter data, boolean haveZ, boolean haveM) {
+        int count = data.getInt();
+        LinearRing[] rings = new LinearRing[count];
+        for (int i = 0; i < count; i++) {
+            rings[i] = parseLinearRing(data, haveZ, haveM);
+        }
+        return new Polygon(rings);
+    }
+
+    private MultiLineString parseMultiLineString(ValueGetter data) {
+        int count = data.getInt();
+        LineString[] strings = new LineString[count];
+        parseGeometryArray(data, strings);
+        return new MultiLineString(strings);
+    }
+
+    private MultiPolygon parseMultiPolygon(ValueGetter data) {
+        int count = data.getInt();
+        Polygon[] polys = new Polygon[count];
+        parseGeometryArray(data, polys);
+        return new MultiPolygon(polys);
+    }
+
+    private GeometryCollection parseCollection(ValueGetter data) {
+        int count = data.getInt();
+        Geometry[] geoms = new Geometry[count];
+        parseGeometryArray(data, geoms);
+        return new GeometryCollection(geoms);
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/binary/ByteGetter.java b/jdbc2/src/org/postgis/binary/ByteGetter.java
new file mode 100644 (file)
index 0000000..9e6a392
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * ByteGetter.java
+ * 
+ * (C) 15.01.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
+ * 
+ * $Id$
+ */
+package org.postgis.binary;
+
+public abstract class ByteGetter {
+    /**
+     * Get ab byte.
+     * 
+     * @return The result is returned as Int to eliminate sign problems when
+     *         or'ing several values together.
+     */
+    public abstract int get(int index);
+
+    public static class BinaryByteGetter extends ByteGetter {
+        private byte[] array;
+
+        public BinaryByteGetter(byte[] array) {
+            this.array = array;
+        }
+
+        public int get(int index) {
+            return array[index] & 0xFF; //mask out sign-extended bits.
+        }
+    }
+
+    public static class StringByteGetter extends ByteGetter {
+        private String rep;
+
+        public StringByteGetter(String rep) {
+            this.rep = rep;
+        }
+
+        public int get(int index) {
+            index *= 2;
+            int high = unhex(rep.charAt(index));
+            int low = unhex(rep.charAt(index + 1));
+            return (high << 4) + low;
+        }
+
+        public static byte unhex(char c) {
+            if (c >= '0' && c <= '9') {
+                return (byte) (c - '0');
+            } else if (c >= 'A' && c <= 'F') {
+                return (byte) (c - 'A'+10);
+            } else if (c >= 'a' && c <= 'f') {
+                return (byte) (c - 'a'+10);
+            } else {
+                throw new IllegalArgumentException("No valid Hex char " + c);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/src/org/postgis/binary/ValueGetter.java b/jdbc2/src/org/postgis/binary/ValueGetter.java
new file mode 100644 (file)
index 0000000..027200c
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * ValueGetter.java
+ * 
+ * Currently, this is not thread safe!
+ * 
+ * (C) 15.01.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
+ * 
+ * $Id$
+ */
+package org.postgis.binary;
+
+public abstract class ValueGetter {
+    ByteGetter data;
+    int position;
+    public final byte endian;
+
+    public ValueGetter(ByteGetter data, byte endian) {
+        this.data = data;
+        this.endian = endian;
+    }
+
+    /**
+     * Get a byte, should be equal for all endians
+     */
+    public byte getByte() {
+        return (byte) data.get(position++);
+    }
+
+    public int getInt() {
+        int res = getInt(position);
+        position += 4;
+        return res;
+    }
+
+    public long getLong() {
+        long res = getLong(position);
+        position += 8;
+        return res;
+    }
+
+    /** Get a 32-Bit integer */
+    protected abstract int getInt(int index);
+
+    /**
+     * Get a long value. This is not needed directly, but as a nice side-effect
+     * from GetDouble.
+     */
+    protected abstract long getLong(int index);
+
+    /**
+     * Get a double.
+     */
+    public double getDouble() {
+        long bitrep = getLong();
+        return Double.longBitsToDouble(bitrep);
+    }
+
+    public static class XDR extends ValueGetter {
+        public static final byte NUMBER = 0;
+
+        public XDR(ByteGetter data) {
+            super(data, NUMBER);
+        }
+
+        protected int getInt(int index) {
+            return (data.get(index) << 24) + (data.get(index + 1) << 16) + (data.get(index + 2) << 8)
+                    + data.get(index + 3);
+        }
+
+        protected long getLong(int index) {
+            return ((long) data.get(index) << 56) + ((long) data.get(index + 1) << 48)
+                    + ((long) data.get(index + 2) << 40) + ((long) data.get(index + 3) << 32)
+                    + ((long) data.get(index + 4) << 24) + ((long) data.get(index + 5) << 16)
+                    + ((long) data.get(index + 6) << 8) + ((long) data.get(index + 7) << 0);
+        }
+    }
+
+    public static class NDR extends ValueGetter {
+        public static final byte NUMBER = 1;
+
+        public NDR(ByteGetter data) {
+            super(data, NUMBER);
+        }
+
+        protected int getInt(int index) {
+            int hg = data.get(index + 3);
+            int high = ((int) hg << 24);
+            int hmed = ((int) data.get(index + 2) << 16);
+            int lmed = ((int) data.get(index + 1) << 8);
+            int low = (int) data.get(index);
+            return high + hmed + lmed + low;
+        }
+
+        protected long getLong(int index) {
+            return ((long) data.get(index + 7) << 56) + ((long) data.get(index + 6) << 48)
+                    + ((long) data.get(index + 5) << 40) + ((long) data.get(index + 4) << 32)
+                    + ((long) data.get(index + 3) << 24) + ((long) data.get(index + 2) << 16)
+                    + ((long) data.get(index + 1) << 8) + ((long) data.get(index) << 0);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdbc2/todo.txt b/jdbc2/todo.txt
new file mode 100644 (file)
index 0000000..f346172
--- /dev/null
@@ -0,0 +1,31 @@
+Todo for PostGIS 1.0 compatible JDBC classes
+
+- Review RADME
+
+- Review Makefile
+
+- Testing
+
+- WKT parsing of M and 4d geometries
+
+- Handling of length() - esp. with modifying the geometries
+
+- Handling of hashCode() - esp. with modifying the geometries
+
+- Test correctness of toString() and getValue() for compatibility reasons
+
+- PGbox3D and newly created PGbox cleanup and tests
+
+- Check whether servertest still works.
+
+- See where the code can be cleaned and leaned.
+
+- Run tests against other PostGIS releases (I did 0.8 and 1.0CVS).
+
+- Evaluate whether and how we should drop ".0" in WKT creation for ordinates 
+  that happen to be integers.
+  
+- Review copyright notices in source files.
+
+- Possibly relicensing under LGPL
+