[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