Index: liblwgeom/liblwgeom.h
===================================================================
--- liblwgeom/liblwgeom.h	(revision 4009)
+++ liblwgeom/liblwgeom.h	(working copy)
@@ -9,7 +9,7 @@
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU General Public Licence. See the COPYING file.
- * 
+ *
  **********************************************************************/
 
 #ifndef _LIBLWGEOM_H
@@ -21,17 +21,17 @@
 
 /**
 * @file liblwgeom.h
-* 
+*
 * This library is the generic geometry handling section of PostGIS. The geometry
 * objects, constructors, destructors, and a set of spatial processing functions,
-* are implemented here. 
-* 
-* The library is designed for use in non-PostGIS applications if necessary. The 
-* units tests at cunit/cu_tester.c and the loader/dumper programs at 
+* are implemented here.
+*
+* The library is designed for use in non-PostGIS applications if necessary. The
+* units tests at cunit/cu_tester.c and the loader/dumper programs at
 * ../loader/shp2pgsql.c are examples of non-PostGIS applications using liblwgeom.
-* 
+*
 * Programs using this library should set up the default memory managers and error
-* handlers by implementing an lwgeom_init_allocators() function, which can be as 
+* handlers by implementing an lwgeom_init_allocators() function, which can be as
 * a wrapper around the lwgeom_install_default_allocators() function if you want
 * no special handling for memory management and error reporting.
 */
@@ -71,8 +71,8 @@
 
 #endif
 
-/** 
-* Global functions for memory/logging handlers. 
+/**
+* Global functions for memory/logging handlers.
 */
 typedef void* (*lwallocator)(size_t size);
 typedef void* (*lwreallocator)(void *mem, size_t size);
@@ -113,7 +113,7 @@
 void lwerror(const char *fmt, ...);
 
 /**
-* The default memory/logging handlers installed by lwgeom_install_default_allocators() 
+* The default memory/logging handlers installed by lwgeom_install_default_allocators()
 */
 void *default_allocator(size_t size);
 void *default_reallocator(void *mem, size_t size);
@@ -167,8 +167,8 @@
 
 typedef struct
 {
-        double xmin, ymin, zmin;
-        double xmax, ymax, zmax;
+	double xmin, ymin, zmin;
+	double xmax, ymax, zmax;
 } BOX3D;
 
 typedef struct chiptag
@@ -241,9 +241,18 @@
  * NOTE: for GEOS integration, we'll probably set z=NaN
  *        so look out - z might be NaN for 2d geometries!
  */
-typedef struct { double	x,y,z; } POINT3DZ;
-typedef struct { double	x,y,z; } POINT3D; /* alias for POINT3DZ */
-typedef struct { double	x,y,m; } POINT3DM;
+typedef struct
+{
+	double	x,y,z;
+} POINT3DZ;
+typedef struct
+{
+	double	x,y,z;
+} POINT3D; /* alias for POINT3DZ */
+typedef struct
+{
+	double	x,y,m;
+} POINT3DM;
 
 
 /*
@@ -252,18 +261,26 @@
  */
 typedef struct
 {
-	 double x;
-	 double y;
+	double x;
+	double y;
 } POINT2D;
 
 typedef struct
 {
-	 double x;
-	 double y;
-	 double z;
-	 double m;
+	double x;
+	double y;
+	double z;
+	double m;
 } POINT4D;
 
+typedef struct
+{
+	double d;	/*the distance between p1 and p2*/
+	POINT2D p1;
+	POINT2D p2;
+	int thedir;	/*the direction of looking, if thedir = -1 then we look for maxdistance and if it is 1 then we look for mindistance*/
+	int twisted; /*To preserve the order of incoming points to match the first and secon point in shortest and longest line*/
+} DISTPTS;
 /******************************************************************/
 
 /*
@@ -274,22 +291,23 @@
  */
 typedef struct
 {
-    /* array of POINT 2D, 3D or 4D. probably missaligned. */
-    uchar *serialized_pointlist;
+	/* array of POINT 2D, 3D or 4D. probably missaligned. */
+	uchar *serialized_pointlist;
 
-    /* use TYPE_* macros to handle */
-    uchar  dims;
+	/* use TYPE_* macros to handle */
+	uchar  dims;
 
-    uint32 npoints;
+	uint32 npoints;
 }  POINTARRAY;
 
 
 /*
  * Use the following to build pointarrays
- * when number of points in output is not 
+ * when number of points in output is not
  * known in advance
  */
-typedef struct {
+typedef struct
+{
 	POINTARRAY *pa;
 	size_t ptsize;
 	size_t capacity; /* given in points */
@@ -311,7 +329,7 @@
  * respectively.
  */
 extern int dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d,
-	int allow_duplicates);
+                                 int allow_duplicates);
 
 /******************************************************************
  *
@@ -321,7 +339,7 @@
 
 typedef struct
 {
-	uchar type; 
+	uchar type;
 	BOX2DFLOAT4 *bbox;
 	uint32 SRID; /* -1 == unneeded */
 	void *data;
@@ -332,8 +350,8 @@
 {
 	uchar type; /* POINTTYPE */
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
-   	POINTARRAY *point;  /* hide 2d/3d (this will be an array of 1 point) */
+	uint32 SRID;
+	POINTARRAY *point;  /* hide 2d/3d (this will be an array of 1 point) */
 }  LWPOINT; /* "light-weight point" */
 
 /* LINETYPE */
@@ -341,7 +359,7 @@
 {
 	uchar type; /* LINETYPE */
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
+	uint32 SRID;
 	POINTARRAY    *points; /* array of POINT3D */
 } LWLINE; /* "light-weight line" */
 
@@ -350,7 +368,7 @@
 {
 	uchar type; /* POLYGONTYPE */
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
+	uint32 SRID;
 	int  nrings;
 	POINTARRAY **rings; /* list of rings (list of points) */
 } LWPOLY; /* "light-weight polygon" */
@@ -358,90 +376,90 @@
 /* MULTIPOINTTYPE */
 typedef struct
 {
-	uchar type;  
+	uchar type;
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
+	uint32 SRID;
 	int  ngeoms;
 	LWPOINT **geoms;
-} LWMPOINT; 
+} LWMPOINT;
 
 /* MULTILINETYPE */
 typedef struct
-{  
-	uchar type; 
+{
+	uchar type;
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
+	uint32 SRID;
 	int  ngeoms;
 	LWLINE **geoms;
-} LWMLINE; 
+} LWMLINE;
 
 /* MULTIPOLYGONTYPE */
 typedef struct
-{  
-	uchar type; 
+{
+	uchar type;
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
+	uint32 SRID;
 	int  ngeoms;
 	LWPOLY **geoms;
-} LWMPOLY; 
+} LWMPOLY;
 
 /* COLLECTIONTYPE */
 typedef struct
-{   
-	uchar type; 
+{
+	uchar type;
 	BOX2DFLOAT4 *bbox;
-   	uint32 SRID;	
+	uint32 SRID;
 	int  ngeoms;
 	LWGEOM **geoms;
-} LWCOLLECTION; 
+} LWCOLLECTION;
 
 /* CIRCSTRINGTYPE */
 typedef struct
 {
-        uchar type; /* CIRCSTRINGTYPE */
-        BOX2DFLOAT4 *bbox;
-        uint32 SRID;
-        POINTARRAY *points; /* array of POINT(3D/3DM) */
+	uchar type; /* CIRCSTRINGTYPE */
+	BOX2DFLOAT4 *bbox;
+	uint32 SRID;
+	POINTARRAY *points; /* array of POINT(3D/3DM) */
 } LWCIRCSTRING; /* "light-weight circularstring" */
 
 /* COMPOUNDTYPE */
 typedef struct
 {
-        uchar type; /* COMPOUNDTYPE */
-        BOX2DFLOAT4 *bbox;
-        uint32 SRID;
-        int ngeoms;
-        LWGEOM **geoms;
+	uchar type; /* COMPOUNDTYPE */
+	BOX2DFLOAT4 *bbox;
+	uint32 SRID;
+	int ngeoms;
+	LWGEOM **geoms;
 } LWCOMPOUND; /* "light-weight compound line" */
 
 /* CURVEPOLYTYPE */
 typedef struct
 {
-        uchar type; /* CURVEPOLYTYPE */
-        BOX2DFLOAT4 *bbox;
-        uint32 SRID;
-        int nrings;
-        LWGEOM **rings; /* list of rings (list of points) */
+	uchar type; /* CURVEPOLYTYPE */
+	BOX2DFLOAT4 *bbox;
+	uint32 SRID;
+	int nrings;
+	LWGEOM **rings; /* list of rings (list of points) */
 } LWCURVEPOLY; /* "light-weight polygon" */
 
 /* MULTICURVE */
 typedef struct
 {
-        uchar type;
-        BOX2DFLOAT4 *bbox;
-        uint32 SRID;
-        int ngeoms;
-        LWGEOM **geoms;
+	uchar type;
+	BOX2DFLOAT4 *bbox;
+	uint32 SRID;
+	int ngeoms;
+	LWGEOM **geoms;
 } LWMCURVE;
 
 /* MULTISURFACETYPE */
 typedef struct
 {
-        uchar type;
-        BOX2DFLOAT4 *bbox;
-        uint32 SRID;
-        int ngeoms;
-        LWGEOM **geoms;
+	uchar type;
+	BOX2DFLOAT4 *bbox;
+	uint32 SRID;
+	int ngeoms;
+	LWGEOM **geoms;
 } LWMSURFACE;
 
 /* Casts LWGEOM->LW* (return NULL if cast is illegal) */
