]> granicus.if.org Git - postgis/commitdiff
JTS binary parser now passes basic regression suite
authorMarkus Schaber <markus@schabi.de>
Wed, 25 May 2005 10:08:56 +0000 (10:08 +0000)
committerMarkus Schaber <markus@schabi.de>
Wed, 25 May 2005 10:08:56 +0000 (10:08 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1729 b70326c6-7e19-0410-871a-916f4a2858ee

jdbc2/Makefile
jdbc2/jtssrc/examples/JtsTestParser.java
jdbc2/jtssrc/org/postgis/jts/JtsBinaryParser.java
jdbc2/jtssrc/org/postgis/jts/JtsBinaryWriter.java
jdbc2/jtssrc/org/postgis/jts/JtsGeometry.java
jdbc2/jtssrc/org/postgis/jts/JtsGisWrapper.java
jdbc2/src/org/postgis/binary/ByteSetter.java
jdbc2/src/org/postgis/binary/ValueSetter.java

index 6f04a4bc4d770a52745b180185886b219db75eb6..ebb1fc04e0afffd72cb997f3da3830ec2e1d32d4 100644 (file)
@@ -133,7 +133,7 @@ VERSIONPATH=$(BUILD)/org/postgis
 VERSIONTARGET=$(VERSIONPATH)/version.properties
 
 # Output redirect for tests
-TESTRD= >>$(TESTOUTPUT) 
+TESTRD?= >>$(TESTOUTPUT) 
 
 # Preliminary jts support - not stable yet!
 JTSDIR=jtssrc
@@ -278,7 +278,7 @@ jtscompile: compile stubcompile $(JTSBUILD) $(SRCCONF) $(JTSSRC)
        touch jtscompile
        
 jtstestoffline: jtscompile     
-       $(JAVA) $(EXEC_ADDCP) "$(JTSPATH)" $(EXAMPLES)/JtsTestParser offline
+       $(JAVA) $(EXEC_ADDCP) "$(JTSPATH)" $(EXAMPLES)/JtsTestParser $(TESTRD) offline
 
 jtstest: jtscompile
        $(JAVA) $(EXEC_ADDCP) "$(JTSPATH)" $(EXAMPLES)/JtsTestParser $(TESTRD) \
index 65fb916c3b9f4f72931cb391a7f84a14a7cb980c..0452efd281597ed9a3d49f94bdea49d0601a538e 100644 (file)
 
 package examples;
 
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.WKTReader;
-
+import org.postgis.binary.ValueSetter;
+import org.postgis.jts.JtsBinaryParser;
+import org.postgis.jts.JtsBinaryWriter;
 import org.postgis.jts.JtsGeometry;
+
 import org.postgresql.util.PGtokenizer;
 
+import com.vividsolutions.jts.geom.Geometry;
+
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.sql.Types;
 
 public class JtsTestParser {
-    final static WKTReader reader = new WKTReader();
+
+    public static String ALL = "ALL", ONLY10 = "ONLY10", EQUAL10 = "EQUAL10";
 
     /**
      * Our set of geometries to test.
      */
-    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", // 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[][] testset = new String[][]{
+        {
+            ALL, // 2D
+            "POINT(10 10)"},
+        {
+            ALL, // 3D with 3rd coordinate set to 0
+            "POINT(10 10 0)"},
+        {
+            ALL, // 3D
+            "POINT(10 10 20)"},
+        {
+            ALL,
+            "MULTIPOINT(11 12, 20 20)"},
+        {
+            ALL,
+            "MULTIPOINT(11 12 13, 20 20 20)"},
+        {
+            ALL,
+            "LINESTRING(10 10,20 20,50 50,34 34)"},
+        {
+            ALL,
+            "LINESTRING(10 10 20,20 20 20,50 50 50,34 34 34)"},
+        {
+            ALL,
+            "POLYGON((10 10,20 10,20 20,20 10,10 10),(5 5,5 6,6 6,6 5,5 5))"},
+        {
+            ALL,
+            "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))"},
+        {
+            ALL,
+            "MULTIPOLYGON(((10 10,20 10,20 20,20 10,10 10),(5 5,5 6,6 6,6 5,5 5)),((10 10,20 10,20 20,20 10,10 10),(5 5,5 6,6 6,6 5,5 5)))"},
+        {
+            ALL,
+            "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)))"},
+        {
+            ALL,
+            "MULTILINESTRING((10 10,20 10,20 20,20 10,10 10),(5 5,5 6,6 6,6 5,5 5))"},
+        {
+            ALL,
+            "MULTILINESTRING((10 10 5,20 10 5,20 20 0,20 10 0,10 10 0),(5 5 0,5 6 0,6 6 0,6 5 0,5 5 0))"},
+        {
+            ALL,
+            "GEOMETRYCOLLECTION(POINT(10 10),POINT(20 20))"},
+        {
+            ALL,
+            "GEOMETRYCOLLECTION(POINT(10 10 20),POINT(20 20 20))"},
+        {
+            ALL,
+            "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))"},
+        {
+            ALL,
+            "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)))"},
+        {
+            ONLY10, // Cannot be parsed by 0.X servers
+            "GEOMETRYCOLLECTION(MULTIPOINT(10 10 10, 20 20 20),MULTIPOINT(10 10 10, 20 20 20))"},
+        {
+            EQUAL10, // PostGIs 0.X "flattens" this geometry, so it is not
+            // equal after reparsing.
+            "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)))"},
+        {
+            EQUAL10,// PostGIs 0.X "flattens" this geometry, so it is not equal
+            // after reparsing.
+            "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))))"},
+        {
+            ALL,
+            "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)))"},
+        {
+            ONLY10, // Collections that contain both X and MultiX do not work on
+            // PostGIS 0.x
+            "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)))"},
+        {
+            ALL,// new (correct) representation
+            "GEOMETRYCOLLECTION EMPTY"},
+    // end
     };
 
     /** The srid we use for the srid tests */
@@ -77,8 +135,11 @@ public class JtsTestParser {
     /** How much tests did fail? */
     public static int failcount = 0;
 
+    private static JtsBinaryParser bp = new JtsBinaryParser();
+    private static final JtsBinaryWriter bw = new JtsBinaryWriter();
+
     /** The actual test method */
-    public static void test(String WKT, Connection[] conns) throws SQLException {
+    public static void test(String WKT, Connection[] conns, String flags) throws SQLException {
         System.out.println("Original:  " + WKT);
         Geometry geom = JtsGeometry.geomFromString(WKT);
         String parsed = geom.toString();
@@ -86,7 +147,7 @@ public class JtsTestParser {
         Geometry regeom = JtsGeometry.geomFromString(parsed);
         String reparsed = regeom.toString();
         System.out.println("Re-Parsed: " + reparsed);
-        if (safeGeomUnequal(geom, regeom)) {
+        if (!geom.equalsExact(regeom)) {
             System.out.println("--- Geometries are not equal!");
             failcount++;
         } else if (!reparsed.equals(parsed)) {
@@ -95,52 +156,222 @@ public class JtsTestParser {
         } else {
             System.out.println("Equals:    yes");
         }
+
+        String hexNWKT = bw.writeHexed(regeom, ValueSetter.NDR.NUMBER);
+        System.out.println("NDRHex:    " + hexNWKT);
+        regeom = JtsGeometry.geomFromString(hexNWKT);
+        System.out.println("ReNDRHex:  " + regeom.toString());
+        if (!geom.equalsExact(regeom)) {
+            System.out.println("--- Geometries are not equal!");
+            failcount++;
+        } else {
+            System.out.println("Equals:    yes");
+        }
+
+        String hexXWKT = bw.writeHexed(regeom, ValueSetter.XDR.NUMBER);
+        System.out.println("XDRHex:    " + hexXWKT);
+        regeom = JtsGeometry.geomFromString(hexXWKT);
+        System.out.println("ReXDRHex:  " + regeom.toString());
+        if (!geom.equalsExact(regeom)) {
+            System.out.println("--- Geometries are not equal!");
+            failcount++;
+        } else {
+            System.out.println("Equals:    yes");
+        }
+
+        byte[] NWKT = bw.writeBinary(regeom, ValueSetter.NDR.NUMBER);
+        regeom = bp.parse(NWKT);
+        System.out.println("NDR:       " + regeom.toString());
+        if (!geom.equalsExact(regeom)) {
+            System.out.println("--- Geometries are not equal!");
+            failcount++;
+        } else {
+            System.out.println("Equals:    yes");
+        }
+
+        byte[] XWKT = bw.writeBinary(regeom, ValueSetter.XDR.NUMBER);
+        regeom = bp.parse(XWKT);
+        System.out.println("XDR:       " + regeom.toString());
+        if (!geom.equalsExact(regeom)) {
+            System.out.println("--- Geometries are not equal!");
+            failcount++;
+        } 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 (safeGeomUnequal(geom, sqlGeom)) {
-                    System.out.println("--- Geometries after SQL are not equal!");
+            Connection connection = conns[i];
+            Statement statement = connection.createStatement();
+            int serverPostgisMajor = TestAutoregister.getPostgisMajor(statement);
+
+            if ((flags == ONLY10) && serverPostgisMajor < 1) {
+                System.out.println("PostGIS server too old, skipping test on connection " + i
+                        + ": " + connection.getCatalog());
+            } else {
+                System.out.println("Testing on connection " + i + ": " + connection.getCatalog());
+                try {
+                    Geometry sqlGeom = viaSQL(WKT, statement);
+                    System.out.println("SQLin    : " + sqlGeom.toString());
+                    if (!geom.equalsExact(sqlGeom)) {
+                        System.out.println("--- Geometries after SQL are not equal!");
+                        if (flags == EQUAL10 && serverPostgisMajor < 1) {
+                            System.out.println("--- This is expected with PostGIS "
+                                    + serverPostgisMajor + ".X");
+                        } else {
+                            failcount++;
+                        }
+                    } else {
+                        System.out.println("Eq SQL in: yes");
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
                     failcount++;
-                } else {
-                    System.out.println("Eq SQL in: yes");
                 }
-            } catch (SQLException e) {
-                System.out.println("--- Server side error: " + e.toString());
-                failcount++;
-            }
 
-            try {
-                Geometry sqlreGeom = viaSQL(parsed, statement);
-                System.out.println("SQLout  :  " + sqlreGeom.toString());
-                if (safeGeomUnequal(geom, sqlreGeom)) {
-                    System.out.println("--- reparsed Geometries after SQL are not equal!");
+                try {
+                    Geometry sqlreGeom = viaSQL(parsed, statement);
+                    System.out.println("SQLout  :  " + sqlreGeom.toString());
+                    if (!geom.equalsExact(sqlreGeom)) {
+                        System.out.println("--- reparsed Geometries after SQL are not equal!");
+                        if (flags == EQUAL10 && serverPostgisMajor < 1) {
+                            System.out.println("--- This is expected with PostGIS "
+                                    + serverPostgisMajor + ".X");
+                        } else {
+                            failcount++;
+                        }
+                    } else {
+                        System.out.println("Eq SQLout: yes");
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+
+                try {
+                    Geometry sqlreGeom = viaPrepSQL(geom, connection);
+                    System.out.println("Prepared:  " + sqlreGeom.toString());
+                    if (!geom.equalsExact(sqlreGeom)) {
+                        System.out.println("--- reparsed Geometries after prepared StatementSQL are not equal!");
+                        if (flags == EQUAL10 && serverPostgisMajor < 1) {
+                            System.out.println("--- This is expected with PostGIS "
+                                    + serverPostgisMajor + ".X");
+                        } else {
+                            failcount++;
+                        }
+                    } else {
+                        System.out.println("Eq Prep: yes");
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+
+                // asEWKT() function is not present on PostGIS 0.X, and the test
+                // is pointless as 0.X uses EWKT as canonical rep so the same
+                // functionality was already tested above.
+                try {
+                    if (serverPostgisMajor >= 1) {
+                        Geometry sqlGeom = ewktViaSQL(WKT, statement);
+                        System.out.println("asEWKT   : " + sqlGeom.toString());
+                        if (!geom.equalsExact(sqlGeom)) {
+                            System.out.println("--- Geometries after EWKT SQL are not equal!");
+                            failcount++;
+                        } else {
+                            System.out.println("equal   : yes");
+                        }
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+
+                // asEWKB() function is not present on PostGIS 0.X.
+                try {
+                    if (serverPostgisMajor >= 1) {
+                        Geometry sqlGeom = ewkbViaSQL(WKT, statement);
+                        System.out.println("asEWKB   : " + sqlGeom.toString());
+                        if (!geom.equalsExact(sqlGeom)) {
+                            System.out.println("--- Geometries after EWKB SQL are not equal!");
+                            failcount++;
+                        } else {
+                            System.out.println("equal    : yes");
+                        }
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+
+                // HexEWKB parsing is not present on PostGIS 0.X.
+                try {
+                    if (serverPostgisMajor >= 1) {
+                        Geometry sqlGeom = viaSQL(hexNWKT, statement);
+                        System.out.println("hexNWKT:   " + sqlGeom.toString());
+                        if (!geom.equalsExact(sqlGeom)) {
+                            System.out.println("--- Geometries after EWKB SQL are not equal!");
+                            failcount++;
+                        } else {
+                            System.out.println("equal    : yes");
+                        }
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+                try {
+                    if (serverPostgisMajor >= 1) {
+                        Geometry sqlGeom = viaSQL(hexXWKT, statement);
+                        System.out.println("hexXWKT:   " + sqlGeom.toString());
+                        if (!geom.equalsExact(sqlGeom)) {
+                            System.out.println("--- Geometries after EWKB SQL are not equal!");
+                            failcount++;
+                        } else {
+                            System.out.println("equal    : yes");
+                        }
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
                     failcount++;
-                } else {
-                    System.out.println("Eq SQLout: yes");
                 }
-            } catch (SQLException e) {
-                System.out.println("--- Server side error: " + e.toString());
-                failcount++;
-            }
 
+                // Canonical binary input is not present before 1.0
+                try {
+                    if (serverPostgisMajor >= 1) {
+                        Geometry sqlGeom = binaryViaSQL(NWKT, connection);
+                        System.out.println("NWKT:      " + sqlGeom.toString());
+                        if (!geom.equalsExact(sqlGeom)) {
+                            System.out.println("--- Geometries after EWKB SQL are not equal!");
+                            failcount++;
+                        } else {
+                            System.out.println("equal    : yes");
+                        }
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+                try {
+                    if (serverPostgisMajor >= 1) {
+                        Geometry sqlGeom = binaryViaSQL(XWKT, connection);
+                        System.out.println("XWKT:      " + sqlGeom.toString());
+                        if (!geom.equalsExact(sqlGeom)) {
+                            System.out.println("--- Geometries after EWKB SQL are not equal!");
+                            failcount++;
+                        } else {
+                            System.out.println("equal    : yes");
+                        }
+                    }
+                } catch (SQLException e) {
+                    System.out.println("--- Server side error: " + e.toString());
+                    failcount++;
+                }
+
+            }
             statement.close();
         }
         System.out.println("***");
     }
 
-    private static boolean safeGeomUnequal(Geometry geom, Geometry regeom) {
-        try {
-            return !geom.equals(regeom);
-        } catch (java.lang.IllegalArgumentException e) {
-            System.out.println(".equals call failed: " + e.getMessage());
-            return false;
-        }
-    }
-
     /** Pass a geometry representation through the SQL server */
     private static Geometry viaSQL(String rep, Statement stat) throws SQLException {
         ResultSet rs = stat.executeQuery("SELECT geometry_in('" + rep + "')");
@@ -148,6 +379,46 @@ public class JtsTestParser {
         return ((JtsGeometry) rs.getObject(1)).getGeometry();
     }
 
+    /**
+     * Pass a geometry representation through the SQL server via prepared
+     * statement
+     */
+    private static Geometry viaPrepSQL(Geometry geom, Connection conn) throws SQLException {
+        PreparedStatement prep = conn.prepareStatement("SELECT ?::geometry");
+        JtsGeometry wrapper = new JtsGeometry(geom);
+        prep.setObject(1, wrapper, Types.OTHER);
+        ResultSet rs = prep.executeQuery();
+        rs.next();
+        JtsGeometry resultwrapper = ((JtsGeometry) rs.getObject(1));
+        return resultwrapper.getGeometry();
+    }
+
+    /** Pass a geometry representation through the SQL server via EWKT */
+    private static Geometry ewktViaSQL(String rep, Statement stat) throws SQLException {
+        ResultSet rs = stat.executeQuery("SELECT asEWKT(geometry_in('" + rep + "'))");
+        rs.next();
+        String resrep = rs.getString(1);
+        return JtsGeometry.geomFromString(resrep);
+    }
+
+    /** Pass a geometry representation through the SQL server via EWKB */
+    private static Geometry ewkbViaSQL(String rep, Statement stat) throws SQLException {
+        ResultSet rs = stat.executeQuery("SELECT asEWKB(geometry_in('" + rep + "'))");
+        rs.next();
+        byte[] resrep = rs.getBytes(1);
+        return bp.parse(resrep);
+    }
+
+    /** Pass a EWKB geometry representation through the server */
+    private static Geometry binaryViaSQL(byte[] rep, Connection conn) throws SQLException {
+        PreparedStatement prep = conn.prepareStatement("SELECT ?::bytea::geometry");
+        prep.setBytes(1, rep);
+        ResultSet rs = prep.executeQuery();
+        rs.next();
+        JtsGeometry resultwrapper = ((JtsGeometry) rs.getObject(1));
+        return resultwrapper.getGeometry();
+    }
+
     /**
      * Connect to the databases
      * 
@@ -156,21 +427,23 @@ public class JtsTestParser {
      * 
      * @param dbuser
      * 
-     * @throws ClassNotFoundException
-     * 
      * @see org.postgis.DriverWrapper
      * 
      */
-    public static Connection connect(String url, String dbuser, String dbpass) throws SQLException,
-            ClassNotFoundException {
+    public static Connection connect(String url, String dbuser, String dbpass) throws SQLException {
         Connection conn;
-        Class.forName("org.postgis.jts.JtsWrapper");
         conn = DriverManager.getConnection(url, dbuser, dbpass);
         return conn;
     }
 
+    public static void loadDrivers() throws ClassNotFoundException {
+        Class.forName("org.postgis.jts.JtsWrapper");
+    }
+
     /** Our apps entry point */
     public static void main(String[] args) throws SQLException, ClassNotFoundException {
+        loadDrivers();
+
         PGtokenizer dburls;
         String dbuser = null;
         String dbpass = null;
@@ -185,8 +458,8 @@ public class JtsTestParser {
             dbuser = args[1];
             dbpass = args[2];
         } else {
-            System.err.println("Usage: java examples/JtsTestParser dburls user pass [tablename]");
-            System.err.println("   or: java examples/JtsTestParser offline");
+            System.err.println("Usage: java examples/TestParser dburls user pass [tablename]");
+            System.err.println("   or: java examples/TestParser offline");
             System.err.println();
             System.err.println("dburls has one or more jdbc urls separated by ; in the following format");
             System.err.println("jdbc:postgresql://HOST:PORT/DATABASENAME");
@@ -207,8 +480,8 @@ public class JtsTestParser {
         System.out.println("***");
 
         for (int i = 0; i < testset.length; i++) {
-            test(testset[i], conns);
-            test(SRIDPREFIX + testset[i], conns);
+            test(testset[i][1], conns, testset[i][0]);
+            test(SRIDPREFIX + testset[i][1], conns, testset[i][0]);
         }
 
         System.out.print("cleaning up...");
@@ -216,7 +489,8 @@ public class JtsTestParser {
             conns[i].close();
         }
 
-        // System.out.println("Finished.");
         System.out.println("Finished, " + failcount + " tests failed!");
+        System.err.println("Finished, " + failcount + " tests failed!");
+        System.exit(failcount);
     }
 }
index cb21c4f99735013840a6530a21760641331aea63..4818d9f6d9bfc40e67c6ac38a3bc94606ca9d3fd 100644 (file)
@@ -58,7 +58,7 @@ import org.postgis.binary.ByteGetter.StringByteGetter;
  *  
  */
 public class JtsBinaryParser {
-    final static GeometryFactory geofac = new GeometryFactory();
+    protected final GeometryFactory geofac = new GeometryFactory();
 
     /**
      * Get the appropriate ValueGetter for my endianness
@@ -118,6 +118,7 @@ public class JtsBinaryParser {
         if (haveS) {
             srid = data.getInt();
         }
+        
         Geometry result1;
         switch (realtype) {
         case org.postgis.Geometry.POINT :
index 099bbc463b2ab21d116dc2f5e852e099b120b9a2..0f64a897bfd172d6a5aa4c92f31fbd88b20fc287 100644 (file)
@@ -38,7 +38,7 @@ import org.postgis.binary.ValueSetter;
 
 /**
  * Create binary representation of geometries. Currently, only text rep (hexed)
- * implementation is tested.
+ * implementation is tested. Supports only 2 dimensional geometries.
  * 
  * It should be easy to add char[] and CharSequence ByteGetter instances,
  * although the latter one is not compatible with older jdks.
@@ -114,29 +114,29 @@ public class JtsBinaryWriter {
 
     /** Parse a geometry starting at offset. */
     protected void writeGeometry(Geometry geom, ValueSetter dest) {
-        if (geom.getDimension() < 2 || geom.getDimension() > 4) {
-            throw new IllegalArgumentException("Unsupported geometry dimensionality: "
-                    + geom.getDimension());
+        final int dimension = getCoordDim(geom);
+        if (dimension < 2 || dimension > 4) {
+            throw new IllegalArgumentException("Unsupported geometry dimensionality: " + dimension);
         }
         // write endian flag
         dest.setByte(dest.endian);
 
         // write typeword
-        int plaintype = getWKBType(geom);
+        final int plaintype = getWKBType(geom);
         int typeword = plaintype;
-        if (geom.getDimension() == 3 || geom.getDimension() == 4) {
-            typeword &= 0x80000000;
+        if (dimension == 3 || dimension == 4) {
+            typeword |= 0x80000000;
         }
-        if (geom.getDimension() == 4) {
-            typeword &= 0x40000000;
+        if (dimension == 4) {
+            typeword |= 0x40000000;
         }
-        if (geom.getSRID() != -1) {
-            typeword &= 0x20000000;
+        if (checkSrid(geom)) {
+            typeword |= 0x20000000;
         }
 
         dest.setInt(typeword);
 
-        if (geom.getSRID() != -1) {
+        if (checkSrid(geom)) {
             dest.setInt(geom.getSRID());
         }
 
@@ -193,7 +193,7 @@ public class JtsBinaryWriter {
      * ordinates and measure. Used by writeGeometry.
      */
     private void writePoint(Point geom, ValueSetter dest) {
-        writeCoordinates(geom.getCoordinateSequence(), geom.getDimension(), dest);
+        writeCoordinates(geom.getCoordinateSequence(), getCoordDim(geom), dest);
     }
 
     /**
@@ -219,7 +219,8 @@ public class JtsBinaryWriter {
     }
 
     private void writeLineString(LineString geom, ValueSetter dest) {
-        writeCoordinates(geom.getCoordinateSequence(), geom.getDimension(), dest);
+        dest.setInt(geom.getNumPoints());
+        writeCoordinates(geom.getCoordinateSequence(), getCoordDim(geom), dest);
     }
 
     private void writePolygon(Polygon geom, ValueSetter dest) {
@@ -231,25 +232,24 @@ public class JtsBinaryWriter {
     }
 
     private void writeMultiLineString(MultiLineString geom, ValueSetter dest) {
-        dest.setInt(geom.getNumGeometries());
-        for (int i = 0; i < geom.getNumGeometries(); i++) {
-            writeLineString((LineString) geom.getGeometryN(i), dest);
-        }
+        writeGeometryArray(geom, dest);
     }
 
     private void writeMultiPolygon(MultiPolygon geom, ValueSetter dest) {
-        dest.setInt(geom.getNumGeometries());
-        for (int i = 0; i < geom.getNumGeometries(); i++) {
-            writePolygon((Polygon) geom.getGeometryN(i), dest);
-        }
+        writeGeometryArray(geom, dest);
     }
 
     private void writeCollection(GeometryCollection geom, ValueSetter dest) {
+        writeGeometryArray(geom, dest);
+    }
+    
+    private void writeGeometryArray(Geometry geom, ValueSetter dest) {
         dest.setInt(geom.getNumGeometries());
         for (int i = 0; i < geom.getNumGeometries(); i++) {
             writeGeometry(geom.getGeometryN(i), dest);
         }
     }
+    
 
     /** Estimate how much bytes a geometry will need in WKB. */
     protected int estimateBytes(Geometry geom) {
@@ -261,7 +261,7 @@ public class JtsBinaryWriter {
         // write typeword
         result += 4;
 
-        if (geom.getSRID() != -1) {
+        if (checkSrid(geom)) {
             result += 4;
         }
 
@@ -293,8 +293,15 @@ public class JtsBinaryWriter {
         return result;
     }
 
+    private boolean checkSrid(Geometry geom) {
+        final int srid = geom.getSRID();
+        // SRID is default 0 with jts geometries
+        final boolean result = srid != -1 && srid != 0;
+        return result;
+    }
+
     private int estimatePoint(Point geom) {
-        return 8 * geom.getDimension();
+        return 8*getCoordDim(geom);
     }
 
     /** Write an Array of "full" Geometries */
@@ -338,9 +345,11 @@ public class JtsBinaryWriter {
     }
 
     private int estimateLineString(LineString geom) {
-        return estimatePointArray(geom.getNumGeometries(), (Point) (geom.getNumGeometries() > 0
-                ? geom.getGeometryN(0)
-                : null));
+        if (geom == null || geom.getNumGeometries() == 0) {
+            return 0;
+        } else {
+            return estimatePointArray(geom.getNumPoints(), geom.getStartPoint());
+        }
     }
 
     private int estimatePolygon(Polygon geom) {
@@ -367,4 +376,14 @@ public class JtsBinaryWriter {
         // 4-byte count + subgeometries
         return 4 + estimateGeometryArray(geom);
     }
+
+    public static final int getCoordDim(Geometry geom) {
+        // TODO: Fix geometries with more dimensions
+        //geom.getFactory().getCoordinateSequenceFactory()
+        if (geom == null) {
+            return 0;
+        } else {
+            return 2;
+        }
+    }
 }
index 5407be11db8cb6602c34654bc2f62ac06e389b7b..fd068a56769f79a38c100dddd8da227b4760a8de 100644 (file)
@@ -33,7 +33,8 @@ import org.postgresql.util.PGobject;
 import java.sql.SQLException;
 
 /**
- * JTS Geometry SQL wrapper
+ * JTS Geometry SQL wrapper. Supports PostGIS 1.x (lwgeom hexwkb) for writing
+ * and both PostGIS 0.x (EWKT) and 1.x (lwgeom hexwkb) for reading.
  * 
  * @author Markus Schaber
  */
@@ -46,6 +47,7 @@ public class JtsGeometry extends PGobject {
 
     final static WKTReader reader = new WKTReader();
     final static JtsBinaryParser bp = new JtsBinaryParser();
+    final static JtsBinaryWriter bw = new JtsBinaryWriter();
 
     /** Constructor called by JDBC drivers */
     public JtsGeometry() {
@@ -99,7 +101,7 @@ public class JtsGeometry extends PGobject {
     }
 
     public String getValue() {
-        return geom.toString();
+        return bw.writeHexed(getGeometry());
     }
 
     public Object clone() {
index cfeaf6373bbe94f90a457fc256638a8dfb32af83..bee777489f5525ae11497234f9741beda32d136e 100644 (file)
@@ -40,7 +40,7 @@ import java.util.Properties;
  * This method currently works with J2EE DataSource implementations, and with
  * DriverManager framework.
  * 
- * Simply replace the "jdbc:postgresql:" with a "jdbc:postgresql_postGIS" in the
+ * Simply replace the "jdbc:postgresql:" with a "jdbc:postgresql_JTS" in the
  * jdbc URL.
  * 
  * @author markus.schaber@logix-tt.com
index a0b5320c9978d430ae486d4fe437e62aed3490bf..e5d8d7707a71f3674590d75cd8562a21ba7c7ab3 100644 (file)
@@ -46,6 +46,14 @@ public abstract class ByteSetter {
         public byte[] result() {
             return array;
         }
+        
+        public String toString() {
+            char[] arr = new char[array.length];
+            for (int i=0; i<array.length; i++) {
+                arr[i] = (char)(array[i]&0xFF);
+            }
+            return new String(arr);
+        }
     }
 
     public static class StringByteSetter extends ByteSetter {
@@ -69,5 +77,9 @@ public abstract class ByteSetter {
         public String result() {
             return new String(rep);
         }
+        
+        public String toString() {
+            return new String(rep);
+        }
     }
 }
index 8a8d552bcd5490e1e0cce63ae45aab884a24a5ff..c3109cebacf8be3e5a8ce32823ff39bb4a6bd7a9 100644 (file)
@@ -69,6 +69,11 @@ public abstract class ValueSetter {
         setLong(bitrep);
     }
 
+    public String toString() {
+        String[] buff = getClass().getName().split("\\.");
+        return buff[buff.length-1]+"('"+(data==null?"NULL":data.toString()+"')");
+    }
+    
     public static class XDR extends ValueSetter {
         public static final byte NUMBER = 0;