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