Changeset: 13d799d7d4f0 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=13d799d7d4f0
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geom.mal
geom/monetdb5/geomBulk.c
geom/sql/40_geom.sql
Branch: sfcgal
Log Message:
Add ST_IntersectsXYZ, it does the same as ST_Intersects for points but you can
pass the point as X, Y and Z coordinates and also the SRID. This avoids us to
use ST_SetSRID(ST_MakePoint(...
diffs (truncated from 305 to 300 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -4692,6 +4692,75 @@ wkbBuffer(wkb **out, wkb **geom, dbl *di
return MAL_SUCCEED;
}
+/* Gets a geometry and Point(X, Y, Z, SRID) and returns a Boolean by comparing
them */
+static str
+wkbspatialXYZ(bit *out, wkb **geomWKB_a, double *x, double *y, double *z, int
*srid, char (*func) (const GEOSGeometry *, const GEOSGeometry *), const char
*name)
+{
+ int res;
+ GEOSGeom geosGeometry_a, geosGeometry_b;
+ GEOSCoordSeq seq;
+
+ if (wkb_isnil(*geomWKB_a)) {
+ *out = bit_nil;
+ return MAL_SUCCEED;
+ }
+
+ geosGeometry_a = wkb2geos(*geomWKB_a);
+ if (geosGeometry_a == NULL) {
+ throw(MAL, name, "wkb2geos failed");
+ }
+
+ /*Build Geometry b*/
+ if (*x == dbl_nil || *y == dbl_nil || *z == dbl_nil) {
+ GEOSGeom_destroy(geosGeometry_a);
+ *out = bit_nil;
+ return MAL_SUCCEED;
+ }
+
+ //create the point from the coordinates
+ seq = GEOSCoordSeq_create(1, 3);
+
+ if (seq == NULL) {
+ GEOSGeom_destroy(geosGeometry_a);
+ throw(MAL, name, "GEOSCoordSeq_create failed");
+ }
+
+ if (!GEOSCoordSeq_setOrdinate(seq, 0, 0, *x) ||
+ !GEOSCoordSeq_setOrdinate(seq, 0, 1, *y) ||
+ !GEOSCoordSeq_setOrdinate(seq, 0, 2, *z)) {
+ GEOSGeom_destroy(geosGeometry_a);
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, name, "GEOSCoordSeq_setOrdinate failed");
+ }
+
+ if ((geosGeometry_b = GEOSGeom_createPoint(seq)) == NULL) {
+ GEOSGeom_destroy(geosGeometry_a);
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, name, "Failed to create GEOSGeometry from the
coordinates");
+ }
+
+ if (*srid != int_nil)
+ GEOSSetSRID(geosGeometry_b, *srid);
+
+ if (GEOSGetSRID(geosGeometry_a) != GEOSGetSRID(geosGeometry_b)) {
+ GEOSGeom_destroy(geosGeometry_a);
+ GEOSGeom_destroy(geosGeometry_b);
+ throw(MAL, name, "Geometries of different SRID");
+ }
+
+ res = (*func) (geosGeometry_a, geosGeometry_b);
+
+ GEOSGeom_destroy(geosGeometry_a);
+ GEOSGeom_destroy(geosGeometry_b);
+
+ if (res == 2)
+ throw(MAL, name, "GEOS%s failed", name + 5);
+
+ *out = res;
+
+ return MAL_SUCCEED;
+}
+
/* Gets two geometries and returns a Boolean by comparing them */
static str
wkbspatial(bit *out, wkb **geomWKB_a, wkb **geomWKB_b, char (*func) (const
GEOSGeometry *, const GEOSGeometry *), const char *name)
@@ -4764,6 +4833,12 @@ wkbIntersects(bit *out, wkb **geomWKB_a,
}
str
+wkbIntersectsXYZ(bit *out, wkb **geomWKB_a, dbl *x, dbl *y, dbl *z, int *srid)
+{
+ return wkbspatialXYZ(out, geomWKB_a, x, y, z, srid, GEOSIntersects,
"geom.Intersects");
+}
+
+str
wkbOverlaps(bit *out, wkb **geomWKB_a, wkb **geomWKB_b)
{
return wkbspatial(out, geomWKB_a, geomWKB_b, GEOSOverlaps,
"geom.Overlaps");
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -144,7 +144,9 @@ geom_export str wkbBoundary_bat(bat *inB
geom_export str wkbEquals(bit*, wkb**, wkb**);
geom_export str wkbDisjoint(bit*, wkb**, wkb**);
geom_export str wkbIntersects(bit*, wkb**, wkb**);
+geom_export str wkbIntersectsXYZ(bit*, wkb**, dbl*, dbl*, dbl*, int*);
geom_export str wkbIntersects_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id);
+geom_export str wkbIntersectsXYZ_bat(bat *outBAT_id, bat *inBAT_id, bat
*inXBAT_id, double *dx, bat *inYBAT_id, double *dy, bat *inZBAT_id, double *dz,
int* srid);
geom_export str wkbTouches(bit*, wkb**, wkb**);
geom_export str wkbCrosses(bit*, wkb**, wkb**);
geom_export str wkbWithin(bit*, wkb**, wkb**);
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -304,6 +304,8 @@ command Equals(a:wkb, b:wkb) :bit addres
comment "Returns true if the given geometries represent the same geometry.
Directionality is ignored.";
command Intersects(a:wkb, b:wkb) :bit address wkbIntersects
comment "Returns true if these Geometries 'spatially intersect in 2D'";
+command IntersectsXYZ(a:wkb, x:dbl, y:dbl, z:dbl, srid:int) :bit address
wkbIntersectsXYZ
+comment "Returns true if these Geometries 'spatially intersect in 2D'";
command Overlaps(a:wkb, b:wkb) :bit address wkbOverlaps
comment " Returns TRUE if the Geometries intersect but are not completely
contained by each other.";
command Relate(a:wkb, b:wkb, intersection_matrix_pattern:str) :bit address
wkbRelate
@@ -831,6 +833,44 @@ comment "Returns the area of the surface
command Intersects(a:bat[:oid,:wkb], b:bat[:oid,:wkb]) :bat[:oid,:bit] address
wkbIntersects_bat
comment "Returns true if these Geometries 'spatially intersect in 2D'";
+command Intersects3D(g:bat[:oid,:wkb], dxBAT:bat[:oid,:dbl], dx:dbl,
dyBAT:bat[:oid,:dbl], dy:dbl, dzBAT:bat[:oid,:dbl], dz:dbl, srid:int)
:bat[:oid,:bit] address wkbIntersectsXYZ_bat
+comment "Returns true if these Geometries 'spatially intersect in 2D'";
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dxBAT:bat[:oid,:dbl],
dyBAT:bat[:oid,:dbl], dzBAT:bat[:oid,:dbl], srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, dxBAT, 0:dbl, dyBAT, 0:dbl, dzBAT, 0:dbl, srid);
+ return x;
+end IntersectsXYZ;
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dx:dbl, dy:dbl, dzBAT:bat[:oid,:dbl],
srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, nil:bat, dx, nil:bat, dy, dzBAT, 0:dbl, srid);
+ return x;
+end IntersectsXYZ;
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dxBAT:bat[:oid,:dbl], dy:dbl,
dzBAT:bat[:oid,:dbl], srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, dxBAT, 0:dbl, nil:bat, dy, dzBAT, 0:dbl, srid);
+ return x;
+end IntersectsXYZ;
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dx:dbl, dyBAT:bat[:oid,:dbl],
dzBAT:bat[:oid,:dbl], srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, nil:bat, dx, dyBAT, 0:dbl, dzBAT, 0:dbl, srid);
+ return x;
+end IntersectsXYZ;
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dxBAT:bat[:oid,:dbl],
dyBAT:bat[:oid,:dbl], dz:dbl, srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, dxBAT, 0:dbl, dyBAT, 0:dbl, nil:bat, dz, srid);
+ return x;
+end IntersectsXYZ;
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dx:dbl, dyBAT:bat[:oid,:dbl], dz:dbl,
srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, nil:bat, dx, dyBAT, 0:dbl, nil:bat, dz, srid);
+ return x;
+end IntersectsXYZ;
+
+function IntersectsXYZ(g:bat[:oid,:wkb], dxBAT:bat[:oid,:dbl], dy:dbl, dz:dbl,
srid:int) :bat[:oid,:bit];
+ x := Intersects3D(g, dxBAT, 0:dbl, nil:bat, dy, nil:bat, dz, srid);
+ return x;
+end IntersectsXYZ;
+
module calc;
command mbr(v:str) :mbr address mbrFromString;
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -586,6 +586,119 @@ wkbIntersects_bat(bat *outBAT_id, bat *a
return WKBWKBtoBIT_bat(outBAT_id, aBAT_id, bBAT_id, wkbIntersects,
"batgeom.wkbIntersects");
}
+/******************************************************************************************/
+/************************* IN: wkb dbl dbl dbl - OUT: bit - SRID
**************************/
+/******************************************************************************************/
+
+static str
+WKBtoBITxyzDBL_bat(bat *outBAT_id, bat *inBAT_id, bat *inXBAT_id, double *dx,
bat *inYBAT_id, double *dy, bat *inZBAT_id, double * dz, int *srid, str (*func)
(bit *, wkb **, double *x, double *y, double *z, int *srid), const char *name)
+{
+ BAT *outBAT = NULL, *inBAT = NULL, *inXBAT = NULL, *inYBAT = NULL,
*inZBAT = NULL;
+ BUN p = 0, q = 0;
+ BATiter inBAT_iter, inXBAT_iter, inYBAT_iter, inZBAT_iter;
+
+ //get the descriptor of the BAT
+ if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
+ throw(MAL, name, RUNTIME_OBJECT_MISSING);
+ }
+ if (*inXBAT_id != bat_nil && (inXBAT = BATdescriptor(*inXBAT_id)) ==
NULL) {
+ BBPunfix(inBAT->batCacheid);
+ throw(MAL, name, RUNTIME_OBJECT_MISSING);
+ }
+ if (*inYBAT_id != bat_nil && (inYBAT = BATdescriptor(*inYBAT_id)) ==
NULL) {
+ BBPunfix(inBAT->batCacheid);
+ if (*inXBAT_id != bat_nil)
+ BBPunfix(inXBAT->batCacheid);
+ throw(MAL, name, RUNTIME_OBJECT_MISSING);
+ }
+ if (*inZBAT_id != bat_nil && (inZBAT = BATdescriptor(*inZBAT_id)) ==
NULL) {
+ BBPunfix(inBAT->batCacheid);
+ if (*inXBAT_id != bat_nil)
+ BBPunfix(inXBAT->batCacheid);
+ if (*inYBAT_id != bat_nil)
+ BBPunfix(inYBAT->batCacheid);
+ throw(MAL, name, RUNTIME_OBJECT_MISSING);
+ }
+
+ //create a new for the output BAT
+ if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("bit"),
BATcount(inBAT), TRANSIENT)) == NULL) {
+ BBPunfix(inBAT->batCacheid);
+ if (*inXBAT_id != bat_nil)
+ BBPunfix(inXBAT->batCacheid);
+ if (*inYBAT_id != bat_nil)
+ BBPunfix(inYBAT->batCacheid);
+ if (*inZBAT_id != bat_nil)
+ BBPunfix(inZBAT->batCacheid);
+ throw(MAL, name, MAL_MALLOC_FAIL);
+ }
+
+ //iterator over the input BAT
+ inBAT_iter = bat_iterator(inBAT);
+
+ if (*inXBAT_id != bat_nil)
+ inXBAT_iter = bat_iterator(inXBAT);
+ if (*inYBAT_id != bat_nil)
+ inYBAT_iter = bat_iterator(inYBAT);
+ if (*inZBAT_id != bat_nil)
+ inZBAT_iter = bat_iterator(inZBAT);
+
+ BATloop(inBAT, p, q) { //iterate over all valid elements
+ str err = NULL;
+ wkb *inWKB = NULL;
+ bit outSingle;
+ double x, y, z;
+
+
+ inWKB = (wkb *) BUNtail(inBAT_iter, p);
+
+ if (*inXBAT_id != bat_nil)
+ x = *(double *) BUNtail(inXBAT_iter, p);
+ else
+ x = *dx;
+ if (*inYBAT_id != bat_nil)
+ y = *(double *) BUNtail(inYBAT_iter, p);
+ else
+ y = *dy;
+ if (*inZBAT_id != bat_nil)
+ z = *(double *) BUNtail(inZBAT_iter, p);
+ else
+ z = *dz;
+
+ if ((err = (*func) (&outSingle, &inWKB, &x, &y, &z, srid)) !=
MAL_SUCCEED) {
+ BBPunfix(inBAT->batCacheid);
+ if (*inXBAT_id != bat_nil)
+ BBPunfix(inXBAT->batCacheid);
+ if (*inYBAT_id != bat_nil)
+ BBPunfix(inYBAT->batCacheid);
+ if (*inZBAT_id != bat_nil)
+ BBPunfix(inZBAT->batCacheid);
+ BBPunfix(outBAT->batCacheid);
+ return err;
+ }
+ BUNappend(outBAT, &outSingle, TRUE); //add the result to the
new BAT
+ }
+
+ //set the number of elements in the outBAT
+ BATsetcount(outBAT, BATcount(inBAT));
+
+ BBPunfix(inBAT->batCacheid);
+ if (*inXBAT_id != bat_nil)
+ BBPunfix(inXBAT->batCacheid);
+ if (*inYBAT_id != bat_nil)
+ BBPunfix(inYBAT->batCacheid);
+ if (*inZBAT_id != bat_nil)
+ BBPunfix(inZBAT->batCacheid);
+ BBPkeepref(*outBAT_id = outBAT->batCacheid);
+
+ return MAL_SUCCEED;
+}
+
+str
+wkbIntersectsXYZ_bat(bat *outBAT_id, bat *inBAT_id, bat *inXBAT_id, double
*dx, bat *inYBAT_id, double *dy, bat *inZBAT_id, double *dz, int* srid)
+{
+ return WKBtoBITxyzDBL_bat(outBAT_id, inBAT_id, inXBAT_id, dx,
inYBAT_id, dy, inZBAT_id, dz, srid, wkbIntersectsXYZ, "batgeom.IntersectsXYZ");
+}
+
/***************************************************************************/
/*************************** IN: wkb - OUT: int ****************************/
/***************************************************************************/
@@ -755,7 +868,7 @@ wkbGetCoordinate_bat(bat *outBAT_id, bat
}
/******************************************************************************************/
-/************************** IN: wkb - OUT: wkb - X, Y and Z: dbl
**************************/
+/***************************** IN: wkb dbl dbl dbl - OUT: wkb
*****************************/
/******************************************************************************************/
static str
diff --git a/geom/sql/40_geom.sql b/geom/sql/40_geom.sql
--- a/geom/sql/40_geom.sql
+++ b/geom/sql/40_geom.sql
@@ -4035,6 +4035,7 @@ CREATE FUNCTION ST_Envelope(geom Geometr
CREATE FUNCTION ST_Equals(geom1 Geometry, geom2 Geometry) RETURNS boolean
EXTERNAL NAME geom."Equals";
CREATE FUNCTION ST_Disjoint(geom1 Geometry, geom2 Geometry) RETURNS boolean
EXTERNAL NAME geom."Disjoint";
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list