Changeset: f9a57b64a01b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f9a57b64a01b
Modified Files:
        geom/monetdb5/geom.c
Branch: sfcgal
Log Message:

Add our implementation of GEOSGeomGetZ, make some function externaly available 
such as geos2wkb, function to get the 3D bounding box, functions to export X3D 
and GeoJson. In numPointsGeometry we commented out the case the Multi Geometry 
only contains one geometry. There are cases where the user creates a 
MultiGeometry to then be able to feed it to SFCGAL 3D functions. Indentation 
and CreatePolygon


diffs (truncated from 524 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
@@ -15,8 +15,6 @@
 
 int TYPE_mbr;
 
-static wkb *geos2wkb(const GEOSGeometry *geosGeometry);
-
 static inline int
 geometryHasZ(int info)
 {
@@ -1343,32 +1341,36 @@ translatePolygon(GEOSGeometry **outGeome
                throw(MAL, "geom.Translate", "GEOSGetInteriorRingN failed.");
        }
 
-       /* iterate over the interiorRing and translate each one of them */
-       transformedInteriorRingGeometries = GDKmalloc(numInteriorRings * 
sizeof(GEOSGeometry *));
-       if (transformedInteriorRingGeometries == NULL) {
-               *outGeometry = NULL;
-               GEOSGeom_destroy(transformedExteriorRingGeometry);
-               throw(MAL, "geom.Translate", MAL_MALLOC_FAIL);
-       }
-       for (i = 0; i < numInteriorRings; i++) {
-               if ((err = 
translateLinearRing(&transformedInteriorRingGeometries[i], 
GEOSGetInteriorRingN(geosGeometry, i), dx, dy, dz)) != MAL_SUCCEED) {
-                       while (--i >= 0)
-                               
GEOSGeom_destroy(transformedInteriorRingGeometries[i]);
-                       GDKfree(transformedInteriorRingGeometries);
-                       GEOSGeom_destroy(transformedExteriorRingGeometry);
-                       *outGeometry = NULL;
-                       return err;
-               }
-       }
-
-       *outGeometry = GEOSGeom_createPolygon(transformedExteriorRingGeometry, 
transformedInteriorRingGeometries, numInteriorRings);
-       if (*outGeometry == NULL) {
-               for (i = 0; i < numInteriorRings; i++)
-                       GEOSGeom_destroy(transformedInteriorRingGeometries[i]);
-               err = createException(MAL, "geom.Translate", 
"GEOSGeom_createPolygon failed");
-       }
-       GDKfree(transformedInteriorRingGeometries);
-       GEOSGeom_destroy(transformedExteriorRingGeometry);
+    /* iterate over the interiorRing and translate each one of them */
+    if (numInteriorRings) {
+        transformedInteriorRingGeometries = GDKmalloc(numInteriorRings * 
sizeof(GEOSGeometry *));
+        if (transformedInteriorRingGeometries == NULL) {
+            *outGeometry = NULL;
+            GEOSGeom_destroy(transformedExteriorRingGeometry);
+            throw(MAL, "geom.Translate", MAL_MALLOC_FAIL);
+        }
+        for (i = 0; i < numInteriorRings; i++) {
+            if ((err = 
translateLinearRing(&transformedInteriorRingGeometries[i], 
GEOSGetInteriorRingN(geosGeometry, i), dx, dy, dz)) != MAL_SUCCEED) {
+                while (--i >= 0)
+                    GEOSGeom_destroy(transformedInteriorRingGeometries[i]);
+                GDKfree(transformedInteriorRingGeometries);
+                GEOSGeom_destroy(transformedExteriorRingGeometry);
+                *outGeometry = NULL;
+                return err;
+            }
+        }
+
+        *outGeometry = GEOSGeom_createPolygon(transformedExteriorRingGeometry, 
transformedInteriorRingGeometries, numInteriorRings);
+        if (*outGeometry == NULL) {
+            for (i = 0; i < numInteriorRings; i++)
+                GEOSGeom_destroy(transformedInteriorRingGeometries[i]);
+            err = createException(MAL, "geom.Translate", 
"GEOSGeom_createPolygon failed");
+        }
+        GDKfree(transformedInteriorRingGeometries);
+        GEOSGeom_destroy(transformedExteriorRingGeometry);
+    } else {
+        *outGeometry = GEOSGeom_createPolygon(transformedExteriorRingGeometry, 
NULL, 0);
+    }
 
        return err;
 }
@@ -1927,6 +1929,53 @@ wkbDumpPoints(bat *idBAT_id, bat *geomBA
        return MAL_SUCCEED;
 }
 
+str wkbPolygonize(wkb** outWKB, wkb** geom){
+       GEOSGeom geosGeometry = wkb2geos(*geom);
+       int i = 0, geometriesNum = GEOSGetNumGeometries(geosGeometry);
+       GEOSGeometry* outGeometry;
+       const GEOSGeometry **multiGeometry;
+
+       multiGeometry = malloc(sizeof(GEOSGeometry*) * geometriesNum);
+       for(i=0; i<geometriesNum; i++) {
+               multiGeometry[i] = GEOSGetGeometryN(geosGeometry, i);
+       }
+
+       if(!(outGeometry = GEOSPolygonize(multiGeometry, geometriesNum))) {
+               *outWKB = NULL;
+               for (i = 0; i < geometriesNum; i++) {
+                       GEOSGeom_destroy((GEOSGeometry *)multiGeometry[i]);
+               }
+               return createException(MAL, "geom.Polygonize", "GEOSPolygonize 
failed");
+       }
+
+       for (i = 0; i < geometriesNum; i++) {
+               GEOSGeom_destroy((GEOSGeometry *)multiGeometry[i]);
+       }
+
+       *outWKB = geos2wkb(outGeometry);
+       GEOSGeom_destroy(outGeometry);
+
+       return MAL_SUCCEED;
+}
+
+str wkbSimplifyPreserveTopology(wkb** outWKB, wkb** geom, float* tolerance){
+       GEOSGeom geosGeometry = wkb2geos(*geom);
+       GEOSGeometry* outGeometry;
+
+       if(!(outGeometry = GEOSTopologyPreserveSimplify(geosGeometry, 
*tolerance))) {
+               *outWKB = NULL;
+               GEOSGeom_destroy(geosGeometry);
+               return createException(MAL, "geom.SimplifyPreserveTopology", 
"GEOSSimplifyPreserveTopology failed");
+       }
+
+       GEOSGeom_destroy(geosGeometry);
+
+       *outWKB = geos2wkb(outGeometry);
+       GEOSGeom_destroy(outGeometry);
+
+       return MAL_SUCCEED;
+}
+
 str
 geom_2_geom(wkb **resWKB, wkb **valueWKB, int *columnType, int *columnSRID)
 {
@@ -2008,6 +2057,30 @@ geoGetType(char **res, int *info, int *f
        return MAL_SUCCEED;
 }
 
+str GEOSGeomGetZ(const GEOSGeometry *geom, double *z) {
+    const GEOSCoordSequence* gcs_new;
+    int type = GEOSGeomTypeId(geom)+1;
+    
+    if (type != wkbPoint_mdb) {
+               *z = dbl_nil;
+               return createException(MAL, "geom.GEOSGeomGetZ", "Geometry type 
should be POINT not %s", geom_type2str(type,0));
+    }
+
+    gcs_new = GEOSGeom_getCoordSeq(geom);      
+
+       if(gcs_new == NULL) {
+               *z = dbl_nil;
+               return createException(MAL, "geom.GEOSGeomGetZ", 
"GEOSGeom_getCoordSeq failed");
+       }
+
+    if(!GEOSCoordSeq_getZ(gcs_new, 0, z)) {
+               *z = dbl_nil;
+        return createException(MAL, "geom.GEOSGeomGetZ", "GEOSCoordSeq_getZ 
failed");
+    }
+
+    return MAL_SUCCEED;
+}
+
 /* initialize geos */
 str
 geom_prelude(void *ret)
@@ -2196,7 +2269,7 @@ wkbaFROMSTR_withSRID(char *fromStr, int 
  * It makes sure to make all checks before returning
  * the input geosGeometry should not be altered by this function
  * return NULL on error */
-static wkb *
+wkb *
 geos2wkb(const GEOSGeometry *geosGeometry)
 {
        size_t wkbLen = 0;
@@ -2293,6 +2366,178 @@ mbrFromGeos(const GEOSGeom geosGeometry)
        return geomMBR;
 }
 
+/* gets the bbox3D from the geometry */
+
+static str
+minMaxZLineString(double *zmin, double *zmax, const GEOSGeometry* 
geosGeometry) {
+       /* get the coordinates of the points comprising the geometry */
+       const GEOSCoordSequence* coordSeq = GEOSGeom_getCoordSeq(geosGeometry);
+    uint32_t i, npoints = 0;
+    double zval;
+    str err;
+
+       if(coordSeq == NULL)
+               return createException(MAL, "geom.MinMaxZ", 
"GEOSGeom_getCoordSeq failed");
+
+       /* get the number of points in the geometry */
+    if (!GEOSCoordSeq_getSize(coordSeq, &npoints)) {
+        *zmin = dbl_nil;
+        *zmax = dbl_nil;
+               return createException(MAL, "geom.MinMaxZ", 
"GEOSGeomGetNumPoints failed");
+    }
+
+    for (i = 0; i < npoints; i++) {
+        GEOSGeom point = (GEOSGeom) GEOSGetGeometryN(geosGeometry, i);
+        if((err = GEOSGeomGetZ(point, &zval)) != MAL_SUCCEED) {
+            str msg = createException(MAL, "geom.MinMaxZ", "%s", err);
+                   GDKfree(err);
+               return msg;
+        }
+        if (zval <= *zmin)
+            *zmin = zval;
+        if (zval > *zmax)
+            *zmax = zval;
+    }
+
+       return MAL_SUCCEED;
+}
+
+static str minMaxZPolygon(double *zmin, double *zmax, const GEOSGeometry* 
geosGeometry) {
+       const GEOSGeometry* exteriorRingGeometry;
+       int numInteriorRings=0, i=0;
+       str err;
+
+       /* get the exterior ring of the polygon */
+       exteriorRingGeometry = GEOSGetExteriorRing(geosGeometry);
+       if(!exteriorRingGeometry) {
+               *zmin = dbl_nil;
+               *zmax = dbl_nil;
+               return createException(MAL, "geom.MinMaxZ","GEOSGetExteriorRing 
failed");
+       }
+       //get the zmin and zmax in the exterior ring
+       if((err = minMaxZLineString(zmin, zmax, exteriorRingGeometry)) != 
MAL_SUCCEED) {
+               str msg = createException(MAL, "geom.MinMaxZ", "%s", err);
+               *zmin = dbl_nil;
+               *zmax = dbl_nil;
+               GDKfree(err);
+               return msg;
+       }
+
+       //check the interior rings
+       numInteriorRings = GEOSGetNumInteriorRings(geosGeometry);
+       if (numInteriorRings == -1 ) {
+               *zmin = dbl_nil;
+               *zmax = dbl_nil;
+               return createException(MAL, "geom.MinMaxZ", 
"GEOSGetNumInteriorRings failed");
+       }
+       // iterate over the interiorRing and transform each one of them
+       for(i=0; i<numInteriorRings; i++) {
+               if((err = minMaxZLineString(zmin, zmax, 
GEOSGetInteriorRingN(geosGeometry, i))) != MAL_SUCCEED) {
+                       str msg = createException(MAL, "geom.MinMaxZ", "%s", 
err);
+                   *zmin = dbl_nil;
+               *zmax = dbl_nil;
+                       GDKfree(err);
+                       return msg;
+               }
+       }
+
+       return MAL_SUCCEED;
+}
+
+static str minMaxZGeometry(double * zmin, double *zmax, const GEOSGeometry 
*geosGeometry);
+static str minMaxZMultiGeometry(double *zmin, double *zmax, const GEOSGeometry 
*geosGeometry) {
+       int geometriesNum, i;
+       const GEOSGeometry *multiGeometry = NULL;
+       str err;
+
+       geometriesNum = GEOSGetNumGeometries(geosGeometry);
+
+       for(i=0; i<geometriesNum; i++) {
+               multiGeometry = GEOSGetGeometryN(geosGeometry, i);
+               if((err = minMaxZGeometry(zmin, zmax, multiGeometry)) != 
MAL_SUCCEED) {
+                       str msg = createException(MAL, "geom.MinMaxZ", "%s", 
err);
+                       GDKfree(err);
+                   *zmin = dbl_nil;
+               *zmax = dbl_nil;
+                       return msg;
+               }
+       }
+
+       return MAL_SUCCEED;
+}
+
+static
+str minMaxZGeometry(double * zmin, double *zmax, const GEOSGeometry 
*geosGeometry) {
+    int geometryType = GEOSGeomTypeId(geosGeometry)+1;
+    str err;
+
+    //check the type of the geometry
+    switch(geometryType) {
+        case wkbPoint_mdb:
+        case wkbLineString_mdb:
+        case wkbLinearRing_mdb:
+            if((err = minMaxZLineString(zmin, zmax, geosGeometry)) != 
MAL_SUCCEED){
+                str msg = createException(MAL, "geom.minMaxZ", "%s",err);
+                GDKfree(err);
+                return msg;
+            }
+            break;
+        case wkbPolygon_mdb:
+            if((err = minMaxZPolygon(zmin, zmax, geosGeometry)) != 
MAL_SUCCEED){
+                str msg = createException(MAL, "geom.minMaxZ", "%s",err);
+                GDKfree(err);
+                return msg;
+            }
+            break;
+        case wkbMultiPoint_mdb:
+        case wkbMultiLineString_mdb:
+        case wkbMultiPolygon_mdb:
+        case  wkbGeometryCollection_mdb:
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to