26 #include "../postgis_config.h"
49 #if POSTGIS_PROJ_VERSION < 61
56 if (pj_is_latlong(pj->pj_from))
to_rad(pt) ;
58 LWDEBUGF(4,
"transforming POINT(%f %f) from '%s' to '%s'",
59 orig_pt.
x, orig_pt.
y, pj_get_def(pj->pj_from,0), pj_get_def(pj->pj_to,0));
61 if (pj_transform(pj->pj_from, pj->pj_to, 1, 0, &(pt->
x), &(pt->
y), &(pt->
z)) != 0)
63 int pj_errno_val = *pj_get_errno_ref();
64 if (pj_errno_val == -38)
66 lwnotice(
"PostGIS was unable to transform the point because either no grid"
67 " shift files were found, or the point does not lie within the "
68 "range for which the grid shift is defined. Refer to the "
69 "ST_Transform() section of the PostGIS manual for details on how "
70 "to configure PostGIS to alter this behaviour.");
71 lwerror(
"transform: couldn't project point (%g %g %g): %s (%d)",
72 orig_pt.
x, orig_pt.
y, orig_pt.
z,
73 pj_strerrno(pj_errno_val), pj_errno_val);
78 pj_strerrno(pj_errno_val), pj_errno_val);
83 if (pj_is_latlong(pj->pj_to))
to_dec(pt);
97 for ( i = 0; i < pa->
npoints; i++ )
100 if ( ! point4d_transform(&p, pj) )
return LW_FAILURE;
114 pj.pj_from = projpj_from_string(instr);
117 pj_errstr = pj_strerrno(*pj_get_errno_ref());
118 if (!pj_errstr) pj_errstr =
"";
119 lwerror(
"could not parse proj string '%s'", instr);
123 pj.pj_to = projpj_from_string(outstr);
127 pj_errstr = pj_strerrno(*pj_get_errno_ref());
128 if (!pj_errstr) pj_errstr =
"";
129 lwerror(
"could not parse proj string '%s'", outstr);
142 projpj_from_string(
const char *str1)
144 if (!str1 || str1[0] ==
'\0')
148 return pj_init_plus(str1);
158 uint8_t source_is_latlong =
LW_FALSE;
159 double semi_major_metre = DBL_MAX, semi_minor_metre = DBL_MAX;
162 if (! (str_in && str_out))
165 PJ* pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX, str_in, str_out, NULL);
172 if (strcmp(str_in, str_out) == 0)
174 PJ *pj_source_crs = proj_get_source_crs(PJ_DEFAULT_CTX, pj);
176 PJ_TYPE pj_type = proj_get_type(pj_source_crs);
177 if (pj_type == PJ_TYPE_UNKNOWN)
180 lwerror(
"%s: unable to access source crs type", __func__);
183 source_is_latlong = (pj_type == PJ_TYPE_GEOGRAPHIC_2D_CRS) || (pj_type == PJ_TYPE_GEOGRAPHIC_3D_CRS);
185 pj_ellps = proj_get_ellipsoid(PJ_DEFAULT_CTX, pj_source_crs);
186 proj_destroy(pj_source_crs);
190 lwerror(
"%s: unable to access source crs ellipsoid", __func__);
193 if (!proj_ellipsoid_get_parameters(PJ_DEFAULT_CTX,
200 proj_destroy(pj_ellps);
202 lwerror(
"%s: unable to access source crs ellipsoid parameters", __func__);
205 proj_destroy(pj_ellps);
209 PJ* pj_norm = proj_normalize_for_visualization(PJ_DEFAULT_CTX, pj);
214 else if (pj != pj_norm)
232 PJ *pj_in = proj_create(PJ_DEFAULT_CTX, instr);
235 proj_errno_reset(NULL);
236 lwerror(
"could not parse proj string '%s'", instr);
240 PJ *pj_out = proj_create(PJ_DEFAULT_CTX, outstr);
243 proj_errno_reset(NULL);
244 lwerror(
"could not parse proj string '%s'", outstr);
246 proj_destroy(pj_out);
247 lwerror(
"%s: Failed to transform", __func__);
251 proj_destroy(lp->
pj);
268 if (proj_angular_input(pj->
pj, PJ_FWD))
270 for (i = 0; i < pa->
npoints; i++)
280 PJ_XYZT v = {pa_double[0], pa_double[1], has_z ? pa_double[2] : 0.0, 0.0};
283 PJ_COORD t = proj_trans(pj->
pj, PJ_FWD, c);
285 int pj_errno_val = proj_errno_reset(pj->
pj);
288 lwerror(
"transform: %s (%d)", proj_errno_string(pj_errno_val), pj_errno_val);
291 pa_double[0] = (t.xyzt).
x;
292 pa_double[1] = (t.xyzt).
y;
294 pa_double[2] = (t.xyzt).z;
306 n_converted = proj_trans_generic(pj->
pj,
314 has_z ? pa_double + 2 : NULL,
315 has_z ? point_size : 0,
316 has_z ? n_points : 0,
322 if (n_converted != n_points)
324 lwerror(
"ptarray_transform: converted (%d) != input (%d)", n_converted, n_points);
328 int pj_errno_val = proj_errno_reset(pj->
pj);
331 lwerror(
"transform: %s (%d)", proj_errno_string(pj_errno_val), pj_errno_val);
337 if (proj_angular_output(pj->
pj, PJ_FWD))
339 for (i = 0; i < pa->
npoints; i++)
378 for ( i = 0; i < g->
nrings; i++ )
396 for ( i = 0; i < g->
ngeoms; i++ )
404 lwerror(
"lwgeom_transform: Cannot handle type '%s'",
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define POLYHEDRALSURFACETYPE
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
void * lwalloc(size_t size)
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
int ptarray_has_z(const POINTARRAY *pa)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
static size_t ptarray_point_size(const POINTARRAY *pa)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
uint8_t source_is_latlong
double source_semi_major_metre
double source_semi_minor_metre
uint8_t * serialized_pointlist