@@ -466,7 +484,7 @@
 extern LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj);
 
 /*
- * Call this function everytime LWGEOM coordinates 
+ * Call this function everytime LWGEOM coordinates
  * change so to invalidate bounding box
  */
 extern void lwgeom_changed(LWGEOM *lwgeom);
@@ -552,7 +570,7 @@
  * possibly corrupt the POINTARRAY.
  *
  * WARNING: Don't cast this to a POINT !
- * it would not be reliable due to memory alignment constraints 
+ * it would not be reliable due to memory alignment constraints
  */
 extern uchar *getPoint_internal(const POINTARRAY *pa, int n);
 
@@ -568,9 +586,9 @@
  *	 'points' points to.  No data conversion is done.
  */
 extern POINTARRAY *pointArray_construct(uchar *points, char hasz, char hasm,
-	uint32 npoints);
+                                        uint32 npoints);
 
-/* 
+/*
  * Calculate the (BOX3D) bounding box of a set of points.
  * Returns an alloced BOX3D or NULL (for empty geom) in the first form.
  * Write result in user-provided BOX3D in second form (return 0 if untouched).
@@ -639,7 +657,8 @@
  * This is the binary representation of lwgeom compatible
  * with postgresql varlena struct
  */
-typedef struct {
+typedef struct
+{
 	uint32 size;        /* varlena header (do not touch directly!) */
 	uchar type;         /* encodes ndims, type, bbox presence,
 		                srid presence */
@@ -656,7 +675,7 @@
  * from the serialized form.
  */
 extern PG_LWGEOM *PG_LWGEOM_construct(uchar *serialized, int SRID,
-	int wantbbox);
+                                      int wantbbox);
 
 /*
  * Compute bbox of serialized geom
@@ -715,7 +734,7 @@
 
 /*
  * convert this point into its serialize form
- * result's first char will be the 8bit type. 
+ * result's first char will be the 8bit type.
  * See serialized form doc
  */
 extern uchar *lwpoint_serialize(LWPOINT *point);
@@ -724,7 +743,7 @@
 extern void lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *size);
 
 /*
- * find bounding box (standard one) 
+ * find bounding box (standard one)
  * zmin=zmax=0 if 2d (might change to NaN)
  */
 extern BOX3D *lwpoint_compute_box3d(LWPOINT *point);
@@ -1060,15 +1079,15 @@
  * MEMORY MANAGEMENT
  ****************************************************************/
 
-/* 
- * The lwfree_* family of functions frees *all* memory associated 
+/*
+ * The lwfree_* family of functions frees *all* memory associated
  * with the pointer, including the serialized__pointlist in the
  * point arrays. Do not use these on LWGEOMs de-serialized from
  * PG_LWGEOMs or they will try to free an underlying structure
- * managed by PgSQL. Only use these on LWGEOMs you have 
+ * managed by PgSQL. Only use these on LWGEOMs you have
  * constructed yourself.
  */
- 
+
 extern void ptarray_free(POINTARRAY *pa);
 extern void lwpoint_free(LWPOINT *pt);
 extern void lwline_free(LWLINE *line);
@@ -1084,9 +1103,9 @@
 
 /*
  * The *_release family of functions frees the LWGEOM structures
- * surrounding the POINTARRAYs but leaves the POINTARRAYs 
+ * surrounding the POINTARRAYs but leaves the POINTARRAYs
  * intact. Use these on LWGEOMs that have been de-serialized
- * from PG_LWGEOMs. Do not use these on LWGEOMs you have 
+ * from PG_LWGEOMs. Do not use these on LWGEOMs you have
  * constructed yourself, or you will leak lots of memory.
  */
 
@@ -1145,23 +1164,29 @@
 extern void lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize);
 extern void lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize);
 extern void lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
+
 extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
+extern void lw_dist2d_comp_pt_pt(POINT2D *p1, POINT2D *p2, DISTPTS *dl);
 extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
-extern double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
-extern double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
-extern double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
+extern void lw_dist2d_comp_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B, DISTPTS *dl);
+extern void lw_dist2d_comp_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D, DISTPTS *dl);
+extern void lw_dist2d_comp_pt_ptarray(POINT2D *p, POINTARRAY *pa, DISTPTS *dl);
+extern void lw_dist2d_comp_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2, DISTPTS *dl);
 extern int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
 extern int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
-extern double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
-extern double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
-extern double distance2d_point_line(LWPOINT *point, LWLINE *line);
-extern double distance2d_line_line(LWLINE *line1, LWLINE *line2);
-extern double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
-extern double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
-extern double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
+extern void lw_dist2d_comp_ptarray_poly(POINTARRAY *pa, LWPOLY *poly, DISTPTS *dl);
+extern void lw_dist2d_comp_point_point(LWPOINT *point1, LWPOINT *point2, DISTPTS *dl);
+extern void lw_dist2d_comp_point_line(LWPOINT *point, LWLINE *line, DISTPTS *dl);
+extern void lw_dist2d_comp_line_line(LWLINE *line1, LWLINE *line2, DISTPTS *dl);
+extern void lw_dist2d_comp_point_poly(LWPOINT *point, LWPOLY *poly, DISTPTS *dl);
+extern void lw_dist2d_comp_poly_poly(LWPOLY *poly1, LWPOLY *poly2, DISTPTS *dl);
+extern void lw_dist2d_comp_line_poly(LWLINE *line, LWPOLY *poly, DISTPTS *dl);
 extern int azimuth_pt_pt(POINT2D *p1, POINT2D *p2, double *ret);
 extern double lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2);
 extern double lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance);
+extern double lwgeom_maxdistance2d_recursive(uchar *lw1, uchar *lw2);
+extern double lwgeom_maxdistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance);
+extern void lw_dist2d_comp(uchar *lw1, uchar *lw2, double tolerance, DISTPTS *dl);
 extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
 extern int32 lwgeom_npoints(uchar *serialized);
 extern char ptarray_isccw(const POINTARRAY *pa);
@@ -1224,7 +1249,7 @@
 /*
  * Clone an LWGEOM
  * pointarray are not copied.
- * BBOXes are copied 
+ * BBOXes are copied
  */
 extern LWGEOM *lwgeom_clone(const LWGEOM *lwgeom);
 extern LWPOINT *lwpoint_clone(const LWPOINT *lwgeom);
@@ -1240,21 +1265,21 @@
  * Take ownership of arguments
  */
 extern LWPOINT  *lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox,
-	POINTARRAY *point);
+                                   POINTARRAY *point);
 extern LWLINE *lwline_construct(int SRID, BOX2DFLOAT4 *bbox,
-	POINTARRAY *points);
+                                POINTARRAY *points);
 
 /*
  * Construct a new LWPOLY.  arrays (points/points per ring) will NOT be copied
  * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
  */
 extern LWPOLY *lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox,
-	unsigned int nrings, POINTARRAY **points);
+                                unsigned int nrings, POINTARRAY **points);
 
 extern LWCOLLECTION *lwcollection_construct(unsigned int type, int SRID,
-	BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms);
+        BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms);
 extern LWCOLLECTION *lwcollection_construct_empty(int SRID,
-	char hasZ, char hasM);
+        char hasZ, char hasM);
 
 /*
  * Construct a new LWCIRCSTRING.  arrays (points/points per ring) will NOT be copied
@@ -1288,7 +1313,7 @@
  */
 
 extern POINTARRAY *ptarray_addPoint(POINTARRAY *pa, uchar *p, size_t pdims,
-	unsigned int where);
+                                    unsigned int where);
 extern POINTARRAY *ptarray_removePoint(POINTARRAY *pa, unsigned int where);
 
 extern int ptarray_isclosed2d(const POINTARRAY *pa);
