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

Reply via email to