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

Reply via email to