@@ -1323,7 +1348,7 @@
 #define PARSER_CHECK_ALL	(PARSER_CHECK_MINPOINTS | PARSER_CHECK_ODD | PARSER_CHECK_CLOSURE)
 
 /*
- * Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM 
+ * Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM
  */
 typedef struct struct_lwgeom_parser_result
 {
@@ -1338,16 +1363,16 @@
  * Parser error messages (these must match the message array in lwgparse.c)
  */
 #define PARSER_ERROR_MOREPOINTS     1
-#define PARSER_ERROR_ODDPOINTS      2	
-#define PARSER_ERROR_UNCLOSED       3 
-#define PARSER_ERROR_MIXDIMS        4	
+#define PARSER_ERROR_ODDPOINTS      2
+#define PARSER_ERROR_UNCLOSED       3
+#define PARSER_ERROR_MIXDIMS        4
 #define PARSER_ERROR_INVALIDGEOM    5
 #define PARSER_ERROR_INVALIDWKBTYPE 6
 #define PARSER_ERROR_INCONTINUOUS	7
 
 
 /*
- * Unparser result structure: returns the result of attempting to convert LWGEOM to (E)WKT/(E)WKB 
+ * Unparser result structure: returns the result of attempting to convert LWGEOM to (E)WKT/(E)WKB
  */
 typedef struct struct_lwgeom_unparser_result
 {
@@ -1362,8 +1387,8 @@
  * Unparser error messages (these must match the message array in lwgunparse.c)
  */
 #define UNPARSER_ERROR_MOREPOINTS 	1
-#define UNPARSER_ERROR_ODDPOINTS	2	
-#define UNPARSER_ERROR_UNCLOSED		3 
+#define UNPARSER_ERROR_ODDPOINTS	2
+#define UNPARSER_ERROR_UNCLOSED		3
 
 
 /* Parser access routines */
Index: liblwgeom/measures.c
===================================================================
--- liblwgeom/measures.c	(revision 4009)
+++ liblwgeom/measures.c	(working copy)
@@ -7,7 +7,7 @@
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU General Public Licence. See the COPYING file.
- * 
+ *
  **********************************************************************/
 
 #include <math.h>
@@ -39,8 +39,8 @@
 	if ( memcmp(&first, &last, sizeof(POINT2D)) )
 	{
 		lwerror("pt_in_ring_2d: V[n] != V[0] (%g %g != %g %g)",
-			first.x, first.y, last.x, last.y);
-			
+		        first.x, first.y, last.x, last.y);
+
 	}
 #endif
 
@@ -49,20 +49,20 @@
 
 	/* loop through all edges of the polygon */
 	getPoint2d_p(ring, 0, &v1);
-    	for (i=0; i<ring->npoints-1; i++)
-	{   
+	for (i=0; i<ring->npoints-1; i++)
+	{
 		double vt;
 		getPoint2d_p(ring, i+1, &v2);
 
 		/* edge from vertex i to vertex i+1 */
-       		if
+		if
 		(
-			/* an upward crossing */
-			((v1.y <= p->y) && (v2.y > p->y))
-			/* a downward crossing */
-       		 	|| ((v1.y > p->y) && (v2.y <= p->y))
+		    /* an upward crossing */
+		    ((v1.y <= p->y) && (v2.y > p->y))
+		    /* a downward crossing */
+		    || ((v1.y > p->y) && (v2.y <= p->y))
 		)
-	 	{
+		{
 
 			vt = (double)(p->y - v1.y) / (v2.y - v1.y);
 
@@ -70,7 +70,7 @@
 			if (p->x < v1.x + vt * (v2.x - v1.x))
 			{
 				/* a valid crossing of y=p.y right of p.x */
-           	     		++cn;
+				++cn;
 			}
 		}
 		v1 = v2;
@@ -81,6 +81,31 @@
 	return (cn&1);    /* 0 if even (out), and 1 if odd (in) */
 }
 
+/*Compares incomming points and stores the points closest to each other or most far away from each other depending on dl->thedir (thedirection) */
+void lw_dist2d_comp_pt_pt(POINT2D *thep1, POINT2D *thep2,DISTPTS *dl)
+{
+	double hside = thep2->x - thep1->x;
+	double vside = thep2->y - thep1->y;
+	double dist = sqrt ( hside*hside + vside*vside );
+	if (((dl->d - dist)*(dl->thedir))>0)
+	{
+		dl->d = dist;
+		/*	lwnotice("lw_dist2d_comp_pt_pt %e",dl->twisted);*/
+		if (dl->twisted>0)
+		{
+			dl->p1 = *thep1;
+			dl->p2 = *thep2;
+		}
+		else
+		{
+			dl->p1 = *thep2;
+			dl->p2 = *thep1;
+		}
+	}
+	return;
+}
+
+/*The old function nessecary for ptarray_segmentize2d in ptarray.c*/
 double distance2d_pt_pt(POINT2D *p1, POINT2D *p2)
 {
 	double hside = p2->x - p1->x;
@@ -94,7 +119,81 @@
 		);  */
 }
 
-/*distance2d from p to line A->B */
+/*lw_dist2d_comp from p to line A->B
+This one is now sending every occation to lw_dist2d_comp_pt_pt
+Berfore it was handling occations where r was between 0 and 1 internally and just returning the distance without identifying the points.
+To get this points it was nessecary to change and it also showed to be about 10%faster. */
+void lw_dist2d_comp_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B, DISTPTS *dl)
+{
+	/*lwnotice("lw_dist2d_comp_pt_seg %e",dl->d);*/
+	double	r;
+
+	/*if start==end, then use pt distance */
+	if (  ( A->x == B->x) && (A->y == B->y) )
+	{
+		lw_dist2d_comp_pt_pt(p,A,dl);
+		return;
+	}
+	/*
+	 * otherwise, we use comp.graphics.algorithms
+	 * Frequently Asked Questions method
+	 *
+	 *  (1)     	      AC dot AB
+	     *         r = ---------
+	     *               ||AB||^2
+	 *	r has the following meaning:
+	 *	r=0 P = A
+	 *	r=1 P = B
+	 *	r<0 P is on the backward extension of AB
+	 *	r>1 P is on the forward extension of AB
+	 *	0<r<1 P is interior to AB
+	 */
+
+	r = ( (p->x-A->x) * (B->x-A->x) + (p->y-A->y) * (B->y-A->y) )/( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
+
+	/*This is for finding the maxdistance.
+	the maxdistance have to be between two vertexes as I understand it,
+	compared to mindistance which can be ebtween some point between the vertices and a vertex.*/
+	if (dl->thedir < 1)
+	{
+		if (r>=0.5)
+		{
+			lw_dist2d_comp_pt_pt(p,A,dl);
+			return;
+		}
+		if (r<0.5)
+		{
+			lw_dist2d_comp_pt_pt(p,B,dl);
+			return;
+		}
+	}
+
+	if (r<0)	/*If the first vertex A is closest to the point p*/
+	{
+		lw_dist2d_comp_pt_pt(p,A,dl);
+		return;
+	}
+	if (r>1)	/*If the second vertex B is closest to the point p*/
+	{
+	
+		lw_dist2d_comp_pt_pt(p,B,dl);
+		return;
+	}
+
+
+	/*else if the point p is closer to some point between a and b then we find that point and send it to lw_dist2d_comp_pt_pt*/
+	POINT2D c;
+	c.x=A->x + r * (B->x-A->x);
+	c.y=A->y + r * (B->y-A->y);
+
+	lw_dist2d_comp_pt_pt(p,&c,dl);
+	return;
+}
+
+
+
+
+/*The old function nessecary for ptarray_segmentize2d in ptarray.c*/
 double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B)
 {
 	double	r,s;
@@ -108,8 +207,8 @@
 	 * Frequently Asked Questions method
 	 *
 	 *  (1)     	      AC dot AB
-         *         r = ---------
-         *               ||AB||^2
+	     *         r = ---------
+	     *               ||AB||^2
 	 *	r has the following meaning:
 	 *	r=0 P = A
 	 *	r=1 P = B
@@ -135,33 +234,43 @@
 	 */
 
 	s = ( (A->y-p->y)*(B->x-A->x)- (A->x-p->x)*(B->y-A->y) ) /
-		( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
+	    ( (B->x-A->x)*(B->x-A->x) +(B->y-A->y)*(B->y-A->y) );
 
 	return LW_ABS(s) * sqrt(
-		(B->x-A->x)*(B->x-A->x) + (B->y-A->y)*(B->y-A->y)
-		);
+	           (B->x-A->x)*(B->x-A->x) + (B->y-A->y)*(B->y-A->y)
+	       );
 }
 
-/* find the minimum 2d distance from AB to CD */
-double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D)
+
+
+
+
+/*This function is changed so it is not doing any comparasion of distance
+but just sending every possible combination further to lw_dist2d_comp_pt_seg*/
+void lw_dist2d_comp_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D, DISTPTS *dl)
 {
-
+	/*lwnotice("lw_dist2d_comp_seg_seg %e \n",dl->d);*/
 	double	s_top, s_bot,s;
 	double	r_top, r_bot,r;
 
-	LWDEBUGF(2, "distance2d_seg_seg [%g,%g]->[%g,%g] by [%g,%g]->[%g,%g]",
-		A->x,A->y,B->x,B->y, C->x,C->y, D->x, D->y);
 
+	LWDEBUGF(2, "lw_dist2d_comp_seg_seg [%g,%g]->[%g,%g] by [%g,%g]->[%g,%g]",
+	         A->x,A->y,B->x,B->y, C->x,C->y, D->x, D->y);
 
 	/*A and B are the same point */
 	if (  ( A->x == B->x) && (A->y == B->y) )
-		return distance2d_pt_seg(A,C,D);
+	{
+		lw_dist2d_comp_pt_seg(A,C,D,dl);
+		return;
+	}
+	/*U and V are the same point */
 
-		/*U and V are the same point */
-
 	if (  ( C->x == D->x) && (C->y == D->y) )
-		return distance2d_pt_seg(D,A,B);
-
+	{
+		dl->twisted= ((dl->twisted) * (-1));
+		lw_dist2d_comp_pt_seg(D,A,B,dl);
+		return;
+	}
 	/* AB and CD are line segments */
 	/* from comp.graphics.algo
 
@@ -190,115 +299,114 @@
 	s_top = (A->y-C->y)*(B->x-A->x) - (A->x-C->x)*(B->y-A->y);
 	s_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x);
 
-	if  ( (r_bot==0) || (s_bot == 0) )
-	{
-		return (
-			LW_MIN(distance2d_pt_seg(A,C,D),
-				LW_MIN(distance2d_pt_seg(B,C,D),
-					LW_MIN(distance2d_pt_seg(C,A,B),
-						distance2d_pt_seg(D,A,B))
-				)
-			)
-		);
-	}
 	s = s_top/s_bot;
 	r=  r_top/r_bot;
 
-	if ((r<0) || (r>1) || (s<0) || (s>1) )
+
+	if ((r<0)||(r>1)||(s<0)||(s>1)||(dl->thedir <0))
 	{
-		/*no intersection */
-		return (
-			LW_MIN(distance2d_pt_seg(A,C,D),
-				LW_MIN(distance2d_pt_seg(B,C,D),
-					LW_MIN(distance2d_pt_seg(C,A,B),
-						distance2d_pt_seg(D,A,B))
-				)
-			)
-		);
-
+		lw_dist2d_comp_pt_seg(A,C,D,dl);
+		lw_dist2d_comp_pt_seg(B,C,D,dl);
+		
+		dl->twisted= ((dl->twisted) * (-1));  /*here we change the order of inputted geometrys and that we  notice by changing sign on dl->twisted*/
+		lw_dist2d_comp_pt_seg(C,A,B,dl);
+		lw_dist2d_comp_pt_seg(D,A,B,dl);
+		return;
 	}
 	else
