]> granicus.if.org Git - postgis/commitdiff
lwgeom_same new implementation
authorSandro Santilli <strk@keybit.net>
Mon, 11 Oct 2004 07:15:20 +0000 (07:15 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 11 Oct 2004 07:15:20 +0000 (07:15 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@974 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/TODO
lwgeom/liblwgeom.h
lwgeom/lwcollection.c
lwgeom/lwgeom.c
lwgeom/lwline.c
lwgeom/lwpoint.c
lwgeom/lwpoly.c
lwgeom/ptarray.c

index ced577fcc4136c3f6b88066097476ff87b4b4886..5f98159640d3f5cd8ffbbeca544519f38497cf19 100644 (file)
@@ -1,5 +1,3 @@
-- geometry_same implementation
-
 - WKB support in loader (canonical form is OK)
 
 - lwgeom_clone_deep / lwgeom_release_deep
index ec01664e37de217d337573adac52a69554512fb2..413561a2e4a56e687adef25c1c4754b666f293c0 100644 (file)
@@ -917,7 +917,6 @@ extern double lwgeom_mindistance2d_recursive(char *lw1, char *lw2);
 extern void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, double zoff);
 extern void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
 extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
-extern POINTARRAY *ptarray_segmentize2d(POINTARRAY *ipa, double dist);
 extern int32 lwgeom_npoints(char *serialized);
 extern char ptarray_isccw(const POINTARRAY *pa);
 extern void lwgeom_reverse(LWGEOM *lwgeom);
@@ -940,8 +939,14 @@ extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2);
 // args may overlap !
 extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox);
 extern int lwgeom_compute_bbox_p(LWGEOM *lwgeom, BOX2DFLOAT4 *box);
-// is lwgeom1 geometrically equal to lwgeom2 ?
-char lwgeom_same(LWGEOM *lwgeom1, LWGEOM *lwgeom2);
+
+// Is lwgeom1 geometrically equal to lwgeom2 ?
+char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2);
+char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2);
+char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2);
+char lwline_same(const LWLINE *p1, const LWLINE *p2);
+char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2);
+char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2);
 
 // Add 'what' to 'to' at position 'where'.
 // where=0 == prepend
@@ -990,10 +995,14 @@ extern int32 lwgeom_nrings_recursive(char *serialized);
 extern void dump_lwexploded(LWGEOM_EXPLODED *exploded);
 extern void ptarray_reverse(POINTARRAY *pa);
 
+// Ensure every segment is at most 'dist' long.
+// Returned LWGEOM might is unchanged if a POINT.
 extern LWGEOM *lwgeom_segmentize2d(LWGEOM *line, double dist);
+extern POINTARRAY *ptarray_segmentize2d(POINTARRAY *ipa, double dist);
 extern LWLINE *lwline_segmentize2d(LWLINE *line, double dist);
 extern LWPOLY *lwpoly_segmentize2d(LWPOLY *line, double dist);
 extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
+
 extern unsigned char   parse_hex(char *str);
 extern void deparse_hex(unsigned char str, unsigned char *result);
 extern char *parse_lwgeom_wkt(char *wkt_input);
index 79c9e853afded1f4113bc6d4b4422f1add863ba0..268a2c54356cf3ade0ed7fab70af3881e9b67574 100644 (file)
@@ -274,3 +274,20 @@ lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
        return lwcollection_construct(col->type, col->SRID, col->bbox,
                col->ngeoms, newgeoms);
 }
+
+// check for same geometry composition
+char
+lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
+{
+       unsigned int i,j;
+
+       if ( TYPE_GETTYPE(c1->type) != TYPE_GETTYPE(c2->type) ) return 0;
+       if ( c1->ngeoms != c2->ngeoms ) return 0;
+
+       for (i=0; i<c1->ngeoms; i++)
+       {
+               if ( ! lwgeom_same(c1->geoms[0], c2->geoms[1]) )
+                       return 0;
+       }
+       return 1;
+}
index d7b76506af7cd9342b89b6ea719c5f68970b456f..387b36a4b9acc9ec4f97a06a53645b68238699c2 100644 (file)
@@ -357,7 +357,7 @@ lwgeom_to_wkt(LWGEOM *lwgeom)
 //      + each object in geom1 has a corresponding object in geom2 (see above)
 //
 char
-lwgeom_same(LWGEOM *lwgeom1, LWGEOM *lwgeom2)
+lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
 {
        if ( TYPE_GETTYPE(lwgeom1->type) != TYPE_GETTYPE(lwgeom2->type) )
                return 0;
@@ -372,8 +372,30 @@ lwgeom_same(LWGEOM *lwgeom1, LWGEOM *lwgeom2)
                if ( ! box2d_same(lwgeom1->bbox, lwgeom2->bbox) ) return 0;
        }
 
-       lwnotice("geometry_same only checked for type,dims and boxes");
-       return 1;
+       // geoms have same type, invoke type-specific function
+       switch(TYPE_GETTYPE(lwgeom1->type))
+       {
+               case POINTTYPE:
+                       return lwpoint_same((LWPOINT *)lwgeom1,
+                               (LWPOINT *)lwgeom2);
+               case LINETYPE:
+                       return lwline_same((LWLINE *)lwgeom1,
+                               (LWLINE *)lwgeom2);
+               case POLYGONTYPE:
+                       return lwpoly_same((LWPOLY *)lwgeom1,
+                               (LWPOLY *)lwgeom2);
+               case MULTIPOINTTYPE:
+               case MULTILINETYPE:
+               case MULTIPOLYGONTYPE:
+               case COLLECTIONTYPE:
+                       return lwcollection_same((LWCOLLECTION *)lwgeom1,
+                               (LWCOLLECTION *)lwgeom2);
+               default:
+                       lwerror("lwgeom_same: unknown geometry type: %d",
+                               TYPE_GETTYPE(lwgeom1->type));
+                       return 0;
+       }
+
 }
 
 void
index 1572992d8adab86720f64fa25a61b886ea6ad4e2..15225a80d537d5ab599cd24124a9d25422f2ef52 100644 (file)
@@ -365,3 +365,11 @@ lwline_segmentize2d(LWLINE *line, double dist)
        return lwline_construct(line->SRID, line->bbox,
                ptarray_segmentize2d(line->points, dist));
 }
+
+// check coordinate equality 
+char
+lwline_same(const LWLINE *l1, const LWLINE *l2)
+{
+       return ptarray_same(l1->points, l2->points);
+}
+
index 25360e8375c6be571f1ed50f3b0239cda791d709..365716a794660759dfa275006a5fff88e408736f 100644 (file)
@@ -356,5 +356,9 @@ lwnotice("lwgeom_size_point: has srid (%d)", result);
        return result;
 }
 
-
-
+// check coordinate equality 
+char
+lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
+{
+       return ptarray_same(p1->point, p2->point);
+}
index 52807745bdcfa364a418661cea9db02a2a534967..6622cfdcbb2289e3372f6012c4138f4e558c27d7 100644 (file)
@@ -524,3 +524,19 @@ lwpoly_segmentize2d(LWPOLY *poly, double dist)
        return lwpoly_construct(poly->SRID, poly->bbox,
                poly->nrings, newrings);
 }
+
+// check coordinate equality 
+// ring and coordinate order is considered
+char
+lwpoly_same(const LWPOLY *p1, const LWPOLY *p2)
+{
+       unsigned int i;
+
+       if ( p1->nrings != p2->nrings ) return 0;
+       for (i=0; i<p1->nrings; i++)
+       {
+               if ( ! ptarray_same(p1->rings[i], p2->rings[i]) )
+                       return 0;
+       }
+       return 1;
+}
index dc7e1e9e343f354c0528498b9d2aec67fb837488..2bea2baba4a4cd3ada9d655bd5ea35705a0c6e0a 100644 (file)
@@ -188,3 +188,23 @@ ptarray_segmentize2d(POINTARRAY *ipa, double dist)
        return opa;
 }
 
+char
+ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
+{
+       unsigned int i;
+       size_t ptsize;
+
+       if ( TYPE_GETZM(pa1->dims) != TYPE_GETZM(pa2->dims) ) return 0;
+
+       if ( pa1->npoints != pa2->npoints ) return 0;
+
+       ptsize = pointArray_ptsize(pa1);
+
+       for (i=0; i<pa1->npoints; i++)
+       {
+               if ( memcmp(getPoint(pa1, i), getPoint(pa2, i), ptsize) )
+                       return 0;
+       }
+
+       return 1;
+}