Changeset: 8a27bd9efb0f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/8a27bd9efb0f
Modified Files:
        geom/monetdb5/geom.c
        geom/monetdb5/geom.h
Branch: geo-update
Log Message:

Added simpler data types to represent geometries (instead of using GEOSGeom) 
and refactored the code to use them.


diffs (truncated from 913 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
@@ -16,54 +16,22 @@
 #include "mal_exception.h"
 
 /**
- * Auxilary Functions
- * 
- **/
-/* Destroy a Geos geometry */
-static void destroyGeom(GEOSGeom *g)
-{
-       if (*g)
-               GEOSGeom_destroy((*g));
-       (*g) = NULL;
-}
-
-/* Converts wkb into Geos Geometries, if they are not NULL and have the same 
SRID (used for geographic functions) */
-static str wkbGetComplatibleGeometries(wkb **a, wkb **b, GEOSGeom *ga, 
GEOSGeom *gb)
-{
-       str err = MAL_SUCCEED;
-
-       if (is_wkb_nil(*a) || is_wkb_nil(*b))
-       {
-               destroyGeom(ga);
-               destroyGeom(gb);
-               return MAL_SUCCEED;
-       }
-       (*ga) = wkb2geos(*a);
-       (*gb) = wkb2geos(*b);
-       if ((*ga) == NULL || (*gb) == NULL)
-       {
-               destroyGeom(ga);
-               destroyGeom(gb);
-               err = createException(MAL, "geom.GetComplatibleGeometries", 
SQLSTATE(38000) "Geos operation wkb2geos failed");
-       }
-       else if (GEOSGetSRID((*ga)) != GEOSGetSRID((*gb)))
-       {
-               destroyGeom(ga);
-               destroyGeom(gb);
-               err = createException(MAL, "geom.GetComplatibleGeometries", 
SQLSTATE(38000) "Geometries of different SRID");
-       }
-       return err;
-}
-
-/**
  *  Convertions 
  * 
  **/
 
-/* Converts a latitude value in degrees to radians */
-static double longitudeDegreesToRadians(double lon_degrees)
-{
+const double earth_radius = 6371.009;
+const double earth_radius_meters = 6371009;
+
+/**
+ *  Converts a longitude value in degrees to radians 
+ *  The normalization part was taken from PostGIS
+ */
+static double deg2RadLongitude(double lon_degrees)
+{
+       //Convert
        double lon = M_PI * lon_degrees / 180.0;
+       //Normalize
        if (lon == -1.0 * M_PI)
                return M_PI;
        if (lon == -2.0 * M_PI)
@@ -87,10 +55,15 @@ static double longitudeDegreesToRadians(
        return lon;
 }
 
-/* Converts a latitude value in degrees to radians */
-static double latitudeDegreesToRadians(double lat_degrees)
-{
+/**
+ *  Converts a latitude value in degrees to radians 
+ *  The normalization part was taken from PostGIS
+ */
+static double deg2RadLatitude(double lat_degrees)
+{
+       //Convert
        double lat = M_PI * lat_degrees / 180.0;
+       //Normalize
        if (lat > 2.0 * M_PI)
                lat = remainder(lat, 2.0 * M_PI);
 
@@ -112,135 +85,264 @@ static double latitudeDegreesToRadians(d
        return lat;
 }
 
+/* Converts the GeoPoint from degrees to radians latitude and longitude*/
+static GeoPoint deg2RadPoint(GeoPoint geo)
+{
+       geo.lon = deg2RadLongitude(geo.lon);
+       geo.lat = deg2RadLatitude(geo.lat);
+       return geo;
+}
+
+#if 0
 /**
-* Convert spherical coordinates to cartesian coordinates on unit sphere
-* From PostGIS
-*/
-static void geog2cart(double lon, double lat, double *x, double *y, double *z)
-{
-       (*x) = cos(lat) * cos(lon);
-       (*y) = cos(lat) * sin(lon);
-       (*z) = sin(lat);
-}
-
-static void geog2cart_r(double lon, double lat, double *x, double *y, double 
*z)
-{
-       double r = 6371.009;
-       (*x) = r * cos(lat) * cos(lon);
-       (*y) = r * cos(lat) * sin(lon);
-       (*z) = r * sin(lat);
+ *  Converts a longitude value in radians to degrees
+ *  The normalization part was taken from PostGIS
+ */
+static double rad2DegLongitude(double lon_radians)
+{
+       //Convert
+       double lon = lon_radians * 180.0 / M_PI;
+       //Normalize
+       if (lon > 360.0)
+               lon = remainder(lon, 360.0);
+
+       if (lon < -360.0)
+               lon = remainder(lon, -360.0);
+
+       if (lon > 180.0)
+               lon = -360.0 + lon;
+
+       if (lon < -180.0)
+               lon = 360 + lon;
+
+       if (lon == -180.0)
+               return 180.0;
+
+       if (lon == -360.0)
+               return 0.0;
+
+       return lon;
 }
 
 /**
-* Convert cartesian coordinates on unit sphere to spherical coordinates
-* From PostGIS
-*/
-/*static void cart2geog(double x, double y, double z, double *lon, double *lat)
-{
-       (*lon) = atan2(y, x);
-       (*lat) = asin(z);
+ *  Converts a latitude value in radians to degrees
+ *  The normalization part was taken from PostGIS
+ */
+static double rad2DegLatitude(double lat_radians)
+{
+       //Convert
+       double lat = lat_radians * 180.0 / M_PI;
+       //Normalize
+       if (lat > 360.0)
+               lat = remainder(lat, 360.0);
+
+       if (lat < -360.0)
+               lat = remainder(lat, -360.0);
+
+       if (lat > 180.0)
+               lat = 180.0 - lat;
+
+       if (lat < -180.0)
+               lat = -180.0 - lat;
+
+       if (lat > 90.0)
+               lat = 180.0 - lat;
+
+       if (lat < -90.0)
+               lat = -180.0 - lat;
+
+       return lat;
+}
+
+/* Converts the GeoPoint from degrees to radians latitude and longitude*/
+static void rad2DegPoint(GeoPoint *geo)
+{
+       geo->lon = rad2DegLongitude(geo->lon);
+       geo->lat = rad2DegLatitude(geo->lat);
+}
+#endif
+
+static GeoPoint geoPointFromGeom(GEOSGeom geom)
+{
+       GeoPoint geo;
+       GEOSGeomGetX(geom, &(geo.lon));
+       GEOSGeomGetY(geom, &(geo.lat));
+       return geo;
+}
+
+/*static GeoLine geoLineFromGeom(GEOSGeom geom)
+{
+       GeoLine geo;
+       GEOSGeomGetX(GEOSGeomGetStartPoint(geom), &(geo.start.lon));
+       GEOSGeomGetY(GEOSGeomGetStartPoint(geom), &(geo.start.lat));
+       GEOSGeomGetX(GEOSGeomGetEndPoint(geom), &(geo.end.lon));
+       GEOSGeomGetY(GEOSGeomGetEndPoint(geom), &(geo.end.lat));
+       return geo;
 }*/
 
-static void cart2geog_r(double x, double y, double z, double *lon, double *lat)
-{
-       double r = 6371.009;
-       (*lon) = atan2(y, x);
-       (*lat) = asin(z / r);
-}
-
-/* Returns the latitude and longitude (in radians) from a geographic Geom 
point */
-static void pointToRadian(GEOSGeom geom, double *lat_r, double *lon_r)
-{
-       double lat_d, lon_d;
-       GEOSGeomGetX(geom, &lon_d);
-       GEOSGeomGetY(geom, &lat_d);
-
-       (*lat_r) = latitudeDegreesToRadians(lat_d);
-       (*lon_r) = longitudeDegreesToRadians(lon_d);
-}
-
-/* Converts two lat/lon points into cartesian coordinates and creates a Line 
geometry */
-static GEOSGeom geographicPointsToCartesianLine(double lat1, double lon1, 
double lat2, double lon2)
-{
-       double x1, y1, z1, x2, y2, z2;
-       geog2cart(lon1, lat1, &x1, &y1, &z1);
-       geog2cart(lon2, lat2, &x2, &y2, &z2);
-       GEOSCoordSequence *lineSeq = GEOSCoordSeq_create(2, 3);
-       GEOSCoordSeq_setXYZ(lineSeq, 0, x1, y1, z1);
-       GEOSCoordSeq_setXYZ(lineSeq, 1, x2, y2, z2);
-       return GEOSGeom_createLineString(lineSeq);
-}
+static GeoLines geoLinesFromGeom(GEOSGeom geom)
+{
+       const GEOSCoordSequence *gcs = GEOSGeom_getCoordSeq(geom);
+       int segmentCount = GEOSGeomGetNumPoints(geom) - 1;
+       GeoLines geo;
+       geo.segmentCount = segmentCount;
+       //TODO Malloc fail exception?
+       geo.segments = GDKmalloc(sizeof(GeoLine) * segmentCount);
+       for (int i = 0; i < segmentCount; i++)
+       {
+               GEOSCoordSeq_getXY(gcs, i, &geo.segments[i].start.lon, 
&geo.segments[i].start.lat);
+               GEOSCoordSeq_getXY(gcs, i + 1, &geo.segments[i].end.lon, 
&geo.segments[i].end.lat);
+       }
+       return geo;
+}
+
+static GeoPoint geoPointFromLatLon(double lon, double lat)
+{
+       GeoPoint geo;
+       geo.lon = lon;
+       geo.lat = lat;
+       return geo;
+}
+
+static CartPoint cartPointFromXYZ(double x, double y, double z)
+{
+       CartPoint cart;
+       cart.x = x;
+       cart.y = y;
+       cart.z = z;
+       return cart;
+}
+
+/* Converts Well-Known Bytes into Geos Geometries, if they are not NULL and 
have the same SRID (used for geographic functions) */
+static str wkbGetComplatibleGeometries(wkb **a, wkb **b, GEOSGeom *ga, 
GEOSGeom *gb)
+{
+       str err = MAL_SUCCEED;
+
+       if (is_wkb_nil(*a) || is_wkb_nil(*b))
+       {
+               (*ga) = NULL;
+               (*gb) = NULL;
+               return MAL_SUCCEED;
+       }
+       (*ga) = wkb2geos(*a);
+       (*gb) = wkb2geos(*b);
+       if ((*ga) == NULL || (*gb) == NULL)
+       {
+               err = createException(MAL, "geom.wkbGetComplatibleGeometries", 
SQLSTATE(38000) "Geos operation wkb2geos failed");
+       }
+       else if (GEOSGetSRID((*ga)) != GEOSGetSRID((*gb)))
+       {
+               GEOSGeom_destroy(*ga);
+               GEOSGeom_destroy(*gb);
+               err = createException(MAL, "geom.wkbGetComplatibleGeometries", 
SQLSTATE(38000) "Geometries of different SRID");
+       }
+       return err;
+}
+
+/**
+* Convert spherical coordinates to cartesian coordinates on unit sphere
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to