-		return -0; /*intersection exists */
+	{
+		if (dl->thedir >0)	/*If there is intersection we identify the intersection point and return it but only if we are looking for mindistance*/
+		{			/*lwnotice("intersection lines: %e %e %e %e",A->x,A->y,B->x,B->y);*/
+			POINT2D theP;
+			
+			if(((A->x==C->x)&&(A->y==C->y))||((A->x==D->x)&&(A->y==D->y)))
+			{
+			theP.x = A->x;
+			theP.y = A->y;
+			}			
+			else if(((B->x==C->x)&&(B->y==C->y))||((B->x==D->x)&&(B->y==D->y)))
+			{
+			theP.x = B->x;
+			theP.y = B->y;
+			}
+			else 
+			{
+			theP.x = A->x+r*(B->x-A->x); 
+			theP.y = A->y+r*(B->y-A->y);
+			}
+			/*lwnotice("intersection: %e %e ",theP.x, theP.y);*/
+			dl->d=0;
+			dl->p1=theP;
+			dl->p2=theP;
+		}	
+		return;
 
+	}
+
 }
 
-/*
- * search all the segments of pointarray to see which one is closest to p1
- * Returns minimum distance between point and pointarray
- */
-double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa)
+void lw_dist2d_comp_pt_ptarray(POINT2D *p, POINTARRAY *pa,DISTPTS *dl)
 {
-	double result = 0;
+
+
 	int t;
 	POINT2D	start, end;
-
+	int twist = dl->twisted;
 	getPoint2d_p(pa, 0, &start);
 
 	for (t=1; t<pa->npoints; t++)
 	{
-		double dist;
+		dl->twisted=twist;
 		getPoint2d_p(pa, t, &end);
-		dist = distance2d_pt_seg(p, &start, &end);
-		if (t==1) result = dist;
-		else result = LW_MIN(result, dist);
+		lw_dist2d_comp_pt_seg(p, &start, &end,dl);
+		start = end;
 
-		if ( result == 0 ) return 0;
-
-		start = end;
 	}
 
-	return result;
+	return;
 }
 
 /* test each segment of l1 against each segment of l2.  Return min */
-double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2)
+void lw_dist2d_comp_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2,DISTPTS *dl)
 {
-	double 	result = 99999999999.9;
-	char result_okay = 0; /*result is a valid min */
+	/*lwnotice("lw_dist2d_comp_ptarray_ptarray");*/
 	int t,u;
 	POINT2D	start, end;
 	POINT2D	start2, end2;
+	int twist = dl->twisted;
+	LWDEBUGF(2, "lw_dist2d_comp_ptarray_ptarray called (points: %d-%d)",
+	         l1->npoints, l2->npoints);
 
-	LWDEBUGF(2, "distance2d_ptarray_ptarray called (points: %d-%d)",
-			l1->npoints, l2->npoints);
-
 	getPoint2d_p(l1, 0, &start);
 	for (t=1; t<l1->npoints; t++) /*for each segment in L1 */
 	{
 		getPoint2d_p(l1, t, &end);
-
 		getPoint2d_p(l2, 0, &start2);
 		for (u=1; u<l2->npoints; u++) /*for each segment in L2 */
 		{
-			double dist;
-
 			getPoint2d_p(l2, u, &end2);
+			dl->twisted=twist;
+			lw_dist2d_comp_seg_seg(&start, &end, &start2, &end2,dl);
+#if PGIS_DEBUG > 1
+			printf("line_line; seg %i * seg %i, dist = %g\n",t,u,dist_this);
+#endif
 
-			dist = distance2d_seg_seg(&start, &end, &start2, &end2);
+#ifdef PGIS_DEBUG
+			lwnotice(" seg%d-seg%d dist: %f, mindist: %f",
+			         t, u, dist, result);
+#endif
 
-			LWDEBUGF(4, "line_line; seg %i * seg %i, dist = %g\n",t,u,dist);
-
-			if (result_okay)
-				result = LW_MIN(result,dist);
-			else
-			{
-				result_okay = 1;
-				result = dist;
-			}
-
-			LWDEBUGF(3, " seg%d-seg%d dist: %f, mindist: %f",
-				t, u, dist, result);
-
-			if (result <= 0) return 0; /*intersection */
-
 			start2 = end2;
 		}
 		start = end;
 	}
-
-	return result;
+	return ;
 }
 
+
+
+
+
 /* true if point is in poly (and not in its holes) */
 int pt_in_poly_2d(POINT2D *p, LWPOLY *poly)
 {
@@ -327,24 +435,28 @@
  * otherwise return min distance to a ring (could be outside
  * polygon or inside a hole)
  */
-double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly)
+
+
+
+
+
+
+void lw_dist2d_comp_ptarray_poly(POINTARRAY *pa, LWPOLY *poly, DISTPTS *dl)
 {
 	POINT2D pt;
 	int i;
-	double mindist = 0;
 
-	LWDEBUGF(2, "distance2d_ptarray_poly called (%d rings)", poly->nrings);
 
+	LWDEBUGF(2, "lw_dist2d_comp_ptarray_poly called (%d rings)", poly->nrings);
+
+
 	for (i=0; i<poly->nrings; i++)
 	{
-		double dist = distance2d_ptarray_ptarray(pa, poly->rings[i]);
-		if (i) mindist = LW_MIN(mindist, dist);
-		else mindist = dist;
+		lw_dist2d_comp_ptarray_ptarray(pa, poly->rings[i], dl);
 
 		LWDEBUGF(3, " distance from ring %d: %f, mindist: %f",
-			i, dist, mindist);
+		         i, dist, mindist);
 
-		if ( mindist <= 0 ) return 0.0; /* intersection */
 	}
 
 	/*
@@ -357,9 +469,11 @@
 	 * Outside outer ring, so min distance to a ring
 	 * is the actual min distance
 	 */
-	if ( ! pt_in_ring_2d(&pt, poly->rings[0]) ) return mindist;
+	if ( ! pt_in_ring_2d(&pt, poly->rings[0]) )
+	{
+		return ;
+	}
 
-
 	/*
 	 * Its in the outer ring.
 	 * Have to check if its inside a hole
@@ -372,14 +486,26 @@
 			 * Its inside a hole, then the actual
 			 * distance is the min ring distance
 			 */
-			return mindist;
+			return;
 		}
 	}
+	if (dl->thedir >0)
+	{
+		dl->d=0;
+		dl->p1.x=pt.x;
+		dl->p1.y=pt.y;
+		dl->p2.x=pt.x;
+		dl->p2.y=pt.y;
+	}
+	return ; /* Not in hole, so inside polygon */
 
-	return 0.0; /* Not in hole, so inside polygon */
 }
 
-double distance2d_point_point(LWPOINT *point1, LWPOINT *point2)
+
+
+
+
+void lw_dist2d_comp_point_point(LWPOINT *point1, LWPOINT *point2, DISTPTS *dl)
 {
 	POINT2D p1;
 	POINT2D p2;
@@ -387,22 +513,25 @@
 	getPoint2d_p(point1->point, 0, &p1);
 	getPoint2d_p(point2->point, 0, &p2);
 
-	return distance2d_pt_pt(&p1, &p2);
+	lw_dist2d_comp_pt_pt(&p1, &p2,dl);
+	return;
 }
 
-double distance2d_point_line(LWPOINT *point, LWLINE *line)
+void lw_dist2d_comp_point_line(LWPOINT *point, LWLINE *line, DISTPTS *dl)
 {
 	POINT2D p;
 	POINTARRAY *pa = line->points;
 	getPoint2d_p(point->point, 0, &p);
-	return distance2d_pt_ptarray(&p, pa);
+	lw_dist2d_comp_pt_ptarray(&p, pa, dl);
+	return;
 }
 
-double distance2d_line_line(LWLINE *line1, LWLINE *line2)
+void lw_dist2d_comp_line_line(LWLINE *line1, LWLINE *line2, DISTPTS *dl)
 {
 	POINTARRAY *pa1 = line1->points;
 	POINTARRAY *pa2 = line2->points;
-	return distance2d_ptarray_ptarray(pa1, pa2);
+	lw_dist2d_comp_ptarray_ptarray(pa1, pa2, dl);
+	return;
 }
 
 /*
@@ -410,45 +539,71 @@
  * 2. if in the boundary, test to see if its in a hole.
  *    if so, then return dist to hole, else return 0 (point in polygon)
  */
