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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to