]> granicus.if.org Git - postgis/commitdiff
Prototype segmentation code and move lwalgorith.h prototypes into liblwgeom.h and...
authorPaul Ramsey <pramsey@cleverelephant.ca>
Sat, 25 Jun 2011 22:36:51 +0000 (22:36 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Sat, 25 Jun 2011 22:36:51 +0000 (22:36 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7487 b70326c6-7e19-0410-871a-916f4a2858ee

12 files changed:
liblwgeom/Makefile.in
liblwgeom/cunit/cu_algorithm.c
liblwgeom/g_box.c
liblwgeom/liblwgeom.h
liblwgeom/liblwgeom_internal.h
liblwgeom/lwalgorithm.c
liblwgeom/lwalgorithm.h [deleted file]
liblwgeom/lwsegmentize.c
liblwgeom/lwtree.c
postgis/lwgeom_functions_analytic.c
postgis/lwgeom_functions_basic.c
postgis/lwgeom_geos_split.c

index bb10d47de74ca45f4b6a853634b4974a5b66ab07..a233a8e114a6f22bcf56dafb0b055741edcf4fae 100644 (file)
@@ -75,7 +75,6 @@ NM_OBJS = \
 SA_HEADERS = \
        liblwgeom.h \
        liblwgeom_internal.h \
-       lwalgorithm.h \
        libtgeom.h 
 
 all: liblwgeom.a
index e03099e3c624c6a9faf711fac15ce662f2a15c6c..5aba73dd7661e09fb2b17987b77f624f9cbf18b1 100644 (file)
@@ -16,7 +16,6 @@
 #include "CUnit/Basic.h"
 
 #include "liblwgeom_internal.h"
-#include "lwalgorithm.h"
 #include "cu_tester.h"
 
 /*
index 85292c2466289f028ef839dbd9e9e4bd47d02f45..d14a76c547e6915423cf990b3ff40fd844a297d7 100644 (file)
@@ -10,7 +10,6 @@
  **********************************************************************/
 
 #include "liblwgeom_internal.h"
-#include "lwalgorithm.h"
 #include <math.h>
 #include <stdlib.h>
 
@@ -337,13 +336,6 @@ size_t gbox_serialized_size(uchar flags)
 }
 
 
-static inline int signum(double n)
-{
-       if( n < 0 ) return -1;
-       if( n > 0 ) return 1;
-       return 0;
-}
-
 /* ********************************************************************************
 ** Compute cartesian bounding GBOX boxes from LWGEOM.
 */
index cf53d3a2fdf1cd6248eb29cc22eb3823c393cda4..02fcc55038ec503929ef43d4fade6d255f954a2f 100644 (file)
@@ -1775,6 +1775,39 @@ extern LWLINE *lwline_segmentize2d(LWLINE *line, double dist);
 extern LWPOLY *lwpoly_segmentize2d(LWPOLY *line, double dist);
 extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
 
+/**
+* Calculate the GeoHash (http://geohash.org) string for a geometry. Caller must free.
+*/
+char *lwgeom_geohash(const LWGEOM *lwgeom, int precision);
+
+
+/**
+* The return values of lwline_crossing_direction()
+*/
+enum CG_LINE_CROSS_TYPE {
+    LINE_NO_CROSS = 0,
+    LINE_CROSS_LEFT = -1,
+    LINE_CROSS_RIGHT = 1,
+    LINE_MULTICROSS_END_LEFT = -2,
+    LINE_MULTICROSS_END_RIGHT = 2,
+    LINE_MULTICROSS_END_SAME_FIRST_LEFT = -3,
+    LINE_MULTICROSS_END_SAME_FIRST_RIGHT = 3
+};
+
+/**
+* Given two lines, characterize how (and if) they cross each other
+*/
+int lwline_crossing_direction(LWLINE *l1, LWLINE *l2);
+
+/**
+* Clip a line based on the from/to range of one of its ordinates. Use for m- and z- clipping 
+*/
+LWCOLLECTION *lwline_clip_to_ordinate_range(LWLINE *line, int ordinate, double from, double to);
+
+/**
+* Clip a multi-line based on the from/to range of one of its ordinates. Use for m- and z- clipping 
+*/
+LWCOLLECTION *lwmline_clip_to_ordinate_range(LWMLINE *mline, int ordinate, double from, double to);
 
 /*
  * Export functions
index 9243435a8e155cbfce7074a2ab411fc650114063..088bb9509ccd53fa4e7f39ba65588d9815bed111 100644 (file)
@@ -21,6 +21,8 @@
 #include <ieeefp.h>
 #endif
 
+#ifndef LIBLWGEOM_INTERNAL
+#define LIBLWGEOM_INTERNAL
 
 /**
 * PI
@@ -112,6 +114,57 @@ LWLINE* lwline_simplify(const LWLINE *iline, double dist);
 LWPOLY* lwpoly_simplify(const LWPOLY *ipoly, double dist);
 LWCOLLECTION* lwcollection_simplify(const LWCOLLECTION *igeom, double dist);
 
+/*
+* Computational geometry
+*/
+int signum(double n);
+
+/*
+* The possible ways a pair of segments can interact. Returned by lw_segment_intersects 
+*/
+enum CG_SEGMENT_INTERSECTION_TYPE {
+    SEG_ERROR = -1,
+    SEG_NO_INTERSECTION = 0,
+    SEG_COLINEAR = 1,
+    SEG_CROSS_LEFT = 2,
+    SEG_CROSS_RIGHT = 3,
+    SEG_TOUCH_LEFT = 4,
+    SEG_TOUCH_RIGHT = 5
+};
+
+/*
+* Do the segments intersect? How?
+*/
+int lw_segment_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2);
+
+/*
+* What side of the line formed by p1 and p2 does q fall? 
+* Returns < 0 for left and > 0 for right and 0 for co-linearity
+*/
+double lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q);
+
+/* 
+* Do the envelopes of the the segments intersect?
+*/
+int lw_segment_envelope_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2);
+
+/*
+* Get/Set an enumeratoed ordinate. (x,y,z,m)
+*/
+double lwpoint_get_ordinate(const POINT4D *p, int ordinate);
+void lwpoint_set_ordinate(POINT4D *p, int ordinate, double value);
+
+/* 
+* Generate an interpolated coordinate p given an interpolation value and ordinate to apply it to
+*/
+int lwpoint_interpolate(const POINT4D *p1, const POINT4D *p2, POINT4D *p, int ndims, int ordinate, double interpolation_value);
+
+/*
+* Geohash
+*/
+int lwgeom_geohash_precision(GBOX bbox, GBOX *bounds);
+char *geohash_point(double longitude, double latitude, int precision);
+
 /*
 * Point comparisons
 */
