Changeset: e7f20b0bc1d8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e7f20b0bc1d8
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geomBulk.c
geom/sql/40_geom.sql
monetdb5/optimizer/opt_mitosis.c
Branch: geo-update-dev
Log Message:
DWithin with RTree index implementation, add distance parameter to
rtree/no_index C functions
diffs (248 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -5517,14 +5517,16 @@ static mel_func geom_init_funcs[] = {
command("rtree", "Intersectsselect", wkbIntersectsSelectRTree, false, "TODO",
args(1, 5, batarg("", oid), batarg("b", wkb), batarg("s", oid), arg("c", wkb),
arg("anti",bit))),
command("rtree", "Intersectsjoin", wkbIntersectsJoinRTree, false, "TODO",
args(2, 8, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb), batarg("b",
wkb),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
- //command("rtree", "DWithin", wkbIntersects, false, "Returns true if these
Geometries 'spatially intersect in 2D'", args(1,3,
arg("",bit),arg("a",wkb),arg("b",wkb))),
- //command("rtree", "DWithinselect", wkbIntersectsSelectRTree, false, "TODO",
args(1, 5, batarg("", oid), batarg("b", wkb), batarg("s", oid), arg("c", wkb),
arg("anti",bit))),
- //command("rtree", "DWithinjoin", wkbIntersectsJoinRTree, false, "TODO",
args(2, 8, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb), batarg("b",
wkb),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
+ command("rtree", "DWithin", wkbDWithin, false, "Returns true if these
Geometries 'spatially intersect in 2D'", args(1,4,
arg("",bit),arg("a",wkb),arg("b",wkb),arg("dst",dbl))),
+ command("rtree", "DWithinselect", wkbDWithinSelectRTree, false, "TODO",
args(1, 6, batarg("", oid), batarg("b", wkb), batarg("s", oid), arg("c", wkb),
arg("dst",dbl), arg("anti",bit))),
+ command("rtree", "DWithinjoin", wkbDWithinJoinRTree, false, "TODO", args(2,
9, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb), batarg("b", wkb),
batarg("sl",oid),batarg("sr",oid),
arg("dst",dbl),arg("nil_matches",bit),arg("estimate",lng))),
command("geom", "Intersects_noindex", wkbIntersects, false, "Returns true if
these Geometries 'spatially intersect in 2D'", args(1,3,
arg("",bit),arg("a",wkb),arg("b",wkb))),
command("geom", "Intersects_noindexselect", wkbIntersectsSelectNoIndex,
false, "TODO", args(1, 5, batarg("", oid), batarg("b", wkb), batarg("s", oid),
arg("c", wkb), arg("anti",bit))),
command("geom", "Intersects_noindexjoin", wkbIntersectsJoinNoIndex, false,
"TODO", args(2, 8, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb),
batarg("b", wkb),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
+ command("geom", "DWithin", wkbDWithin, false, "Returns true if the two
geometries are within the specifies distance from each other", args(1,4,
arg("",bit),arg("a",wkb),arg("b",wkb),arg("dst",dbl))),
+
command("geom", "IntersectsMBR", mbrIntersects, false, "TODO", args(1,3,
arg("",bit),arg("a",mbr),arg("b",mbr))),
command("aggr", "Collect", wkbCollectAggr, false, "TODO", args(1, 2, arg("",
wkb), batarg("val", wkb))),
@@ -5586,7 +5588,6 @@ static mel_func geom_init_funcs[] = {
command("geom", "Within", wkbWithin, false, "Returns TRUE if the geometry A
is completely inside geometry B", args(1,3,
arg("",bit),arg("a",wkb),arg("b",wkb))),
command("geom", "Covers", wkbCovers, false, "Returns TRUE if no point of
geometry B is outside geometry A", args(1,3,
arg("",bit),arg("a",wkb),arg("b",wkb))),
command("geom", "CoveredBy", wkbCoveredBy, false, "Returns TRUE if no point
of geometry A is outside geometry B", args(1,3,
arg("",bit),arg("a",wkb),arg("b",wkb))),
- command("geom", "DWithin", wkbDWithin, false, "Returns true if the two
geometries are within the specifies distance from each other", args(1,4,
arg("",bit),arg("a",wkb),arg("b",wkb),arg("dst",dbl))),
command("geom", "DWithin2", wkbDWithinMbr, false, "" /* <<< desc TODO */,
args(1,6,
arg("",bit),arg("a",wkb),arg("b",wkb),arg("a_mbr",mbr),arg("b_mbr",mbr),arg("dst",dbl))),
command("geom", "GeometryN", wkbGeometryN, false, "Returns the 1-based Nth
geometry if the geometry is a GEOMETRYCOLLECTION, (MULTI)POINT,
(MULTI)LINESTRING, MULTICURVE or (MULTI)POLYGON. Otherwise, return NULL",
args(1,3, arg("",wkb),arg("g",wkb),arg("n",int))),
command("geom", "NumGeometries", wkbNumGeometries, false, "Returns the number
of geometries", args(1,2, arg("",int),arg("g",wkb))),
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -219,6 +219,11 @@ geom_export str geom_sql_upgrade(int);
geom_export str wkbIntersectsJoinNoIndex(bat *lres_id, bat *rres_id, const bat
*l_id, const bat *r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches,
lng *estimate);
geom_export str wkbIntersectsSelectNoIndex(bat* outid, const bat *bid , const
bat *sid, wkb **wkb_const, bit *anti);
+
geom_export str wkbIntersectsJoinRTree(bat *lres_id, bat *rres_id, const bat
*l_id, const bat *r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches,
lng *estimate);
geom_export str wkbIntersectsSelectRTree(bat* outid, const bat *bid , const
bat *sid, wkb **wkb_const, bit *anti);
+
+geom_export str wkbDWithinJoinRTree(bat *lres_id, bat *rres_id, const bat
*l_id, const bat *r_id, const bat *ls_id, const bat *rs_id, double *distance,
bit *nil_matches, lng *estimate);
+geom_export str wkbDWithinSelectRTree(bat* outid, const bat *bid , const bat
*sid, wkb **wkb_const, double *distance, bit *anti);
+
geom_export str mbrIntersects(bit* out, mbr** mbr1, mbr** mbr2);
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -14,23 +14,16 @@
#include "geod.h"
#include "geom_atoms.h"
+//TODO Is GEOSDistanceWithin(g1,g2,0) the same (performance) as
GEOSIntersects(g1,g2)?
+
/********** Geo Update Start **********/
static str
-filterSelectRTree(bat* outid, const bat *bid , const bat *sid, wkb *wkb_const,
bit anti, char (*func) (const GEOSGeometry *, const GEOSGeometry *), const char
*name)
+filterSelectRTree(bat* outid, const bat *bid , const bat *sid, GEOSGeom
const_geom, mbr *const_mbr, double distance, bit anti, char (*func) (const
GEOSGeometry *, const GEOSGeometry *, double), const char *name)
{
BAT *out = NULL, *b = NULL, *s = NULL;
BATiter b_iter;
struct canditer ci;
- GEOSGeom col_geom, const_geom;
-
- //WKB constant is NULL
- if ((const_geom = wkb2geos(wkb_const)) == NULL) {
- if ((out = BATdense(0, 0, 0)) == NULL)
- throw(MAL, name, GDK_EXCEPTION);
- *outid = out->batCacheid;
- BBPkeepref(out);
- return MAL_SUCCEED;
- }
+ GEOSGeom col_geom;
//Get BAT, BATiter and candidate list
if ((b = BATdescriptor(*bid)) == NULL)
@@ -50,19 +43,13 @@ filterSelectRTree(bat* outid, const bat
throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
}
- //Calculate the MBR for the constant geometry
- mbr *const_mbr = NULL;
- wkbMBR(&const_mbr,&wkb_const);
-
//Get a candidate list from searching on the rtree with the constant mbr
- //Note: the candidates returned from RTREEsearch are BUNs not OIDs
BUN* results_rtree = RTREEsearch(b,(mbr_t*)const_mbr, b->batCount);
+ //TODO Change literal value of BUN_NONE to BUN_NONE in loop condition
//Cycle through rtree candidates
//If there is a original candidate list, make sure the rtree cand is in
there
//Then do the actual calculation for the predicate using the GEOS
function
-
- //TODO Change literal value of BUN_NONE to BUN_NONE in loop condition
for (int i = 0; results_rtree[i] != 18446744073709551615U && i < (int)
b->batCount; i++) {
oid cand = results_rtree[i];
@@ -87,7 +74,7 @@ filterSelectRTree(bat* outid, const bat
throw(MAL, name, SQLSTATE(38000) "Geometries of
different SRID");
}
//GEOS function returns 1 on true, 0 on false and 2 on exception
- bit cond = ((*func)(col_geom, const_geom) == 1);
+ bit cond = ((*func)(col_geom, const_geom, distance) == 1);
if (cond != anti) {
if (BUNappend(out, (oid*) &cand, false) != GDK_SUCCEED)
{
GEOSGeom_destroy(col_geom);
@@ -113,12 +100,12 @@ filterSelectRTree(bat* outid, const bat
}
static str
-filterSelectNoIndex(bat* outid, const bat *bid , const bat *sid, wkb
*wkb_const, bit anti, char (*func) (const GEOSGeometry *, const GEOSGeometry
*), const char *name)
+filterSelectNoIndex(bat* outid, const bat *bid , const bat *sid, wkb
*wkb_const, double distance, bit anti, char (*func) (const GEOSGeometry *,
const GEOSGeometry *, double), const char *name)
{
BAT *out = NULL, *b = NULL, *s = NULL;
BATiter b_iter;
struct canditer ci;
- GEOSGeom const_geom, col_geom;
+ GEOSGeom col_geom, const_geom;
//WKB constant is NULL
if ((const_geom = wkb2geos(wkb_const)) == NULL) {
@@ -163,7 +150,7 @@ filterSelectNoIndex(bat* outid, const ba
throw(MAL, name, SQLSTATE(38000) "Geometries of
different SRID");
}
//GEOS function returns 1 on true, 0 on false and 2 on exception
- bit cond = ((*func)(col_geom, const_geom) == 1);
+ bit cond = ((*func)(col_geom, const_geom, distance) == 1);
if (cond != anti) {
if (BUNappend(out, (oid*) &cand, false) != GDK_SUCCEED)
{
if (col_geom)
@@ -194,15 +181,62 @@ filterSelectNoIndex(bat* outid, const ba
str
wkbIntersectsSelectRTree(bat* outid, const bat *bid , const bat *sid, wkb
**wkb_const, bit *anti) {
//If there is an RTree on memory or on file, use the RTree method.
Otherwise, use the no index version.
- if (RTREEexists_bid((bat*)bid))
- return
filterSelectRTree(outid,bid,sid,*wkb_const,*anti,GEOSIntersects,"geom.wkbIntersectsSelectRTree");
+ if (RTREEexists_bid((bat*)bid)) {
+ //Calculate MBR of constant geometry first
+ GEOSGeom const_geom;
+ if ((const_geom = wkb2geos(*wkb_const)) == NULL) {
+ BAT *out = NULL;
+ if ((out = BATdense(0, 0, 0)) == NULL)
+ throw(MAL, "geom.wkbIntersectsSelectRTree",
GDK_EXCEPTION);
+ *outid = out->batCacheid;
+ BBPkeepref(out);
+ return MAL_SUCCEED;
+ }
+ //Calculate the MBR for the constant geometry
+ mbr *const_mbr = NULL;
+ wkbMBR(&const_mbr,wkb_const);
+
+ return
filterSelectRTree(outid,bid,sid,const_geom,const_mbr,0,*anti,GEOSDistanceWithin,"geom.wkbIntersectsSelectRTree");
+ }
else
- return
filterSelectNoIndex(outid,bid,sid,*wkb_const,*anti,GEOSIntersects,"geom.wkbIntersectsSelectNoIndex");
+ return
filterSelectNoIndex(outid,bid,sid,*wkb_const,0,*anti,GEOSDistanceWithin,"geom.wkbIntersectsSelectNoIndex");
+}
+
+str
+wkbDWithinSelectRTree(bat* outid, const bat *bid , const bat *sid, wkb
**wkb_const, double* distance, bit *anti) {
+ //If there is an RTree on memory or on file, use the RTree method.
Otherwise, use the no index version.
+ if (RTREEexists_bid((bat*)bid)) {
+ //Calculate MBR of constant geometry first
+ GEOSGeom const_geom;
+ if ((const_geom = wkb2geos(*wkb_const)) == NULL) {
+ BAT *out = NULL;
+ if ((out = BATdense(0, 0, 0)) == NULL)
+ throw(MAL, "geom.wkbDWithinSelectRTree",
GDK_EXCEPTION);
+ *outid = out->batCacheid;
+ BBPkeepref(out);
+ return MAL_SUCCEED;
+ }
+ //Calculate the MBR for the constant geometry
+ mbr *const_mbr = NULL;
+ wkbMBR(&const_mbr,wkb_const);
+
+ //We expand the bounding box to cover the "distance within" area
+ //And use GEOSIntersects with the expanded bounding box
+ //TODO This expansion is too much
+ const_mbr->xmin -=(*distance);
+ const_mbr->ymin -=(*distance);
+ const_mbr->xmax +=(*distance);
+ const_mbr->ymax +=(*distance);
+
+ return
filterSelectRTree(outid,bid,sid,const_geom,const_mbr,*distance,*anti,GEOSDistanceWithin,"geom.wkbDWithinSelectRTree");
+ }
+ else
+ return
filterSelectNoIndex(outid,bid,sid,*wkb_const,*distance,*anti,GEOSDistanceWithin,"geom.wkbDWithinSelectNoIndex");
}
str
wkbIntersectsSelectNoIndex(bat* outid, const bat *bid , const bat *sid, wkb
**wkb_const, bit *anti) {
- return
filterSelectNoIndex(outid,bid,sid,*wkb_const,*anti,GEOSIntersects,"geom.wkbIntersectsSelectNoIndex");
+ return
filterSelectNoIndex(outid,bid,sid,*wkb_const,0,*anti,GEOSDistanceWithin,"geom.wkbIntersectsSelectNoIndex");
}
static str
@@ -377,6 +411,12 @@ wkbIntersectsJoinRTree(bat *lres_id, bat
}
str
+wkbDWithinJoinRTree(bat *lres_id, bat *rres_id, const bat *l_id, const bat
*r_id, const bat *ls_id, const bat *rs_id, double *distance, bit *nil_matches,
lng *estimate) {
+ (void) distance;
+ return
filterJoinRTree(lres_id,rres_id,l_id,r_id,0,ls_id,rs_id,*nil_matches,estimate,GEOSIntersects,"geom.wkbDWithinJoinRTree");
+}
+
+str
wkbIntersectsJoinNoIndex(bat *lres_id, bat *rres_id, const bat *l_id, const
bat *r_id, const bat *ls_id, const bat *rs_id, bit *nil_matches, lng *estimate)
{
return
filterJoinNoIndex(lres_id,rres_id,l_id,r_id,0,ls_id,rs_id,*nil_matches,estimate,GEOSIntersects,"geom.wkbIntersectsJoinNoIndex");
}
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
@@ -22,6 +22,9 @@ CREATE FILTER FUNCTION ST_IntersectsGeog
CREATE FUNCTION ST_IntersectsMBR(mbr1 mbr, mbr2 mbr) RETURNS bool EXTERNAL
NAME geom."IntersectsMBR";
CREATE FILTER FUNCTION ST_Intersects(geom1 Geometry, geom2 Geometry) EXTERNAL
NAME rtree."Intersects";
CREATE FILTER FUNCTION ST_Intersects_NoIndex(geom1 Geometry, geom2 Geometry)
EXTERNAL NAME geom."Intersects_noindex";
+
+CREATE FILTER FUNCTION ST_DWithin(geom1 Geometry, geom2 Geometry, distance
double) EXTERNAL NAME rtree."DWithin";
+CREATE FUNCTION ST_DWithin_NoIndex(geom1 Geometry, geom2 Geometry, distance
double) RETURNS boolean EXTERNAL NAME geom."DWithin";
-------------------------------------------------------------------------
------------------------- Geography functions ---------------------------
-------------------------------------------------------------------------
@@ -513,8 +516,6 @@ GRANT EXECUTE ON FUNCTION ST_CoveredBy(G
--CREATE FUNCTION ST_LineCrossingDirection RETURNS EXTERNAL NAME
--CREATE FUNCTION ST_Distance(geog1 Geometry, geog2 Geometry) RETURNS double
EXTERNAL NAME geom."Distance"
--CREATE FUNCTION ST_Distance(geog1 Geometry, geog2 Geometry, use_spheroid
boolean) RETURNS double EXTERNAL NAME geom."Distance"
-CREATE FUNCTION ST_DWithin(geom1 Geometry, geom2 Geometry, dst double) RETURNS
boolean EXTERNAL NAME geom."DWithin";
-GRANT EXECUTE ON FUNCTION ST_DWithin(Geometry, Geometry, double) TO PUBLIC;
CREATE FUNCTION ST_DWithin2(geom1 Geometry, geom2 Geometry, bbox1 mbr, bbox2
mbr, dst double) RETURNS boolean EXTERNAL NAME geom."DWithin2";
GRANT EXECUTE ON FUNCTION ST_DWithin2(Geometry, Geometry, mbr, mbr, double) TO
PUBLIC;
--CREATE FUNCTION ST_HausdorffDistance RETURNS EXTERNAL NAME
diff --git a/monetdb5/optimizer/opt_mitosis.c b/monetdb5/optimizer/opt_mitosis.c
--- a/monetdb5/optimizer/opt_mitosis.c
+++ b/monetdb5/optimizer/opt_mitosis.c
@@ -70,8 +70,10 @@ OPTmitosisImplementation(Client cntxt, M
}
/* rtree functions should not be optimized by mitosis
(single-threaded execution) */
- if ( getModuleId(p) == rtreeRef)
+ if ( getModuleId(p) == rtreeRef){
+ pieces = 0;
goto bailout;
+ }
/* do not split up floating point bat that is being summed */
if (p->retc == 1 &&
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]