Index: Geometry.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/Geometry.java,v
retrieving revision 1.2
diff -u -r1.2 Geometry.java
--- Geometry.java	8 Aug 2001 05:25:10 -0000	1.2
+++ Geometry.java	9 Dec 2004 15:10:14 -0000
@@ -1,67 +1,113 @@
 package org.postgis;
 
-public class Geometry 
-{
+import java.io.Serializable;
 
-	/**
+/** The base class of all geometries */
+public class Geometry implements Serializable {
+    public int hashCode() {
+        return dimension | (type * 4);
+    }
+
+    public boolean equals(Object other) {
+        return (other instanceof Geometry) && equals((Geometry) other);
+    }
+
+    public boolean equals(Geometry other) {
+        return ((dimension == other.dimension) && (type == other.type) && (this.hashCode()==other.hashCode()) && (this.numPoints() == other.numPoints()));
+    }
+
+    public int numPoints() {
+        return 0;
+    }
+
+    public Point getFirstPoint() {
+        return null;
+    }
+    public Point getLastPoint() {
+        return null;
+    }
+
+    /**
 	 * The dimensionality of this feature (2,3)
 	 */
-	public int dimension;
-	
-	/**
+    public int dimension;
+
+    /**
 	 * The OGIS geometry type of this feature.
 	 */
-	public int type;
+    public int type;
 
-	/**
+    /**
 	 * The OGIS geometry type number for points.
 	 */
-	public static final int POINT = 1;
+    public static final int POINT = 1;
 
-	/**
+    /**
 	 * The OGIS geometry type number for lines.
 	 */
-	public static final int LINESTRING = 2;
+    public static final int LINESTRING = 2;
 
-	/**
+    /**
 	 * The OGIS geometry type number for polygons.
 	 */
-	public static final int POLYGON = 3;
+    public static final int POLYGON = 3;
 
-	/**
+    /**
 	 * The OGIS geometry type number for aggregate points.
 	 */
-	public static final int MULTIPOINT = 4;
+    public static final int MULTIPOINT = 4;
 
-	/**
+    /**
 	 * The OGIS geometry type number for aggregate lines.
 	 */
-	public static final int MULTILINESTRING = 5;
+    public static final int MULTILINESTRING = 5;
 
-	/**
+    /**
 	 * The OGIS geometry type number for aggregate polygons.
 	 */
-	public static final int MULTIPOLYGON = 6;
-	
-	/**
+    public static final int MULTIPOLYGON = 6;
+
+    /**
 	 * The OGIS geometry type number for feature collections.
-	 * Feature collections are not currently supported by the
-	 * backend.
 	 */
-	public static final int GEOMETRYCOLLECTION = 7;
-	
-	/**
+    public static final int GEOMETRYCOLLECTION = 7;
+
+    /**
 	 * @return The OGIS geometry type number of this geometry.
 	 */
-	public int getType() {
-		return type;
-	}
-	
-	/**
+    public int getType() {
+        return type;
+    }
+
+    public static String getTypeString(int type) {
+        switch (type) {
+            case 1 :
+                return "POINT";
+            case 2 :
+                return "LINESTRING";
+            case 3 :
+                return "POLYGON";
+            case 4 :
+                return "MULTIPOINT";
+            case 5 :
+                return "MULTILINESTRING";
+            case 6 :
+                return "MULTIPOLYGON";
+            case 7 :
+                return "GEOMETRYCOLLECTION";
+            default :
+                throw new IllegalArgumentException("Unknown Geometry type");
+        }
+    }
+
+    public String getTypeString() {
+        return getTypeString(this.type);
+    }
+    /**
 	 * @return The dimensionality (eg, 2D or 3D) of this geometry.
 	 */
-	public int getDimension() {
-		return dimension;
-	}
+    public int getDimension() {
+        return dimension;
+    }
 
 }
Index: GeometryFactory.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/GeometryFactory.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 GeometryFactory.java
--- GeometryFactory.java	22 Jun 2001 17:39:30 -0000	1.1.1.1
+++ GeometryFactory.java	9 Dec 2004 15:10:14 -0000
@@ -2,11 +2,28 @@
 
 public class GeometryFactory {
 
-	public static byte[] Geometry2WKB(Geometry geom) {}
+	/**TODO: create function!
+	 * @param geom
+	 * @return
+	 */
+	public static byte[] Geometry2WKB(Geometry geom) {
+		return null;
+	}
 
-	public static Geometry WKB2Geometry(byte[] wkb) {}
+	/**TODO: create function!
+	 * @param wkb
+	 * @return
+	 */
+	public static Geometry WKB2Geometry(byte[] wkb) {
+		return null;
+	}
 
-	public static Geometry WKS2Geometry(String wks) {}
+	/**TODO: create function!
+	 * @param wks
+	 * @return
+	 */
+	public static Geometry WKS2Geometry(String wks) {
+		return null;
+	}
 
 }
-
Index: LineString.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/LineString.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 LineString.java
--- LineString.java	22 Jun 2001 17:39:30 -0000	1.1.1.1
+++ LineString.java	9 Dec 2004 15:10:15 -0000
@@ -1,75 +1,137 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
-import java.util.*;
-
-
-public class LineString extends Geometry 
-{
-
-	Point[] points;
-	
-	public LineString() 
-	{
-		type = LINESTRING;
-	}
-
-	public LineString(Point[] points) 
-	{
-		this();
-		this.points = points;
-		dimension = points[0].dimension;
-	}
-	
-	public LineString(String value) throws SQLException
-	{
-		this();
-		value = value.trim();
-		if ( value.indexOf("LINESTRING") == 0 ) 
-		{
-			value = value.substring(10).trim();
-		}
-		PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value),',');
-		int npoints = t.getSize();
-		points = new Point[npoints];
-		for( int p = 0; p < npoints; p++)
-		{
-			points[p] = new Point(t.getToken(p));
-		}
-		dimension = points[0].dimension;
-	}
-	
-	public String toString() 
-	{
-		return "LINESTRING " + getValue();
-	}
-
-	public String getValue() 
-	{
-		StringBuffer b = new StringBuffer("(");
-		for( int p = 0; p < points.length; p++ )
-		{
-			if( p > 0 ) b.append(",");
-			b.append(points[p].getValue());
-		}
-		b.append(")");
-		return b.toString();
-	}
-	
-	public int numPoints() 
-	{
-		return points.length;
-	}
-	
-	public Point getPoint(int idx)
-	{
-		if ( idx >= 0 & idx < points.length ) {
-			return points[idx];
-		}
-		else {
-			return null;
-		}
-	}
+import java.sql.SQLException;
+
+import org.postgresql.util.PGtokenizer;
+
+public class LineString extends Geometry {
+
+    Point[] points;
+    double len = -1.;
+    boolean nohash=true; int hashcode=0;
+
+    public LineString() {
+        type = LINESTRING;
+    }
+
+    public int hashCode() {
+        if (nohash) {
+            hashcode = super.hashCode() ^ points.hashCode();
+            nohash=false;
+        }
+        return hashcode;
+    }
+
+    public LineString(Point[] points) {
+        this();
+        this.points = points;
+        dimension = points[0].dimension;
+    }
+
+    public boolean equals(Geometry other) {
+        return (other instanceof LineString) && super.equals(other)
+                && (this.points.equals(((LineString) other).points));
+    }
+
+    public LineString reverse() {
+        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) {
+        boolean cutPoint = this.getLastPoint()==null || this.getLastPoint().equals(other.getFirstPoint());
+        int len = this.points.length + other.points.length - (cutPoint ? 1 : 0);
+        int i, j;
+        Point[] p = new Point[len];
+        for (i = 0; i < this.points.length; i++) {
+            p[i] = this.points[i];
+        }
+        if (!cutPoint) {
+            p[i++] = other.getFirstPoint();
+        }
+        for (j = 1; j < other.points.length; j++, i++) {
+            p[i] = other.points[j];
+        }
+        return new LineString(p);
+    }
+
+    public Point getFirstPoint() {
+        if ((points != null) && (points.length > 0)) {
+            return points[0];
+        } else
+            return null;
+    }
+    public Point getLastPoint() {
+        if ((points != null) && (points.length > 0)) {
+            return points[points.length - 1];
+        } else
+            return null;
+    }
+
+    public double length() {
+        if (len < 0) {
+            if ((this.points == null) || (this.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;
+    }
+
+    public LineString(String value) throws SQLException {
+        this();
+        value = value.trim();
+        if (value.indexOf("LINESTRING") == 0) {
+            value = value.substring(10).trim();
+        }
+        PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(value), ',');
+        int npoints = t.getSize();
+        points = new Point[npoints];
+        for (int p = 0; p < npoints; p++) {
+            points[p] = new Point(t.getToken(p));
+        }
+        dimension = points[0].dimension;
+    }
+
+    public String toString() {
+        return "LINESTRING " + getValue();
+    }
+
+    public String getValue() {
+        StringBuffer b = new StringBuffer("(");
+        for (int p = 0; p < points.length; p++) {
+            if (p > 0)
+                b.append(",");
+            b.append(points[p].getValue());
+        }
+        b.append(")");
+        return b.toString();
+    }
+
+    public int numPoints() {
+        return points.length;
+    }
+
+    public Point getPoint(int idx) {
+        if (idx >= 0 & idx < points.length) {
+            return points[idx];
+        } else {
+            return null;
+        }
+    }
+
+    public Point[] getPoints() {
+        return points;
+    }
 
 }
Index: LinearRing.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/LinearRing.java,v
retrieving revision 1.2
diff -u -r1.2 LinearRing.java
--- LinearRing.java	6 Sep 2002 20:29:50 -0000	1.2
+++ LinearRing.java	9 Dec 2004 15:10:15 -0000
@@ -1,8 +1,8 @@
 package org.postgis;
 
-import java.io.*;
-import java.sql.*;
-import org.postgresql.util.*;
+import java.sql.SQLException;
+
+import org.postgresql.util.PGtokenizer;
 
 /** 
  * This represents the LinearRing GIS datatype. This type is used to 
@@ -23,6 +23,17 @@
 		dimension = points[0].dimension;
 	}
 
+	public Point getFirstPoint() {
+		if ((points != null) && (points.length>0)) {
+			return points[0];
+		} else return null;
+	}
+	public Point getLastPoint() {
+		if ((points != null) && (points.length>0)) {
+			return points[points.length-1];
+		} else return null;
+	}
+	
 	/**
 	 * This is called to construct a LinearRing from the 
 	 * PostGIS string representation of a ring.
Index: MultiLineString.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/MultiLineString.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 MultiLineString.java
--- MultiLineString.java	22 Jun 2001 17:39:30 -0000	1.1.1.1
+++ MultiLineString.java	9 Dec 2004 15:10:15 -0000
@@ -1,76 +1,110 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
-import java.util.*;
-
-
-public class MultiLineString extends Geometry 
-{
-
-	LineString[] lines;
-	
-	public MultiLineString() 
-	{
-		type = MULTILINESTRING;
-	}
-
-	public MultiLineString(LineString[] lines) 
-	{
-		this();
-		this.lines = lines;
-		dimension = lines[0].dimension;
-	}
-	
-	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();
-			lines = new LineString[nlines];
-			for( int p = 0; p < nlines; p++)
-			{
-				lines[p] = new LineString(t.getToken(p));
-			}
-			dimension = lines[0].dimension;
-		} else {
-			throw new SQLException("postgis.multilinestringgeometry");
-		}
-	}
-	
-	public String toString() 
-	{
-		return "MULTILINESTRING " + getValue();
-	}
-
-	public String getValue() 
-	{
-		StringBuffer b = new StringBuffer("(");
-		for( int p = 0; p < lines.length; p++ )
-		{
-			if( p > 0 ) b.append(",");
-			b.append(lines[p].getValue());
-		}
-		b.append(")");
-		return b.toString();
-	}
-	
-	public int numLines() 
-	{
-		return lines.length;
-	}
-	
-	public LineString getLine(int idx) 
-	{
-		if( idx >= 0 & idx < lines.length ) {
-			return lines[idx];
-		}
-		else {
-			return null;
-		}
-	}
+import java.sql.SQLException;
 
+import org.postgresql.util.PGtokenizer;
+
+public class MultiLineString extends Geometry {
+
+    LineString[] lines;
+    double len = -1;
+
+    public int hashCode() {
+        return super.hashCode() ^ (int)this.length();
+    }
+    
+    public Point getFirstPoint() {
+        if ((lines != null) && (lines.length > 0)) {
+            return lines[0].getFirstPoint();
+        } else
+            return null;
+    }
+    public Point getLastPoint() {
+        if ((lines != null) && (lines.length > 0)) {
+            return lines[lines.length - 1].getLastPoint();
+        } else
+            return null;
+    }
+
+    public MultiLineString() {
+        type = MULTILINESTRING;
+    }
+
+    public MultiLineString(LineString[] lines) {
+        this();
+        this.lines = lines;
+        dimension = lines[0].dimension;
+    }
+
+    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();
+            lines = new LineString[nlines];
+            for (int p = 0; p < nlines; p++) {
+                lines[p] = new LineString(t.getToken(p));
+            }
+            dimension = lines[0].dimension;
+        } else {
+            throw new SQLException("postgis.multilinestringgeometry");
+        }
+    }
+
+    public String toString() {
+        return "MULTILINESTRING " + getValue();
+    }
+
+    public String getValue() {
+        StringBuffer b = new StringBuffer("(");
+        for (int p = 0; p < lines.length; p++) {
+            if (p > 0)
+                b.append(",");
+            b.append(lines[p].getValue());
+        }
+        b.append(")");
+        return b.toString();
+    }
+
+    public int numLines() {
+        return lines.length;
+    }
+
+    public LineString[] getLines() {
+        return (LineString[]) lines.clone();
+    }
+    
+    public LineString getLine(int idx) {
+        if (idx >= 0 & idx < lines.length) {
+            return lines[idx];
+        } else {
+            return null;
+        }
+    }
+
+    public double length() {
+        if (len < 0) {
+            if (this.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;
+    }
+    
+    public int numPoints() {
+        int result=0;
+        for (int i=0; i<lines.length; i++) {
+            result += lines[i].numPoints();
+        }
+        return result;
+    }
+
+    
 }
Index: MultiPoint.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/MultiPoint.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 MultiPoint.java
--- MultiPoint.java	22 Jun 2001 17:39:30 -0000	1.1.1.1
+++ MultiPoint.java	9 Dec 2004 15:10:15 -0000
@@ -1,14 +1,25 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
-import java.util.*;
+import java.sql.SQLException;
+
+import org.postgresql.util.PGtokenizer;
 
 
 public class MultiPoint extends Geometry 
 {
 
 	Point[] points;
+
+	public Point getFirstPoint() {
+		if ((points != null) && (points.length>0)) {
+			return points[0];
+		} else return null;
+	}
+	public Point getLastPoint() {
+		if ((points != null) && (points.length>0)) {
+			return points[points.length-1];
+		} else return null;
+	}
 	
 	public MultiPoint() 
 	{
@@ -72,6 +83,12 @@
 			return null;
 		}
 	}
+    /**
+     * @return
+     */
+    public Point[] getPoints() {
+        return points;
+    }
 	
 
 }
Index: MultiPolygon.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/MultiPolygon.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 MultiPolygon.java
--- MultiPolygon.java	22 Jun 2001 17:39:30 -0000	1.1.1.1
+++ MultiPolygon.java	9 Dec 2004 15:10:15 -0000
@@ -1,14 +1,25 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
-import java.util.*;
+import java.sql.SQLException;
+
+import org.postgresql.util.PGtokenizer;
 
 
 public class MultiPolygon extends Geometry 
 {
 
 	Polygon[] polygons;
+
+	public Point getFirstPoint() {
+		if ((polygons != null) && (polygons.length>0)) {
+			return polygons[0].getFirstPoint();
+		} else return null;
+	}
+	public Point getLastPoint() {
+		if ((polygons != null) && (polygons.length>0)) {
+			return polygons[polygons.length-1].getLastPoint();
+		} else return null;
+	}
 	
 	public MultiPolygon() 
 	{
Index: PGbox3d.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/PGbox3d.java,v
retrieving revision 1.2
diff -u -r1.2 PGbox3d.java
--- PGbox3d.java	24 Oct 2002 15:53:42 -0000	1.2
+++ PGbox3d.java	9 Dec 2004 15:10:15 -0000
@@ -1,7 +1,9 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
+import java.sql.SQLException;
+
+import org.postgresql.util.PGobject;
+import org.postgresql.util.PGtokenizer;
 
 /*
  * Updates Oct 2002
Index: PGgeometry.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/PGgeometry.java,v
retrieving revision 1.2
diff -u -r1.2 PGgeometry.java
--- PGgeometry.java	24 Oct 2002 15:53:42 -0000	1.2
+++ PGgeometry.java	9 Dec 2004 15:10:15 -0000
@@ -1,8 +1,9 @@
 package org.postgis;
 
+import java.sql.SQLException;
+
 import org.postgresql.util.PGobject;
 import org.postgresql.util.PGtokenizer;
-import java.sql.*;
 
 /*
  * Updates Oct 2002
@@ -28,7 +29,11 @@
 
 	public void setValue(String value) throws SQLException
 	{
-		value = value.trim();
+		geom = geomFromString(value);
+	}
+
+	public static Geometry geomFromString(String value) throws SQLException {
+        value = value.trim();
 		if( value.startsWith("SRID")) {
 			//break up geometry into srid and wkt
 			PGtokenizer t = new PGtokenizer(value,';');
@@ -36,23 +41,25 @@
 		}
 
 		if( value.startsWith("MULTIPOLYGON")) {
-			geom = new MultiPolygon(value);
+			return new MultiPolygon(value);
 		} else if( value.startsWith("MULTILINESTRING")) {
-			geom = new MultiLineString(value);
+            return new MultiLineString(value);
 		} else if( value.startsWith("MULTIPOINT")) {
-			geom = new MultiPoint(value);
+            return new MultiPoint(value);
 		} else if( value.startsWith("POLYGON")) {
-			geom = new Polygon(value);
+            return new Polygon(value);
 		} else if( value.startsWith("LINESTRING")) {
-			geom = new LineString(value);
+            return new LineString(value);
 		} else if( value.startsWith("POINT")) {
-			geom = new Point(value);
+            return new Point(value);
+		} else if( value.startsWith("GEOMETRYCOLLECTION")) {
+            return new GeometryCollection(value);
 		} else {
 			throw new SQLException("Unknown type: " + value);
 		}
-	}
+    }
 
-	public Geometry getGeometry() {
+    public Geometry getGeometry() {
 		return geom;
 	}
 
Index: Point.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/Point.java,v
retrieving revision 1.3
diff -u -r1.3 Point.java
--- Point.java	6 Oct 2004 07:19:27 -0000	1.3
+++ Point.java	9 Dec 2004 15:10:15 -0000
@@ -1,136 +1,163 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
-import java.util.*;
+import java.sql.SQLException;
 
+import org.postgresql.util.PGtokenizer;
+import org.postgresql.util.PSQLException;
 
-public class Point extends Geometry 
-{
+public class Point extends Geometry {
 
-	/**
+    public int hashCode() {
+        return super.hashCode() ^ hashCode(x) ^ hashCode(y) ^ hashCode(z);
+    }
+
+    public static int hashCode(double value) {
+        long v = Double.doubleToLongBits(value);
+        return (int) (v ^ (v >>> 32));
+    }
+    
+    public boolean equals(Object other) {
+        return (other instanceof Point) && equals((Point) other);
+    }
+
+    public boolean equals(Point other) {
+        if (other == null)
+            return false;
+        return x == other.x && y == other.y && z == other.z && super.equals(other);
+    }
+
+    public Point getFirstPoint() {
+        return this;
+    }
+    public Point getLastPoint() {
+        return this;
+    }
+
+    /**
 	 * The X coordinate of the point.
 	 */
-	public double x;
+    public double x;
 
-	/**
+    /**
 	 * The Y coordinate of the point.
 	 */
-	public double y;
+    public double y;
 
-	/**
+    /**
 	 * The Z coordinate of the point.
 	 */
-	public double z;
-
-	public Point() 
-	{
-		type = 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 String toString() 
-	{
-		return "POINT (" + getValue() + ")";
-	}
-
-	public String getValue()
-	{
-		if ( dimension == 3 )
-		{
-			return x+" "+y+" "+z;
-		} else {
-			return x+" "+y;
-		}
-	}
-	
-	public double getX()
-	{
-		return x;
-	}
-	
-	public double getY() 
-	{
-		return y;
-	}
-	
-	public double getZ()
-	{
-		return z;
-	}
-	
-	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 setX(int x)
-	{
-		this.x = (double)x;
-	}
-
-	public void setY(int y)
-	{
-		this.y = (double)y;
-	}
-
-	public void setZ(int z)
-	{
-		this.z = (double)z;
-	}
+    public double z;
 
+    public Point() {
+        type = 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 PSQLException("postgis.Point"+ e.toString());
+        }
+    }
+
+    public String toString() {
+        return "POINT (" + getValue() + ")";
+    }
+
+    public String getValue() {
+        if (dimension == 3) {
+            return x + " " + y + " " + z;
+        } else {
+            return x + " " + y;
+        }
+    }
+
+    public double getX() {
+        return x;
+    }
+
+    public double getY() {
+        return y;
+    }
+
+    public double getZ() {
+        return z;
+    }
+
+    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 setX(int x) {
+        this.x = (double) x;
+    }
+
+    public void setY(int y) {
+        this.y = (double) y;
+    }
+
+    public void setZ(int z) {
+        this.z = (double) 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);
+        }
+    }
 }
Index: Polygon.java
===================================================================
RCS file: /home/cvs/postgis/postgis/jdbc/org/postgis/Polygon.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Polygon.java
--- Polygon.java	22 Jun 2001 17:39:30 -0000	1.1.1.1
+++ Polygon.java	9 Dec 2004 15:10:15 -0000
@@ -1,20 +1,31 @@
 package org.postgis;
 
-import org.postgresql.util.*;
-import java.sql.*;
-import java.util.*;
+import java.sql.SQLException;
+
+import org.postgresql.util.PGtokenizer;
 
 
 public class Polygon extends Geometry 
 {
 
 	LinearRing[] rings;
-	
+		
 	public Polygon() 
 	{
 		type = POLYGON;
 	}
-
+	public Point getFirstPoint() {
+		if ((rings != null) && (rings.length>0)) {
+			return rings[0].getFirstPoint();
+		} else return null;
+	}
+    
+	public Point getLastPoint() {
+		if ((rings != null) && (rings.length>0)) {
+			return rings[rings.length-1].getLastPoint();
+		} else return null;
+	}	
+	
 	public Polygon(LinearRing[] rings) 
 	{
 		this();