-double distance2d_point_poly(LWPOINT *point, LWPOLY *poly)
+
+
+
+
+
+void lw_dist2d_comp_point_poly(LWPOINT *point, LWPOLY *poly, DISTPTS *dl)
 {
 	POINT2D p;
 	int i;
 
 	getPoint2d_p(point->point, 0, &p);
 
-	LWDEBUG(2, "distance2d_point_poly called");
+	LWDEBUG(2, "lw_dist2d_comp_point_poly called");
 
+
 	/* Return distance to outer ring if not inside it */
 	if ( ! pt_in_ring_2d(&p, poly->rings[0]) )
 	{
+
 		LWDEBUG(3, " not inside outer-ring");
 
-		return distance2d_pt_ptarray(&p, poly->rings[0]);
+
+		lw_dist2d_comp_pt_ptarray(&p, poly->rings[0], dl);
+		return;
 	}
 
+	if (dl->thedir < 0)
+	{
+		LWDEBUG(3, "inside outer-ring but looking for maxdistance");
+		lw_dist2d_comp_pt_ptarray(&p, poly->rings[0], dl);
+		return;
+	}
 	/*
 	 * Inside the outer ring.
 	 * Scan though each of the inner rings looking to
 	 * see if its inside.  If not, distance==0.
 	 * Otherwise, distance = pt to ring distance
 	 */
-	for (i=1; i<poly->nrings; i++) 
+	for (i=1; i<poly->nrings; i++)
 	{
 		/* Inside a hole. Distance = pt -> ring */
 		if ( pt_in_ring_2d(&p, poly->rings[i]) )
 		{
 			LWDEBUG(3, " inside an hole");
 
-			return distance2d_pt_ptarray(&p, poly->rings[i]);
+			lw_dist2d_comp_pt_ptarray(&p, poly->rings[i], dl);
+			return;
 		}
 	}
 
 	LWDEBUG(3, " inside the polygon");
-
-	return 0.0; /* Is inside the polygon */
+	if (dl->thedir >0)
+	{
+		dl->d=0;
+		dl->p1.x=p.x;
+		dl->p1.y=p.y;
+		dl->p2.x=p.x;
+		dl->p2.y=p.y;
+	}
+	return ; /* Is inside the polygon */
 }
 
+
+
+
 /*
  * Brute force.
  * Test to see if any rings intersect.
@@ -456,21 +611,40 @@
  * Test to see if one inside the other and if they are inside holes.
  * Find min distance ring-to-ring.
  */
-double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2)
+
+
+
+void lw_dist2d_comp_poly_poly(LWPOLY *poly1, LWPOLY *poly2, DISTPTS *dl)
 {
 	POINT2D pt;
-	double mindist = -1;
+
 	int i;
 
-	LWDEBUG(2, "distance2d_poly_poly called");
+	LWDEBUG(2, "lw_dist2d_comp_poly_poly called");
 
 	/* if poly1 inside poly2 return 0 */
 	getPoint2d_p(poly1->rings[0], 0, &pt);
-	if ( pt_in_poly_2d(&pt, poly2) ) return 0.0;  
+	if (( pt_in_poly_2d(&pt, poly2))  && (dl->thedir >0))
+	{
+		dl->d=0;
+		dl->p1.x=pt.x;
+		dl->p1.y=pt.y;
+		dl->p2.x=pt.x;
+		dl->p2.y=pt.y;
+		return ;
+	}
 
 	/* if poly2 inside poly1 return 0 */
 	getPoint2d_p(poly2->rings[0], 0, &pt);
-	if ( pt_in_poly_2d(&pt, poly1) ) return 0.0;  
+	if ( (pt_in_poly_2d(&pt, poly1)) && (dl->thedir >0))
+	{
+		dl->d=0;
+		dl->p1.x=pt.x;
+		dl->p1.y=pt.y;
+		dl->p2.x=pt.x;
+		dl->p2.y=pt.y;
+		return ;
+	}
 
 	LWDEBUG(3, "  polys not inside each other");
 
@@ -484,30 +658,30 @@
 		int j;
 		for (j=0; j<poly2->nrings; j++)
 		{
-			double d = distance2d_ptarray_ptarray(poly1->rings[i],
-				poly2->rings[j]);
-			if ( d <= 0 ) return 0.0;
-
+			lw_dist2d_comp_ptarray_ptarray(poly1->rings[i],	poly2->rings[j],dl);
+			if ( dl->d <= 0 )
+			{
+				if (dl->thedir >0)
+				{
+					return;
+				}
+				
+			}
 			/* mindist is -1 when not yet set */
-			if (mindist > -1) mindist = LW_MIN(mindist, d);
-			else mindist = d;
-
-			LWDEBUGF(3, "  ring%i-%i dist: %f, mindist: %f", i, j, d, mindist);
+			LWDEBUGF(3, "  ring%i-%i dist: %f", i, j, d);
 		}
-
 	}
-
 	/* otherwise return closest approach of rings (no intersection) */
-	return mindist;
+	return ;
 
 }
 
-double distance2d_line_poly(LWLINE *line, LWPOLY *poly)
+void lw_dist2d_comp_line_poly(LWLINE *line, LWPOLY *poly, DISTPTS *dl)
 {
-	return distance2d_ptarray_poly(line->points, poly);
+	lw_dist2d_comp_ptarray_poly(line->points, poly, dl);
+	return;
 }
 
-
 /*find the 2d length of the given POINTARRAY (even if it's 3d) */
 double lwgeom_pointarray_length2d(POINTARRAY *pts)
 {
@@ -517,12 +691,12 @@
 	POINT2D to;
 
 	if ( pts->npoints < 2 ) return 0.0;
-	for (i=0; i<pts->npoints-1;i++)
+	for (i=0; i<pts->npoints-1; i++)
 	{
 		getPoint2d_p(pts, i, &frm);
 		getPoint2d_p(pts, i+1, &to);
 		dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) )  +
-				((frm.y - to.y)*(frm.y - to.y) ) );
+		              ((frm.y - to.y)*(frm.y - to.y) ) );
 	}
 	return dist;
 }
@@ -544,15 +718,14 @@
 	/* compute 2d length if 3d is not available */
 	if ( ! TYPE_HASZ(pts->dims) ) return lwgeom_pointarray_length2d(pts);
 
-	for (i=0; i<pts->npoints-1;i++)
+	for (i=0; i<pts->npoints-1; i++)
 	{
 		getPoint3dz_p(pts, i, &frm);
 		getPoint3dz_p(pts, i+1, &to);
 		dist += sqrt( ( (frm.x - to.x)*(frm.x - to.x) )  +
-				((frm.y - to.y)*(frm.y - to.y) ) +
-				((frm.z - to.z)*(frm.z - to.z) ) );
+		              ((frm.y - to.y)*(frm.y - to.y) ) +
+		              ((frm.z - to.z)*(frm.z - to.z) ) );
 	}
-
 	return dist;
 }
 
@@ -562,8 +735,8 @@
 double
 lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly)
 {
-        LWPOLY *poly = (LWPOLY *)lwgeom_segmentize((LWGEOM *)curvepoly, 32);
-        return lwgeom_polygon_area(poly);
+	LWPOLY *poly = (LWPOLY *)lwgeom_segmentize((LWGEOM *)curvepoly, 32);
+	return lwgeom_polygon_area(poly);
 }
 
 /*
@@ -589,7 +762,7 @@
 		LWDEBUGF(4, " rings %d has %d points", i, ring->npoints);
 
 		for (j=0; j<ring->npoints-1; j++)
-    		{
+		{
 			getPoint2d_p(ring, j, &p1);
 			getPoint2d_p(ring, j+1, &p2);
 			ringarea += ( p1.x * p2.y ) - ( p1.y * p2.x );
@@ -644,17 +817,53 @@
 }
 
 double
+lwgeom_maxdistance2d_recursive(uchar *lw1, uchar *lw2)
+{
+	return lwgeom_maxdistance2d_recursive_tolerance( lw1, lw2, 99999999 );
+}
+
+
+double
+lwgeom_maxdistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance)
+{
+	/*double thedist;*/
+	DISTPTS thedl;
+	thedl.thedir = (-1);
+	thedl.d= thedl.thedir * 99999999;
+	DISTPTS *dl = &thedl;
+	lw_dist2d_comp( lw1, lw2,tolerance, dl );
+	return dl->d;
+	/*lwgeom_release((DISTPTS *)dl);
+	  return thedist;
+	  return 1212.00;*/
+}
+
+double
 lwgeom_mindistance2d_recursive(uchar *lw1, uchar *lw2)
 {
-  return lwgeom_mindistance2d_recursive_tolerance( lw1, lw2, 0.0 );
+	return lwgeom_mindistance2d_recursive_tolerance( lw1, lw2, 0.0 );
 }
 
