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-2006 Refractions Research Inc.
22 *
23 **********************************************************************/
24
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "../postgis_config.h"
30 /*#define POSTGIS_DEBUG_LEVEL 4*/
31 #include "liblwgeom_internal.h"
32 #include "lwgeom_log.h"
33
34
35 /*
36 * Convenience functions to hide the POINTARRAY
37 * TODO: obsolete this
38 */
39 int
lwpoint_getPoint2d_p(const LWPOINT * point,POINT2D * out)40 lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out)
41 {
42 return lwpoint_is_empty(point) ? 0 : getPoint2d_p(point->point, 0, out);
43 }
44
45 /* convenience functions to hide the POINTARRAY */
46 int
lwpoint_getPoint3dz_p(const LWPOINT * point,POINT3DZ * out)47 lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out)
48 {
49 return lwpoint_is_empty(point) ? 0 : getPoint3dz_p(point->point,0,out);
50 }
51 int
lwpoint_getPoint3dm_p(const LWPOINT * point,POINT3DM * out)52 lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out)
53 {
54 return lwpoint_is_empty(point) ? 0 : getPoint3dm_p(point->point,0,out);
55 }
56 int
lwpoint_getPoint4d_p(const LWPOINT * point,POINT4D * out)57 lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
58 {
59 return lwpoint_is_empty(point) ? 0 : getPoint4d_p(point->point,0,out);
60 }
61
62 double
lwpoint_get_x(const LWPOINT * point)63 lwpoint_get_x(const LWPOINT *point)
64 {
65 POINT4D pt;
66 if ( lwpoint_is_empty(point) )
67 {
68 lwerror("lwpoint_get_x called with empty geometry");
69 return 0;
70 }
71 getPoint4d_p(point->point, 0, &pt);
72 return pt.x;
73 }
74
75 double
lwpoint_get_y(const LWPOINT * point)76 lwpoint_get_y(const LWPOINT *point)
77 {
78 POINT4D pt;
79 if ( lwpoint_is_empty(point) )
80 {
81 lwerror("lwpoint_get_y called with empty geometry");
82 return 0;
83 }
84 getPoint4d_p(point->point, 0, &pt);
85 return pt.y;
86 }
87
88 double
lwpoint_get_z(const LWPOINT * point)89 lwpoint_get_z(const LWPOINT *point)
90 {
91 POINT4D pt;
92 if ( lwpoint_is_empty(point) )
93 {
94 lwerror("lwpoint_get_z called with empty geometry");
95 return 0;
96 }
97 if ( ! FLAGS_GET_Z(point->flags) )
98 {
99 lwerror("lwpoint_get_z called without z dimension");
100 return 0;
101 }
102 getPoint4d_p(point->point, 0, &pt);
103 return pt.z;
104 }
105
106 double
lwpoint_get_m(const LWPOINT * point)107 lwpoint_get_m(const LWPOINT *point)
108 {
109 POINT4D pt;
110 if ( lwpoint_is_empty(point) )
111 {
112 lwerror("lwpoint_get_m called with empty geometry");
113 return 0;
114 }
115 if ( ! FLAGS_GET_M(point->flags) )
116 {
117 lwerror("lwpoint_get_m called without m dimension");
118 return 0;
119 }
120 getPoint4d_p(point->point, 0, &pt);
121 return pt.m;
122 }
123
124 /*
125 * Construct a new point. point will not be copied
126 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
127 */
128 LWPOINT *
lwpoint_construct(int32_t srid,GBOX * bbox,POINTARRAY * point)129 lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
130 {
131 LWPOINT *result;
132 lwflags_t flags = 0;
133
134 if (point == NULL)
135 return NULL; /* error */
136
137 result = lwalloc(sizeof(LWPOINT));
138 result->type = POINTTYPE;
139 FLAGS_SET_Z(flags, FLAGS_GET_Z(point->flags));
140 FLAGS_SET_M(flags, FLAGS_GET_M(point->flags));
141 FLAGS_SET_BBOX(flags, bbox?1:0);
142 result->flags = flags;
143 result->srid = srid;
144 result->point = point;
145 result->bbox = bbox;
146
147 return result;
148 }
149
150 LWPOINT *
lwpoint_construct_empty(int32_t srid,char hasz,char hasm)151 lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
152 {
153 LWPOINT *result = lwalloc(sizeof(LWPOINT));
154 result->type = POINTTYPE;
155 result->flags = lwflags(hasz, hasm, 0);
156 result->srid = srid;
157 result->point = ptarray_construct(hasz, hasm, 0);
158 result->bbox = NULL;
159 return result;
160 }
161
162 LWPOINT *
lwpoint_make2d(int32_t srid,double x,double y)163 lwpoint_make2d(int32_t srid, double x, double y)
164 {
165 POINT4D p = {x, y, 0.0, 0.0};
166 POINTARRAY *pa = ptarray_construct_empty(0, 0, 1);
167
168 ptarray_append_point(pa, &p, LW_TRUE);
169 return lwpoint_construct(srid, NULL, pa);
170 }
171
172 LWPOINT *
lwpoint_make3dz(int32_t srid,double x,double y,double z)173 lwpoint_make3dz(int32_t srid, double x, double y, double z)
174 {
175 POINT4D p = {x, y, z, 0.0};
176 POINTARRAY *pa = ptarray_construct_empty(1, 0, 1);
177
178 ptarray_append_point(pa, &p, LW_TRUE);
179
180 return lwpoint_construct(srid, NULL, pa);
181 }
182
183 LWPOINT *
lwpoint_make3dm(int32_t srid,double x,double y,double m)184 lwpoint_make3dm(int32_t srid, double x, double y, double m)
185 {
186 POINT4D p = {x, y, 0.0, m};
187 POINTARRAY *pa = ptarray_construct_empty(0, 1, 1);
188
189 ptarray_append_point(pa, &p, LW_TRUE);
190
191 return lwpoint_construct(srid, NULL, pa);
192 }
193
194 LWPOINT *
lwpoint_make4d(int32_t srid,double x,double y,double z,double m)195 lwpoint_make4d(int32_t srid, double x, double y, double z, double m)
196 {
197 POINT4D p = {x, y, z, m};
198 POINTARRAY *pa = ptarray_construct_empty(1, 1, 1);
199
200 ptarray_append_point(pa, &p, LW_TRUE);
201
202 return lwpoint_construct(srid, NULL, pa);
203 }
204
205 LWPOINT *
lwpoint_make(int32_t srid,int hasz,int hasm,const POINT4D * p)206 lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p)
207 {
208 POINTARRAY *pa = ptarray_construct_empty(hasz, hasm, 1);
209 ptarray_append_point(pa, p, LW_TRUE);
210 return lwpoint_construct(srid, NULL, pa);
211 }
212
lwpoint_free(LWPOINT * pt)213 void lwpoint_free(LWPOINT *pt)
214 {
215 if ( ! pt ) return;
216
217 if ( pt->bbox )
218 lwfree(pt->bbox);
219 if ( pt->point )
220 ptarray_free(pt->point);
221 lwfree(pt);
222 }
223
printLWPOINT(LWPOINT * point)224 void printLWPOINT(LWPOINT *point)
225 {
226 lwnotice("LWPOINT {");
227 lwnotice(" ndims = %i", (int)FLAGS_NDIMS(point->flags));
228 lwnotice(" BBOX = %i", FLAGS_GET_BBOX(point->flags) ? 1 : 0 );
229 lwnotice(" SRID = %i", (int)point->srid);
230 printPA(point->point);
231 lwnotice("}");
232 }
233
234 /* @brief Clone LWPOINT object. Serialized point lists are not copied.
235 *
236 * @see ptarray_clone
237 */
238 LWPOINT *
lwpoint_clone(const LWPOINT * g)239 lwpoint_clone(const LWPOINT *g)
240 {
241 LWPOINT *ret = lwalloc(sizeof(LWPOINT));
242
243 LWDEBUG(2, "lwpoint_clone called");
244
245 memcpy(ret, g, sizeof(LWPOINT));
246
247 ret->point = ptarray_clone(g->point);
248
249 if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
250 return ret;
251 }
252
253
254
255 void
lwpoint_release(LWPOINT * lwpoint)256 lwpoint_release(LWPOINT *lwpoint)
257 {
258 lwgeom_release(lwpoint_as_lwgeom(lwpoint));
259 }
260
261
262 /* check coordinate equality */
263 char
lwpoint_same(const LWPOINT * p1,const LWPOINT * p2)264 lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
265 {
266 return ptarray_same(p1->point, p2->point);
267 }
268
269
270 LWPOINT*
lwpoint_force_dims(const LWPOINT * point,int hasz,int hasm)271 lwpoint_force_dims(const LWPOINT *point, int hasz, int hasm)
272 {
273 POINTARRAY *pdims = NULL;
274 LWPOINT *pointout;
275
276 /* Return 2D empty */
277 if( lwpoint_is_empty(point) )
278 {
279 pointout = lwpoint_construct_empty(point->srid, hasz, hasm);
280 }
281 else
282 {
283 /* Always we duplicate the ptarray and return */
284 pdims = ptarray_force_dims(point->point, hasz, hasm);
285 pointout = lwpoint_construct(point->srid, NULL, pdims);
286 }
287 pointout->type = point->type;
288 return pointout;
289 }
290
291
292