Changeset: a8408633b65e for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a8408633b65e
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geom.mal
geom/sql/40_geom.sql
Branch: sfcgal
Log Message:
Aggregation function for Polygonize. Fix typo in MAL exception
diffs (260 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -2073,33 +2073,163 @@ wkbDumpPointsP(bat *parentBAT_id, bat *i
return wkbDumpPoints_(parentBAT_id, idBAT_id, geomBAT_id, geomWKB, parent);
}
-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))) {
+static str
+wkbPolygonize_(wkb** outWKB, wkb** geom1, wkb** geom2){
+ str msg = MAL_SUCCEED;
+ GEOSGeom geos1Geometry = NULL, geos2Geometry = NULL;
+ GEOSGeometry* outGeometry = NULL;
+ int i = 0, geos1Num = 0, geos2Num = 0, geos1Type, geos2Type;
+ const GEOSGeometry **multiGeometry = NULL;
+ bit single1 = 0, single2 = 0;
+
+
+ if ((geos1Geometry = wkb2geos(*geom1)) == NULL) {
*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;
+ throw(MAL, "geom.wkbPolygonize_", "wkb2geos failed");
+ }
+
+ geos1Type = GEOSGeomTypeId(geos1Geometry) + 1;
+ switch(geos1Type) {
+ case wkbPoint_mdb:
+ case wkbLineString_mdb:
+ case wkbLinearRing_mdb:
+ case wkbPolygon_mdb:
+ geos1Num = 1;
+ single1 = 1;
+ break;
+ case wkbMultiPoint_mdb:
+ case wkbMultiLineString_mdb:
+ case wkbMultiPolygon_mdb:
+ case wkbGeometryCollection_mdb:
+ if ( (geos1Num = GEOSGetNumGeometries(geos1Geometry)) < 0) {
+ GEOSGeom_destroy(geos1Geometry);
+ *outWKB = NULL;
+ throw(MAL, "geom.wkbPolygonize_", "GEOSGetNumGeometries
failed");
+ }
+ break;
+ default:
+ return createException(MAL, "geom.wkbPolygonize", "%s Unknown
geometry type", geom_type2str(geos1Type,0));
+ }
+
+ if ( (geos2Geometry = wkb2geos(*geom2)) == NULL) {
+ GEOSGeom_destroy(geos1Geometry);
+ *outWKB = NULL;
+ throw(MAL, "geom.wkbPolygonize_", "wkb2geos failed");
+ }
+
+ geos2Type = GEOSGeomTypeId(geos2Geometry) + 1;
+ switch(geos2Type) {
+ case wkbPoint_mdb:
+ case wkbLineString_mdb:
+ case wkbLinearRing_mdb:
+ case wkbPolygon_mdb:
+ geos2Num = 1;
+ single2 = 1;
+ break;
+ case wkbMultiPoint_mdb:
+ case wkbMultiLineString_mdb:
+ case wkbMultiPolygon_mdb:
+ case wkbGeometryCollection_mdb:
+ if ( (geos2Num = GEOSGetNumGeometries(geos2Geometry)) < 0) {
+ GEOSGeom_destroy(geos1Geometry);
+ GEOSGeom_destroy(geos2Geometry);
+ *outWKB = NULL;
+ throw(MAL, "geom.wkbPolygonize_", "GEOSGetNumGeometries
failed");
+ }
+ break;
+ default:
+ return createException(MAL, "geom.wkbPolygonize", "%s Unknown
geometry type", geom_type2str(geos2Type,0));
+ }
+
+ multiGeometry = GDKzalloc(sizeof(GEOSGeometry*) * (geos1Num +
geos2Num));
+
+ for(i=0; i < geos1Num; i++) {
+ if (single1)
+ multiGeometry[i] = geos1Geometry;
+ else
+ multiGeometry[i] = GEOSGetGeometryN(geos1Geometry, i);
+ }
+
+ for(i=0; i< geos2Num; i++) {
+ if (single2)
+ multiGeometry[i+geos1Num] = geos2Geometry;
+ else
+ multiGeometry[i+geos1Num] = GEOSGetGeometryN(geos2Geometry, i);
+ }
+
+ if(!(outGeometry = GEOSPolygonize(multiGeometry, (geos1Num + geos2Num)))) {
+ *outWKB = NULL;
+ msg = createException(MAL, "geom.Polygonize", "GEOSPolygonize
failed");
+ } else {
+ *outWKB = geos2wkb(outGeometry);
+ GEOSGeom_destroy(outGeometry);
+ }
+
+ for(i = 0; i < geos1Num; i++) {
+ GEOSGeom_destroy((GEOSGeometry *)multiGeometry[i]);
+ }
+ for(i = 0; i < geos2Num; i++) {
+ GEOSGeom_destroy((GEOSGeometry *)multiGeometry[i+geos1Num]);
+ }
+ if (multiGeometry)
+ GDKfree(multiGeometry);
+
+ return msg;
+}
+
+str
+wkbPolygonize(wkb** outWKB, wkb** geom1) {
+ wkb *geom2 =
geos2wkb(GEOSGeom_createEmptyCollection(wkbGeometryCollection_mdb - 1));
+ return wkbPolygonize_(outWKB, geom1, &geom2);
+}
+
+str
+wkbsubPolygonize(bat *outBAT_id, bat* bBAT_id, bat *gBAT_id, bat *eBAT_id,
bit* flag)
+{
+ (void) flag;
+ int skip_nils = 1, i = 0;
+ const char *msg = MAL_SUCCEED;
+ str err;
+ BAT *b = NULL, *g = NULL, *e = NULL;
+ oid min, max;
+ BUN ngrp;
+ BUN start, end, cnt;
+ wkb **empty_geoms = NULL;
+ const oid *cand = NULL, *candend = NULL;
+
+ if ((b = BATdescriptor(*bBAT_id)) == NULL) {
+ throw(MAL, "geom.wkbPolygonize", RUNTIME_OBJECT_MISSING);
+ }
+ if ((g = BATdescriptor(*gBAT_id)) == NULL) {
+ BBPunfix(b->batCacheid);
+ throw(MAL, "geom.wkbPolygonize", RUNTIME_OBJECT_MISSING);
+ }
+ if ((e = BATdescriptor(*eBAT_id)) == NULL) {
+ BBPunfix(b->batCacheid);
+ BBPunfix(g->batCacheid);
+ throw(MAL, "geom.wkbPolygonize", RUNTIME_OBJECT_MISSING);
+ }
+
+ if ((msg = BATgroupaggrinit(b, g, e, NULL, &min, &max, &ngrp,
+ &start, &end, &cnt,
+ &cand, &candend)) != NULL) {
+ throw(MAL, "BATgroupPolygonize: %s\n", msg);
+ }
+
+ /*Create the empty geoms*/
+ empty_geoms = (wkb**) GDKmalloc(sizeof(wkb*)*ngrp);
+ for (i = 0; i < ngrp; i++)
+ empty_geoms[i] =
geos2wkb(GEOSGeom_createEmptyCollection(wkbGeometryCollection_mdb - 1));
+
+ err = BATgroupWKBWKBtoWKB(outBAT_id, b, g, e, skip_nils, min, max, ngrp,
start, end, empty_geoms, wkbPolygonize_, "wkbPolygonize");
+ BBPkeepref(*outBAT_id);
+
+ GDKfree(empty_geoms);
+ BBPunfix(b->batCacheid);
+ BBPunfix(g->batCacheid);
+ BBPunfix(e->batCacheid);
+
+ return err;
}
str wkbSimplifyPreserveTopology(wkb** outWKB, wkb** geom, float* tolerance){
@@ -4754,22 +4884,22 @@ wkbsubUnion(bat *outBAT_id, bat* bBAT_id
const oid *cand = NULL, *candend = NULL;
if ((b = BATdescriptor(*bBAT_id)) == NULL) {
- throw(MAL, "geom.wkbCollect", RUNTIME_OBJECT_MISSING);
+ throw(MAL, "geom.wkbUnion", RUNTIME_OBJECT_MISSING);
}
if ((g = BATdescriptor(*gBAT_id)) == NULL) {
BBPunfix(b->batCacheid);
- throw(MAL, "geom.wkbCollect", RUNTIME_OBJECT_MISSING);
+ throw(MAL, "geom.wkbUnion", RUNTIME_OBJECT_MISSING);
}
if ((e = BATdescriptor(*eBAT_id)) == NULL) {
BBPunfix(b->batCacheid);
BBPunfix(g->batCacheid);
- throw(MAL, "geom.wkbCollect", RUNTIME_OBJECT_MISSING);
+ throw(MAL, "geom.wkbUnion", RUNTIME_OBJECT_MISSING);
}
if ((msg = BATgroupaggrinit(b, g, e, NULL, &min, &max, &ngrp,
&start, &end, &cnt,
&cand, &candend)) != NULL) {
- throw(MAL, "BATgroupCollect: %s\n", msg);
+ throw(MAL, "BATgroupUnion: %s\n", msg);
}
/*Create the empty geoms*/
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -256,6 +256,7 @@ geom_export str wkbDumpPoints(bat* idBAT
geom_export str wkbDumpPointsP(bat* partentBAT_id, bat* idBAT_id, bat*
geomBAT_id, wkb**, int* parent);
geom_export str dumpGeometriesGeometry(BAT *idBAT, BAT *geomBAT, const
GEOSGeometry *geosGeometry, const char *path);
geom_export str wkbPolygonize(wkb **res, wkb **geom);
+geom_export str wkbsubPolygonize(bat *outBAT_id, bat* bBAT_id, bat *gBAT_id,
bat *eBAT_id, bit* flag);
geom_export str wkbSimplifyPreserveTopology(wkb **res, wkb **geom, float
*tolerance);
geom_export str geom_2_geom(wkb** resWKB, wkb **valueWKB, int* columnType,
int* columnSRID);
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -354,8 +354,12 @@ command DumpPoints(a:wkb) (id:bat[:oid,
comment "Gets a Geometry and returns the Points in it";
command DumpPointsP(a:wkb, p:int) (parent:bat[:oid, :int], id:bat[:oid, :str],
geom:bat[:oid, :wkb]) address wkbDumpPointsP
comment "Gets a Geometry and returns the Points in it";
+
command Polygonize(a:wkb) :wkb address wkbPolygonize
comment "Creates a GeometryCollection containing possible polygons formed from
the constituent linework of a set of geometries.";
+command subPolygonize(a:bat[:wkb], g:bat[:oid], e:bat[:oid], :bit) :bat[:wkb]
address wkbsubPolygonize
+comment "Creates a GeometryCollection containing possible polygons formed from
the constituent linework of a set of geometries.";
+
command SimplifyPreserveTopology(a:wkb, t:flt) :wkb address
wkbSimplifyPreserveTopology
comment "Returns a \"simplified\" version of the given geometry using the
Douglas-Peucker algorithm.";
diff --git a/geom/sql/40_geom.sql b/geom/sql/40_geom.sql
--- a/geom/sql/40_geom.sql
+++ b/geom/sql/40_geom.sql
@@ -4377,7 +4377,8 @@ CREATE FUNCTION ST_DumpPoints(geom Geome
--CREATE FUNCTION ST_MakeValid RETURNS EXTERNAL NAME
--CREATE FUNCTION ST_MemUnion RETURNS EXTERNAL NAME
--CREATE FUNCTION ST_MinimumBoundingCircle RETURNS EXTERNAL NAME
-CREATE FUNCTION ST_Polygonize(gemo1 Geometry) RETURNS Geometry EXTERNAL NAME
geom."Polygonize";
+CREATE FUNCTION ST_Polygonize(geom Geometry) RETURNS Geometry EXTERNAL NAME
geom."Polygonize";
+CREATE AGGREGATE ST_Polygonize(geom Geometry) RETURNS Geometry EXTERNAL NAME
geom."Polygonize";
--CREATE FUNCTION ST_Node RETURNS EXTERNAL NAME
--CREATE FUNCTION ST_OffsetCurve RETURNS EXTERNAL NAME
--CREATE FUNCTION ST_RemoveRepeatedPoints RETURNS EXTERNAL NAME
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list