Changeset: 5476a6de4962 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5476a6de4962
Added Files:
        geom/sql/Tests/functions/Tests/ST_NRings.sql
        geom/sql/Tests/functions/Tests/ST_NRings.stable.err
        geom/sql/Tests/functions/Tests/ST_NRings.stable.out
        geom/sql/Tests/functions/Tests/ST_NumInteriorRings.sql
        geom/sql/Tests/functions/Tests/ST_NumInteriorRings.stable.err
        geom/sql/Tests/functions/Tests/ST_NumInteriorRings.stable.out
Removed Files:
        geom/sql/Tests/functions/Tests/numRings.sql
        geom/sql/Tests/functions/Tests/numRings.stable.err
        geom/sql/Tests/functions/Tests/numRings.stable.out
Modified Files:
        geom/monetdb5/geom.c
        geom/monetdb5/geom.h
        geom/monetdb5/geom.mal
        geom/monetdb5/geomBulk.c
        geom/sql/40_geom.sql
        geom/sql/Tests/functions/Tests/All
        geom/sql/Tests/functions/Tests/ST_Boundary.stable.out
        geom/sql/Tests/functions/Tests/ST_CoordDim.stable.out
        geom/sql/Tests/functions/Tests/ST_GeomFromText.stable.err
        geom/sql/Tests/functions/Tests/ST_LineFromText.stable.err
        geom/sql/Tests/functions/Tests/ST_MLineFromText.stable.err
        geom/sql/Tests/functions/Tests/ST_MPointFromText.stable.err
        geom/sql/Tests/functions/Tests/ST_MPolygonFromText.stable.err
        geom/sql/Tests/functions/Tests/ST_MakeBox2D.stable.err
        geom/sql/Tests/functions/Tests/ST_MakePoint.stable.err
        geom/sql/Tests/functions/Tests/ST_NumPoints.stable.err
        geom/sql/Tests/functions/Tests/ST_PointFromText.stable.err
        geom/sql/Tests/functions/Tests/ST_PolygonFromText.stable.err
        geom/sql/Tests/functions/Tests/XYZ.stable.err
        geom/sql/Tests/functions/Tests/XYZMinMax.stable.out
        geom/sql/Tests/functions/Tests/loadTestGeometries.sql
        geom/sql/Tests/functions/Tests/loadTestGeometries.stable.out
Branch: geo
Log Message:

ST_NumInteriorRings + ST_NRings : mtest + bulk