+
 double
 lwgeom_mindistance2d_recursive_tolerance(uchar *lw1, uchar *lw2, double tolerance)
 {
+	double thedist;
+	DISTPTS thedl;
+	thedl.thedir = (1);
+	thedl.d= thedl.thedir * 99999999;
+	DISTPTS *dl = &thedl;
+	lw_dist2d_comp( lw1, lw2,tolerance, dl );
+	thedist = dl->d;
+	/*lwgeom_release((DISTPTS *)dl);*/
+	return thedist;
+}
+
+void
+lw_dist2d_comp(uchar *lw1, uchar *lw2, double tolerance, DISTPTS *dl)
+{
 	LWGEOM_INSPECTED *in1, *in2;
 	int i, j;
-	double mindist = -1;
 
 	in1 = lwgeom_inspect(lw1);
 	in2 = lwgeom_inspect(lw2);
@@ -663,15 +872,16 @@
 	{
 		uchar *g1 = lwgeom_getsubgeometry_inspected(in1, i);
 		int t1 = lwgeom_getType(g1[0]);
-		double dist=tolerance;
 
-		/* Argument 1 is a multitype... recurse */
+		/* it's a multitype... recurse */
 		if ( lwgeom_contains_subgeoms(t1) )
 		{
-			dist = lwgeom_mindistance2d_recursive_tolerance(g1, lw2, tolerance);
-			if ( dist <= tolerance ) return tolerance; /* can't be closer */
-			if ( mindist == -1 ) mindist = dist;
-			else mindist = LW_MIN(dist, mindist);
+			lw_dist2d_comp(g1, lw2, tolerance, dl);
+			if ( ((tolerance - dl->d)*dl->thedir) >0 )
+			{
+				dl->d=tolerance;
+				return; /* can't be closer */
+			}
 			continue;
 		}
 
@@ -680,125 +890,133 @@
 			uchar *g2 = lwgeom_getsubgeometry_inspected(in2, j);
 			int t2 = lwgeom_getType(g2[0]);
 
-			/* Argument 2 is a multitype... recurse */
 			if ( lwgeom_contains_subgeoms(t2) )
 			{
-				dist = lwgeom_mindistance2d_recursive_tolerance(g1, g2, tolerance);
-				if ( dist <= tolerance ) return tolerance; /* can't be closer */
-				if ( mindist == -1 ) mindist = dist;
-				else mindist = LW_MIN(dist, mindist);
+				lw_dist2d_comp(g1, g2, tolerance, dl);
+				if ( ((tolerance - dl->d)*dl->thedir) >0 )
+				{
+					dl->d=tolerance;
+					return; /* can't be closer */
+				}
 				continue;
 			}
-			
 			if  ( t1 == POINTTYPE )
 			{
 				if  ( t2 == POINTTYPE )
 				{
-					dist = distance2d_point_point(
-						lwpoint_deserialize(g1),
-						lwpoint_deserialize(g2)
-					);
+					dl->twisted=1;
+					lw_dist2d_comp_point_point(
+					    lwpoint_deserialize(g1),
+					    lwpoint_deserialize(g2),
+					    dl);
 				}
 				else if  ( t2 == LINETYPE )
 				{
-					dist = distance2d_point_line(
-						lwpoint_deserialize(g1),
-						lwline_deserialize(g2)
-					);
+					dl->twisted=1;
+					lw_dist2d_comp_point_line(
+					    lwpoint_deserialize(g1),
+					    lwline_deserialize(g2),
+					    dl);
 				}
 				else if  ( t2 == POLYGONTYPE )
 				{
-					dist = distance2d_point_poly(
-						lwpoint_deserialize(g1),
-						lwpoly_deserialize(g2)
-					);
+					dl->twisted=1;
+					lw_dist2d_comp_point_poly(
+					    lwpoint_deserialize(g1),
+					    lwpoly_deserialize(g2),
+					    dl);
 				}
 				else
 				{
-					lwerror("Unsupported geometry type: %s", lwgeom_typename(t2));
-				}	
+					lwerror("Unsupported geometry type1: %s", lwgeom_typename(t2));
+				}
 			}
 			else if ( t1 == LINETYPE )
 			{
 				if ( t2 == POINTTYPE )
 				{
-					dist = distance2d_point_line(
-						lwpoint_deserialize(g2),
-						lwline_deserialize(g1)
-					);
+					dl->twisted=(-1);
+					lw_dist2d_comp_point_line(
+					    lwpoint_deserialize(g2),
+					    lwline_deserialize(g1),
+					    dl);
 				}
 				else if ( t2 == LINETYPE )
 				{
-					dist = distance2d_line_line(
-						lwline_deserialize(g1),
-						lwline_deserialize(g2)
-					);
+					dl->twisted=1;
+					/*lwnotice("start line");*/
+					lw_dist2d_comp_line_line(
+					    lwline_deserialize(g1),
+					    lwline_deserialize(g2),
+					    dl);
 				}
 				else if ( t2 == POLYGONTYPE )
 				{
-					dist = distance2d_line_poly(
-						lwline_deserialize(g1),
-						lwpoly_deserialize(g2)
-					);
+					dl->twisted=1;
+					lw_dist2d_comp_line_poly(
+					    lwline_deserialize(g1),
+					    lwpoly_deserialize(g2),
+					    dl);
 				}
 				else
 				{
-					lwerror("Unsupported geometry type: %s", lwgeom_typename(t2));
-				}	
+					lwerror("Unsupported geometry type2: %s", lwgeom_typename(t2));
+				}
 			}
 			else if ( t1 == POLYGONTYPE )
 			{
 				if ( t2 == POLYGONTYPE )
 				{
-					dist = distance2d_poly_poly(
-						lwpoly_deserialize(g2),
-						lwpoly_deserialize(g1)
-					);
+					dl->twisted=(-1);
+					lw_dist2d_comp_poly_poly(
+					    lwpoly_deserialize(g2),
+					    lwpoly_deserialize(g1),
+					    dl);
 				}
 				else if ( t2 == POINTTYPE )
 				{
-					dist = distance2d_point_poly(
-						lwpoint_deserialize(g2),
-						lwpoly_deserialize(g1)
-					);
+					dl->twisted=(-1);
+					lw_dist2d_comp_point_poly(
+					    lwpoint_deserialize(g2),
+					    lwpoly_deserialize(g1),
+					    dl);
 				}
 				else if ( t2 == LINETYPE )
 				{
-					dist = distance2d_line_poly(
-						lwline_deserialize(g2),
-						lwpoly_deserialize(g1)
-					);
+					dl->twisted=(-1);
+					lw_dist2d_comp_line_poly(
+					    lwline_deserialize(g2),
+					    lwpoly_deserialize(g1),
+					    dl);
 				}
 				else
 				{
-					lwerror("Unsupported geometry type: %s", lwgeom_typename(t2));
-				}	
+					lwerror("Unsupported geometry type3: %s", lwgeom_typename(t2));
+				}
 			}
-//			else if (lwgeom_contains_subgeoms(t1)) /* it's a multitype... recurse */
-//			{
-//				dist = lwgeom_mindistance2d_recursive_tolerance(g1, g2, tolerance);
-//			}
+			/*			else if (lwgeom_contains_subgeoms(t1))
+						{
+							lw_dist2d_comp(g1, g2, tolerance,dl);
+
+						}*/
 			else
 			{
-				lwerror("Unsupported geometry type: %s", lwgeom_typename(t1));
+				lwerror("Unsupported geometry type4: %s", lwgeom_typename(t1));
 			}
 
-			if (mindist == -1 ) mindist = dist;
-			else mindist = LW_MIN(dist, mindist);
 
-			LWDEBUGF(3, "dist %d-%d: %f - mindist: %f",
-				i, j, dist, mindist);
 
 
-			if (mindist <= tolerance) return tolerance; /* can't be closer */
+			if ( ((tolerance - dl->d)*dl->thedir) >0 )
+			{
+				dl->d=tolerance;
+				return; /* can't be closer */
+			}
 
 		}
 
 	}
-
-	if (mindist<0) mindist = 0; 
-
-	return mindist;
+	return ;
 }
 
 
Index: postgis/lwgeom_functions_basic.c
===================================================================
--- postgis/lwgeom_functions_basic.c	(revision 4009)
+++ postgis/lwgeom_functions_basic.c	(working copy)
@@ -43,8 +43,10 @@
 Datum LWGEOM_length_linestring(PG_FUNCTION_ARGS);
 Datum LWGEOM_perimeter2d_poly(PG_FUNCTION_ARGS);
 Datum LWGEOM_perimeter_poly(PG_FUNCTION_ARGS);
+Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS);
 Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS);
-Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS);
+Datum LWGEOM_shortestline2d(PG_FUNCTION_ARGS);
+Datum LWGEOM_longestline2d(PG_FUNCTION_ARGS);
 Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS);
 Datum LWGEOM_collect(PG_FUNCTION_ARGS);
 Datum LWGEOM_accum(PG_FUNCTION_ARGS);
@@ -602,7 +604,7 @@
 			TYPE_SETZM(nring->dims, 0, 0);
 			nring->npoints = ring->npoints;
 			nring->serialized_pointlist =
