Changeset: 17e0c58c6652 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=17e0c58c6652
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.mal
geom/sql/40_geom.sql
Branch: geo
Log Message:
BdPolyFromText + small changes here and there
diffs (truncated from 355 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
@@ -130,6 +130,8 @@ geom_export mbr* mbrFromGeos(const GEOSG
geom_export str wkbFromText(wkb **geomWKB, str *geomWKT, int* srid, int *tpe);
+geom_export str wkbMLineStringToPolygon(wkb** geomWKB, str* geomWKT, int*
srid, int* flag);
+
/* Basic Methods on Geometric objects (OGC) */
geom_export str wkbDimension(int*, wkb**);
@@ -1114,7 +1116,7 @@ str wkbFromText(wkb **geomWKB, str *geom
*geomWKB = wkb_nil;
}
if (*tpe > 0 && te != *tpe)
- throw(MAL, "wkb.FromText", "Trying to read Geometry type '%s'
with function for Geometry type '%s'", geom_type2str(te,0),
geom_type2str(*tpe,0));
+ throw(MAL, "wkb.FromText", "Geometry not type '%s'",
geom_type2str(*tpe,0));
errbuf = GDKerrbuf;
if (errbuf) {
if (strncmp(errbuf, "!ERROR: ", 8) == 0)
@@ -1187,6 +1189,169 @@ str wkbAsText(char **txt, wkb **geomWKB,
throw(MAL, "geom.AsText", "Failed to create Text from Well Known
Format");
}
+str wkbMLineStringToPolygon(wkb** geomWKB, str* geomWKT, int* srid, int* flag)
{
+ int itemsNum =0, i, type=wkbMultiLineString;
+ str ret = MAL_SUCCEED;
+ wkb* inputWKB = NULL;
+
+ wkb **linestringsWKB;
+ double *linestringsArea;
+
+ bit ordered = 0;
+
+ //make wkb from wkt
+ ret = wkbFromText(&inputWKB, geomWKT, srid, &type);
+ if(ret != MAL_SUCCEED) {
+ *geomWKB = wkb_nil;
+
+ if(inputWKB)
+ GDKfree(inputWKB);
+ return ret;
+ }
+
+ //read the number of linestrings in the input
+ ret = wkbNumGeometries(&itemsNum, &inputWKB);
+ if(ret != MAL_SUCCEED) {
+ *geomWKB = wkb_nil;
+ return ret;
+ }
+
+ linestringsWKB = (wkb**)GDKmalloc(itemsNum*sizeof(wkb*));
+ linestringsArea = (double*)GDKmalloc(itemsNum*sizeof(double));
+ //create oen polygon for each lineString and compute the are of each of
them
+ for(i=1; i<=itemsNum; i++) {
+ wkb* polygonWKB;
+ int batId=0;
+
+ ret = wkbGeometryN(&linestringsWKB[i-1], &inputWKB, &i);
+ if(ret != MAL_SUCCEED || !linestringsWKB[i-1]) {
+ *geomWKB = wkb_nil;
+
+ GDKfree(inputWKB);
+ for(;i>0; i--)
+ if(linestringsWKB[i-1])
+ GDKfree(linestringsWKB[i-1]);
+ GDKfree(linestringsWKB);
+
+ return ret;
+ }
+
+ ret = wkbMakePolygon(&polygonWKB, &linestringsWKB[i-1], &batId,
srid);
+ if(ret != MAL_SUCCEED) {
+ *geomWKB = wkb_nil;
+
+ GDKfree(inputWKB);
+ for(;i>0; i--)
+ if(linestringsWKB[i-1])
+ GDKfree(linestringsWKB[i-1]);
+ GDKfree(linestringsWKB);
+
+ throw(MAL, "geom.MLineStringToPolygon", "All linestring
should be closed");
+ }
+
+ ret = wkbArea(&linestringsArea[i-1], &polygonWKB);
+ if(ret != MAL_SUCCEED) {
+ *geomWKB = wkb_nil;
+
+ GDKfree(inputWKB);
+ for(;i>0; i--)
+ if(linestringsWKB[i-1])
+ GDKfree(linestringsWKB[i-1]);
+ GDKfree(linestringsWKB);
+
+ return ret;
+ }
+
+ GDKfree(polygonWKB);
+ }
+
+ GDKfree(inputWKB);
+
+ //order the linestrings with decreasing (polygons) area
+ while(!ordered) {
+ ordered = 1;
+
+ for(i=0; i<itemsNum-1; i++) {
+ if(linestringsArea[i+1] > linestringsArea[i]) {
+ //switch
+ wkb* linestringWKB = linestringsWKB[i];
+ double linestringArea = linestringsArea[i];
+
+ linestringsWKB[i] = linestringsWKB[i+1];
+ linestringsArea[i] = linestringsArea[i+1];
+
+ linestringsWKB[i+1] = linestringWKB;
+ linestringsArea[i+1] = linestringArea;
+
+ ordered = 0;
+ }
+ }
+ }
+
+ //print areas
+ for(i=0; i<itemsNum; i++) {
+ char* toStr = NULL;
+ int len = 0;
+ wkbTOSTR(&toStr, &len, linestringsWKB[i]);
+ fprintf(stderr, "%f %s\n", linestringsArea[i], toStr);
+ GDKfree(toStr);
+ }
+
+ if(*flag == 0) {
+ //the biggest polygon is the external shell
+ GEOSCoordSeq coordSeq_external;
+ GEOSGeom externalGeometry, linearRingExternalGeometry,
*internalGeometries, finalGeometry;
+
+ externalGeometry = wkb2geos(linestringsWKB[0]);
+ if(!externalGeometry) {
+ *geomWKB = wkb_nil;
+ throw(MAL, "geom.MLineStringToPolygon", "Error in
wkb2geos");
+ }
+
+ coordSeq_external =
GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(externalGeometry));
+ linearRingExternalGeometry =
GEOSGeom_createLinearRing(coordSeq_external);
+
+ //all remaining should be internal
+ internalGeometries =
(GEOSGeom*)GDKmalloc((itemsNum-1)*sizeof(GEOSGeom*));
+ for(i=1; i<itemsNum; i++) {
+ GEOSCoordSeq coordSeq_internal;
+ GEOSGeom internalGeometry;
+
+ internalGeometry = wkb2geos(linestringsWKB[i]);
+ if(!internalGeometry) {
+ *geomWKB = wkb_nil;
+ throw(MAL, "geom.MLineStringToPolygon", "Error
in wkb2geos");
+ }
+
+ coordSeq_internal =
GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(internalGeometry));
+ internalGeometries[i-1] =
GEOSGeom_createLinearRing(coordSeq_internal);
+ }
+
+ finalGeometry =
GEOSGeom_createPolygon(linearRingExternalGeometry, internalGeometries,
itemsNum-1);
+ if(finalGeometry == NULL) {
+ GEOSGeom_destroy(linearRingExternalGeometry);
+ *geomWKB = wkb_nil;
+ throw(MAL, "geom.MLineStringToPolygon", "Error creating
Polygon from LinearRing");
+ }
+
+ GEOSSetSRID(finalGeometry, *srid);
+ *geomWKB = geos2wkb(finalGeometry);
+
+ GEOSGeom_destroy(finalGeometry);
+ GDKfree(internalGeometries);
+ } else if(*flag == 1) {
+ //} else {
+ *geomWKB = wkb_nil;
+ throw(MAL, "geom.MLineStringToPolygon", "Uknown flag");
+ }
+
+ for(i=0;i<itemsNum; i++)
+ GDKfree(linestringsWKB[i]);
+ GDKfree(linestringsWKB);
+ GDKfree(linestringsArea);
+ return MAL_SUCCEED;
+}
+
static str geomMakePoint(wkb **geomWKB, GEOSGeom geosGeometry) {
*geomWKB = geos2wkb(geosGeometry);
@@ -1902,6 +2067,7 @@ str wkbMakePolygon(wkb** out, wkb** exte
GEOSSetSRID(geosGeometry, *srid);
*out = geos2wkb(geosGeometry);
+ GEOSGeom_destroy(geosGeometry);
return MAL_SUCCEED;
@@ -3928,7 +4094,7 @@ int wkbFROMSTR(char* geomWKT, int* len,
/* the srid was lost with the transformation of the GEOSGeom to wkb
* so we decided to store it in the wkb */
- /* we have a GEOSGeometry will number of coordinates and SRID and we
+ /* we have a GEOSGeometry with number of coordinates and SRID and we
* want to get the wkb out of it */
*geomWKB = geos2wkb(geosGeometry);
GEOSGeom_destroy(geosGeometry);
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -74,8 +74,8 @@ comment "returns the str representation
command GeometryType{unsafe}(w:wkb, flag:int) :str address wkbGeometryType;
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";
+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";
#Geometry Constructors
@@ -180,14 +180,14 @@ function NRings{unsafe}(w:wkb) :int;
return x;
end NRings;
-#function BdPolyFromText{unsafe}(wkt:str, srid:int) :wkb;
-# x := MLineStringToPolygon(wkt,srid,0);
-# return x;
-#end BdPolyFromText;
-#function BdMPolyFromText{unsafe}(wkt:str, srid:int) :wkb;
-# x := MLineStringToPolygon(wkt,srid,1);
-# return x;
-#end BdMPolyFromText;
+function BdPolyFromText{unsafe}(wkt:str, srid:int) :wkb;
+ x := MLineStringToPolygon(wkt,srid,0);
+ return x;
+end BdPolyFromText;
+function BdMPolyFromText{unsafe}(wkt:str, srid:int) :wkb;
+ x := MLineStringToPolygon(wkt,srid,1);
+ return x;
+end BdMPolyFromText;
command MakePoint{unsafe}(x:dbl, y:dbl) :wkb address geomMakePoint2D
comment "creates a point using the coordinates";
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
@@ -3994,13 +3994,16 @@ CREATE FUNCTION mbr(geom Geometry) RETUR
------------------------- Management Functions- -------------------------
-------------------------------------------------------------------------
--CREATE PROCEDURE AddGeometryColumn(table_name string, column_name string,
srid integer, geometryType string, dimension integer)
+--CREATE FUNCTION AddGeometryColumn(table_name string, column_name string,
srid integer, geometryType string, dimension integer) RETURNS string
--BEGIN
- --DECLARE column_type string;
- --SET column_type = concat('geometry( ', geometryType);
- --SET column_type = concat(column_type, ', ');
- --SET column_type = concat(column_type, srid);
- --SET column_type = concat(column_type, ')');
- --ALTER TABLE table_name ADD column_name
+-- DECLARE column_type string;
+-- SET column_type = concat('geometry( ', geometryType);
+-- SET column_type = concat(column_type, ', ');
+-- SET column_type = concat(column_type, srid);
+-- SET column_type = concat(column_type, ' )');
+-- ALTER TABLE table_name ADD column_name column_type; --geometry('point',
28992);
+--
+-- RETURN column_type;
--END;
--CREATE PROCEDURE t(table_name string, column_name string, column_type string)
@@ -4088,12 +4091,11 @@ CREATE FUNCTION ST_SetExteriorRing(geom
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 GeometryA 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";
+--CREATE FUNCTION ST_SetInteriorRings(geom GeometryA) RETURNS Geometry
EXTERNAL NAME geom."SetInteriorRings"; --what is this function supposed to
do????
+
+--Functions on GeomCollection
+CREATE FUNCTION ST_NumGeometries(geom Geometry) RETURNS integer EXTERNAL NAME
geom."NumGeometries";
+CREATE FUNCTION ST_GeometryN(geom Geometry, positionNum integer) RETURNS
Geometry EXTERNAL NAME geom."GeometryN";
--Functions on Polyhedral Surfaces (a simple surface, consisting of a number
of Polygon pathes or facets)
--CREATE FUNCTION ST_Geometries(geom Geometry) RETURNS TABLE(geom Geometries)
EXTERNAL NAME geom."Geometries";
@@ -4111,14 +4113,9 @@ END;
--BoundingPolygons
--IsClosed
---Functions on GeomCollection
-CREATE FUNCTION ST_NumGeometries(geom Geometry) RETURNS integer EXTERNAL NAME
geom."NumGeometries";
-CREATE FUNCTION ST_GeometryN(geom Geometry, positionNum integer) RETURNS
Geometry EXTERNAL NAME geom."GeometryN";
-
-
-----------------
--- DEPRECATED --
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list