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