From 163159d7762ce01e3051f6695b0d49fafd79c5d4 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Mon, 11 Oct 2004 07:15:20 +0000 Subject: [PATCH] lwgeom_same new implementation git-svn-id: http://svn.osgeo.org/postgis/trunk@974 b70326c6-7e19-0410-871a-916f4a2858ee --- lwgeom/TODO | 2 -- lwgeom/liblwgeom.h | 15 ++++++++++++--- lwgeom/lwcollection.c | 17 +++++++++++++++++ lwgeom/lwgeom.c | 28 +++++++++++++++++++++++++--- lwgeom/lwline.c | 8 ++++++++ lwgeom/lwpoint.c | 8 ++++++-- lwgeom/lwpoly.c | 16 ++++++++++++++++ lwgeom/ptarray.c | 20 ++++++++++++++++++++ 8 files changed, 104 insertions(+), 10 deletions(-) diff --git a/lwgeom/TODO b/lwgeom/TODO index ced577fcc..5f9815964 100644 --- a/lwgeom/TODO +++ b/lwgeom/TODO @@ -1,5 +1,3 @@ -- geometry_same implementation - - WKB support in loader (canonical form is OK) - lwgeom_clone_deep / lwgeom_release_deep diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index ec01664e3..413561a2e 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -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); diff --git a/lwgeom/lwcollection.c b/lwgeom/lwcollection.c index 79c9e853a..268a2c543 100644 --- a/lwgeom/lwcollection.c +++ b/lwgeom/lwcollection.c @@ -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; ingeoms; i++) + { + if ( ! lwgeom_same(c1->geoms[0], c2->geoms[1]) ) + return 0; + } + return 1; +} diff --git a/lwgeom/lwgeom.c b/lwgeom/lwgeom.c index d7b76506a..387b36a4b 100644 --- a/lwgeom/lwgeom.c +++ b/lwgeom/lwgeom.c @@ -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 diff --git a/lwgeom/lwline.c b/lwgeom/lwline.c index 1572992d8..15225a80d 100644 --- a/lwgeom/lwline.c +++ b/lwgeom/lwline.c @@ -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); +} + diff --git a/lwgeom/lwpoint.c b/lwgeom/lwpoint.c index 25360e837..365716a79 100644 --- a/lwgeom/lwpoint.c +++ b/lwgeom/lwpoint.c @@ -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); +} diff --git a/lwgeom/lwpoly.c b/lwgeom/lwpoly.c index 52807745b..6622cfdcb 100644 --- a/lwgeom/lwpoly.c +++ b/lwgeom/lwpoly.c @@ -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; inrings; i++) + { + if ( ! ptarray_same(p1->rings[i], p2->rings[i]) ) + return 0; + } + return 1; +} diff --git a/lwgeom/ptarray.c b/lwgeom/ptarray.c index dc7e1e9e3..2bea2baba 100644 --- a/lwgeom/ptarray.c +++ b/lwgeom/ptarray.c @@ -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; inpoints; i++) + { + if ( memcmp(getPoint(pa1, i), getPoint(pa2, i), ptsize) ) + return 0; + } + + return 1; +} -- 2.40.0