PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
postgis/lwgeom_transform.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * PostGIS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * PostGIS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **********************************************************************
20 *
21 * Copyright (C) 2001-2003 Refractions Research Inc.
22 *
23 **********************************************************************/
24
25
26#include "postgres.h"
27#include "fmgr.h"
28#include "utils/builtins.h"
29
30#include "../postgis_config.h"
31#include "liblwgeom.h"
32#include "lwgeom_transform.h"
33
34#include "float.h" /* DBL_DIG */
35
36Datum transform(PG_FUNCTION_ARGS);
37Datum transform_geom(PG_FUNCTION_ARGS);
38Datum postgis_proj_version(PG_FUNCTION_ARGS);
39Datum LWGEOM_asKML(PG_FUNCTION_ARGS);
40
48Datum transform(PG_FUNCTION_ARGS)
49{
50 GSERIALIZED* geom;
51 GSERIALIZED* result=NULL;
52 LWGEOM* lwgeom;
53 LWPROJ *pj;
54 int32 srid_to, srid_from;
55
56 srid_to = PG_GETARG_INT32(1);
57 if (srid_to == SRID_UNKNOWN)
58 {
59 elog(ERROR, "ST_Transform: %d is an invalid target SRID", SRID_UNKNOWN);
60 PG_RETURN_NULL();
61 }
62
63 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
64 srid_from = gserialized_get_srid(geom);
65
66 if ( srid_from == SRID_UNKNOWN )
67 {
68 PG_FREE_IF_COPY(geom, 0);
69 elog(ERROR, "ST_Transform: Input geometry has unknown (%d) SRID", SRID_UNKNOWN);
70 PG_RETURN_NULL();
71 }
72
73 /* Input SRID and output SRID are equal, noop */
74 if ( srid_from == srid_to )
75 PG_RETURN_POINTER(geom);
76
77 if ( GetPJUsingFCInfo(fcinfo, srid_from, srid_to, &pj) == LW_FAILURE )
78 {
79 PG_FREE_IF_COPY(geom, 0);
80 elog(ERROR, "ST_Transform: Failure reading projections from spatial_ref_sys.");
81 PG_RETURN_NULL();
82 }
83
84 /* now we have a geometry, and input/output PJ structs. */
85 lwgeom = lwgeom_from_gserialized(geom);
86 lwgeom_transform(lwgeom, pj);
87 lwgeom->srid = srid_to;
88
89 /* Re-compute bbox if input had one (COMPUTE_BBOX TAINTING) */
90 if ( lwgeom->bbox )
91 {
92 lwgeom_refresh_bbox(lwgeom);
93 }
94
95 result = geometry_serialize(lwgeom);
96 lwgeom_free(lwgeom);
97 PG_FREE_IF_COPY(geom, 0);
98
99 PG_RETURN_POINTER(result); /* new geometry */
100}
101
111Datum transform_geom(PG_FUNCTION_ARGS)
112{
113 GSERIALIZED *gser, *gser_result=NULL;
114 LWGEOM *geom;
115 char *input_srs, *output_srs;
116 int32 result_srid;
117 int rv;
118
119 /* Take a copy, since we will be altering the coordinates */
120 gser = PG_GETARG_GSERIALIZED_P_COPY(0);
121
122 /* Convert from text to cstring for libproj */
123 input_srs = text_to_cstring(PG_GETARG_TEXT_P(1));
124 output_srs = text_to_cstring(PG_GETARG_TEXT_P(2));
125 result_srid = PG_GETARG_INT32(3);
126
127 /* now we have a geometry, and input/output PJ structs. */
128 geom = lwgeom_from_gserialized(gser);
129 rv = lwgeom_transform_from_str(geom, input_srs, output_srs);
130 pfree(input_srs);
131 pfree(output_srs);
132
133 if (rv == LW_FAILURE)
134 {
135 elog(ERROR, "coordinate transformation failed");
136 PG_RETURN_NULL();
137 }
138
139 /* Re-compute bbox if input had one (COMPUTE_BBOX TAINTING) */
140 geom->srid = result_srid;
141 if (geom->bbox)
143
144 gser_result = geometry_serialize(geom);
145 lwgeom_free(geom);
146 PG_FREE_IF_COPY(gser, 0);
147
148 PG_RETURN_POINTER(gser_result); /* new geometry */
149}
150
151
153Datum postgis_proj_version(PG_FUNCTION_ARGS)
154{
155#if POSTGIS_PROJ_VERSION < 60
156 const char *ver = pj_get_release();
157 text *result = cstring_to_text(ver);
158#else
159 PJ_INFO pji = proj_info();
160 text *result = cstring_to_text(pji.version);
161#endif
162 PG_RETURN_POINTER(result);
163}
164
165
170Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
171{
172 LWGEOM *lwgeom;
173 char *kml;
174 text *result;
175 const char *default_prefix = ""; /* default prefix */
176 char *prefixbuf;
177 const char *prefix = default_prefix;
178 int32_t srid_from;
179 const int32_t srid_to = 4326;
180
181 /* Get the geometry */
182 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
183 int precision = PG_GETARG_INT32(1);
184 text *prefix_text = PG_GETARG_TEXT_P(2);
185 srid_from = gserialized_get_srid(geom);
186
187 if ( srid_from == SRID_UNKNOWN )
188 {
189 PG_FREE_IF_COPY(geom, 0);
190 elog(ERROR, "ST_AsKML: Input geometry has unknown (%d) SRID", SRID_UNKNOWN);
191 PG_RETURN_NULL();
192 }
193
194 /* Condition precision */
195 if (precision > DBL_DIG)
196 precision = DBL_DIG;
197 if (precision < 0)
198 precision = 0;
199
200 if (VARSIZE_ANY_EXHDR(prefix_text) > 0)
201 {
202 /* +2 is one for the ':' and one for term null */
203 prefixbuf = palloc(VARSIZE_ANY_EXHDR(prefix_text)+2);
204 memcpy(prefixbuf, VARDATA(prefix_text),
205 VARSIZE_ANY_EXHDR(prefix_text));
206 /* add colon and null terminate */
207 prefixbuf[VARSIZE_ANY_EXHDR(prefix_text)] = ':';
208 prefixbuf[VARSIZE_ANY_EXHDR(prefix_text)+1] = '\0';
209 prefix = prefixbuf;
210 }
211
212 lwgeom = lwgeom_from_gserialized(geom);
213
214 if (srid_from != srid_to)
215 {
216 LWPROJ *pj;
217 if (GetPJUsingFCInfo(fcinfo, srid_from, srid_to, &pj) == LW_FAILURE)
218 {
219 PG_FREE_IF_COPY(geom, 0);
220 elog(ERROR, "ST_AsKML: Failure reading projections from spatial_ref_sys.");
221 PG_RETURN_NULL();
222 }
223 lwgeom_transform(lwgeom, pj);
224 }
225
226 kml = lwgeom_to_kml2(lwgeom, precision, prefix);
227 lwgeom_free(lwgeom);
228 PG_FREE_IF_COPY(geom, 0);
229
230 if (!kml)
231 PG_RETURN_NULL();
232
233 result = cstring_to_text(kml);
234 lwfree(kml);
235
236 PG_RETURN_POINTER(result);
237}
static uint8_t precision
Definition cu_in_twkb.c:25
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
Definition lwgeom.c:689
#define LW_FAILURE
Definition liblwgeom.h:110
int lwgeom_transform(LWGEOM *geom, LWPROJ *pj)
Transform (reproject) a geometry in-place.
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
char * lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix)
Definition lwout_kml.c:44
void lwfree(void *mem)
Definition lwutil.c:242
int lwgeom_transform_from_str(LWGEOM *geom, const char *instr, const char *outstr)
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:229
This library is the generic geometry handling section of PostGIS.
char * text_to_cstring(const text *textptr)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum transform_geom(PG_FUNCTION_ARGS)
Datum transform(PG_FUNCTION_ARGS)
Datum postgis_proj_version(PG_FUNCTION_ARGS)
Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(transform)
transform( GEOMETRY, INT (output srid) ) tmpPts - if there is a nadgrid error (-38),...
unsigned int int32
Definition shpopen.c:273
GBOX * bbox
Definition liblwgeom.h:444
int32_t srid
Definition liblwgeom.h:446