Changeset: 570056773af2 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=570056773af2
Modified Files:
        geom/monetdb5/geom.c
        geom/monetdb5/geom.mal
        geom/sql/40_geom.sql
        geom/sql/Tests/All
Branch: geo
Log Message:

mTests asText, isClosed, isSimple, isValid, isRing, coordinates and srid


diffs (truncated from 313 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
@@ -71,11 +71,11 @@ geom_export wkb* geos2wkb(GEOSGeom geosG
 /* gets a WKB and creates a GEOSGeometry */
 //geom_export GEOSGeom wkb2geos(wkb* geomWKB);
 
-
+/* the len argument is needed for correct storage and retrieval */
 geom_export int mbrFROMSTR(char *src, int *len, mbr **atom);
 geom_export int mbrTOSTR(char **dst, int *len, mbr *atom);
-geom_export int wkbFROMSTR(char* geomWKT, wkb** geomWKB, int srid);
-geom_export int wkbTOSTR(char **dst, int *len, wkb *atom);
+geom_export int wkbFROMSTR(char* geomWKT, int *len, wkb** geomWKB, int srid);
+geom_export int wkbTOSTR(char **geomWKT, int *len, wkb *geomWKB);
 geom_export str wkbFromText(wkb **w, str *wkt, int* srid, int *tpe);
 geom_export str wkbAsText(str *r, wkb **w);
 //geom_export str wkbFromString(wkb**, str*); 
@@ -89,7 +89,8 @@ geom_export str wkbGeometryType(char**, 
 geom_export str wkbBoundary(wkb**, wkb**);
 geom_export str wkbCoordDim(int* , wkb**);
 geom_export str wkbDimension(int*, wkb**);
-geom_export str wkbSRID(int*, wkb**);
+geom_export str wkbGetSRID(int*, wkb**);
+geom_export str wkbSetSRID(wkb**, wkb**, int*);
 geom_export str wkbGetCoordX(double*, wkb**);
 geom_export str wkbGetCoordY(double*, wkb**);
 geom_export str wkbGetCoordZ(double*, wkb**);
@@ -336,7 +337,7 @@ int mbrTOSTR(char **dst, int *len, mbr *
 
 /* Creates WKB representation (including srid) from WKT representation */
 /* return number of parsed characters. */
-int wkbFROMSTR(char* geomWKT, wkb **geomWKB, int srid) {
+int wkbFROMSTR(char* geomWKT, int* len, wkb **geomWKB, int srid) {
        GEOSGeom geosGeometry = NULL;   /* The geometry object that is parsed 
from the src string. */
        //unsigned char *geometry_TO_wkb = NULL;        /* The "well known 
binary" serialization of the geometry object. */
        //size_t wkbLen = 0;            /* The length of the wkbSer string. */
@@ -344,6 +345,8 @@ int wkbFROMSTR(char* geomWKT, wkb **geom
        //int coordinateDimensions = 0;
        GEOSWKTReader *WKT_reader;
 
+//fprintf(stderr, "wkbFROMSTR: %s\n", geomWKT);
+
        if (strcmp(geomWKT, str_nil) == 0) {
                *geomWKB = GDKmalloc(sizeof(wkb));
                **geomWKB = *wkbNULL();
@@ -389,6 +392,10 @@ int wkbFROMSTR(char* geomWKT, wkb **geom
        /* we have a GEOSGeometry will number of coordinates and SRID and we 
        * want to get the wkb out of it */
        *geomWKB = geos2wkb(geosGeometry);
+       GEOSGeom_destroy(geosGeometry);
+
+       *len = (int) wkb_size((*geomWKB)->len);
+
 /*
 //             geometry_TO_wkb = GEOSGeomToWKB_buf(geometry_FROM_wkt, &wkbLen);
 //             GEOSGeom_destroy(geometry_FROM_wkt);
@@ -422,10 +429,12 @@ int wkbFROMSTR(char* geomWKT, wkb **geom
 
 /* Creates the string representation (WKT) of a WKB */
 /* return length of resulting string. */
-int wkbTOSTR(char **dst, int *len, wkb *atom) {
+int wkbTOSTR(char **geomWKT, int* len, wkb *geomWKB) {
        char *wkt = NULL;
        int dstStrLen = 3;                      /* "nil" */
-       GEOSGeom geosGeometry = wkb2geos(atom);
+
+       /* from WKB to GEOSGeometry */
+       GEOSGeom geosGeometry = wkb2geos(geomWKB);
 
        
        if (geosGeometry) {
@@ -442,18 +451,15 @@ int wkbTOSTR(char **dst, int *len, wkb *
                GEOSGeom_destroy(geosGeometry);
        }
 
-       if (*len < dstStrLen + 1) {     /* + 1 for the '\0' */
-               if (*dst)
-                       GDKfree(*dst);
-               *dst = GDKmalloc(*len = dstStrLen + 1);
-       }
-
        if (wkt) {
-               snprintf(*dst, *len, "\"%s\"", wkt);
+               *geomWKT = GDKmalloc(dstStrLen+1);
+               snprintf(*geomWKT, dstStrLen+1, "\"%s\"", wkt);
                GEOSFree(wkt);
        } else {
-               strcpy(*dst, "nil");
+               strcpy(*geomWKT, "nil");
        }
+       
+       *len = dstStrLen+1;
 
        return dstStrLen;
 }
@@ -462,17 +468,18 @@ int wkbTOSTR(char **dst, int *len, wkb *
 /*int* tpe is needed to verify that the type of the FromText function used is 
the
  * same with the type of the geometry created from the wkt representation */
 str wkbFromText(wkb **geomWKB, str *geomWKT, int* srid, int *tpe) {
-       int te = *tpe;
+       int len=0, te = *tpe;
        char *errbuf;
        str ex;
 
        *geomWKB = NULL;
-       if (wkbFROMSTR(*geomWKT, geomWKB, *srid) &&
+       if (wkbFROMSTR(*geomWKT, &len, geomWKB, *srid) &&
            (wkb_isnil(*geomWKB) || *tpe==0 || *tpe == wkbGeometryCollection || 
(te = *((*geomWKB)->data + 1) & 0x0f) == *tpe))
                return MAL_SUCCEED;
-       if (*geomWKB == NULL)
+       if (*geomWKB == NULL) {
                *geomWKB = (wkb *) GDKmalloc(sizeof(wkb));
-       **geomWKB = *wkbNULL();
+               **geomWKB = *wkbNULL();
+       }
        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));
        errbuf = GDKerrbuf;
@@ -492,11 +499,9 @@ str wkbFromText(wkb **geomWKB, str *geom
 }
 
 /*create textual representation of the wkb */
-str wkbAsText(str *r, wkb **w) {
-       int len = 0;
-
-       wkbTOSTR(r, &len, *w);
-       if (len)
+str wkbAsText(str *geomWKT, wkb **geomWKB) {
+       int len =0;
+       if(wkbTOSTR(geomWKT, &len, *geomWKB))
                return MAL_SUCCEED;
        throw(MAL, "geom.AsText", "Failed to create Text from Well Known 
Format");
 }
@@ -634,9 +639,28 @@ str wkbDimension(int *out, wkb **geom) {
 }
 
 /* returns the srid of the geometry */
-/* there is no srid information on the wkb representation of the wkb*/
-str wkbSRID(int *out, wkb **geom) {
-       return wkbBasicInt(out, geom, GEOSGetSRID, "geom.SRID");
+str wkbGetSRID(int *out, wkb **geom) {
+       return wkbBasicInt(out, geom, GEOSGetSRID, "geom.getSRID");
+}
+
+/* sets the srid of the geometry */
+str wkbSetSRID(wkb** resultGeomWKB, wkb **geom, int* srid) {
+       GEOSGeom geosGeometry = wkb2geos(*geom);
+
+       if (!geosGeometry) {
+               *resultGeomWKB = (wkb *) GDKmalloc(sizeof(wkb));
+               **resultGeomWKB = *wkbNULL();   
+               return MAL_SUCCEED;
+       }
+
+       GEOSSetSRID(geosGeometry, *srid);
+       *resultGeomWKB = geos2wkb(geosGeometry);
+       GEOSGeom_destroy(geosGeometry);
+
+       if(*resultGeomWKB == NULL)
+               throw(MAL, "geom.setSRID", "wkbSetSRID failed");
+
+       return MAL_SUCCEED;
 }
 
 
@@ -655,6 +679,9 @@ static str wkbGetCoord(double *out, wkb 
                throw(MAL, name, "wkb2geos failed");
        }
 
+       if((GEOSGeomTypeId(geosGeometry)+1) != wkbPoint)
+               throw(MAL, name, "Geometry not a Point"); 
+
        gcs = GEOSGeom_getCoordSeq(geosGeometry);
 
        if (!gcs) {
@@ -935,6 +962,7 @@ static int wkbBasicBoolean(wkb **geom, c
  * a linestring. I made it to be like PostGIS */
 str wkbIsClosed(bit *out, wkb **geom) {
        int res = -1;
+       int geometryType = 0;
        GEOSGeom geosGeometry = wkb2geos(*geom);
 
        *out = bit_nil;
@@ -942,12 +970,22 @@ str wkbIsClosed(bit *out, wkb **geom) {
        if (!geosGeometry)
                throw(MAL, "geom.IsClosed", "wkb2geos failed");
 
-       if(GEOSGeomTypeId(geosGeometry) != GEOS_LINESTRING) {
+       geometryType = GEOSGeomTypeId(geosGeometry)+1;
+
+       /* if the geometry is point or multipoint it is always closed */
+       if(geometryType == wkbPoint || geometryType == wkbMultiPoint) {
                *out = 1;
                GEOSGeom_destroy(geosGeometry);
                return MAL_SUCCEED;     
        }
 
+       /* if the geometry is not a point, multipoint or linestring, it is 
always not closed */
+       if(geometryType != wkbLineString) {
+               *out = 0;
+               GEOSGeom_destroy(geosGeometry);
+               return MAL_SUCCEED;     
+       }
+
        
        res = GEOSisClosed(geosGeometry);
        GEOSGeom_destroy(geosGeometry);
@@ -991,21 +1029,6 @@ str wkbIsSimple(bit *out, wkb **geom) {
        *out = res;
 
        return MAL_SUCCEED;
-/*     GEOSGeom geosGeometry = wkb2geos(*geom);
-
-       if (!geosGeometry) {
-               *out = bit_nil;
-               return MAL_SUCCEED;
-       }
-
-       *out = GEOSisSimple(geosGeometry);
-
-       GEOSGeom_destroy(geosGeometry);
-
-       if (GDKerrbuf && GDKerrbuf[0])
-               throw(MAL, "geom.IsSimple", "GEOSisSimple failed");
-       return MAL_SUCCEED;
-*/
 }
 
 /*geom prints a message sayig the reasom why the geometry is not valid but
@@ -1025,21 +1048,26 @@ str wkbIsValid(bit *out, wkb **geom) {
        return MAL_SUCCEED;
 }
 
-str wkbIsValidReason(char** out, wkb **geom) {
+str wkbIsValidReason(char** reason, wkb **geom) {
        GEOSGeom geosGeometry = wkb2geos(*geom);
+       char* GEOSReason = NULL;
 
        if (!geosGeometry) {
-               *out = NULL;
+               *reason = NULL;
                throw(MAL, "geom.IsValidReason", "wkb2geos failed");
        }
 
-       *out = GEOSisValidReason(geosGeometry);
+       GEOSReason = GEOSisValidReason(geosGeometry);
 
        GEOSGeom_destroy(geosGeometry);
 
-       if(*out == NULL)
+       if(GEOSReason == NULL)
                throw(MAL, "geom.IsValidReason", "GEOSisValidReason failed");
        
+       *reason = GDKmalloc((int)sizeof(GEOSReason)+1);
+       strcpy(*reason, GEOSReason);
+       GEOSFree(GEOSReason);
+
        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
@@ -160,8 +160,10 @@ command CoordDim(w:wkb) :int address wkb
 comment " Return the coordinate dimension of the geometry";
 command Dimension(w:wkb) :int address wkbDimension
 comment "The inherent dimension of this Geometry object, which must be less 
than or equal to the coordinate dimension.";
-command SRID(w:wkb) :int address wkbSRID
+command getSRID(w:wkb) :int address wkbGetSRID
 comment "Returns the Spatial Reference System ID for this Geometry.";
+command setSRID(w:wkb, srid:int) :wkb address wkbSetSRID
+comment "Sets the Reference System ID for this Geometry.";
 command X(g:wkb) :dbl address wkbGetCoordX
 comment  "Return the X coordinate of the point, or NULL if not available. 
Input must be a point.";
 command Y(g:wkb) :dbl address wkbGetCoordY
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
@@ -160,7 +160,7 @@ CREATE FUNCTION ST_NumInteriorRing(geom 
 CREATE FUNCTION ST_NumPoints(geom Geometry) RETURNS integer EXTERNAL NAME 
geom."NumPoints";
 --CREATE FUNCTION ST_PatchN(geom Geometry, patchNum integer) RETURNS Geometry 
EXTERNAL NAME --works with polyhedral surface
 CREATE FUNCTION ST_PointN(geom Geometry, pointNum integer) RETURNS Geometry 
EXTERNAL NAME geom."PointN";
-CREATE FUNCTION ST_SRID(geom Geometry) RETURNS integer EXTERNAL NAME 
geom."SRID";
+CREATE FUNCTION ST_SRID(geom Geometry) RETURNS integer EXTERNAL NAME 
geom."getSRID";
 CREATE FUNCTION ST_StartPoint(geom Geometry) RETURNS geometry EXTERNAL NAME 
geom."StartPoint";
 --CREATE FUNCTION ST_Summary(geom Geometry) RETURNS string EXTERNAL NAME
 CREATE FUNCTION ST_X(geom Geometry) RETURNS double EXTERNAL NAME geom."X"; 
--gets point
@@ -199,7 +199,7 @@ CREATE FUNCTION ST_Z(geom Geometry) RETU
 --CREATE FUNCTION ST_Scale RETURNS EXTERNAL NAME
 --CREATE FUNCTION ST_Segmentize RETURNS EXTERNAL NAME
 --CREATE FUNCTION ST_SetPoint RETURNS EXTERNAL NAME
---CREATE FUNCTION ST_SetSRID RETURNS EXTERNAL NAME
+CREATE FUNCTION ST_SetSRID(geom Geometry, srid integer) RETURNS Geometry 
EXTERNAL NAME geom."setSRID";
 --CREATE FUNCTION ST_SnapToGrid RETURNS EXTERNAL NAME
 --CREATE FUNCTION ST_Snap RETURNS EXTERNAL NAME
 --CREATE FUNCTION ST_Transform RETURNS EXTERNAL NAME
diff --git a/geom/sql/Tests/All b/geom/sql/Tests/All
--- a/geom/sql/Tests/All
+++ b/geom/sql/Tests/All
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to