-- geometry_same implementation
-
- WKB support in loader (canonical form is OK)
- lwgeom_clone_deep / lwgeom_release_deep
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);
// 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
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);
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;
+}
// + 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;
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
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);
+}
+
return result;
}
-
-
+// check coordinate equality
+char
+lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
+{
+ return ptarray_same(p1->point, p2->point);
+}
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;
+}
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;
+}