Changeset: 3a797d26700d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3a797d26700d
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:
ST_DWithin(geom, x, y, z, srid, dist) is now available and also in bulk mode
diffs (truncated from 846 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
@@ -5756,7 +5756,63 @@ 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");
+ return wkbspatialXYZ(out, geomWKB_a, x, y, z, srid, GEOSIntersects,
"geom.IntersectsXYZ");
+}
+
+str
+wkbDWithinXYZ(bit *out, wkb **geomWKB_a, dbl *x, dbl *y, dbl *z, int *srid,
double *distance)
+{
+ double distanceComputed;
+ str err;
+ wkb **geomWKB_b = NULL;
+
+ GEOSGeom geosGeometry_b;
+ GEOSCoordSeq seq;
+
+ if (wkb_isnil(*geomWKB_a)) {
+ *out = bit_nil;
+ return MAL_SUCCEED;
+ }
+
+ /*Build Geometry b*/
+ if (*x == dbl_nil || *y == dbl_nil || *z == dbl_nil) {
+ *out = bit_nil;
+ return MAL_SUCCEED;
+ }
+
+ //create the point from the coordinates
+ seq = GEOSCoordSeq_create(1, 3);
+
+ if (seq == NULL) {
+ throw(MAL, "wkbDWithinXYZ", "GEOSCoordSeq_create failed");
+ }
+
+ if (!GEOSCoordSeq_setOrdinate(seq, 0, 0, *x) ||
+ !GEOSCoordSeq_setOrdinate(seq, 0, 1, *y) ||
+ !GEOSCoordSeq_setOrdinate(seq, 0, 2, *z)) {
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, "wkbDWithinXYZ", "GEOSCoordSeq_setOrdinate failed");
+ }
+
+ if ((geosGeometry_b = GEOSGeom_createPoint(seq)) == NULL) {
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, "wkbDWithinXYZ", "Failed to create GEOSGeometry from
the coordinates");
+ }
+
+ if (*srid != int_nil)
+ GEOSSetSRID(geosGeometry_b, *srid);
+
+ if (wkb_isnil(*geomWKB_a) || wkb_isnil(*geomWKB_b) || *distance ==
dbl_nil) {
+ *out = bit_nil;
+ return MAL_SUCCEED;
+ }
+ if ((err = wkbDistance(&distanceComputed, geomWKB_a, geomWKB_b)) !=
MAL_SUCCEED) {
+ return err;
+ }
+
+ *out = (distanceComputed <= *distance);
+
+ return MAL_SUCCEED;
}
str
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -163,7 +163,9 @@ geom_export str wkbRelate(bit*, wkb**, w
geom_export str wkbCovers(bit *out, wkb **geomWKB_a, wkb **geomWKB_b);
geom_export str wkbCoveredBy(bit *out, wkb **geomWKB_a, wkb **geomWKB_b);
geom_export str wkbDWithin(bit*, wkb**, wkb**, dbl*);
+geom_export str wkbDWithinXYZ(bit*, wkb**, dbl*, dbl*, dbl*, int*, dbl*);
geom_export str wkbDWithin_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id,
dbl*);
+geom_export str wkbDWithinXYZ_bat(bat *outBAT_id, bat *inBAT_id, bat
*inXBAT_id, double *dx, bat *inYBAT_id, double *dy, bat *inZBAT_id, double *dz,
int* srid, dbl* dist);
//LocateAlong
//LocateBetween
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -330,8 +330,12 @@ command Covers(a:wkb, b:wkb) :bit addres
comment "Returns TRUE if no point of geometry B is outside geometry A";
command CoveredBy(a:wkb, b:wkb) :bit address wkbCoveredBy
comment "Returns TRUE if no point of geometry A is outside geometry B";
+
command DWithin(a:wkb, b:wkb, dst:dbl) :bit address wkbDWithin
comment "Returns true if the two geometries are within the specifies distance
from each other";
+command DWithinXYZ(a:wkb, x:dbl, y:dbl, z:dbl, srid:int, dst:dbl) :bit address
wkbDWithinXYZ
+comment "Returns true if a geometry and a point are within the specifies
distance from each other";
+
command GeometryN(g:wkb, n:int) :wkb address wkbGeometryN
comment "Returns the 1-based Nth geometry if the geometry is a
GEOMETRYCOLLECTION, (MULTI)POINT, (MULTI)LINESTRING, MULTICURVE or
(MULTI)POLYGON. Otherwise, return NULL";
command NumGeometries(g:wkb) :int address wkbNumGeometries
@@ -760,6 +764,44 @@ comment "Returns TRUE if the geometry A
command DWithin(a:bat[:wkb], b:bat[:wkb], dst:dbl) :bat[:bit] address
wkbDWithin_bat
comment "Returns true if the two geometries are within the specifies distance
from each other";
+command DWithin3D(g:bat[:wkb], dxBAT:bat[:dbl], dx:dbl, dyBAT:bat[:dbl],
dy:dbl, dzBAT:bat[:dbl], dz:dbl, srid:int, dist:dbl) :bat[:bit] address
wkbDWithinXYZ_bat
+comment "Returns true if these Geometries 'spatially intersect in 2D'";
+
+function DWithinXYZ(g:bat[:wkb], dxBAT:bat[:dbl], dyBAT:bat[:dbl],
dzBAT:bat[:dbl], srid:int, dist:dbl) :bat[:bit];
+ x := DWithin3D(g, dxBAT, 0:dbl, dyBAT, 0:dbl, dzBAT, 0:dbl, srid, dist);
+ return x;
+end DWithinXYZ;
+
+function DWithinXYZ(g:bat[:wkb], dx:dbl, dy:dbl, dzBAT:bat[:dbl], srid:int,
dist:dbl) :bat[:bit];
+ x := DWithin3D(g, nil:bat, dx, nil:bat, dy, dzBAT, 0:dbl, srid, dist);
+ return x;
+end DWithinXYZ;
+
+function DWithinXYZ(g:bat[:wkb], dxBAT:bat[:dbl], dy:dbl, dzBAT:bat[:dbl],
srid:int, dist:dbl) :bat[:bit];
+ x := DWithin3D(g, dxBAT, 0:dbl, nil:bat, dy, dzBAT, 0:dbl, srid, dist);
+ return x;
+end DWithinXYZ;
+
+function DWithinXYZ(g:bat[:wkb], dx:dbl, dyBAT:bat[:dbl], dzBAT:bat[:dbl],
srid:int, dist:dbl) :bat[:bit];
+ x := DWithin3D(g, nil:bat, dx, dyBAT, 0:dbl, dzBAT, 0:dbl, srid, dist);
+ return x;
+end DWithinXYZ;
+
+function DWithinXYZ(g:bat[:wkb], dxBAT:bat[:dbl], dyBAT:bat[:dbl], dz:dbl,
srid:int, dist:dbl) :bat[:bit];
+ x := DWithin3D(g, dxBAT, 0:dbl, dyBAT, 0:dbl, nil:bat, dz, srid, dist);
+ return x;
+end DWithinXYZ;
+
+function DWithinXYZ(g:bat[:wkb], dx:dbl, dyBAT:bat[:dbl], dz:dbl, srid:int,
dist:dbl) :bat[:bit];
+ x := DWithin3D(g, nil:bat, dx, dyBAT, 0:dbl, nil:bat, dz, srid, dist);
+ return x;
+end DWithinXYZ;
+
+function DWithinXYZ(g:bat[:wkb], dxBAT:bat[:dbl], dy:dbl, dz:dbl, srid:int,
dist:dbl) :bat[:bit];
+ x := DWithin3D(g, dxBAT, 0:dbl, nil:bat, dy, nil:bat, dz, srid, dist);
+ return x;
+end DWithinXYZ;
+
command GeometryN(w:bat[:wkb], n:int) :bat[:wkb] address wkbGeometryN_bat
comment "Returns the 1-based Nth geometry if the geometry is a
GEOMETRYCOLLECTION, (MULTI)POINT, (MULTI)LINESTRING, MULTICURVE or
(MULTI)POLYGON. Otherwise, return NULL";
command NumGeometries(w:bat[:wkb]) :bat[:int] address wkbNumGeometries_bat
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -1078,11 +1078,11 @@ wkbCollect_bat(bat *outBAT_id, bat *aBAT
}
/******************************************************************************************/
-/************************* IN: wkb dbl dbl dbl - OUT: bit - SRID
**************************/
+/************************* IN: wkb dbl dbl dbl int - OUT: bit
*****************************/
/******************************************************************************************/
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)
+WKBDBLDBLDBLINTtoBIT_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;
@@ -1207,276 +1207,25 @@ WKBtoBITxyzDBL_bat(bat *outBAT_id, bat *
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");
+ return WKBDBLDBLDBLINTtoBIT_bat(outBAT_id, inBAT_id, inXBAT_id, dx,
inYBAT_id, dy, inZBAT_id, dz, srid, wkbIntersectsXYZ, "batgeom.IntersectsXYZ");
}
-/***************************************************************************/
-/*************************** IN: wkb - OUT: int ****************************/
-/***************************************************************************/
+/******************************************************************************************/
+/******************* IN: wkb dbl dbl dbl int - OUT: bit - flag dbl
************************/
+/******************************************************************************************/
static str
-WKBtoINT_bat(bat *outBAT_id, bat *inBAT_id, str (*func) (int *, wkb **), const
char *name)
+WKBDBLDBLDBLINTtoBITflagDBL_bat(bat *outBAT_id, bat *inBAT_id, bat *inXBAT_id,
double *dx, bat *inYBAT_id, double *dy, bat *inZBAT_id, double * dz, int *srid,
double *flag, str (*func) (bit *, wkb **, double *x, double *y, double *z, int
*srid, double *flag), const char *name)
{
- BAT *outBAT = NULL, *inBAT = NULL;
+ BAT *outBAT = NULL, *inBAT = NULL, *inXBAT = NULL, *inYBAT = NULL,
*inZBAT = NULL;
BUN p = 0, q = 0;
- BATiter inBAT_iter;
+ BATiter inBAT_iter, inXBAT_iter, inYBAT_iter, inZBAT_iter;
str msg = MAL_SUCCEED;
#ifdef GEOMBULK_DEBUG
static struct timeval start, stop;
unsigned long long t;
#endif
- int *outs;
-
- //get the descriptor of the BAT
- if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
- throw(MAL, name, RUNTIME_OBJECT_MISSING);
- }
-
- //create a new for the output BAT
- if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("int"),
BATcount(inBAT), TRANSIENT)) == NULL) {
- BBPunfix(inBAT->batCacheid);
- throw(MAL, name, MAL_MALLOC_FAIL);
- }
-
- //iterator over the input BAT
- inBAT_iter = bat_iterator(inBAT);
-
- omp_set_dynamic(OPENCL_DYNAMIC); // Explicitly disable dynamic teams
- omp_set_num_threads(OPENCL_THREADS);
- q = BUNlast(inBAT);
-#ifdef GEOMBULK_DEBUG
- fprintf(stdout, "%s %d %d\n", name, p, q);
- gettimeofday(&start, NULL);
-#endif
- //BATloop(inBAT, p, q) { //iterate over all valid elements
- outs = (int*) Tloc(outBAT, 0);
- #pragma omp parallel for
- for (p = 0; p < q; p++) {
- str err = NULL;
- wkb *inWKB = NULL;
- //int outSingle;
-
- inWKB = (wkb *) BUNtail(inBAT_iter, p);
- //if ((err = (*func) (&outSingle, &inWKB)) != MAL_SUCCEED) {
- if ((err = (*func) (&outs[p], &inWKB)) != MAL_SUCCEED) {
- msg = err;
- #pragma omp cancelregion
- }
- //BUNappend(outBAT, &outSingle, TRUE); //add the result to the
new BAT
- }
-#ifdef GEOMBULK_DEBUG
- gettimeofday(&stop, NULL);
- t = 1000 * (stop.tv_sec - start.tv_sec) + (stop.tv_usec - start.tv_usec) /
1000;
- fprintf(stdout, "%s %llu ms\n", name, t);
-#endif
-
- BBPunfix(inBAT->batCacheid);
-
- if (msg != MAL_SUCCEED) {
- BBPunfix(outBAT->batCacheid);
- return msg;
- }
-
- BATsetcount(outBAT, BATcount(inBAT));
- BATrmprops(outBAT)
- BATsettrivprop(outBAT);
- BBPkeepref(*outBAT_id = outBAT->batCacheid);
-
- return MAL_SUCCEED;
-
-}
-
-str
-wkbDimension_bat(bat *outBAT_id, bat *inBAT_id)
-{
- return WKBtoINT_bat(outBAT_id, inBAT_id, wkbDimension,
"batgeom.wkbDimension");
-}
-
-str
-wkbNumGeometries_bat(bat *outBAT_id, bat *inBAT_id)
-{
- return WKBtoINT_bat(outBAT_id, inBAT_id, wkbNumGeometries,
"batgeom.wkbNumGeometries");
-}
-
-/***************************************************************************************/
-/*************************** IN: wkb - OUT: int - FLAG: int
****************************/
-/***************************************************************************************/
-
-static str
-WKBtoINTflagINT_bat(bat *outBAT_id, bat *inBAT_id, int *flag, str (*func) (int
*, wkb **, int *), const char *name)
-{
- BAT *outBAT = NULL, *inBAT = NULL;
- BUN p = 0, q = 0;
- BATiter inBAT_iter;
- str msg = MAL_SUCCEED;
-#ifdef GEOMBULK_DEBUG
- static struct timeval start, stop;
- unsigned long long t;
-#endif
- int *outs;
-
- //get the descriptor of the BAT
- if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
- throw(MAL, name, RUNTIME_OBJECT_MISSING);
- }
-
- //create a new for the output BAT
- if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("int"),
BATcount(inBAT), TRANSIENT)) == NULL) {
- BBPunfix(inBAT->batCacheid);
- throw(MAL, name, MAL_MALLOC_FAIL);
- }
-
- //iterator over the input BAT
- inBAT_iter = bat_iterator(inBAT);
-
- omp_set_dynamic(OPENCL_DYNAMIC); // Explicitly disable dynamic teams
- omp_set_num_threads(OPENCL_THREADS);
- q = BUNlast(inBAT);
-#ifdef GEOMBULK_DEBUG
- fprintf(stdout, "%s %d %d\n", name, p, q);
- gettimeofday(&start, NULL);
-#endif
- //BATloop(inBAT, p, q) { //iterate over all valid elements
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list