Changeset: 552397b0ccb1 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=552397b0ccb1 Modified Files: geom/lib/libgeom.c geom/lib/libgeom.h geom/monetdb5/geom.c geom/monetdb5/geom.mal geom/sql/40_geom.sql Branch: geo Log Message:
most functions added in 40_geom.sql diffs (truncated from 688 to 300 lines): diff --git a/geom/lib/libgeom.c b/geom/lib/libgeom.c --- a/geom/lib/libgeom.c +++ b/geom/lib/libgeom.c @@ -126,26 +126,46 @@ getMbrGeom(mbr *res, wkb *geom) return 0; } -const char * -geom_type2str(int t) -{ - switch (t) { - //case wkbGeometry: - // return "GEOMETRY"; - case wkbPoint: - return "POINT"; - case wkbLineString: - return "LINESTRING"; - case wkbPolygon: - return "POLYGON"; - case wkbMultiPoint: - return "MULTIPOINT"; - case wkbMultiLineString: - return "MULTILINESTRING"; - case wkbMultiPolygon: - return "MULTIPOLYGON"; - case wkbGeometryCollection: - return "GEOMETRYCOLLECTION"; +const char* geom_type2str(int t, int flag){ + if(flag == 0) { + switch (t) { + //case wkbGeometry: + // return "GEOMETRY"; + case wkbPoint: + return "POINT"; + case wkbLineString: + return "LINESTRING"; + case wkbPolygon: + return "POLYGON"; + case wkbMultiPoint: + return "MULTIPOINT"; + case wkbMultiLineString: + return "MULTILINESTRING"; + case wkbMultiPolygon: + return "MULTIPOLYGON"; + case wkbGeometryCollection: + return "GEOMETRYCOLLECTION"; + } } + else if(flag == 1) { + switch (t) { + //case wkbGeometry: + // return "ST_Geometry"; + case wkbPoint: + return "ST_Point"; + case wkbLineString: + return "ST_Linestring"; + case wkbPolygon: + return "ST_Polygon"; + case wkbMultiPoint: + return "ST_MultiPoint"; + case wkbMultiLineString: + return "ST_MultiLinestring"; + case wkbMultiPolygon: + return "ST_MultiPolygon"; + case wkbGeometryCollection: + return "ST_GeometryCollection"; + } +} return "UKNOWN"; } diff --git a/geom/lib/libgeom.h b/geom/lib/libgeom.h --- a/geom/lib/libgeom.h +++ b/geom/lib/libgeom.h @@ -107,7 +107,7 @@ typedef enum wkb_type { wkbGeometryCollection = 7 } wkb_type; -libgeom_export const char *geom_type2str(int t); +libgeom_export const char *geom_type2str(int t, int flag); typedef struct wkb { int len; diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c --- a/geom/monetdb5/geom.c +++ b/geom/monetdb5/geom.c @@ -54,7 +54,7 @@ int TYPE_mbr; geom_export void geoHasZ(int* res, int* info); geom_export void geoHasM(int* res, int* info); -geom_export void geoGetType(char** res, int* info); +geom_export void geoGetType(char** res, int* info, int flag); geom_export bat *geom_prelude(void); geom_export void geom_epilogue(void); @@ -78,7 +78,7 @@ geom_export str geomMakePoint3D(wkb**, d geom_export str geomMakePoint4D(wkb**, double*, double*, double*, double*); geom_export str geomMakePointM(wkb**, double*, double*, double*); -geom_export str wkbGeometryType(char**, wkb**); +geom_export str wkbGeometryType(char**, wkb**, int* flag); geom_export str wkbBoundary(wkb**, wkb**); geom_export str wkbCoordDim(int* , wkb**); geom_export str wkbDimension(int*, wkb**); @@ -94,9 +94,13 @@ geom_export str wkbEnvelope(wkb **out, w geom_export str wkbExteriorRing(wkb**, wkb**); geom_export str wkbInteriorRingN(wkb**, wkb**, short*); geom_export str wkbNumInteriorRings(int*, wkb**); - +geom_export str wkbIsClosed(bit *out, wkb **geom); geom_export str wkbIsEmpty(bit *out, wkb **geom); +geom_export str wkbIsRing(bit *out, wkb **geom); geom_export str wkbIsSimple(bit *out, wkb **geom); +geom_export str wkbIsValid(bit *out, wkb **geom); +geom_export str wkbIsValidReason(char** out, wkb **geom); +geom_export str wkbIsValidDetail(char** out, wkb **geom); /*check if the geometry has z coordinate*/ @@ -112,9 +116,9 @@ void geoHasM(int* res, int* info) { } /*check the geometry subtype*/ /*returns the length of the resulting string*/ -void geoGetType(char** res, int* info) { +void geoGetType(char** res, int* info, int flag) { int type = (*info >> 2); - const char* typeStr=geom_type2str(type) ; + const char* typeStr=geom_type2str(type, flag) ; *res=GDKmalloc(strlen(typeStr)); strcpy(*res, typeStr); @@ -374,7 +378,7 @@ str wkbFromText(wkb **w, str *wkt, int s *w = (wkb *) GDKmalloc(sizeof(wkb)); **w = *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), geom_type2str(*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; if (errbuf) { if (strncmp(errbuf, "!ERROR: ", 8) == 0) @@ -526,13 +530,13 @@ static str wkbBasicInt(int *out, wkb **g /* returns the type of the geometry as a string*/ -str wkbGeometryType(char** out, wkb** geom) { +str wkbGeometryType(char** out, wkb** geom, int* flag) { int typeId = 0; str ret = MAL_SUCCEED; ret = wkbBasicInt(&typeId, geom, GEOSGeomTypeId, "geom.GeometryType"); typeId = ((typeId+1) << 2); - geoGetType(out, &typeId); + geoGetType(out, &typeId, *flag); return ret; } @@ -831,34 +835,84 @@ str wkbNumInteriorRings(int* out, wkb** return wkbBasicInt(out, geom, GEOSGetNumInteriorRings, "geom.NumInteriorRings"); } - - - - -str wkbIsEmpty(bit *out, wkb **geom) -{ +/* it handles functions that return boolean */ +static int wkbBasicBoolean(wkb **geom, char (*func)(const GEOSGeometry*)) { + int res = -1; GEOSGeom geosGeometry = wkb2geos(*geom); - if (!geosGeometry) { - *out = bit_nil; - return MAL_SUCCEED; - } + if (!geosGeometry) + return 3; - *out = GEOSisEmpty(geosGeometry); + res = (*func)(geosGeometry); GEOSGeom_destroy(geosGeometry); - if (GDKerrbuf && GDKerrbuf[0]) - throw(MAL, "geom.IsEmpty", "GEOSisEmpty failed"); - return MAL_SUCCEED; - + return res; } -str -wkbIsSimple(bit *out, wkb **geom) -{ +/* the function checks whether the geometry is closed. GEOS works only with + * linestring geometries but PostGIS returns true in any geometry that is not + * a linestring. I made it to be like PostGIS */ +str wkbIsClosed(bit *out, wkb **geom) { + int res = -1; GEOSGeom geosGeometry = wkb2geos(*geom); + *out = bit_nil; + + if (!geosGeometry) + throw(MAL, "geom.IsClosed", "wkb2geos failed"); + + if(GEOSGeomTypeId(geosGeometry) != GEOS_LINESTRING) { + *out = 1; + GEOSGeom_destroy(geosGeometry); + return MAL_SUCCEED; + } + + + res = GEOSisClosed(geosGeometry); + GEOSGeom_destroy(geosGeometry); + + if(res == 2) + throw(MAL, "geom.IsClosed", "GEOSisClosed failed"); + *out = res; + return MAL_SUCCEED; +} + +str wkbIsEmpty(bit *out, wkb **geom) { + int res = wkbBasicBoolean(geom, GEOSisEmpty); + + if(res == 3) + throw(MAL, "geom.IsEmpty", "wkb2geos failed"); + if(res == 2) + throw(MAL, "geom.IsEmpty", "GEOSisEmpty failed"); + *out = res; + return MAL_SUCCEED; +} + +str wkbIsRing(bit *out, wkb **geom) { + int res = wkbBasicBoolean(geom, GEOSisRing); + + if(res == 3) + throw(MAL, "geom.IsRing", "wkb2geos failed"); + if(res == 2) + throw(MAL, "geom.IsRing", "GEOSisRing failed"); + *out = res; + return MAL_SUCCEED; +} + + +str wkbIsSimple(bit *out, wkb **geom) { + int res = wkbBasicBoolean(geom, GEOSisSimple); + + if(res == 3) + throw(MAL, "geom.IsSimple", "wkb2geos failed"); + if(res == 2) + throw(MAL, "geom.IsSimple", "GEOSisSimple failed"); + *out = res; + + return MAL_SUCCEED; +/* GEOSGeom geosGeometry = wkb2geos(*geom); + if (!geosGeometry) { *out = bit_nil; return MAL_SUCCEED; @@ -871,10 +925,77 @@ wkbIsSimple(bit *out, wkb **geom) 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 + * since there is also isValidReason I skip this here */ +str wkbIsValid(bit *out, wkb **geom) { + int res = wkbBasicBoolean(geom, GEOSisValid); + + if(res == 3) + throw(MAL, "geom.IsValid", "wkb2geos failed"); + if(res == 2) + throw(MAL, "geom.IsValid", "GEOSisValid failed"); + *out = res; + if (GDKerrbuf) + GDKerrbuf[0] = '\0'; + + return MAL_SUCCEED; +} + +str wkbIsValidReason(char** out, wkb **geom) { + GEOSGeom geosGeometry = wkb2geos(*geom); + + if (!geosGeometry) { + *out = NULL; + throw(MAL, "geom.IsValidReason", "wkb2geos failed"); + } + + *out = GEOSisValidReason(geosGeometry); + + GEOSGeom_destroy(geosGeometry); + + if(*out == NULL) + throw(MAL, "geom.IsValidReason", "GEOSisValidReason failed"); + + return MAL_SUCCEED; +} _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list