-			        lwalloc(ring->npoints*sizeof(POINT2D));
+			    lwalloc(ring->npoints*sizeof(POINT2D));
 			loc = nring->serialized_pointlist;
 			for (k=0; k<ring->npoints; k++)
 			{
@@ -624,9 +626,9 @@
 	}
 
 	if ( type != MULTIPOINTTYPE && type != MULTIPOLYGONTYPE &&
-	                type != MULTILINETYPE && type != COLLECTIONTYPE &&
-	                type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
-	                type != MULTICURVETYPE && type != MULTISURFACETYPE)
+	        type != MULTILINETYPE && type != COLLECTIONTYPE &&
+	        type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
+	        type != MULTICURVETYPE && type != MULTISURFACETYPE)
 	{
 		lwerror("lwgeom_force2d_recursive: unknown geometry: %d",
 		        type);
@@ -818,7 +820,7 @@
 			TYPE_SETZM(nring->dims, 1, 0);
 			nring->npoints = ring->npoints;
 			nring->serialized_pointlist =
-			        lwalloc(ring->npoints*sizeof(POINT3DZ));
+			    lwalloc(ring->npoints*sizeof(POINT3DZ));
 			loc = nring->serialized_pointlist;
 			for (k=0; k<ring->npoints; k++)
 			{
@@ -1012,7 +1014,7 @@
 			TYPE_SETZM(nring->dims, 0, 1);
 			nring->npoints = ring->npoints;
 			nring->serialized_pointlist =
-			        lwalloc(ring->npoints*sizeof(POINT3DM));
+			    lwalloc(ring->npoints*sizeof(POINT3DM));
 			loc = nring->serialized_pointlist;
 			for (k=0; k<ring->npoints; k++)
 			{
@@ -1034,9 +1036,9 @@
 	}
 
 	if ( type != MULTIPOINTTYPE && type != MULTIPOLYGONTYPE &&
-	                type != MULTILINETYPE && type != COLLECTIONTYPE &&
-	                type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
-	                type != MULTICURVETYPE && type != MULTISURFACETYPE)
+	        type != MULTILINETYPE && type != COLLECTIONTYPE &&
+	        type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
+	        type != MULTICURVETYPE && type != MULTISURFACETYPE)
 	{
 		lwerror("lwgeom_force3dm_recursive: unknown geometry: %d",
 		        type);
@@ -1224,7 +1226,7 @@
 			TYPE_SETZM(nring->dims, 1, 1);
 			nring->npoints = ring->npoints;
 			nring->serialized_pointlist =
-			        lwalloc(ring->npoints*sizeof(POINT4D));
+			    lwalloc(ring->npoints*sizeof(POINT4D));
 			loc = nring->serialized_pointlist;
 			for (k=0; k<ring->npoints; k++)
 			{
@@ -1252,9 +1254,9 @@
 
 	/* Add type */
 	*optr = lwgeom_makeType_full(
-	                1, 1,
-	                lwgeom_hasSRID(serialized[0]),
-	                type, lwgeom_hasBBOX(serialized[0]));
+	            1, 1,
+	            lwgeom_hasSRID(serialized[0]),
+	            type, lwgeom_hasBBOX(serialized[0]));
 	optr++;
 	totsize++;
 	loc=serialized+1;
@@ -1449,7 +1451,7 @@
 	 * automatic bbox addition FOR_COMPLEX_GEOMS.
 	 */
 	if ( TYPE_GETTYPE(geom->type) == COLLECTIONTYPE &&
-	                TYPE_HASBBOX(geom->type) )
+	        TYPE_HASBBOX(geom->type) )
 	{
 		PG_RETURN_POINTER(geom);
 	}
@@ -1473,8 +1475,8 @@
 		lwgeom->bbox = NULL;
 		lwgeoms[0] = lwgeom;
 		lwgeom = (LWGEOM *)lwcollection_construct(COLLECTIONTYPE,
-		                SRID, bbox, 1,
-		                lwgeoms);
+		         SRID, bbox, 1,
+		         lwgeoms);
 	}
 
 	result = pglwgeom_serialize(lwgeom);
@@ -1510,8 +1512,8 @@
 	/* deserialize into lwgeoms[0] */
 	lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
 	ogeom = lwgeom_as_multi(lwgeom);
-		printf("ogeom %p\n",ogeom);
-		printf("ogeom->type %d\n", ogeom->type);
+	printf("ogeom %p\n",ogeom);
+	printf("ogeom->type %d\n", ogeom->type);
 
 	result = pglwgeom_serialize(ogeom);
 
@@ -1520,6 +1522,115 @@
 	PG_RETURN_POINTER(result);
 }
 
+
+PG_FUNCTION_INFO_V1(LWGEOM_shortestline2d);
+Datum LWGEOM_shortestline2d(PG_FUNCTION_ARGS)
+{
+
+	PG_LWGEOM *geom1;
+	PG_LWGEOM *geom2;
+	LWPOINT *point1;
+	LWPOINT *point2;
+	int SRID;
+	double x1,x2,y1,y2;
+	PG_LWGEOM *result=NULL;
+	LWPOINT *lwpoints[2];
+	LWLINE *outline;
+
+	DISTPTS thedl;
+	DISTPTS *dl = &thedl;
+	dl->d=99999999;
+	dl->thedir=(1);
+
+	geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+	geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	{
+		elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
+		PG_RETURN_NULL();
+	}
+
+	SRID = pglwgeom_getSRID(geom1);
+
+	lw_dist2d_comp( SERIALIZED_FORM(geom1),SERIALIZED_FORM(geom2),0.0, dl );
+
+	x1=dl->p1.x;
+	y1=dl->p1.y;
+	x2=dl->p2.x;
+	y2=dl->p2.y;
+/*	
+	if(x1==0)
+	{
+		if((x2==0)&&(y1==0)&&(y2==0))
+		{
+				PG_RETURN_NULL();
+		}
+	}
+	*/
+	point1 = make_lwpoint2d(SRID, x1, y1);
+	point2 = make_lwpoint2d(SRID, x2, y2);
+
+	lwpoints[0] = lwpoint_deserialize(SERIALIZED_FORM(pglwgeom_serialize((LWGEOM *)point1)));
+	lwpoints[1] = lwpoint_deserialize(SERIALIZED_FORM(pglwgeom_serialize((LWGEOM *)point2)));
+
+	outline = lwline_from_lwpointarray(SRID, 2, lwpoints);
+
+	result = pglwgeom_serialize((LWGEOM *)outline);
+	PG_RETURN_POINTER(result);
+	
+}
+
+PG_FUNCTION_INFO_V1(LWGEOM_longestline2d);
+Datum LWGEOM_longestline2d(PG_FUNCTION_ARGS)
+{
+
+	PG_LWGEOM *geom1;
+	PG_LWGEOM *geom2;
+	LWPOINT *point1;
+	LWPOINT *point2;
+	int SRID;
+
+	double x1,x2,y1,y2;
+	PG_LWGEOM *result=NULL;
+	LWPOINT *lwpoints[2];
+	LWLINE *outline;
+	DISTPTS thedl;
+	DISTPTS *dl = &thedl;
+	dl->d=0;
+	dl->thedir=(-1);
+
+	geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+	geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	{
+		elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
+		PG_RETURN_NULL();
+	}
+
+	SRID = pglwgeom_getSRID(geom1);
+
+	lw_dist2d_comp( SERIALIZED_FORM(geom1),SERIALIZED_FORM(geom2),99999999, dl );
+
+	x1=dl->p1.x;
+	y1=dl->p1.y;
+	x2=dl->p2.x;
+	y2=dl->p2.y;
+
+	point1 = make_lwpoint2d(SRID, x1, y1);
+	point2 = make_lwpoint2d(SRID, x2, y2);
+
+	lwpoints[0] = lwpoint_deserialize(SERIALIZED_FORM(pglwgeom_serialize((LWGEOM *)point1)));
+	lwpoints[1] = lwpoint_deserialize(SERIALIZED_FORM(pglwgeom_serialize((LWGEOM *)point2)));
+
+	outline = lwline_from_lwpointarray(SRID, 2, lwpoints);
+
+	result = pglwgeom_serialize((LWGEOM *)outline);
+
+	PG_RETURN_POINTER(result);
+}
+
 /* Minimum 2d distance between objects in geom1 and geom2. */
 PG_FUNCTION_INFO_V1(LWGEOM_mindistance2d);
 Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS)
@@ -1540,7 +1651,7 @@
 	}
 
 	mindist = lwgeom_mindistance2d_recursive(SERIALIZED_FORM(geom1),
-	                SERIALIZED_FORM(geom2));
+	          SERIALIZED_FORM(geom2));
 
 	PROFSTOP(PROF_QRUN);
 	PROFREPORT("dist",geom1, geom2, NULL);
@@ -1551,98 +1662,81 @@
 	PG_RETURN_FLOAT8(mindist);
 }
 
