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

Reply via email to