Changeset: af48dc29c457 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=af48dc29c457
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.mal
geom/sql/40_geom.sql
Branch: geo
Log Message:
attempt to create ST_InteriorRings
diffs (144 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -162,6 +162,7 @@ geom_export str wkbMakePolygon(wkb** out
geom_export str wkbExteriorRing(wkb**, wkb**);
geom_export str wkbInteriorRingN(wkb**, wkb**, short*);
geom_export str wkbNumRings(int*, wkb**, int*);
+geom_export str wkbInteriorRings(int* outBAT_id, wkb** geomWKB);
geom_export str wkbIsClosed(bit *out, wkb **geom);
geom_export str wkbIsRing(bit *out, wkb **geom);
geom_export str wkbIsValid(bit *out, wkb **geom);
@@ -2262,13 +2263,13 @@ str wkbInteriorRingN(wkb **interiorRingW
if (!geosGeometry) {
*interiorRingWKB = wkb_nil;
- throw(MAL, "geom.interiorRing", "wkb2geos failed");
+ throw(MAL, "geom.interiorRingN", "wkb2geos failed");
}
- if (GEOSGeomTypeId(geosGeometry) != GEOS_POLYGON) {
+ if ((GEOSGeomTypeId(geosGeometry)+1) != wkbPolygon) {
*interiorRingWKB = wkb_nil;
GEOSGeom_destroy(geosGeometry);
- throw(MAL, "geom.interiorRing", "Geometry not a Polygon");
+ throw(MAL, "geom.interiorRingN", "Geometry not a Polygon");
}
@@ -2285,13 +2286,82 @@ str wkbInteriorRingN(wkb **interiorRingW
throw(MAL, "geom.interiorRingN", "GEOSGetInteriorRingN failed.
Not enough interior rings");
}
- /* get the exterior ring of the geometry */
+ /* get the interior ring of the geometry */
interiorRingGeometry = GEOSGetInteriorRingN(geosGeometry, *ringNum);
+ if (!interiorRingGeometry) {
+ *interiorRingWKB = wkb_nil;
+ throw(MAL, "geom.interiorRingN", "GEOSGetInteriorRingN failed");
+ }
/* get the wkb representation of it */
*interiorRingWKB = geos2wkb(interiorRingGeometry);
+
+ return MAL_SUCCEED;
+}
+
+str wkbInteriorRings(int* outBAT_id, wkb** geomWKB) {
+ BAT* outBAT;
+ int interiorRingsNum = 0, i=0;
+ GEOSGeom geosGeometry;
+ str ret = MAL_SUCCEED;
+fprintf(stderr, "in wkbInteriorRings");
+
+ if (wkb_isnil(*geomWKB)) {
+ throw(MAL, "geom.InteriorRings", "Null input geometry");
+ }
+
+ geosGeometry = wkb2geos(*geomWKB);
+
+ if(!geosGeometry) {
+ throw(MAL, "geom.InteriorRings", "Error in wkb2geos");
+ }
- return MAL_SUCCEED;
-
+ if ((GEOSGeomTypeId(geosGeometry)+1) != wkbPolygon) {
+ GEOSGeom_destroy(geosGeometry);
+ throw(MAL, "geom.interiorRings", "Geometry not a Polygon");
+
+ }
+
+ ret = wkbNumRings(&interiorRingsNum, geomWKB, &i);
+
+ if(ret != MAL_SUCCEED) {
+ GEOSGeom_destroy(geosGeometry);
+ throw(MAL, "geom.InteriorRings", "Error in wkbNumRings");
+ }
+
+ //create a new BAT for the output
+ if ((outBAT = BATnew(TYPE_void, ATOMindex("wkb"), interiorRingsNum,
TRANSIENT)) == NULL) {
+ GEOSGeom_destroy(geosGeometry);
+ throw(MAL, "batgeom.Contains", MAL_MALLOC_FAIL);
+ }
+ //set the first idx of the output BAT equal to that of the aBAT
+ BATseqbase(outBAT, 0);
+
+
+ for (i = 0; i < interiorRingsNum; i++) {
+ const GEOSGeometry* interiorRingGeometry;
+ wkb* interiorRingWKB;
+
+ /* get the interior ring of the geometry */
+ interiorRingGeometry = GEOSGetInteriorRingN(geosGeometry, i);
+ if (!interiorRingGeometry) {
+ interiorRingWKB = wkb_nil;
+ throw(MAL, "geom.InteriorRings", "GEOSGetInteriorRingN
failed");
+ }
+ /* get the wkb representation of it */
+ interiorRingWKB = geos2wkb(interiorRingGeometry);
+ if(!interiorRingWKB) {
+ BBPreleaseref(outBAT->batCacheid);
+ throw(MAL, "geom.InteriorRings", "Error in wkb2geos");
+ }
+
+ BUNappend(outBAT,&interiorRingWKB,TRUE); //add the result to
the outBAT
+ }
+
+ //set some properties of the new BAT
+ BATsettrivprop(outBAT);
+ BATderiveProps(outBAT,FALSE);
+ BBPkeepref(*outBAT_id = outBAT->batCacheid);
+
return MAL_SUCCEED;
}
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -429,6 +429,9 @@ geom.prelude();
module batgeom;
+command InteriorRings(w:wkb) :bat[:oid,:wkb] address wkbInteriorRings
+comment "Returns a table with all the interior rings of the polygon";
+
command ContainsFilter{unsafe}(a:bat[:oid,:wkb], b:bat[:oid,:wkb])
(aFiltered:bat[:oid,:wkb], bFiltered:bat[:oid,:wkb]) address
wkbContainsFilter_bat
comment "Filters the points in the bats according to the MBR of the other
bat.";
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
@@ -4087,7 +4087,12 @@ CREATE FUNCTION ST_ExteriorRing(geom Geo
CREATE FUNCTION ST_SetExteriorRing(geom Geometry) RETURNS Geometry external
name geom."MakePolygon"; --gets a linestring and creates a polygon (postGIS:
ST_MakePolygon)
CREATE FUNCTION ST_NumInteriorRing(geom Geometry) RETURNS integer EXTERNAL
NAME geom."NumInteriorRings";
CREATE FUNCTION ST_InteriorRingN(geom Geometry, positionNum integer) RETURNS
Geometry EXTERNAL NAME geom."InteriorRingN";
---CREATE FUNCTION ST_InteriorRings(geom Geometry) RETURNS TABLE(geom Geometry)
EXTERNAL NAME geom."InteriorRings";
+CREATE FUNCTION ST_InteriorRings(geom Geometry) RETURNS Geometry EXTERNAL NAME
geom."InteriorRings";
+--BEGIN
+-- DECLARE TABLE res(ring integer);
+-- INSERT INTO res VALUES(1);
+-- RETURN res;
+--END;
--CREATE FUNCTION ST_SetInteriorRings(geom Geometry[]) RETURNS Geometry
EXTERNAL NAME geom."InteriorRings";
--Functions on Polyhedral Surfaces
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list