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

Reply via email to