PostGIS  2.1.10dev-r@@SVN_REVISION@@
geometry_inout.c
Go to the documentation of this file.
1 #include "postgres.h"
2 #include "utils/geo_decls.h"
3 
4 #include "../postgis_config.h"
5 
6 #include "liblwgeom.h" /* For standard geometry types. */
7 #include "lwgeom_pg.h" /* For debugging macros. */
8 
9 
10 Datum geometry_to_point(PG_FUNCTION_ARGS);
11 Datum point_to_geometry(PG_FUNCTION_ARGS);
12 Datum geometry_to_path(PG_FUNCTION_ARGS);
13 Datum path_to_geometry(PG_FUNCTION_ARGS);
14 Datum geometry_to_polygon(PG_FUNCTION_ARGS);
15 Datum polygon_to_geometry(PG_FUNCTION_ARGS);
16 
21 Datum point_to_geometry(PG_FUNCTION_ARGS)
22 {
23  Point *point;
24  LWPOINT *lwpoint;
25  GSERIALIZED *geom;
26 
27  POSTGIS_DEBUG(2, "point_to_geometry called");
28 
29  if ( PG_ARGISNULL(0) )
30  PG_RETURN_NULL();
31 
32  point = PG_GETARG_POINT_P(0);
33 
34  if ( ! point )
35  PG_RETURN_NULL();
36 
37  lwpoint = lwpoint_make2d(SRID_UNKNOWN, point->x, point->y);
38  geom = geometry_serialize(lwpoint_as_lwgeom(lwpoint));
39  lwpoint_free(lwpoint);
40 
41  PG_RETURN_POINTER(geom);
42 }
43 
48 Datum geometry_to_point(PG_FUNCTION_ARGS)
49 {
50  Point *point;
51  LWGEOM *lwgeom;
52  LWPOINT *lwpoint;
53  GSERIALIZED *geom;
54 
55  POSTGIS_DEBUG(2, "geometry_to_point called");
56 
57  if ( PG_ARGISNULL(0) )
58  PG_RETURN_NULL();
59 
60  geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
61 
62  if ( gserialized_get_type(geom) != POINTTYPE )
63  elog(ERROR, "geometry_to_point only accepts Points");
64 
65  lwgeom = lwgeom_from_gserialized(geom);
66 
67  if ( lwgeom_is_empty(lwgeom) )
68  PG_RETURN_NULL();
69 
70  lwpoint = lwgeom_as_lwpoint(lwgeom);
71 
72  point = (Point*)palloc(sizeof(Point));
73  point->x = lwpoint_get_x(lwpoint);
74  point->y = lwpoint_get_y(lwpoint);
75 
76  lwpoint_free(lwpoint);
77  PG_FREE_IF_COPY(geom,0);
78 
79  PG_RETURN_POINT_P(point);
80 }
81 
83 Datum geometry_to_path(PG_FUNCTION_ARGS)
84 {
85  PATH *path;
86  LWLINE *lwline;
87  LWGEOM *lwgeom;
88  GSERIALIZED *geom;
89  POINTARRAY *pa;
90  int i;
91  POINT2D pt;
92  size_t size;
93 
94  POSTGIS_DEBUG(2, "geometry_to_path called");
95 
96  if ( PG_ARGISNULL(0) )
97  PG_RETURN_NULL();
98 
99  geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
100 
101  if ( gserialized_get_type(geom) != LINETYPE )
102  elog(ERROR, "geometry_to_path only accepts LineStrings");
103 
104  lwgeom = lwgeom_from_gserialized(geom);
105  if ( lwgeom_is_empty(lwgeom) )
106  PG_RETURN_NULL();
107  lwline = lwgeom_as_lwline(lwgeom);
108 
109  pa = lwline->points;
110  size = offsetof(PATH, p[0]) + sizeof(path->p[0]) * pa->npoints;
111  path = (PATH*)palloc(size);
112  SET_VARSIZE(path, size);
113  path->npts = pa->npoints;
114  path->closed = 0;
115  path->dummy = 0;
116 
117  for ( i = 0; i < pa->npoints; i++ )
118  {
119  getPoint2d_p(pa, i, &pt);
120  (path->p[i]).x = pt.x;
121  (path->p[i]).y = pt.y;
122  }
123 
124  lwgeom_free(lwgeom);
125  PG_FREE_IF_COPY(geom,0);
126 
127  PG_RETURN_PATH_P(path);
128 }
129 
130 
132 Datum path_to_geometry(PG_FUNCTION_ARGS)
133 {
134  PATH *path;
135  LWLINE *lwline;
136  POINTARRAY *pa;
137  GSERIALIZED *geom;
138  POINT4D pt;
139  Point p;
140  int i;
141 
142  POSTGIS_DEBUG(2, "path_to_geometry called");
143 
144  if ( PG_ARGISNULL(0) )
145  PG_RETURN_NULL();
146 
147  path = PG_GETARG_PATH_P(0);
148 
149  if ( ! path )
150  PG_RETURN_NULL();
151 
152  pa = ptarray_construct_empty(0, 0, path->npts);
153  for ( i = 0; i < path->npts; i++ )
154  {
155  p = path->p[i];
156  pt.x = p.x;
157  pt.y = p.y;
158  ptarray_append_point(pa, &pt, LW_FALSE);
159  }
160  lwline = lwline_construct(SRID_UNKNOWN, NULL, pa);
161  geom = geometry_serialize(lwline_as_lwgeom(lwline));
162  lwline_free(lwline);
163 
164  PG_RETURN_POINTER(geom);
165 }
166 
168 Datum geometry_to_polygon(PG_FUNCTION_ARGS)
169 {
170  POLYGON *polygon;
171  LWPOLY *lwpoly;
172  LWGEOM *lwgeom;
173  GSERIALIZED *geom;
174  POINTARRAY *pa;
175  GBOX gbox;
176  int i;
177  size_t size;
178 
179  POSTGIS_DEBUG(2, "geometry_to_polygon called");
180 
181  if ( PG_ARGISNULL(0) )
182  PG_RETURN_NULL();
183 
184  geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
185 
186  if ( gserialized_get_type(geom) != POLYGONTYPE )
187  elog(ERROR, "geometry_to_polygon only accepts Polygons");
188 
189  lwgeom = lwgeom_from_gserialized(geom);
190  if ( lwgeom_is_empty(lwgeom) )
191  PG_RETURN_NULL();
192  lwpoly = lwgeom_as_lwpoly(lwgeom);
193 
194  pa = lwpoly->rings[0];
195 
196  size = offsetof(POLYGON, p[0]) + sizeof(polygon->p[0]) * pa->npoints;
197  polygon = (POLYGON*)palloc0(size); /* zero any holes */
198  SET_VARSIZE(polygon, size);
199 
200  polygon->npts = pa->npoints;
201 
202  lwgeom_calculate_gbox(lwgeom, &gbox);
203  polygon->boundbox.low.x = gbox.xmin;
204  polygon->boundbox.low.y = gbox.ymin;
205  polygon->boundbox.high.x = gbox.xmax;
206  polygon->boundbox.high.y = gbox.ymax;
207 
208  for ( i = 0; i < pa->npoints; i++ )
209  {
210  POINT2D pt;
211  getPoint2d_p(pa, i, &pt);
212  (polygon->p[i]).x = pt.x;
213  (polygon->p[i]).y = pt.y;
214  }
215 
216  lwgeom_free(lwgeom);
217  PG_FREE_IF_COPY(geom,0);
218 
219  PG_RETURN_POLYGON_P(polygon);
220 }
221 
222 
224 Datum polygon_to_geometry(PG_FUNCTION_ARGS)
225 {
226  POLYGON *polygon;
227  LWPOLY *lwpoly;
228  POINTARRAY *pa;
229  POINTARRAY **ppa;
230  GSERIALIZED *geom;
231  Point p;
232  int i = 0, unclosed = 0;
233 
234  POSTGIS_DEBUG(2, "polygon_to_geometry called");
235 
236  if ( PG_ARGISNULL(0) )
237  PG_RETURN_NULL();
238 
239  polygon = PG_GETARG_POLYGON_P(0);
240 
241  if ( ! polygon )
242  PG_RETURN_NULL();
243 
244  /* Are first and last points different? If so we need to close this ring */
245  if ( memcmp( polygon->p, polygon->p + polygon->npts - 1, sizeof(Point) ) )
246  {
247  unclosed = 1;
248  }
249 
250  pa = ptarray_construct_empty(0, 0, polygon->npts + unclosed);
251 
252  for ( i = 0; i < (polygon->npts+unclosed); i++ )
253  {
254  POINT4D pt;
255  p = polygon->p[i % polygon->npts];
256  pt.x = p.x;
257  pt.y = p.y;
258  ptarray_append_point(pa, &pt, LW_FALSE);
259  }
260 
261  ppa = palloc(sizeof(POINTARRAY*));
262  ppa[0] = pa;
263  lwpoly = lwpoly_construct(SRID_UNKNOWN, NULL, 1, ppa);
264  geom = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
265  lwpoly_free(lwpoly);
266 
267  PG_RETURN_POINTER(geom);
268 }
269 
double x
Definition: liblwgeom.h:308
#define LINETYPE
Definition: liblwgeom.h:61
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Definition: g_serialized.c:56
Datum path_to_geometry(PG_FUNCTION_ARGS)
Datum geometry_to_point(PG_FUNCTION_ARGS)
Datum point_to_geometry(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int npoints
Definition: liblwgeom.h:327
#define POLYGONTYPE
Definition: liblwgeom.h:62
LWPOINT * lwpoint_make2d(int srid, double x, double y)
Definition: lwpoint.c:130
double xmax
Definition: liblwgeom.h:249
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:57
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:180
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1006
void lwline_free(LWLINE *line)
Definition: lwline.c:63
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:125
Datum geometry_to_polygon(PG_FUNCTION_ARGS)
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:80
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:239
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
Definition: lwgeom.c:608
double x
Definition: liblwgeom.h:284
double lwpoint_get_x(const LWPOINT *point)
Definition: lwpoint.c:48
double ymin
Definition: liblwgeom.h:250
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:249
double xmin
Definition: liblwgeom.h:248
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_TRUE, then a duplicate point will not be added.
Definition: ptarray.c:141
#define LW_FALSE
Definition: liblwgeom.h:52
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition: lwpoly.c:29
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:79
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:29
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:154
POINTARRAY ** rings
Definition: liblwgeom.h:413
Datum polygon_to_geometry(PG_FUNCTION_ARGS)
double ymax
Definition: liblwgeom.h:251
double y
Definition: liblwgeom.h:284
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:434
tuple x
Definition: pixval.py:53
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:89
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
PG_FUNCTION_INFO_V1(point_to_geometry)
Cast a PostgreSQL Point to a PostGIS geometry.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:60
double lwpoint_get_y(const LWPOINT *point)
Definition: lwpoint.c:58
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:254
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1229
double y
Definition: liblwgeom.h:308
Datum geometry_to_path(PG_FUNCTION_ARGS)
This library is the generic geometry handling section of PostGIS.
POINTARRAY * points
Definition: liblwgeom.h:378