Changeset: 0074c4e37d27 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0074c4e37d27
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geomBulk.c
geom/sql/40_geom.sql
Branch: geo-update
Log Message:
Added first version of bulk distance function.
diffs (truncated from 318 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
@@ -778,6 +778,53 @@ wkbDWithinGeographic(bit *out, wkb **a,
return err;
}
+/*
+str
+wkbDWithinGeographicSelect(bat* outid, const bat *aid, const bat *bid, dbl *d,
const bat *s1_id, const bat *s2_id, const bit *anti)
+{
+ (void) anti; (void) d;
+ BAT *out = NULL, *a = NULL, *b = NULL, *s1 = NULL, *s2 = NULL;
+ BATiter a_iter, b_iter;
+ str msg = MAL_SUCCEED;
+ BUN count = 0;
+ struct canditer ci1, ci2;
+
+ //get the BATs
+ if ((a = BATdescriptor(*aid)) == NULL || (b = BATdescriptor(*bid)) ==
NULL) {
+ msg = createException(MAL, "geom.wkbDWithinGeographicSelect",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ }
+
+ //check for candidate lists
+ if (s1_id && !is_bat_nil(*s1_id) && !(s1 = BATdescriptor(*s1_id))) {
+ msg = createException(MAL, "geom.wkbDWithinGeographicSelect",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ }
+ if (s2_id && !is_bat_nil(*s2_id) && !(s2 = BATdescriptor(*s2_id))) {
+ msg = createException(MAL, "geom.wkbDWithinGeographicSelect",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ if (s1)
+ BBPunfix(s1->batCacheid);
+ }
+ count = canditer_init(&ci1, a, s1);
+ canditer_init(&ci2, b, s2);
+
+ //create a new BAT for the output
+ if ((out = COLnew(a->hseqbase, ATOMindex("oid"), BATcount(a),
TRANSIENT)) == NULL) {
+ msg = createException(MAL, "geom.wkbDWithinGeographicSelect",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ }
+
+ //iterator over the BATs
+ a_iter = bat_iterator(a);
+ b_iter = bat_iterator(b);
+ return MAL_SUCCEED;
+}
+
+str
+wkbDWithinGeographicJoin(bat *lres, bat *rres, const bat *lwkb, const bat
*rwkb, const bat *lsid, const bat *rsid, const bit *nil_matches, const lng
*estimate)
+{
+ (void) lres; (void) rres; (void) lwkb; (void) rwkb; (void) lsid; (void)
rsid; (void) nil_matches; (void) estimate;
+ return MAL_SUCCEED;
+}
+*/
+
/**
* Intersects
*
@@ -7595,14 +7642,14 @@ static mel_atom geom_init_atoms[] = {
static mel_func geom_init_funcs[] = {
//TODO Fill in descriptions
command("geom", "DistanceGeographic", wkbDistanceGeographic, false, "TODO",
args(1, 3, arg("", dbl), arg("a", wkb), arg("b", wkb))),
- command("geom", "DWithinGeographic", wkbDWithinGeographic, false, "TODO",
args(1, 4, arg("", bit), arg("a", wkb), arg("b", wkb), arg("d", dbl))),
command("geom", "IntersectsGeographic", wkbIntersectsGeographic, false,
"Returns true if the geographic Geometries intersect in any point", args(1, 3,
arg("", bit), arg("a", wkb), arg("b", wkb))),
command("geom", "CoversGeographic", wkbCoversGeographic, false, "TODO",
args(1, 3, arg("", bit), arg("a", wkb), arg("b", wkb))),
command("batgeom", "DistanceGeographic", wkbDistanceGeographic_bat, false,
"TODO", args(1, 3, batarg("", dbl), batarg("a", wkb), batarg("b", wkb))),
command("batgeom", "DistanceGeographic", wkbDistanceGeographic_bat_cand,
false, "TODO", args(1, 5, batarg("", dbl), batarg("a", wkb), batarg("b", wkb),
batarg("s1", oid), batarg("s2", oid))),
-
- //command("geom", "DWithinGeographicselect", wkbDWithinGeographicSelect,
false, "TODO", args(1, 6, batarg("", oid), batarg("a", wkb), batarg("b", wkb),
arg("d", dbl), batarg("cand",oid),arg("anti",bit))),
+
+ command("geom", "DWithinGeographic", wkbDWithinGeographic, false, "TODO",
args(1, 4, arg("", bit), arg("a", wkb), arg("b", wkb), arg("d", dbl))),
+ //command("geom", "DWithinGeographicselect", wkbDWithinGeographicSelect,
false, "TODO", args(1, 7, batarg("", oid), batarg("a", wkb), batarg("b", wkb),
arg("d", dbl), batarg("s1", oid), batarg("s2", oid),arg("anti",bit))),
//command("geom", "DWithinGeographicjoin", wkbDWithinGeographicJoin, false,
"TODO", args(2, 9, batarg("lr",oid),batarg("rr",oid), batarg("a", wkb),
batarg("b", wkb), arg("d", dbl),
batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
command("aggr", "Collect", wkbCollectAggr, false, "TODO", args(1, 2, arg("",
wkb), batarg("val", wkb))),
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -83,7 +83,6 @@ typedef struct CartPoint
/* Geographic functions */
str wkbDistanceGeographic(dbl* out, wkb** a, wkb** b);
-str wkbDWithinGeographic(bit* out, wkb** a, wkb** b, dbl *distance);
str wkbIntersectsGeographic(bit* out, wkb** a, wkb** b);
str wkbCoversGeographic(bit* out, wkb** a, wkb** b);
@@ -91,6 +90,13 @@ str wkbCollectAggrSubGroupedCand(bat* ou
str wkbCollectAggrSubGrouped(bat *out, const bat *bid, const bat *gid, const
bat *eid, const bit *skip_nils);
str wkbCollectAggr (wkb **out, const bat *bid);
+str wkbDistanceGeographic_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id);
+str wkbDistanceGeographic_bat_cand(bat *out_id, bat *a_id, bat *b_id, bat
*s1_id, bat *s2_id);
+
+str wkbDWithinGeographic(bit* out, wkb** a, wkb** b, dbl *distance);
+//str wkbDWithinGeographicSelect(bat* out, const bat *aid, const bat *bid, dbl
*d, const bat *s1_id, const bat *s2_id, const bit *anti);
+//str wkbDWithinGeographicJoin(bat *lres, bat *rres, const bat *lwkb, const
bat *rwkb, const bat *lsid, const bat *rsid, const bit *nil_matches, const lng
*estimate);
+
/**
*
* Geographic update code end
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -12,6 +12,165 @@
#include "geom.h"
+/********** Geo Update **********/
+
+//TODO: Rename these functions with Stefanos
+str
+wkbDistanceGeographic_bat(bat *out_id, bat *a_id, bat *b_id)
+{
+ BAT *out = NULL, *a = NULL, *b = NULL;
+ BATiter a_iter, b_iter;
+ str msg = MAL_SUCCEED;
+
+ //get the BATs
+ if ((a = BATdescriptor(*a_id)) == NULL || (b = BATdescriptor(*b_id)) ==
NULL) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ goto clean;
+ }
+ //check if the BATs are aligned
+ if (a->hseqbase != b->hseqbase || BATcount(a) != BATcount(b)) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(38000) "Columns must be aligned");
+ goto clean;
+ }
+ //create a new BAT for the output
+ if ((out = COLnew(a->hseqbase, ATOMindex("dbl"), BATcount(a),
TRANSIENT)) == NULL) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ goto clean;
+ }
+
+ //iterator over the BATs
+ a_iter = bat_iterator(a);
+ b_iter = bat_iterator(b);
+
+ for (BUN i = 0; i < BATcount(a); i++) {
+ double distanceVal = 0;
+ wkb *aWKB = (wkb *) BUNtvar(a_iter, i);
+ wkb *bWKB = (wkb *) BUNtvar(b_iter, i);
+
+ /*if (i < 1000) {
+ char *geomSTR1, *geomSTR2;
+ wkbAsText(&geomSTR1, &aWKB, NULL);
+ wkbAsText(&geomSTR2, &bWKB, NULL);
+ printf("i: %zu -> (%s %s)\n",i,geomSTR1,geomSTR2);
+ fflush(stdout);
+ }*/
+
+
+ if ((msg = wkbDistanceGeographic(&distanceVal, &aWKB, &bWKB))
!= MAL_SUCCEED) {
+ BBPreclaim(out);
+ goto bailout;
+ }
+ if (BUNappend(out, &distanceVal, false) != GDK_SUCCEED) {
+ BBPreclaim(out);
+ msg = createException(MAL,
"batgeom.DistanceGeographic", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ goto bailout;
+ }
+ }
+
+ BBPkeepref(*out_id = out->batCacheid);
+
+ bailout:
+ bat_iterator_end(&a_iter);
+ bat_iterator_end(&b_iter);
+ clean:
+ if (a)
+ BBPunfix(a->batCacheid);
+ if (b)
+ BBPunfix(b->batCacheid);
+
+ return msg;
+}
+
+str
+wkbDistanceGeographic_bat_cand(bat *out_id, bat *a_id, bat *b_id, bat *s1_id,
bat *s2_id)
+{
+ BAT *out = NULL, *a = NULL, *b = NULL, *s1 = NULL, *s2 = NULL;
+ BATiter a_iter, b_iter;
+ BUN count = 0;
+ str msg = MAL_SUCCEED;
+ struct canditer ci1, ci2;
+ oid off1, off2;
+
+ //get the BATs
+ if ((a = BATdescriptor(*a_id)) == NULL || (b = BATdescriptor(*b_id)) ==
NULL) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ goto clean;
+ }
+ //check if the BATs are aligned
+ if (a->hseqbase != b->hseqbase || BATcount(a) != BATcount(b)) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(38000) "Columns must be aligned");
+ goto clean;
+ }
+ //check for candidate lists
+ if (s1_id && !is_bat_nil(*s1_id) && !(s1 = BATdescriptor(*s1_id))) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ goto clean;
+ }
+ if (s2_id && !is_bat_nil(*s2_id) && !(s2 = BATdescriptor(*s2_id))) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ if (s1)
+ BBPunfix(s1->batCacheid);
+ goto clean;
+ }
+ count = canditer_init(&ci1, a, s1);
+ canditer_init(&ci2, b, s2);
+
+ //create a new BAT for the output
+ if ((out = COLnew(ci1.hseq, ATOMindex("dbl"), count, TRANSIENT)) ==
NULL) {
+ msg = createException(MAL, "batgeom.DistanceGeographic",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ if (s1)
+ BBPunfix(s1->batCacheid);
+ if (s2)
+ BBPunfix(s2->batCacheid);
+ goto clean;
+ }
+
+ off1 = a->hseqbase;
+ off2 = b->hseqbase;
+
+ //iterator over the BATs
+ a_iter = bat_iterator(a);
+ b_iter = bat_iterator(b);
+
+ for (BUN i = 0; i < count; i++) {
+ double distanceVal = 0;
+ oid p1 = (canditer_next(&ci1) - off1);
+ oid p2 = (canditer_next(&ci2) - off2);
+ wkb *aWKB = (wkb *) BUNtvar(a_iter, p1);
+ wkb *bWKB = (wkb *) BUNtvar(b_iter, p2);
+
+ if ((msg = wkbDistanceGeographic(&distanceVal, &aWKB, &bWKB))
!= MAL_SUCCEED) {
+ BBPreclaim(out);
+ goto bailout;
+ }
+ if (BUNappend(out, &distanceVal, false) != GDK_SUCCEED) {
+ BBPreclaim(out);
+ msg = createException(MAL,
"batgeom.DistanceGeographic", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ goto bailout;
+ }
+ }
+
+ BBPkeepref(*out_id = out->batCacheid);
+
+ bailout:
+ bat_iterator_end(&a_iter);
+ bat_iterator_end(&b_iter);
+ if (s1)
+ BBPunfix(s1->batCacheid);
+ if (s2)
+ BBPunfix(s2->batCacheid);
+ clean:
+ if (a)
+ BBPunfix(a->batCacheid);
+ if (b)
+ BBPunfix(b->batCacheid);
+
+ return msg;
+
+}
+
+/********** Geo Update **********/
+
/*******************************/
/********** One input **********/
/*******************************/
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
@@ -4,6 +4,26 @@
--
-- Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
+-------------------------------------------------------------------------
+------------------------- Geography functions ---------------------------
+-------------------------------------------------------------------------
+CREATE FUNCTION ST_DistanceGeographic(geom1 Geometry, geom2 Geometry) RETURNS
double EXTERNAL NAME geom."DistanceGeographic";
+GRANT EXECUTE ON FUNCTION ST_DistanceGeographic(Geometry, Geometry) TO PUBLIC;
+--CREATE FUNCTION ST_DWithinGeographic(geom1 Geometry, geom2 Geometry,
distance double) RETURNS boolean EXTERNAL NAME geom."DWithinGeographic";
+--GRANT EXECUTE ON FUNCTION ST_DWithinGeographic(Geometry, Geometry, double)
TO PUBLIC;
+CREATE FUNCTION ST_IntersectsGeographic(geom1 Geometry, geom2 Geometry)
RETURNS boolean EXTERNAL NAME geom."IntersectsGeographic";
+GRANT EXECUTE ON FUNCTION ST_IntersectsGeographic(Geometry, Geometry) TO
PUBLIC;
+CREATE FUNCTION ST_CoversGeographic(geom1 Geometry, geom2 Geometry) RETURNS
boolean EXTERNAL NAME geom."CoversGeographic";
+GRANT EXECUTE ON FUNCTION ST_CoversGeographic(Geometry, Geometry) TO PUBLIC;
+
+CREATE AGGREGATE ST_Collect(geom Geometry) RETURNS Geometry external name
aggr."Collect";
+
+CREATE FILTER FUNCTION ST_DWithinGeographic(geom1 Geometry, geom2 Geometry,
distance double) EXTERNAL NAME geom."DWithinGeographic";
+
+-------------------------------------------------------------------------
+------------------------- Geography functions ---------------------------
+-------------------------------------------------------------------------
+
-- make sure you load the geom module before loading this sql module
CREATE FUNCTION Has_Z(info integer) RETURNS integer EXTERNAL NAME geom."hasZ";
@@ -4578,18 +4598,3 @@ GRANT EXECUTE ON FUNCTION ST_DumpPoints(
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list