@@ -158,3 +211,4 @@ void ptarray_affine(POINTARRAY *pa, const AFFINE *affine);
 char ptarray_isccw(const POINTARRAY *pa);
 
 
+#endif /* LIBLWGEOM_INTERNAL */
\ No newline at end of file
index 7ba0773174d6ce7272d22a7c742ff370400f2ede..18b1c177db25c605e7531ffb444e64ad78b2142c 100644 (file)
  **********************************************************************/
 
 #include "liblwgeom_internal.h"
-#include "lwalgorithm.h"
 
 
+/**
+* Returns -1 if n < 0.0 and 1 if n > 0.0
+*/
+int signum(double n)
+{
+       if( n < 0 ) return -1;
+       if( n > 0 ) return 1;
+       return 0;
+}
+
 /**
 ** lw_segment_side()
 **
diff --git a/liblwgeom/lwalgorithm.h b/liblwgeom/lwalgorithm.h
deleted file mode 100644 (file)
index 008d1ef..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**********************************************************************
- * $Id$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * Copyright 2008 Paul Ramsey
- *
- * 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>
-
-enum CG_SEGMENT_INTERSECTION_TYPE {
-    SEG_ERROR = -1,
-    SEG_NO_INTERSECTION = 0,
-    SEG_COLINEAR = 1,
-    SEG_CROSS_LEFT = 2,
-    SEG_CROSS_RIGHT = 3,
-    SEG_TOUCH_LEFT = 4,
-    SEG_TOUCH_RIGHT = 5
-};
-
-double lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q);
-int lw_segment_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2);
-int lw_segment_envelope_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2);
-
-
-enum CG_LINE_CROSS_TYPE {
-    LINE_NO_CROSS = 0,
-    LINE_CROSS_LEFT = -1,
-    LINE_CROSS_RIGHT = 1,
-    LINE_MULTICROSS_END_LEFT = -2,
-    LINE_MULTICROSS_END_RIGHT = 2,
-    LINE_MULTICROSS_END_SAME_FIRST_LEFT = -3,
-    LINE_MULTICROSS_END_SAME_FIRST_RIGHT = 3
-};
-
-int lwline_crossing_direction(LWLINE *l1, LWLINE *l2);
-
-double lwpoint_get_ordinate(const POINT4D *p, int ordinate);
-void lwpoint_set_ordinate(POINT4D *p, int ordinate, double value);
-int lwpoint_interpolate(const POINT4D *p1, const POINT4D *p2, POINT4D *p, int ndims, int ordinate, double interpolation_value);
-LWCOLLECTION *lwline_clip_to_ordinate_range(LWLINE *line, int ordinate, double from, double to);
-LWCOLLECTION *lwmline_clip_to_ordinate_range(LWMLINE *mline, int ordinate, double from, double to);
-
-int lwgeom_geohash_precision(GBOX bbox, GBOX *bounds);
-char *lwgeom_geohash(const LWGEOM *lwgeom, int precision);
-char *geohash_point(double longitude, double latitude, int precision);
-
index 2affdf3a3e7e323d625e022756b5e149ef10d8d3..d1621c894607d272c2985c8d0b4e00c013840c52 100644 (file)
@@ -158,10 +158,10 @@ lwcircle_segmentize(POINT4D *p1, POINT4D *p2, POINT4D *p3, uint32 perQuad)
        uchar *pt;
 
        POINT4D center;
-       double radius = 0.0,
-                       sweep = 0.0,
-                               angle = 0.0,
-                                       increment = 0.0;
+       double radius = 0.0;
+       double sweep = 0.0;
+       double angle = 0.0;
+       double increment = 0.0;
        double a1, a2, a3, i;
 
        LWDEBUG(2, "lwcircle_segmentize called. ");
@@ -282,6 +282,86 @@ lwcircle_segmentize(POINT4D *p1, POINT4D *p2, POINT4D *p3, uint32 perQuad)
        return result;
 }
 
+POINTARRAY *
+lwcircle_segmentize2(POINT4D *p1, POINT4D *p2, POINT4D *p3, uint32 perQuad)
+{
+       POINT4D center;
+       POINT4D pt, pt_start, pt_end;
+       int p2_side = 0;
+       double radius; /* Arc radius */
+       double increment; /* Angle per segment */
+       double a1, a2, a3, angle;
+       POINTARRAY *pa;
+       int result;
+
+       LWDEBUG(2, "lwcircle_calculate_gbox called.");
+
+       radius = lwcircle_center(p1, p2, p3, &center);
+       
+       /* Negative radius signals straight line, p1/p2/p3 are colinear */
+       if (radius < 0.0)
+       {
+               /* TODO return straight line from p1 to p3 */
+           return NULL;
+       }
+               
+       /* Matched start/end points imply circle */
+       if ( p1->x == p3->x && p1->y == p3->y )
+       {
+               /* TODO return circle */
+           return NULL;
+       }
+
+       /* The side of the p1/p3 line that p2 falls on dictates the sweep  
+          direction from p1 to p3. */
+       p2_side = signum(lw_segment_side((POINT2D*)p1, (POINT2D*)p3, (POINT2D*)p2));
+       increment = fabs(M_PI_2 / perQuad);
+       
+       /* Angles of each point that defines the arc section */
+       a1 = atan2(p1->y - center.y, p1->x - center.x);
+       a2 = atan2(p2->y - center.y, p2->x - center.x);
+       a3 = atan2(p3->y - center.y, p3->x - center.x);
+
+       /* p2 on left side => Clockwise sweep */
+       if ( p2_side == -1 ) 
+       {
+               /* Swap a1/a3 so we can use an anti-clockwise (positive) sweep */
+               double tmp = a3;
+               a3 = a1;
+               a1 = tmp;
+               pt_start = *p3;
+               pt_end = *p1;
+       }
+       else 
+       {
+               pt_start = *p1;
+               pt_end = *p3;
+       }
+       
+       /* Adjust a3 up so we can increment from a1 to a3 cleanly */
+       if ( a3 < a1 )
+       {
+               a3 += 2.0 * M_PI;
+       }
+       
+       /* Initialize point array */
+       pa = ptarray_construct_empty(0, 0, 32);
+       /* Add in start point */
+       result = ptarray_append_point(pa, &pt_start, LW_FALSE);
+       /* Sweep from a1 to a3 */
+       for( angle = a1 + increment; angle < a3; angle += increment )
+       {
+               pt.x = center.x + radius * cos(angle);
+               pt.y = center.y + radius * sin(angle);
+               result = ptarray_append_point(pa, &pt, LW_FALSE);
+       }
+       /* Add in the end point */
+       result = ptarray_append_point(pa, &pt_end, LW_FALSE);
+       
+       return pa;
+}
+
+
 LWLINE *
 lwcircstring_segmentize(const LWCIRCSTRING *icurve, uint32 perQuad)
 {
index 8b4405b1752364db454accc5981ae27581ccc844..ffdf3091d49f63e83495e786f5efb2647392cfc6 100644 (file)
@@ -1,5 +1,4 @@
 #include "liblwgeom_internal.h"
-#include "lwalgorithm.h"
 #include "lwtree.h"
 
 
index d65821f5489e99352c2ae253bc9cc247235147f5..5c521a30cf63c68b5c375c3c99700625623b756f 100644 (file)
@@ -16,7 +16,6 @@
 #include "lwgeom_pg.h"
 #include "math.h"
 #include "lwgeom_rtree.h"
-#include "lwalgorithm.h"
 #include "lwgeom_functions_analytic.h"
 
 
index 8f2ce0b5c6b9d9fbe51983d20b7a9ff85dbcd125..796389bf875b275b1e38812e3a615a6d9bdef807 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "liblwgeom_internal.h"
 #include "libtgeom.h"
-#include "lwalgorithm.h"
 #include "lwgeom_pg.h"
 #include "profile.h"
 
index 0759e5df9f2f1a8b5fbdd82bd1b61ddd8f41c2e2..67a62feefd5d911463b61defe1bf2def3c85b608 100644 (file)
@@ -37,7 +37,6 @@
  **********************************************************************/
 
 #include "lwgeom_geos.h"
-#include "lwalgorithm.h"
 #include "funcapi.h"
 
 #include <string.h>