Changeset: 641716e02975 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=641716e02975
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:
DistanceXYZ and its bulk version. Fix a bug in DumpPoints, when you get an
empty collection, just do not add anything.
diffs (truncated from 403 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
@@ -1592,38 +1592,38 @@ dumpGeometriesSingle(BAT *idBAT, BAT *ge
{
char *newPath = NULL;
size_t pathLength = strlen(path);
- wkb *singleWKB = geos2wkb(geosGeometry);
+ wkb *singleWKB = NULL;
str err = MAL_SUCCEED;
- if (singleWKB == NULL)
- throw(MAL, "geom.Dump", "geos2wkb failed");
-
- //change the path only if it is empty
- if (pathLength == 0) {
- int lvlDigitsNum = 10; //MAX_UNIT = 4,294,967,295
-
- (*lvl)++;
-
- newPath = GDKmalloc(lvlDigitsNum + 1);
- if (newPath == NULL) {
- GDKfree(singleWKB);
- throw(MAL, "geom.Dump", MAL_MALLOC_FAIL);
- }
- snprintf(newPath, lvlDigitsNum + 1, "%u", *lvl);
- } else {
- //remove the comma at the end of the path
- pathLength--;
- newPath = GDKmalloc(pathLength + 1);
- if (newPath == NULL) {
- GDKfree(singleWKB);
- throw(MAL, "geom.Dump", MAL_MALLOC_FAIL);
- }
- strncpy(newPath, path, pathLength);
- newPath[pathLength] = '\0';
- }
- if (BUNappend(idBAT, newPath, TRUE) != GDK_SUCCEED ||
- BUNappend(geomBAT, singleWKB, TRUE) != GDK_SUCCEED)
- err = createException(MAL, "geom.Dump", "BUNappend failed");
+ if ( (singleWKB = geos2wkb(geosGeometry)) == NULL)
+ throw(MAL, "geom.Dump", "geos2wkb failed");
+
+ //change the path only if it is empty
+ if (pathLength == 0) {
+ int lvlDigitsNum = 10; //MAX_UNIT = 4,294,967,295
+
+ (*lvl)++;
+
+ newPath = GDKmalloc(lvlDigitsNum + 1);
+ if (newPath == NULL) {
+ GDKfree(singleWKB);
+ throw(MAL, "geom.Dump", MAL_MALLOC_FAIL);
+ }
+ snprintf(newPath, lvlDigitsNum + 1, "%u", *lvl);
+ } else {
+ //remove the comma at the end of the path
+ pathLength--;
+ newPath = GDKmalloc(pathLength + 1);
+ if (newPath == NULL) {
+ GDKfree(singleWKB);
+ throw(MAL, "geom.Dump", MAL_MALLOC_FAIL);
+ }
+ strncpy(newPath, path, pathLength);
+ newPath[pathLength] = '\0';
+ }
+ if (BUNappend(idBAT, newPath, TRUE) != GDK_SUCCEED ||
+ BUNappend(geomBAT, singleWKB, TRUE) != GDK_SUCCEED)
+ err = createException(MAL, "geom.Dump", "BUNappend failed");
GDKfree(newPath);
GDKfree(singleWKB);
@@ -1694,8 +1694,10 @@ dumpGeometriesGeometry_(BAT *idBAT, BAT
if (empty) {
str err;
//handle it as single
- if ((err = dumpGeometriesSingle(idBAT, geomBAT,
geosGeometry, &lvl, path)) != MAL_SUCCEED)
- return err;
+ //return dumpGeometriesSingle(idBAT, geomBAT,
geosGeometry, &lvl, path);
+ //When it is empty do not add it.
+ //TODO: check if this is correct.
+ return MAL_SUCCEED;
}
return dumpGeometriesMulti(idBAT, geomBAT, geosGeometry, path);
@@ -5892,13 +5894,22 @@ wkbDWithinXYZ(bit *out, wkb **geomWKB_a,
str err;
wkb *geomWKB_b = NULL;
- GEOSGeom geosGeometry_b;
+ GEOSGeom geosGeometry_b, geosGeometry_a;
GEOSCoordSeq seq;
+ /*
if (wkb_isnil(*geomWKB_a)) {
*out = bit_nil;
return MAL_SUCCEED;
}
+ */
+ if (wkb_isnil(*geomWKB_a) || *distance == dbl_nil) {
+ throw(MAL, "wkbDWithinXYZ", "one of the arguments is NULL");
+ }
+
+ if ( (geosGeometry_a = wkb2geos(*geomWKB_a)) == NULL) {
+ throw(MAL, "wkbDWithinXYZ", "wkb2geos failed");
+ }
/*Build Geometry b*/
if (*x == dbl_nil || *y == dbl_nil || *z == dbl_nil) {
@@ -5927,22 +5938,89 @@ wkbDWithinXYZ(bit *out, wkb **geomWKB_a,
if (*srid != int_nil)
GEOSSetSRID(geosGeometry_b, *srid);
+
+ if (GEOSGetSRID(geosGeometry_a) != GEOSGetSRID(geosGeometry_b)) {
+ GEOSGeom_destroy(geosGeometry_b);
+ GEOSGeom_destroy(geosGeometry_a);
+ return createException(MAL, "geom.wkbDWithinXYZ", "Geometries
of different SRID");
+ }
- if ((geomWKB_b = geos2wkb(geosGeometry_b)) == NULL) {
+ //if ((err = wkbDistance(&distanceComputed, geomWKB_a, &geomWKB_b)) !=
MAL_SUCCEED) {
+ if (!GEOSDistance(geosGeometry_a, geosGeometry_b, &distanceComputed)) {
GEOSGeom_destroy(geosGeometry_b);
- throw(MAL, "wkbDWithinXYZ", "geos2wkb failed");
+ GEOSGeom_destroy(geosGeometry_a);
+ return createException(MAL, "geom.wkbDWithinXYZ", "GEOSDistance
failed");
+ }
+
+ GEOSGeom_destroy(geosGeometry_b);
+ GEOSGeom_destroy(geosGeometry_a);
+ *out = (distanceComputed <= *distance);
+
+ return MAL_SUCCEED;
+}
+
+str
+wkbDistanceXYZ(double *out, wkb **geomWKB_a, dbl *x, dbl *y, dbl *z, int *srid)
+{
+ double distanceComputed;
+ str err;
+ wkb *geomWKB_b = NULL;
+
+ GEOSGeom geosGeometry_b, geosGeometry_a;
+ GEOSCoordSeq seq;
+
+ if (wkb_isnil(*geomWKB_a)) {
+ throw(MAL, "wkbDistanceXYZ", "one of the arguments is NULL");
+ }
+
+ if ( (geosGeometry_a = wkb2geos(*geomWKB_a)) == NULL) {
+ throw(MAL, "wkbDistanceXYZ", "wkb2geos failed");
}
- if (wkb_isnil(*geomWKB_a) || wkb_isnil(geomWKB_b) || *distance ==
dbl_nil) {
+ /*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, "wkbDistanceXYZ", "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, "wkbDistanceXYZ", "GEOSCoordSeq_setOrdinate failed");
+ }
+
+ if ((geosGeometry_b = GEOSGeom_createPoint(seq)) == NULL) {
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, "wkbDistanceXYZ", "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_b);
- throw(MAL, "wkbDWithinXYZ", "one of the arguments is NULL");
- }
- if ((err = wkbDistance(&distanceComputed, geomWKB_a, &geomWKB_b)) !=
MAL_SUCCEED) {
- return err;
+ GEOSGeom_destroy(geosGeometry_a);
+ return createException(MAL, "geom.wkbDistanceXYZ", "Geometries
of different SRID");
+ }
+
+ //if ((err = wkbDistance(&distanceComputed, geomWKB_a, &geomWKB_b)) !=
MAL_SUCCEED) {
+ if (!GEOSDistance(geosGeometry_a, geosGeometry_b, &distanceComputed)) {
+ GEOSGeom_destroy(geosGeometry_b);
+ GEOSGeom_destroy(geosGeometry_a);
+ return createException(MAL, "geom.wkbDistanceXYZ",
"GEOSDistance failed");
}
GEOSGeom_destroy(geosGeometry_b);
- *out = (distanceComputed <= *distance);
+ GEOSGeom_destroy(geosGeometry_a);
+ *out = distanceComputed;
return MAL_SUCCEED;
}
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -226,6 +226,8 @@ geom_export str wkbArea_bat(bat *inBAT_i
geom_export str wkbCentroid(wkb **out, wkb **geom);
geom_export str wkbCentroid_bat(bat *outBAT_id, bat *inBAT_id);
geom_export str wkbDistance(dbl *out, wkb **a, wkb **b);
+geom_export str wkbDistanceXYZ(dbl *out, wkb **a, dbl *x, dbl *y, dbl *z, int
*srid);
+geom_export str wkbDistanceXYZ_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 wkbLength(dbl *out, wkb **a);
geom_export str wkbConvexHull(wkb **out, wkb **geom);
geom_export str wkbIntersection(wkb **out, wkb **a, wkb **b);
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -278,6 +278,8 @@ command Centroid(w:wkb) :wkb address wkb
comment "Computes the geometric center of a geometry, or equivalently, the
center of mass of the geometry as a POINT.";
command Distance(a:wkb, b:wkb) :dbl address wkbDistance
comment "Returns the 2-dimensional minimum cartesian distance between the two
geometries in projected units (spatial ref units.";
+command Distance(a:wkb, x:dbl, y:dbl, z:dbl, srid:int) :dbl address
wkbDistanceXYZ
+comment "Returns the 2-dimensional minimum cartesian distance between the two
geometries in projected units (spatial ref units.";
command Length(w:wkb) :dbl address wkbLength
comment "Returns the cartesian 2D length of the geometry if it is a linestrin
or multilinestring";
command ConvexHull(w:wkb) :wkb address wkbConvexHull
@@ -853,6 +855,14 @@ command Distance(a:bat[:wkb], b:bat[:wkb
command Distance(a:wkb, b:bat[:wkb]) :bat[:dbl] address wkbDistance_geom_bat;
command Distance(a:bat[:wkb], b:wkb) :bat[:dbl] address wkbDistance_bat_geom;
+#TODO: It is necessary to handle all combinations
+command DistanceXYZ_bat(a:bat[:wkb], xb:bat[:dbl], x:dbl, yb:bat[:dbl], y:dbl,
zb:bat[:dbl], z:dbl, srid:int) :bat[:dbl] address wkbDistanceXYZ_bat;
+
+function Distance(a:bat[:wkb], x:bat[:dbl], y:bat[:dbl], z:bat[:dbl],
srid:int) :bat[:dbl];
+ x := DistanceXYZ_bat(a, x, 0:dbl, y, 0:dbl, z, 0:dbl, srid);
+ return x;
+end Distance;
+
command Centroid(w:bat[:wkb]) :bat[:wkb] address wkbCentroid_bat
comment "Computes the geometric center of a geometry, or equivalently, the
center of mass of the geometry as a POINT.";
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -1371,6 +1371,142 @@ wkbDWithinXYZ_bat(bat *outBAT_id, bat *i
return WKBDBLDBLDBLINTtoBITflagDBL_bat(outBAT_id, inBAT_id, inXBAT_id,
dx, inYBAT_id, dy, inZBAT_id, dz, srid, distance, wkbDWithinXYZ,
"batgeom.DWithinXYZ");
}
+/******************************************************************************************/
+/************************* IN: wkb dbl dbl dbl int - OUT: dbl
*****************************/
+/******************************************************************************************/
+
+static str
+WKBDBLDBLDBLINTtoDBL_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) (dbl *, 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;
+ str msg = MAL_SUCCEED;
+#ifdef GEOMBULK_DEBUG
+ static struct timeval start, stop;
+ unsigned long long t;
+#endif
+ dbl *outs = NULL;
+
+ //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("dbl"),
BATcount(inBAT), TRANSIENT)) == NULL) {
+ BBPunfix(inBAT->batCacheid);
+ if (*inXBAT_id != bat_nil)
+ BBPunfix(inXBAT->batCacheid);
+ if (*inYBAT_id != bat_nil)
+ BBPunfix(inYBAT->batCacheid);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list