-/* Minimum 2d distance between objects in geom1 and geom2. */
-PG_FUNCTION_INFO_V1(LWGEOM_dwithin);
-Datum LWGEOM_dwithin(PG_FUNCTION_ARGS)
+PG_FUNCTION_INFO_V1(LWGEOM_maxdistance2d_linestring);
+Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS)
 {
 	PG_LWGEOM *geom1;
 	PG_LWGEOM *geom2;
-	double mindist, tolerance;
+	double maxdist;
 
 	PROFSTART(PROF_QRUN);
 
 	geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 	geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-	tolerance = PG_GETARG_FLOAT8(2);
 
-	if ( tolerance < 0 )
-	{
-		elog(ERROR,"Tolerance cannot be less than zero\n");
-		PG_RETURN_NULL();
-	}
-
 	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
 	{
 		elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
 		PG_RETURN_NULL();
 	}
 
-	mindist = lwgeom_mindistance2d_recursive_tolerance(
-	                  SERIALIZED_FORM(geom1),
-	                  SERIALIZED_FORM(geom2),
-	                  tolerance
-	          );
+	maxdist = lwgeom_maxdistance2d_recursive(SERIALIZED_FORM(geom1),
+	          SERIALIZED_FORM(geom2));
 
 	PROFSTOP(PROF_QRUN);
-	PROFREPORT("dist",geom1, geom2, NULL);
+	PROFREPORT("maxdist",geom1, geom2, NULL);
 
 	PG_FREE_IF_COPY(geom1, 0);
 	PG_FREE_IF_COPY(geom2, 1);
 
-	PG_RETURN_BOOL(tolerance >= mindist);
+	PG_RETURN_FLOAT8(maxdist);
 }
 
-/*
- *  Maximum 2d distance between linestrings.
- *  Returns NULL if given geoms are not linestrings.
- *  This is very bogus (or I'm missing its meaning)
- */
-PG_FUNCTION_INFO_V1(LWGEOM_maxdistance2d_linestring);
-Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS)
+/* Minimum 2d distance between objects in geom1 and geom2. */
+PG_FUNCTION_INFO_V1(LWGEOM_dwithin);
+Datum LWGEOM_dwithin(PG_FUNCTION_ARGS)
 {
-
 	PG_LWGEOM *geom1;
 	PG_LWGEOM *geom2;
-	LWLINE *line1;
-	LWLINE *line2;
-	double maxdist = 0;
-	int i;
+	double mindist, tolerance;
 
-	elog(ERROR, "This function is unimplemented yet");
-	PG_RETURN_NULL();
+	PROFSTART(PROF_QRUN);
 
 	geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-	line1 = lwline_deserialize(SERIALIZED_FORM(geom1));
-	if ( line1 == NULL ) PG_RETURN_NULL(); /* not a linestring */
-
 	geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-	line2 = lwline_deserialize(SERIALIZED_FORM(geom2));
-	if ( line2 == NULL ) PG_RETURN_NULL(); /* not a linestring */
+	tolerance = PG_GETARG_FLOAT8(2);
 
+	if ( tolerance < 0 )
+	{
+		elog(ERROR,"Tolerance cannot be less than zero\n");
+		PG_RETURN_NULL();
+	}
+
 	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
 	{
 		elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
 		PG_RETURN_NULL();
 	}
 
-	for (i=0; i<line1->points->npoints; i++)
-	{
-		POINT2D p;
-		double dist;
+	mindist = lwgeom_mindistance2d_recursive_tolerance(
+	              SERIALIZED_FORM(geom1),
+	              SERIALIZED_FORM(geom2),
+	              tolerance
+	          );
 
-		getPoint2d_p(line1->points, i, &p);
-		dist = distance2d_pt_ptarray(&p, line2->points);
+	PROFSTOP(PROF_QRUN);
+	PROFREPORT("dist",geom1, geom2, NULL);
 
-		if (dist > maxdist) maxdist = dist;
-	}
-
 	PG_FREE_IF_COPY(geom1, 0);
 	PG_FREE_IF_COPY(geom2, 1);
 
-	PG_RETURN_FLOAT8(maxdist);
+	PG_RETURN_BOOL(tolerance >= mindist);
 }
 
 /*
+ *  LWGEOM_maxdistance2d_linestring is deleted and I have a new aproach to it /Nicklas Avén
+ */
+/*
  * Longitude shift:
  *  Y remains the same
  *  X is converted:
@@ -1788,8 +1882,8 @@
 	lwgeom_dropSRID(lwgeoms[1]);
 
 	outlwg = (LWGEOM *)lwcollection_construct(
-	                 outtype, SRID,
-	                 box, 2, lwgeoms);
+	             outtype, SRID,
+	             box, 2, lwgeoms);
 
 	result = pglwgeom_serialize(outlwg);
 
@@ -2062,8 +2156,8 @@
 	POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: outtype = %d", outtype);
 
 	outlwg = (LWGEOM *)lwcollection_construct(
-	                 outtype, SRID,
-	                 box, nelems, lwgeoms);
+	             outtype, SRID,
+	             box, nelems, lwgeoms);
 
 	result = pglwgeom_serialize(outlwg);
 
@@ -2175,7 +2269,7 @@
 		if ( TYPE_GETTYPE(geom->type) != POINTTYPE ) continue;
 
 		lwpoints[npoints++] =
-		        lwpoint_deserialize(SERIALIZED_FORM(geom));
+		    lwpoint_deserialize(SERIALIZED_FORM(geom));
 
 		/* Check SRID homogeneity */
 		if ( npoints == 1 )
@@ -2232,7 +2326,7 @@
 	pglwg2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
 
 	if ( ! TYPE_GETTYPE(pglwg1->type) == POINTTYPE ||
-	                ! TYPE_GETTYPE(pglwg2->type) == POINTTYPE )
+	        ! TYPE_GETTYPE(pglwg2->type) == POINTTYPE )
 	{
 		elog(ERROR, "Input geometries must be points");
 		PG_RETURN_NULL();
@@ -2436,14 +2530,14 @@
 
 
 	if (box.xmin == box.xmax &&
-	                box.ymin == box.ymax)
+	        box.ymin == box.ymax)
 	{
 		/* Construct and serialize point */
 		LWPOINT *point = make_lwpoint2d(SRID, box.xmin, box.ymin);
 		ser = lwpoint_serialize(point);
 	}
 	else if (box.xmin == box.xmax ||
-	                box.ymin == box.ymax)
+	         box.ymin == box.ymax)
 	{
 		LWLINE *line;
 		POINT2D *pts = palloc(sizeof(POINT2D)*2);
@@ -2533,7 +2627,7 @@
 
 	/* Avoid deserialize/serialize steps */
 	if ( (TYPE_GETTYPE(ingeom->type) == POINTTYPE) ||
-	                (TYPE_GETTYPE(ingeom->type) == MULTIPOINTTYPE) )
+	        (TYPE_GETTYPE(ingeom->type) == MULTIPOINTTYPE) )
 		PG_RETURN_POINTER(ingeom);
 
 	inlwgeom = lwgeom_deserialize(SERIALIZED_FORM(ingeom));
@@ -3080,9 +3174,9 @@
 	g1_bvol.ymax = g1_bvol.ymax + dist;
 
 	if (  (g1_bvol.xmin > geom2->bbox->xmax) ||
-	                (g1_bvol.xmax < geom2->bbox->xmin) ||
-	                (g1_bvol.ymin > geom2->bbox->ymax) ||
-	                (g1_bvol.ymax < geom2->bbox->ymin)
+	        (g1_bvol.xmax < geom2->bbox->xmin) ||
+	        (g1_bvol.ymin > geom2->bbox->ymax) ||
+	        (g1_bvol.ymax < geom2->bbox->ymin)
 	   )
 	{
 		PG_RETURN_BOOL(FALSE);  /*bbox not overlap */
@@ -3216,10 +3310,10 @@
 		if (curve != NULL)
 		{
 			lwgeom_affine_ptarray(curve->points,
-				afac, bfac, cfac,
-				dfac, efac, ffac,
-				gfac, hfac, ifac,
-				xoff, yoff, zoff);
+			                      afac, bfac, cfac,
+			                      dfac, efac, ffac,
+			                      gfac, hfac, ifac,
+			                      xoff, yoff, zoff);
 			lwgeom_release((LWGEOM *)curve);
 			continue;
 		}
@@ -3287,37 +3381,37 @@
 Datum ST_GeoHash(PG_FUNCTION_ARGS)
 {
 
-    PG_LWGEOM *geom = NULL;
-    int precision = 0;
-    int len = 0;
-    char *geohash = NULL;
-    char *result = NULL;
+	PG_LWGEOM *geom = NULL;
+	int precision = 0;
+	int len = 0;
+	char *geohash = NULL;
+	char *result = NULL;
 
-    if( PG_ARGISNULL(0) )
-    {
+	if ( PG_ARGISNULL(0) )
+	{
 		PG_RETURN_NULL();
-    }
+	}
 
-    geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+	geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 
-    if( ! PG_ARGISNULL(1) ) 
-    {
-        precision = PG_GETARG_INT32(1);
-    }
+	if ( ! PG_ARGISNULL(1) )
+	{
+		precision = PG_GETARG_INT32(1);
+	}
 
-    geohash = lwgeom_geohash((LWGEOM*)(pglwgeom_deserialize(geom)), precision);
+	geohash = lwgeom_geohash((LWGEOM*)(pglwgeom_deserialize(geom)), precision);
 
-    if( ! geohash ) 
-    {
+	if ( ! geohash )
+	{
 		elog(ERROR,"ST_GeoHash: lwgeom_geohash returned NULL.\n");
 		PG_RETURN_NULL();
-    }
+	}
 
 	len = strlen(geohash) + VARHDRSZ;
-    result = palloc(len);
+	result = palloc(len);
 	SET_VARSIZE(result, len);
 	memcpy(VARDATA(result), geohash, len-VARHDRSZ);
 	pfree(geohash);
 	PG_RETURN_POINTER(result);
-    
+
 }