diffs (truncated from 1474 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
@@ -3286,18 +3286,45 @@ str wkbInteriorRings(wkba** geomArray, w
  * plus the exterior ring depending on the value of exteriorRing*/
 str wkbNumRings(int* out, wkb** geom, int* exteriorRing) {
        str ret = MAL_SUCCEED;
+       bit empty;
+       GEOSGeom geosGeometry;
+
+       //check if the geometry is empty
+       if((ret = wkbIsEmpty(&empty, geom)) != MAL_SUCCEED) {
+               str msg = createException(MAL, "geom.wkbNumRings", "%s", ret);
+               GDKfree(ret);
+               return msg; 
+       }
+       if(empty) {
+               //the geometry is empty
+               (*out) = 0;
+               return MAL_SUCCEED; 
+       }
 
        //check the type of the geometry
-       GEOSGeom geosGeometry = wkb2geos(*geom);
+       geosGeometry = wkb2geos(*geom);
+
+       if(!geosGeometry)
+               throw(MAL, "geom.wkbNumRings", "Problem converting WKB to 
GEOS");
+
        if(GEOSGeomTypeId(geosGeometry)+1 == wkbMultiPolygon) {
                //use the first polygon as done by PostGIS
                ret = wkbBasicInt(out, geos2wkb(GEOSGetGeometryN(geosGeometry, 
0)), GEOSGetNumInteriorRings, "geom.NumRngs");
+       } else if(GEOSGeomTypeId(geosGeometry)+1 == wkbPolygon) {
+               ret = wkbBasicInt(out, *geom, GEOSGetNumInteriorRings, 
"geom.NumRings");
        } else {
-               ret = wkbBasicInt(out, *geom, GEOSGetNumInteriorRings, 
"geom.NumRings");
-       }
-
-       if(ret != MAL_SUCCEED)
-               return ret; 
+               //It is not a polygon so the nu,ber of rings is 0
+               (*out) = 0 - (*exteriorRing);
+       }
+
+       GEOSGeom_destroy(geosGeometry);
+
+       if(ret != MAL_SUCCEED) {
+               str msg = createException(MAL, "geom.wkbNumRings", "%s", ret);
+               GDKfree(ret);                   
+               
+               return msg;
+       }
        
        (*out) += (*exteriorRing);
 
@@ -3377,25 +3404,24 @@ static str geosIsClosed(bit *out, const 
 
 str wkbIsClosed(bit *out, wkb **geomWKB) {
        str err;
-
-       GEOSGeom geosGeometry = wkb2geos(*geomWKB);
-       if (!geosGeometry)
-               throw(MAL, "geom.IsClosed", "wkb2geos failed");
-
+       GEOSGeom geosGeometry;
+       
        //if empty geometry return false
        if((err = wkbIsEmpty(out, geomWKB)) != MAL_SUCCEED) {
                str msg = createException(MAL, "geom.IsEmpty", "%s", err);
                GDKfree(err);
-               GEOSGeom_destroy(geosGeometry);
 
                return msg;
        }
        if(*out) {
                *out = 0;
-               GEOSGeom_destroy(geosGeometry);
                return MAL_SUCCEED;
        }
 
+       geosGeometry = wkb2geos(*geomWKB);
+       if (!geosGeometry)
+               throw(MAL, "geom.IsClosed", "wkb2geos failed");
+
        if((err = geosIsClosed(out, geosGeometry)) != MAL_SUCCEED) {
                str msg = createException(MAL, "geom.IsClosed", "%s", err);
                GDKfree(err);
@@ -4134,26 +4160,28 @@ str wkbNumGeometries(int* out, wkb** geo
 
 /* Creates the mbr for the given geom_geometry. */
 str wkbMBR(mbr **geomMBR, wkb **geomWKB) {
-       GEOSGeom geosGeometry = wkb2geos(*geomWKB);
+       GEOSGeom geosGeometry;
        str ret = MAL_SUCCEED;
-       bit out;
+       bit empty;
 
        //check if the geometry is empty
-       if((ret = wkbIsEmpty(&out, geomWKB)) != MAL_SUCCEED) {
+       if((ret = wkbIsEmpty(&empty, geomWKB)) != MAL_SUCCEED) {
                str msg = createException(MAL, "geom.wkbMBR", "%s", ret);
                GDKfree(ret);
        
-               GEOSGeom_destroy(geosGeometry);
-       
                return msg; 
        }
-
-       if(out) {
-               GEOSGeom_destroy(geosGeometry);
+       if(empty) {
                *geomMBR = mbr_nil;
                return MAL_SUCCEED;
        }
 
+       geosGeometry = wkb2geos(*geomWKB);
+       if(!geosGeometry) {
+               *geomMBR = mbr_nil;
+               throw(MAL, "geom.wkbMBR", "Problem converting GEOS to WKB");
+       }
+
        *geomMBR = mbrFromGeos(geosGeometry);
 
        GEOSGeom_destroy(geosGeometry);
@@ -4683,16 +4711,16 @@ str wkbCoordinateFromMBR(dbl* coordinate
 str wkbCoordinateFromWKB(dbl* coordinateValue, wkb** geomWKB, int* 
coordinateIdx) {
        mbr* geomMBR;
        str ret = MAL_SUCCEED ; 
-       bit out;
+       bit empty;
 
        //check if the geometry is empty
-       if((ret = wkbIsEmpty(&out, geomWKB)) != MAL_SUCCEED) {
+       if((ret = wkbIsEmpty(&empty, geomWKB)) != MAL_SUCCEED) {
                str msg = createException(MAL, "geom.wkbCoordinateFromWKB", 
"%s", ret);
                GDKfree(ret);
                return msg; 
        }
 
-       if(out) {
+       if(empty) {
                *coordinateValue = dbl_nil;
                return MAL_SUCCEED;
        }
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -190,7 +190,10 @@ geom_export str wkbMakeLine(wkb**, wkb**
 geom_export str wkbMakeLineAggr(wkb** outWKB, int* inBAT_id);
 geom_export str wkbExteriorRing(wkb**, wkb**);
 geom_export str wkbInteriorRingN(wkb**, wkb**, short*);
+
 geom_export str wkbNumRings(int*, wkb**, int*);
+geom_export str wkbNumRings_bat(bat *outBAT_id, bat *inBAT_id, int* flag);
+
 geom_export str wkbInteriorRings(wkba**, wkb**);
 
 geom_export str wkbIsClosed(bit *out, wkb **geom);
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -67,8 +67,6 @@ command getType{unsafe}(flags:int, forma
 comment "returns the str representation of the geometry type";
 
 
-command NumRings{unsafe}(w:wkb, exterior:int) :int address wkbNumRings
-comment "Returns the number of interior rings+exterior on the first polygon of 
the geometry";
 command MLineStringToPolygon{unsafe}(wkt:str, srid:int, flag:int) :wkb address 
wkbMLineStringToPolygon
 comment "Creates polygons using the MultiLineString provided as WKT. Depending 
on the flag creates one (flag=0) or multiple (flag=1) polygons"; 
 
@@ -166,11 +164,13 @@ end GeomCollFromText;
 #      return x;
 #end GeomFromWKB;
 
-function NumInteriorRings{unsafe}(w:wkb) :int;
+command NumRings(w:wkb, exterior:int) :int address wkbNumRings
+comment "Returns the number of interior rings+exterior on the first polygon of 
the geometry";
+function NumInteriorRings(w:wkb) :int;
        x := NumRings(w, 0);
        return x;
 end NumInteriorRings
-function NRings{unsafe}(w:wkb) :int;
+function NRings(w:wkb) :int;
        x := NumRings(w, 1);
        return x;
 end NRings;
@@ -665,6 +665,17 @@ comment "Returns the 1-based Nth geometr
 command NumGeometries(w:bat[:oid,:wkb]) :bat[:oid,:int] address 
wkbNumGeometries_bat
 comment "Returns the number of geometries";
 
+command NumRings(w:bat[:oid,:wkb], exterior:int) :bat[:oid,:int] address 
wkbNumRings_bat
+comment "Returns the number of interior rings+exterior on the first polygon of 
the geometry";
+function NumInteriorRings(w:bat[:oid,:wkb]) :bat[:oid,:int];
+       x := NumRings(w, 0);
+       return x;
+end NumInteriorRings
+function NRings(w:bat[:oid,:wkb]) :bat[:oid,:int];
+       x := NumRings(w, 1);
+       return x;
+end NRings;
+
 
 command Boundary(w:bat[:oid,:wkb]) :bat[:oid,:wkb] address wkbBoundary_bat;
 
diff --git a/geom/monetdb5/geomBulk.c b/geom/monetdb5/geomBulk.c
--- a/geom/monetdb5/geomBulk.c
+++ b/geom/monetdb5/geomBulk.c
@@ -524,7 +524,7 @@ str wkbNumGeometries_bat(bat *outBAT_id,
 /*************************** IN: wkb - OUT: int - FLAG: int 
****************************/
 
/***************************************************************************************/
 
-str wkbNumPoints_bat(bat *outBAT_id, bat *inBAT_id, int* flag) {
+static str WKBtoINTflagINT_bat(bat *outBAT_id, bat *inBAT_id, int* flag, str 
(*func)(int*, wkb**, int*), const char *name) {
        BAT *outBAT = NULL, *inBAT = NULL;
        wkb *inWKB = NULL;
        BUN p =0, q =0;
@@ -532,18 +532,18 @@ str wkbNumPoints_bat(bat *outBAT_id, bat
 
        //get the descriptor of the BAT
        if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
-               throw(MAL, "batgeom.wkbNumPoints", RUNTIME_OBJECT_MISSING);
+               throw(MAL, name, RUNTIME_OBJECT_MISSING);
        }
        
        if ( inBAT->htype != TYPE_void ) { //header type of  BAT not void
                BBPreleaseref(inBAT->batCacheid);
-               throw(MAL, "batgeom.wkbNumPoints", "The arguments must have 
dense and aligned heads");
+               throw(MAL, name, "The arguments must have dense and aligned 
heads");
        }
 
        //create a new for the output BAT
        if ((outBAT = BATnew(TYPE_void, ATOMindex("int"), BATcount(inBAT), 
TRANSIENT)) == NULL) {
                BBPreleaseref(inBAT->batCacheid);
-               throw(MAL, "batgeom.wkbNumPoints", MAL_MALLOC_FAIL);
+               throw(MAL, name, MAL_MALLOC_FAIL);
        }
        //set the first idx of the new BAT equal to that of the input BAT
        BATseqbase(outBAT, inBAT->hseqbase);
@@ -555,8 +555,8 @@ str wkbNumPoints_bat(bat *outBAT_id, bat
                int outSingle;
 
                inWKB = (wkb*) BUNtail(inBAT_iter, p);
-               if ((err = wkbNumPoints(&outSingle, &inWKB, flag)) != 
MAL_SUCCEED) {
-                       str msg = createException(MAL, "batgeom.wkbNumPoints", 
"%s", err);
+               if ((err = (*func)(&outSingle, &inWKB, flag)) != MAL_SUCCEED) {
+                       str msg = createException(MAL, name, "%s", err);
                        GDKfree(err);
 
                        BBPreleaseref(inBAT->batCacheid);
@@ -577,6 +577,13 @@ str wkbNumPoints_bat(bat *outBAT_id, bat
 
 }
 
+str wkbNumPoints_bat(bat *outBAT_id, bat *inBAT_id, int* flag) {
+       return WKBtoINTflagINT_bat(outBAT_id, inBAT_id, flag, wkbNumPoints, 
"batgeom.wkbNumPoints");
+}
+str wkbNumRings_bat(bat *outBAT_id, bat *inBAT_id, int* flag) {
+       return WKBtoINTflagINT_bat(outBAT_id, inBAT_id, flag, wkbNumRings, 
"batgeom.wkbNumRings");
+}
+
 
/******************************************************************************************/
 /*************************** IN: wkb - OUT: double - FLAG: int 
****************************/
 
/******************************************************************************************/
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
@@ -4234,9 +4234,12 @@ CREATE FUNCTION ST_YMax(geom Geometry) R
 CREATE FUNCTION ST_YMax(box mbr) RETURNS double EXTERNAL NAME 
geom."YMaxFromMBR";
 CREATE FUNCTION ST_YMin(geom Geometry) RETURNS double EXTERNAL NAME 
geom."YMinFromWKB";
 CREATE FUNCTION ST_YMin(box mbr) RETURNS double EXTERNAL NAME 
geom."YMinFromMBR";
---CREATE FUNCTION ST_ZMax(box3d Geometry_OR_Box2D_OR_Box3D) RETURNS double 
EXTERNAL NAME
+--GEOS creates only 2D Envelope
+--CREATE FUNCTION ST_ZMax(geom Geometry) RETURNS double EXTERNAL NAME 
geom."ZMaxFromWKB";
+--CREATE FUNCTION ST_ZMax(box mbr) RETURNS double EXTERNAL NAME 
geom."ZMaxFromMBR";
+--CREATE FUNCTION ST_ZMin(geom Geometry) RETURNS double EXTERNAL NAME 
geom."ZMinFromWKB";
+--CREATE FUNCTION ST_ZMin(box mbr) RETURNS double EXTERNAL NAME 
geom."ZMinFromMBR";
 --CREATE FUNCTION ST_Zmflag(geom Geometry) RETURNS smallint EXTERNAL NAME 
--0=2d, 1=3dm, 2=3dz, 4=4d
---CREATE FUNCTION ST_ZMin(box3d Geometry_OR_Box2D_OR_Box3D) RETURNS double 
EXTERNAL NAME
 
 -------------------------------------------------------------------------
 --------------------------- Geometry Editors ----------------------------
diff --git a/geom/sql/Tests/functions/Tests/All 
b/geom/sql/Tests/functions/Tests/All
--- a/geom/sql/Tests/functions/Tests/All
+++ b/geom/sql/Tests/functions/Tests/All
@@ -32,7 +32,9 @@ ST_NumGeometries
 ST_NumPoints
 ST_NPoints
 
-#numRings
+ST_NumInteriorRings
+ST_NRings
+
 #transform
 
 ST_Contains #ignores Z coordinate
diff --git a/geom/sql/Tests/functions/Tests/ST_Boundary.stable.out 
b/geom/sql/Tests/functions/Tests/ST_Boundary.stable.out
--- a/geom/sql/Tests/functions/Tests/ST_Boundary.stable.out
+++ b/geom/sql/Tests/functions/Tests/ST_Boundary.stable.out
@@ -74,6 +74,8 @@ Ready.
 [ "MULTILINESTRING Z ((30 40 10, 40 50 20, 30 40 30), (50 60 40, 60 70 50))",  
"MULTIPOINT Z (50 60 40, 60 70 50)"     ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to