[prev in list] [next in list] [prev in thread] [next in thread] 

List:       monetdb-checkins
Subject:    MonetDB: sfcgal - Add our implementation of GEOSGeomGetZ, make s...
From:       Romulo Goncalves <commits+goncalve=cwi.nl () monetdb ! org>
Date:       2016-04-27 11:50:40
Message-ID: hg.f9a57b64a01b.1461757840.6315528441665844383 () monetdb2 ! cwi-incubator ! nl
[Download RAW message or body]

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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic