PGPASS?=guess
SRC= $(SRCDIR)/examples/Test.java \
+ $(SRCDIR)/examples/TestBoxes.java \
$(SRCDIR)/examples/TestParser.java \
$(SRCDIR)/examples/TestServer.java \
$(SRCDIR)/org/postgis/ComposedGeom.java \
$(SRCDIR)/org/postgis/MultiLineString.java \
$(SRCDIR)/org/postgis/MultiPoint.java \
$(SRCDIR)/org/postgis/MultiPolygon.java \
+ $(SRCDIR)/org/postgis/PGbox2d.java \
$(SRCDIR)/org/postgis/PGbox3d.java \
- $(SRCDIR)/org/postgis/PGbox.java \
$(SRCDIR)/org/postgis/PGgeometry.java \
$(SRCDIR)/org/postgis/PointComposedGeom.java \
$(SRCDIR)/org/postgis/Point.java \
all: jar \
- test
+ offlinetests
jar: compile
$(JAR) -cf postgis.jar -C $(BUILD) . -C $(SRCDIR) org/postgresql/postgresql.properties README
ptest: compile
$(JAVA) -classpath "$(BUILD):$(CP)" $(EXAMPLES)/TestParser jdbc:postgresql_postGIS://$(PGHOST):$(PGPORT)/$(PGDATABASE) $(PGUSER) $(PGPASS)
+boxtestoffline: compile
+ $(JAVA) -classpath "$(BUILD):$(CP)" $(EXAMPLES)/TestBoxes offline
+
+boxtest: compile
+ $(JAVA) -classpath "$(BUILD):$(CP)" $(EXAMPLES)/TestBoxes jdbc:postgresql_postGIS://$(PGHOST):$(PGPORT)/$(PGDATABASE) $(PGUSER) $(PGPASS)
+
+offlinetests: boxtestoffline ptestoffline test
+
+onlinetests: boxtest ptest jtest
+
+# boxtest and ptest include boxtestoffline and ptestoffline, so we only need
+# to run test in addition to the onlinetests
+alltests: onlinetests test
+
clean:
$(DELETE) $(BUILD) bin postgis.jar postgis_debug.jar compile
--- /dev/null
+/*
+ * 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.PGbox2d;
+import org.postgis.PGbox3d;
+import org.postgresql.util.PGobject;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class TestBoxes {
+
+ /** Our test candidates: */
+ public static final String[] BOXEN3D = new String[]{
+ "BOX3D(1 2 3,4 5 6)", //3d variant
+ "BOX3D(1 2,4 5)"// 2d variant
+ };
+ public static final String[] BOXEN2D = new String[]{"BOX(1 2,3 4)"};
+
+ /** The srid we use for the srid tests */
+ public static final int SRID = 4326;
+
+ /** The string prefix we get for the srid tests */
+ public static final String SRIDPREFIX = "SRID=" + SRID + ";";
+
+ /** How much tests did fail? */
+ public static int failcount = 0;
+
+ /** The actual test method */
+ public static void test(String orig, PGobject candidate, Connection[] conns)
+ throws SQLException {
+
+ System.out.println("Original: " + orig);
+ String redone = candidate.toString();
+ System.out.println("Parsed: " + redone);
+
+ if (!orig.equals(redone)) {
+ System.out.println("--- Recreated Text Rep not equal!");
+ failcount++;
+ }
+
+ // Let's simulate the way pgjdbc uses to create PGobjects
+ PGobject recreated;
+ try {
+ recreated = (PGobject) candidate.getClass().newInstance();
+ } catch (Exception e) {
+ System.out.println("--- pgjdbc instantiation failed!");
+ System.out.println("--- " + e.getMessage());
+ failcount++;
+ return;
+ }
+ recreated.setValue(redone);
+
+ String reparsed = recreated.toString();
+ System.out.println("Re-Parsed: " + reparsed);
+ if (!recreated.equals(candidate)) {
+ System.out.println("--- Recreated boxen are not equal!");
+ failcount++;
+ } else if (!reparsed.equals(orig)) {
+ System.out.println("--- 2nd generation text reps 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 {
+ PGobject sqlGeom = viaSQL(candidate, statement);
+ System.out.println("SQLin : " + sqlGeom.toString());
+ if (!candidate.equals(sqlGeom)) {
+ System.out.println("--- Geometries after SQL are not equal!");
+ failcount++;
+ } else {
+ System.out.println("Eq SQL in: yes");
+ }
+ } catch (SQLException e) {
+ System.out.println("--- Server side error: " + e.toString());
+ failcount++;
+ }
+
+ try {
+ PGobject sqlreGeom = viaSQL(recreated, statement);
+ System.out.println("SQLout : " + sqlreGeom.toString());
+ if (!candidate.equals(sqlreGeom)) {
+ System.out.println("--- reparsed Geometries after SQL are not equal!");
+ failcount++;
+ } else {
+ System.out.println("Eq SQLout: yes");
+ }
+ } catch (SQLException e) {
+ System.out.println("--- Server side error: " + e.toString());
+ failcount++;
+ }
+ statement.close();
+ }
+ System.out.println("***");
+ }
+
+ /** Pass a geometry representation through the SQL server */
+ private static PGobject viaSQL(PGobject obj, Statement stat) throws SQLException {
+ ResultSet rs = stat.executeQuery("SELECT '" + obj.toString() + "'::" + obj.getType());
+ rs.next();
+ return (PGobject) rs.getObject(1);
+ }
+
+ /**
+ * Connect to the databases
+ *
+ * We use DriverWrapper here. For alternatives, see the DriverWrapper
+ * Javadoc
+ *
+ * @param dbuser
+ *
+ * @throws ClassNotFoundException
+ *
+ * @see org.postgis.DriverWrapper
+ *
+ */
+ public static Connection connect(String url, String dbuser, String dbpass) throws SQLException,
+ ClassNotFoundException {
+ Connection conn;
+ Class.forName("org.postgis.DriverWrapper");
+ conn = DriverManager.getConnection(url, dbuser, dbpass);
+ return conn;
+ }
+
+ /** Our apps entry point */
+ public static void main(String[] args) throws SQLException, ClassNotFoundException {
+ String[] dburls;
+ String dbuser = null;
+ String dbpass = null;
+
+ if (args.length == 1 && args[0].equalsIgnoreCase("offline")) {
+ System.out.println("Performing only offline tests");
+ dburls = new String[0];
+ } else if (args.length == 3) {
+ System.out.println("Performing offline and online tests");
+ dburls = args[0].split(";");
+ dbuser = args[1];
+ dbpass = args[2];
+ } else {
+ 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");
+ System.err.println("tablename is 'jdbc_test' by default.");
+ System.exit(1);
+ // Signal the compiler that code flow ends here.
+ throw new AssertionError();
+ }
+
+ Connection[] conns;
+ conns = new Connection[dburls.length];
+ for (int i = 0; i < dburls.length; i++) {
+ System.out.println("Creating JDBC connection to " + dburls[i]);
+ conns[i] = connect(dburls[i], dbuser, dbpass);
+ }
+
+ System.out.println("Performing tests...");
+ System.out.println("***");
+
+ for (int i = 0; i < BOXEN3D.length; i++) {
+ try {
+ PGbox3d candidate = new PGbox3d(BOXEN3D[i]);
+ test(BOXEN3D[i], candidate, conns);
+ } catch (SQLException e) {
+ System.out.println("--- Instantiation of " + BOXEN3D[i] + "failed:");
+ System.out.println("--- " + e.getMessage());
+ failcount++;
+ }
+ }
+
+ for (int i = 0; i < BOXEN2D.length; i++) {
+ try {
+ PGbox2d candidate = new PGbox2d(BOXEN2D[i]);
+ test(BOXEN2D[i], candidate, conns);
+ } catch (SQLException e) {
+ System.out.println("--- Instantiation of " + BOXEN2D[i] + "failed:");
+ System.out.println("--- " + e.getMessage());
+ failcount++;
+ }
+ }
+
+ System.out.print("cleaning up...");
+ for (int i = 0; i < conns.length; i++) {
+ conns[i].close();
+ }
+
+ //System.out.println("Finished.");
+ System.out.println("Finished, " + failcount + " tests failed!");
+ }
+}
\ No newline at end of file
// 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");
+ pgconn.addDataType("box2d", "org.postgis.PGbox2d");
+
// 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);
+ //pgconn.addDataType("box2d", org.postgis.PGbox2d.class);
}
/**
--- /dev/null
+package org.postgis;
+
+import java.sql.SQLException;
+
+public class PGbox2d extends PGboxbase {
+
+ public PGbox2d() {
+ super();
+ }
+
+ public PGbox2d(Point llb, Point urt) {
+ super(llb, urt);
+ }
+
+ public PGbox2d(String value) throws SQLException {
+ super(value);
+ }
+
+ public void setValue(String value) throws SQLException {
+ super.setValue(value);
+
+ if (llb.dimension!=2 || urt.dimension!=2) {
+ throw new SQLException("PGbox2d is only allowed to have 2 dimensions!");
+ }
+ }
+
+ public String getPrefix() {
+ return "BOX";
+ }
+
+ public String getPGtype() {
+ return "box2d";
+ }
+
+ protected PGboxbase newInstance() {
+ return new PGbox2d();
+ }
+}
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 class PGbox3d extends PGboxbase {
public PGbox3d() {
- // do nothing.
+ super();
}
public PGbox3d(Point llb, Point urt) {
- this.llb = llb;
- this.urt = urt;
+ super(llb, 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() + ")";
+ super(value);
}
- public String toString() {
- return getValue();
+ public String getPrefix() {
+ return ("BOX3D");
}
- public Object clone() {
- PGbox3d obj = new PGbox3d(llb, urt);
- obj.setType(type);
- return obj;
+ public String getPGtype() {
+ return ("box3d");
}
- /** Returns the lower left bottom corner of the box as a Point object */
- public Point getLLB() {
- return llb;
+ protected PGboxbase newInstance() {
+ return new PGbox3d();
}
-
- /** Returns the upper right top corner of the box as a Point object */
- public Point getURT() {
- return urt;
- }
-
-}
\ No newline at end of file
+}
--- /dev/null
+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 abstract class PGboxbase extends PGobject {
+
+ /**
+ * The lower left bottom corner of the box.
+ */
+ protected Point llb;
+
+ /**
+ * The upper right top corner of the box.
+ */
+ protected Point urt;
+
+ /**
+ * The Prefix we have in WKT rep.
+ *
+ * I use an abstract method here so we do not need to replicate the String
+ * object in every instance.
+ *
+ */
+ public abstract String getPrefix();
+
+ /**
+ * The Postgres type we have (same construct as getPrefix())
+ */
+ public abstract String getPGtype();
+
+ public PGboxbase() {
+ this.setType(getPGtype());
+ }
+
+ public PGboxbase(Point llb, Point urt) {
+ this();
+ this.llb = llb;
+ this.urt = urt;
+ }
+
+ public PGboxbase(String value) throws SQLException {
+ this();
+ setValue(value);
+ }
+
+ public void setValue(String value) throws SQLException {
+ int srid = -1;
+ value = value.trim();
+ if (value.startsWith("SRID=")) {
+ String[] temp = value.split(";", 2);
+ value = temp[1].trim();
+ srid = Integer.parseInt(temp[0].substring(5));
+ }
+ if (value.startsWith(getPrefix())) {
+ value = value.substring(getPrefix().length());
+ }
+ PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value.trim()), ',');
+ llb = new Point(t.getToken(0));
+ urt = new Point(t.getToken(1));
+ if (srid != -1) {
+ llb.setSrid(srid);
+ urt.setSrid(srid);
+ }
+ }
+
+ public String getValue() {
+ StringBuffer sb = new StringBuffer();
+ outerWKT(sb);
+ return sb.toString();
+ }
+
+ private void outerWKT(StringBuffer sb) {
+ sb.append(getPrefix());
+ sb.append('(');
+ llb.innerWKT(sb);
+ sb.append(',');
+ urt.innerWKT(sb);
+ sb.append(')');
+ }
+
+ /**
+ * Unlike geometries, toString() does _not_ contain the srid, as server-side
+ * PostGIS cannot parse this.
+ */
+ public String toString() {
+ return getValue();
+ }
+
+ /** 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;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof PGboxbase) {
+ PGboxbase otherbox = (PGboxbase) other;
+ return (compareLazyDim(this.llb, otherbox.llb) && compareLazyDim(this.urt, otherbox.urt));
+ }
+ return false;
+ }
+
+ /**
+ * Compare two coordinates with lazy dimension checking.
+ *
+ * As the Server always returns Box3D with three dimensions, z==0 equals
+ * dimensions==2
+ *
+ */
+ protected static boolean compareLazyDim(Point first, Point second) {
+ return first.x == second.x
+ && first.y == second.y
+ && (((first.dimension == 2 || first.z == 0.0) && (second.dimension == 2 || second.z == 0)) || (first.z == second.z));
+ }
+
+ public Object clone() {
+ PGboxbase obj = newInstance();
+ obj.llb = this.llb;
+ obj.urt = this.urt;
+ obj.setType(type);
+ return obj;
+ }
+
+ /**
+ * We could have used this.getClass().newInstance() here, but this forces us
+ * dealing with InstantiationException and IllegalAccessException. Due to
+ * the PGObject.clone() brokennes that does not allow clone() to throw
+ * CloneNotSupportedException, we cannot even pass this exceptions down to
+ * callers in a sane way.
+ */
+ protected abstract PGboxbase newInstance();
+}