Changeset: dd1092783415 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=dd1092783415
Modified Files:
geom/monetdb5/sfcgal.c
geom/monetdb5/sfcgal.h
Branch: sfcgal
Log Message:
Reorder the functions position. Add conversion from geom to sfcgal geometry and
vice-versa. Add 3 new functions.
diffs (truncated from 751 to 300 lines):
diff --git a/geom/monetdb5/sfcgal.c b/geom/monetdb5/sfcgal.c
--- a/geom/monetdb5/sfcgal.c
+++ b/geom/monetdb5/sfcgal.c
@@ -13,6 +13,628 @@
#include "sfcgal.h"
+static sfcgal_geometry_t* sfcgal_from_geom(str *ret, const GEOSGeometry *geom,
int type);
+static str geom_to_sfcgal(sfcgal_geometry_t **res, GEOSGeom geosGeometry);
+static str sfcgal_to_geom(GEOSGeom *res, const sfcgal_geometry_t* geom, int
force3D, int srid);
+
+static str
+sfcgal_type_to_geom_type(int *res, sfcgal_geometry_type_t type)
+{
+ str ret = MAL_SUCCEED;
+ switch (type)
+ {
+ case SFCGAL_TYPE_POINT:
+ *res = wkbPoint_mdb;
+ break;
+
+ case SFCGAL_TYPE_LINESTRING:
+ *res = wkbLineString_mdb;
+ break;
+
+ case SFCGAL_TYPE_POLYGON:
+ *res = wkbPolygon_mdb;
+ break;
+
+ case SFCGAL_TYPE_MULTIPOINT:
+ *res = wkbMultiPoint_mdb;
+ break;
+
+ case SFCGAL_TYPE_MULTILINESTRING:
+ *res = wkbMultiLineString_mdb;
+ break;
+
+ case SFCGAL_TYPE_MULTIPOLYGON:
+ *res = wkbMultiPolygon_mdb;
+ break;
+
+ case SFCGAL_TYPE_MULTISOLID:
+ case SFCGAL_TYPE_GEOMETRYCOLLECTION:
+ case SFCGAL_TYPE_POLYHEDRALSURFACE:
+ case SFCGAL_TYPE_SOLID:
+ //*res = wkbPolyehdralSurface_mdb;
+ *res = wkbGeometryCollection_mdb;
+ break;
+
+ case SFCGAL_TYPE_TRIANGULATEDSURFACE:
+ case SFCGAL_TYPE_TRIANGLE:
+ *res = wkbTin_mdb;
+ break;
+
+ default:
+ *res = -1;
+ throw(MAL, "cgal2geom", "Unknown sfcgal geometry type");
+ }
+
+ return ret;
+}
+
+static str
+ring_from_sfcgal(GEOSGeom *res, const sfcgal_geometry_t* geom, int want3d)
+{
+ uint32_t i, npoints;
+ double point_x, point_y, point_z;
+ str ret = MAL_SUCCEED;
+ GEOSGeom outGeometry;
+ GEOSCoordSeq outCoordSeq;
+
+ assert(geom);
+ npoints = sfcgal_linestring_num_points(geom);
+ //create the coordSeq for the new geometry
+ if (!(outCoordSeq = GEOSCoordSeq_create(npoints, want3d ? 3 : 2))) {
+ *res = NULL;
+ throw(MAL, "ring_from_sfcgal", "GEOSCoordSeq_create failed");
+ }
+
+ for (i = 0; i < npoints; i++)
+ {
+ const sfcgal_geometry_t* pt = sfcgal_linestring_point_n(geom, i);
+ point_x = sfcgal_point_x(pt);
+ point_y = sfcgal_point_y(pt);
+ GEOSCoordSeq_setX(outCoordSeq, i, point_x);
+ GEOSCoordSeq_setY(outCoordSeq, i, point_y);
+
+ if (sfcgal_geometry_is_3d(geom)) {
+ point_z = sfcgal_point_z(pt);
+ GEOSCoordSeq_setZ(outCoordSeq, i, point_z);
+ } else if (want3d) {
+ point_z = 0.0;
+ GEOSCoordSeq_setZ(outCoordSeq, i, point_z);
+ }
+ }
+
+ if (!(outGeometry = GEOSGeom_createLinearRing(outCoordSeq))) {
+ *res = NULL;
+ throw(MAL, "ring_from_sfcgal", "GEOSGeom_createLinearRing failed");
+ }
+ *res = outGeometry;
+ return ret;
+}
+
+str
+sfcgal_to_geom(GEOSGeom *res, const sfcgal_geometry_t* geom, int force3D, int
srid)
+{
+ uint32_t ngeoms, nshells, npoints;
+ double point_x, point_y, point_z;
+ uint32_t i, j, k, nrings;
+ int type, want3d;
+ str ret = MAL_SUCCEED;
+ GEOSGeom* geoms = NULL;
+ GEOSGeom outGeometry;
+ GEOSCoordSeq outCoordSeq;
+ GEOSGeom externalRing, *internalRings;
+
+ assert(geom);
+
+ want3d = force3D || sfcgal_geometry_is_3d(geom);
+
+ switch (sfcgal_geometry_type_id(geom))
+ {
+ case SFCGAL_TYPE_POINT:
+ if (sfcgal_geometry_is_empty(geom)) {
+ //TODO: How to build an empty GEOSGeom??
+ *res = NULL;
+ break;
+ }
+
+ if (!(outCoordSeq = GEOSCoordSeq_create(1, want3d ? 3 : 2))) {
+ *res = NULL;
+ throw(MAL, "sfcgal_to_geom", "GEOSCoordSeq_create failed");
+ }
+
+ point_x = sfcgal_point_x(geom);
+ point_y = sfcgal_point_y(geom);
+
+ GEOSCoordSeq_setOrdinate(outCoordSeq, 0, 0, point_x);
+ GEOSCoordSeq_setOrdinate(outCoordSeq, 0, 1, point_y);
+
+ if (sfcgal_geometry_is_3d(geom)) {
+ point_z = sfcgal_point_z(geom);
+ GEOSCoordSeq_setOrdinate(outCoordSeq, 0, 2, point_z);
+ } else if (want3d) {
+ point_z = 0.0;
+ GEOSCoordSeq_setOrdinate(outCoordSeq, 0, 2, point_z);
+ }
+
+ if (!(*res = GEOSGeom_createPoint(outCoordSeq))) {
+ throw(MAL, "sfcgal_to_geom", "Failed to create GEOSGeometry
from the coordinates");
+ }
+ break;
+ case SFCGAL_TYPE_LINESTRING:
+ if (sfcgal_geometry_is_empty(geom)) {
+ //TODO: How to build an empty GEOSGeom??
+ *res = NULL;
+ break;
+ }
+
+ npoints = sfcgal_linestring_num_points(geom);
+ //create the coordSeq for the new geometry
+ if (!(outCoordSeq = GEOSCoordSeq_create(npoints, want3d ? 3 : 2)))
{
+ *res = NULL;
+ throw(MAL, "sfcgal_to_geom", "GEOSCoordSeq_create failed");
+ }
+
+ for (i = 0; i < npoints; i++)
+ {
+ const sfcgal_geometry_t* pt = sfcgal_linestring_point_n(geom,
i);
+ point_x = sfcgal_point_x(pt);
+ point_y = sfcgal_point_y(pt);
+ GEOSCoordSeq_setX(outCoordSeq, i, point_x);
+ GEOSCoordSeq_setY(outCoordSeq, i, point_y);
+
+ if (sfcgal_geometry_is_3d(geom)) {
+ point_z = sfcgal_point_z(pt);
+ GEOSCoordSeq_setZ(outCoordSeq, i, point_z);
+ } else if (want3d) {
+ point_z = 0.0;
+ GEOSCoordSeq_setZ(outCoordSeq, i, point_z);
+ }
+ }
+
+ if (!(outGeometry = GEOSGeom_createLineString(outCoordSeq))) {
+ *res = NULL;
+ throw(MAL, "sfcgal_to_geom", "GEOSGeom_createLineString
failed");
+ }
+ *res = outGeometry;
+ break;
+ case SFCGAL_TYPE_TRIANGLE:
+
+ if (sfcgal_geometry_is_empty(geom)) {
+ //TODO: How to build an empty GEOSGeom??
+ *res = NULL;
+ break;
+ }
+
+ npoints = sfcgal_linestring_num_points(geom);
+ //create the coordSeq for the new geometry
+ if (!(outCoordSeq = GEOSCoordSeq_create(npoints, want3d ? 3 : 2)))
{
+ *res = NULL;
+ throw(MAL, "sfcgal_to_geom", "GEOSCoordSeq_create failed");
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ const sfcgal_geometry_t* pt = sfcgal_triangle_vertex(geom,
(i%3));
+ point_x = sfcgal_point_x(pt);
+ point_y = sfcgal_point_y(pt);
+ GEOSCoordSeq_setX(outCoordSeq, i, point_x);
+ GEOSCoordSeq_setY(outCoordSeq, i, point_y);
+
+ if ( sfcgal_geometry_is_3d(geom)) {
+ point_z = sfcgal_point_z(pt);
+ GEOSCoordSeq_setZ(outCoordSeq, i, point_z);
+ } else if (want3d) {
+ point_z = 0.0;
+ GEOSCoordSeq_setZ(outCoordSeq, i, point_z);
+ }
+
+ }
+ if (!(outGeometry = GEOSGeom_createLineString(outCoordSeq))) {
+ *res = NULL;
+ throw(MAL, "sfcgal_to_geom", "GEOSGeom_createLineString
failed");
+ }
+ *res = outGeometry;
+ break;
+ case SFCGAL_TYPE_POLYGON:
+ if (sfcgal_geometry_is_empty(geom)) {
+ //TODO: How to build an empty GEOSGeom??
+ *res = NULL;
+ break;
+ }
+
+ nrings = sfcgal_polygon_num_interior_rings(geom) + 1;
+ internalRings = (GEOSGeom*) GDKmalloc(sizeof(GEOSGeom) * nrings);
+ if ( (ret = ring_from_sfcgal(&externalRing,
sfcgal_polygon_exterior_ring(geom), want3d)) != MAL_SUCCEED) {
+ //TODO: free stuff
+ return ret;
+ }
+
+ for (i = 1; i < nrings; i++)
+ if ( (ret = ring_from_sfcgal(&(internalRings[i-1]),
sfcgal_polygon_interior_ring_n(geom, i-1), want3d)) != MAL_SUCCEED ) {
+ //TODO: free stuff
+ return ret;
+ }
+
+ *res = GEOSGeom_createPolygon(externalRing, internalRings,
nrings-1);
+ break;
+ case SFCGAL_TYPE_MULTIPOINT:
+ case SFCGAL_TYPE_MULTILINESTRING:
+ case SFCGAL_TYPE_MULTIPOLYGON:
+ case SFCGAL_TYPE_GEOMETRYCOLLECTION:
+ ngeoms = sfcgal_geometry_collection_num_geometries(geom);
+ if (ngeoms)
+ {
+ geoms = (GEOSGeom*) GDKmalloc(sizeof(GEOSGeom) * ngeoms);
+ for (i = 0; i < ngeoms; i++)
+ {
+ const sfcgal_geometry_t* g =
sfcgal_geometry_collection_geometry_n(geom, i);
+ if ( (ret = sfcgal_to_geom(&geoms[i], g, 0, srid)) !=
MAL_SUCCEED) {
+ //TODO: free what was allocated
+ *res = NULL;
+ return ret;
+ }
+ }
+ }
+
+ if ( (ret = sfcgal_type_to_geom_type(&type,
sfcgal_geometry_type_id(geom))) != MAL_SUCCEED) {
+ //TODO: free what was allocated
+ *res = NULL;
+ return ret;
+ }
+ *res = GEOSGeom_createCollection(type-1, geoms, ngeoms);
+ break;
+ case SFCGAL_TYPE_POLYHEDRALSURFACE:
+ ngeoms = sfcgal_polyhedral_surface_num_polygons(geom);
+ if (ngeoms)
+ {
+ geoms = (GEOSGeom*) GDKmalloc(sizeof(GEOSGeom) * ngeoms);
+ for (i = 0; i < ngeoms; i++)
+ {
+ const sfcgal_geometry_t* g =
sfcgal_polyhedral_surface_polygon_n( geom, i );
+ if ( (ret = sfcgal_to_geom(&geoms[i], g, 0, srid)) !=
MAL_SUCCEED) {
+ //TODO: free what was allocated
+ *res = NULL;
+ return ret;
+ }
+ }
+ }
+ if ( (ret = sfcgal_type_to_geom_type(&type,
sfcgal_geometry_type_id(geom))) != MAL_SUCCEED) {
+ //TODO: free what was allocated
+ *res = NULL;
+ return ret;
+ }
+ *res = GEOSGeom_createCollection(type-1, geoms, ngeoms);
+ break;
+ /* Solid is map as a closed PolyhedralSurface (for now) */
+ case SFCGAL_TYPE_SOLID:
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list