Changeset: 26c8480c79a9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/26c8480c79a9
Added Files:
geom/sql/functions/Tests/ST_Transform.reqtests
geom/sql/functions/Tests/ST_Transform.test
Modified Files:
geom/lib/libgeom.h
geom/monetdb5/geom.c
geom/sql/functions/Tests/All
Branch: geo-update
Log Message:
Updated PROJ library calls to latest version (we now only support versions from
PROJ 6) in st_transform functions (+ the library include); added tests for
ST_Transform
diffs (truncated from 436 to 300 lines):
diff --git a/geom/lib/libgeom.h b/geom/lib/libgeom.h
--- a/geom/lib/libgeom.h
+++ b/geom/lib/libgeom.h
@@ -27,10 +27,8 @@
#endif
#include <geos_c.h>
-
#ifdef HAVE_PROJ
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#include <proj_api.h> //it is needed to transform from one srid to another
+#include <proj.h>
#endif
/* geos does not support 3d envelope */
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -178,7 +178,6 @@ wkbCollectAggrSubGroupedCand(bat *outid,
geomCollectionType =
GEOSGeom_getCollectionType(GEOSGeomTypeId(inGEOM));
//srid = GEOSGetSRID(inGEOM);
}
-
unionGroup[geomCount] = inGEOM;
geomCount += 1;
if (geomCollectionType != GEOS_GEOMETRYCOLLECTION &&
GEOSGeom_getCollectionType(GEOSGeomTypeId(inGEOM)) != geomCollectionType)
@@ -311,59 +310,57 @@ geometryHasM(int info)
#define M_PI ((double) 3.14159265358979323846) /* pi */
#endif
+//TODO Remove?
/** convert degrees to radians */
-static inline void
+/*static inline void
degrees2radians(double *x, double *y, double *z)
{
double val = M_PI / 180.0;
*x *= val;
*y *= val;
*z *= val;
-}
-
+}*/
+
+//TODO Remove?
/** convert radians to degrees */
-static inline void
+/*static inline void
radians2degrees(double *x, double *y, double *z)
{
double val = 180.0 / M_PI;
*x *= val;
*y *= val;
*z *= val;
-}
+}*/
static str
-transformCoordSeq(int idx, int coordinatesNum, projPJ proj4_src, projPJ
proj4_dst, const GEOSCoordSequence *gcs_old, GEOSCoordSeq gcs_new)
+transformCoordSeq(int idx, int coordinatesNum, PJ *P, const GEOSCoordSequence
*gcs_old, GEOSCoordSeq gcs_new)
{
double x = 0, y = 0, z = 0;
- int *errorNum = 0;
+ int errorNum = 0;
+ PJ_COORD c, c_out;
if (!GEOSCoordSeq_getX(gcs_old, idx, &x) ||
!GEOSCoordSeq_getY(gcs_old, idx, &y) ||
(coordinatesNum > 2 && !GEOSCoordSeq_getZ(gcs_old, idx, &z)))
throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos cannot get
coordinates");
- /* check if the passed reference system is geographic (proj=latlong)
- * and change the degrees to radians because pj_transform works with
radians*/
- if (pj_is_latlong(proj4_src))
- degrees2radians(&x, &y, &z);
-
- pj_transform(proj4_src, proj4_dst, 1, 0, &x, &y, &z);
-
- errorNum = pj_get_errno_ref();
- if (*errorNum != 0) {
+ c.lpzt.lam=x;
+ c.lpzt.phi=y;
+ c.lpzt.z=z;
+ c.lpzt.t = HUGE_VAL;
+
+ c_out = proj_trans(P, PJ_FWD, c);
+
+ errorNum = proj_errno(P);
+ if (errorNum != 0) {
if (coordinatesNum > 2)
- throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos
cannot transform point (%f %f %f): %s\n", x, y, z, pj_strerrno(*errorNum));
+ throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos
cannot transform point (%f %f %f): %s\n", x, y, z, proj_errno_string(errorNum));
else
- throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos
cannot transform point (%f %f): %s\n", x, y, pj_strerrno(*errorNum));
- }
-
- /* check if the destination reference system is geographic and change
- * the destination coordinates from radians to degrees */
- if (pj_is_latlong(proj4_dst))
- radians2degrees(&x, &y, &z);
-
- if (!GEOSCoordSeq_setX(gcs_new, idx, x) ||
- !GEOSCoordSeq_setY(gcs_new, idx, y) ||
+ throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos
cannot transform point (%f %f): %s\n", x, y, proj_errno_string(errorNum));
+ }
+
+ if (!GEOSCoordSeq_setX(gcs_new, idx,c_out.xy.x) ||
+ !GEOSCoordSeq_setY(gcs_new, idx,c_out.xy.y) ||
(coordinatesNum > 2 && !GEOSCoordSeq_setZ(gcs_new, idx, z)))
throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos cannot set
coordinates");
@@ -371,7 +368,7 @@ transformCoordSeq(int idx, int coordinat
}
static str
-transformPoint(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, projPJ proj4_src, projPJ proj4_dst)
+transformPoint(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, PJ *P)
{
int coordinatesNum = 0;
const GEOSCoordSequence *gcs_old;
@@ -394,7 +391,7 @@ transformPoint(GEOSGeometry **transforme
throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos operation
GEOSGeom_getCoordSeq failed");
/* create the transformed coordinates */
- ret = transformCoordSeq(0, coordinatesNum, proj4_src, proj4_dst,
gcs_old, gcs_new);
+ ret = transformCoordSeq(0, coordinatesNum, P, gcs_old, gcs_new);
if (ret != MAL_SUCCEED) {
GEOSCoordSeq_destroy(gcs_new);
return ret;
@@ -411,7 +408,7 @@ transformPoint(GEOSGeometry **transforme
}
static str
-transformLine(GEOSCoordSeq *gcs_new, const GEOSGeometry *geosGeometry, projPJ
proj4_src, projPJ proj4_dst)
+transformLine(GEOSCoordSeq *gcs_new, const GEOSGeometry *geosGeometry, PJ *P)
{
int coordinatesNum = 0;
const GEOSCoordSequence *gcs_old;
@@ -437,7 +434,7 @@ transformLine(GEOSCoordSeq *gcs_new, con
/* create the transformed coordinates */
for (i = 0; i < pointsNum; i++) {
- ret = transformCoordSeq(i, coordinatesNum, proj4_src,
proj4_dst, gcs_old, *gcs_new);
+ ret = transformCoordSeq(i, coordinatesNum, P, gcs_old,
*gcs_new);
if (ret != MAL_SUCCEED) {
GEOSCoordSeq_destroy(*gcs_new);
*gcs_new = NULL;
@@ -449,12 +446,12 @@ transformLine(GEOSCoordSeq *gcs_new, con
}
static str
-transformLineString(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, projPJ proj4_src, projPJ proj4_dst)
+transformLineString(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, PJ *P)
{
GEOSCoordSeq coordSeq;
str ret = MAL_SUCCEED;
- ret = transformLine(&coordSeq, geosGeometry, proj4_src, proj4_dst);
+ ret = transformLine(&coordSeq, geosGeometry, P);
if (ret != MAL_SUCCEED) {
*transformedGeometry = NULL;
return ret;
@@ -471,12 +468,12 @@ transformLineString(GEOSGeometry **trans
}
static str
-transformLinearRing(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, projPJ proj4_src, projPJ proj4_dst)
+transformLinearRing(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, PJ *P)
{
GEOSCoordSeq coordSeq = NULL;
str ret = MAL_SUCCEED;
- ret = transformLine(&coordSeq, geosGeometry, proj4_src, proj4_dst);
+ ret = transformLine(&coordSeq, geosGeometry, P);
if (ret != MAL_SUCCEED) {
*transformedGeometry = NULL;
return ret;
@@ -493,7 +490,7 @@ transformLinearRing(GEOSGeometry **trans
}
static str
-transformPolygon(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, projPJ proj4_src, projPJ proj4_dst, int srid)
+transformPolygon(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, PJ *P, int srid)
{
const GEOSGeometry *exteriorRingGeometry;
GEOSGeometry *transformedExteriorRingGeometry = NULL;
@@ -508,7 +505,7 @@ transformPolygon(GEOSGeometry **transfor
throw(MAL, "geom.Transform", SQLSTATE(38000) "Geos operation
GEOSGetExteriorRing failed");
}
- ret = transformLinearRing(&transformedExteriorRingGeometry,
exteriorRingGeometry, proj4_src, proj4_dst);
+ ret = transformLinearRing(&transformedExteriorRingGeometry,
exteriorRingGeometry, P);
if (ret != MAL_SUCCEED) {
*transformedGeometry = NULL;
return ret;
@@ -532,7 +529,7 @@ transformPolygon(GEOSGeometry **transfor
throw(MAL, "geom.Transform", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
}
for (i = 0; i < numInteriorRings; i++) {
- ret =
transformLinearRing(&transformedInteriorRingGeometries[i],
GEOSGetInteriorRingN(geosGeometry, i), proj4_src, proj4_dst);
+ ret =
transformLinearRing(&transformedInteriorRingGeometries[i],
GEOSGetInteriorRingN(geosGeometry, i), P);
if (ret != MAL_SUCCEED) {
while (--i >= 0)
GEOSGeom_destroy(transformedInteriorRingGeometries[i]);
@@ -546,19 +543,19 @@ transformPolygon(GEOSGeometry **transfor
}
*transformedGeometry =
GEOSGeom_createPolygon(transformedExteriorRingGeometry,
transformedInteriorRingGeometries, numInteriorRings);
+
if (*transformedGeometry == NULL) {
for (i = 0; i < numInteriorRings; i++)
GEOSGeom_destroy(transformedInteriorRingGeometries[i]);
ret = createException(MAL, "geom.Transform", SQLSTATE(38000)
"Geos operation GEOSGeom_createPolygon failed");
}
GDKfree(transformedInteriorRingGeometries);
- GEOSGeom_destroy(transformedExteriorRingGeometry);
-
+ //GEOSGeom_destroy(transformedExteriorRingGeometry);
return ret;
}
static str
-transformMultiGeometry(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, projPJ proj4_src, projPJ proj4_dst, int srid, int geometryType)
+transformMultiGeometry(GEOSGeometry **transformedGeometry, const GEOSGeometry
*geosGeometry, PJ *P, int srid, int geometryType)
{
int geometriesNum, subGeometryType, i;
GEOSGeometry **transformedMultiGeometries = NULL;
@@ -580,16 +577,16 @@ transformMultiGeometry(GEOSGeometry **tr
else {
switch (subGeometryType) {
case wkbPoint_mdb:
- ret =
transformPoint(&transformedMultiGeometries[i], multiGeometry, proj4_src,
proj4_dst);
+ ret =
transformPoint(&transformedMultiGeometries[i], multiGeometry, P);
break;
case wkbLineString_mdb:
- ret =
transformLineString(&transformedMultiGeometries[i], multiGeometry, proj4_src,
proj4_dst);
+ ret =
transformLineString(&transformedMultiGeometries[i], multiGeometry, P);
break;
case wkbLinearRing_mdb:
- ret =
transformLinearRing(&transformedMultiGeometries[i], multiGeometry, proj4_src,
proj4_dst);
+ ret =
transformLinearRing(&transformedMultiGeometries[i], multiGeometry, P);
break;
case wkbPolygon_mdb:
- ret =
transformPolygon(&transformedMultiGeometries[i], multiGeometry, proj4_src,
proj4_dst, srid);
+ ret =
transformPolygon(&transformedMultiGeometries[i], multiGeometry, P, srid);
break;
default:
ret = createException(MAL, "geom.Transform",
SQLSTATE(38000) "Geos unknown geometry type");
@@ -618,48 +615,6 @@ transformMultiGeometry(GEOSGeometry **tr
return ret;
}
-
-/* the following function is used in postgis to get projPJ from str.
- * it is necessary to do it in a detailed way like that because pj_init_plus
- * does not set all parameters correctly and I cannot test whether the
- * coordinate reference systems are geographic or not */
-static projPJ
-projFromStr(const char *projStr)
-{
- int t;
- char *params[1024]; // one for each parameter
- char *loc;
- char *str;
- projPJ result;
-
- if (projStr == NULL)
- return NULL;
-
- str = GDKstrdup(projStr);
- if (str == NULL)
- return NULL;
-
- // first we split the string into a bunch of smaller strings,
- // based on the " " separator
-
- params[0] = str; // 1st param, we'll null terminate at the " "
soon
-
- t = 1;
- for (loc = strchr(str, ' '); loc != NULL; loc = strchr(loc, ' ')) {
- if (t == (int) (sizeof(params) / sizeof(params[0]))) {
- /* too many parameters */
- GDKfree(str);
- return NULL;
- }
- *loc++ = 0; // null terminate and advance
- params[t++] = loc;
- }
-
- result = pj_init(t, params);
- GDKfree(str);
-
- return result;
-}
#endif
/* It gets a geometry and transforms its coordinates to the provided srid */
@@ -673,9 +628,9 @@ wkbTransform(wkb **transformedWKB, wkb *
(void) srid_dst;
(void) proj4_src_str;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]