PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwinline.h
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 2018 Darafei Praliaskouski <me@komzpa.net>
22 * Copyright 2017-2018 Daniel Baston <dbaston@gmail.com>
23 * Copyright 2011 Sandro Santilli <strk@kbt.io>
24 * Copyright 2011 Paul Ramsey <pramsey@cleverelephant.ca>
25 * Copyright 2007-2008 Mark Cave-Ayland
26 * Copyright 2001-2006 Refractions Research Inc.
27 *
28 **********************************************************************/
29
30#include <assert.h>
31
32inline static double
34{
35 double hside = p2->x - p1->x;
36 double vside = p2->y - p1->y;
37
38 return hside * hside + vside * vside;
39}
40
41inline static double
43{
44 double hside = p2->x - p1->x;
45 double vside = p2->y - p1->y;
46 double zside = p2->z - p1->z;
47
48 return hside * hside + vside * vside + zside * zside;
49}
50
51/*
52 * Size of point represeneted in the POINTARRAY
53 * 16 for 2d, 24 for 3d, 32 for 4d
54 */
55static inline size_t
57{
58 return sizeof(double) * FLAGS_NDIMS(pa->flags);
59}
60
61/*
62 * Get a pointer to Nth point of a POINTARRAY
63 * You'll need to cast it to appropriate dimensioned point.
64 * Note that if you cast to a higher dimensional point you'll
65 * possibly corrupt the POINTARRAY.
66 *
67 * Casting to returned pointer to POINT2D* should be safe,
68 * as gserialized format always keeps the POINTARRAY pointer
69 * aligned to double boundary.
70 *
71 * WARNING: Don't cast this to a POINT!
72 * it would not be reliable due to memory alignment constraints
73 */
74static inline uint8_t *
75getPoint_internal(const POINTARRAY *pa, uint32_t n)
76{
77 size_t size;
78 uint8_t *ptr;
79
80 assert(pa);
81 assert(n <= pa->npoints);
82 assert(n <= pa->maxpoints);
83
84 size = ptarray_point_size(pa);
85 ptr = pa->serialized_pointlist + size * n;
86
87 return ptr;
88}
89
96static inline const POINT2D *
97getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
98{
99 return (const POINT2D *)getPoint_internal(pa, n);
100}
101
108static inline const POINT3D *
109getPoint3d_cp(const POINTARRAY *pa, uint32_t n)
110{
111 return (const POINT3D *)getPoint_internal(pa, n);
112}
113
120static inline const POINT4D *
121getPoint4d_cp(const POINTARRAY *pa, uint32_t n)
122{
123 return (const POINT4D *)getPoint_internal(pa, n);
124}
125
126static inline LWPOINT *
128{
129 if (!lwgeom)
130 return NULL;
131 if (lwgeom->type == POINTTYPE)
132 return (LWPOINT *)lwgeom;
133 else
134 return NULL;
135}
136
140static inline uint32_t
142{
143 if (!geom)
144 return 0;
145 return geom->type;
146}
147
148static inline int
150{
151 return !point->point || point->point->npoints < 1;
152}
153
154static inline int
156{
157 return !line->points || line->points->npoints < 1;
158}
159
160static inline int
162{
163 return !circ->points || circ->points->npoints < 1;
164}
165
166static inline int
168{
169 return poly->nrings < 1 || !poly->rings || !poly->rings[0] || poly->rings[0]->npoints < 1;
170}
171
172static inline int
174{
175 return !triangle->points || triangle->points->npoints < 1;
176}
177
178static inline int lwgeom_is_empty(const LWGEOM *geom);
179
180static inline int
182{
183 uint32_t i;
184 if (col->ngeoms == 0 || !col->geoms)
185 return LW_TRUE;
186 for (i = 0; i < col->ngeoms; i++)
187 {
188 if (!lwgeom_is_empty(col->geoms[i]))
189 return LW_FALSE;
190 }
191 return LW_TRUE;
192}
193
198static inline int
200{
201 switch (geom->type)
202 {
203 case POINTTYPE:
204 return lwpoint_is_empty((LWPOINT *)geom);
205 break;
206 case LINETYPE:
207 return lwline_is_empty((LWLINE *)geom);
208 break;
209 case CIRCSTRINGTYPE:
210 return lwcircstring_is_empty((LWCIRCSTRING *)geom);
211 break;
212 case POLYGONTYPE:
213 return lwpoly_is_empty((LWPOLY *)geom);
214 break;
215 case TRIANGLETYPE:
216 return lwtriangle_is_empty((LWTRIANGLE *)geom);
217 break;
218 case MULTIPOINTTYPE:
219 case MULTILINETYPE:
220 case MULTIPOLYGONTYPE:
221 case COMPOUNDTYPE:
222 case CURVEPOLYTYPE:
223 case MULTICURVETYPE:
224 case MULTISURFACETYPE:
226 case TINTYPE:
227 case COLLECTIONTYPE:
228 return lwcollection_is_empty((LWCOLLECTION *)geom);
229 break;
230 default:
231 return LW_FALSE;
232 break;
233 }
234}
235
236inline static uint64_t
237uint64_interleave_2(uint64_t x, uint64_t y)
238{
239 x = (x | (x << 16)) & 0x0000FFFF0000FFFFULL;
240 x = (x | (x << 8)) & 0x00FF00FF00FF00FFULL;
241 x = (x | (x << 4)) & 0x0F0F0F0F0F0F0F0FULL;
242 x = (x | (x << 2)) & 0x3333333333333333ULL;
243 x = (x | (x << 1)) & 0x5555555555555555ULL;
244
245 y = (y | (y << 16)) & 0x0000FFFF0000FFFFULL;
246 y = (y | (y << 8)) & 0x00FF00FF00FF00FFULL;
247 y = (y | (y << 4)) & 0x0F0F0F0F0F0F0F0FULL;
248 y = (y | (y << 2)) & 0x3333333333333333ULL;
249 y = (y | (y << 1)) & 0x5555555555555555ULL;
250
251 return x | (y << 1);
252}
253
254/* Based on https://github.com/rawrunprotected/hilbert_curves Public Domain code */
255inline static uint64_t
256uint32_hilbert(uint32_t px, uint32_t py)
257{
258 uint64_t x = px;
259 uint64_t y = py;
260
261 uint64_t A, B, C, D;
262 uint64_t a, b, c, d;
263 uint64_t i0, i1;
264
265 // Initial prefix scan round, prime with x and y
266 {
267 a = x ^ y;
268 b = 0xFFFFFFFFULL ^ a;
269 c = 0xFFFFFFFFULL ^ (x | y);
270 d = x & (y ^ 0xFFFFFFFFULL);
271
272 A = a | (b >> 1);
273 B = (a >> 1) ^ a;
274 C = ((c >> 1) ^ (b & (d >> 1))) ^ c;
275 D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;
276 }
277
278 {
279 a = A;
280 b = B;
281 c = C;
282 d = D;
283
284 A = ((a & (a >> 2)) ^ (b & (b >> 2)));
285 B = ((a & (b >> 2)) ^ (b & ((a ^ b) >> 2)));
286 C ^= ((a & (c >> 2)) ^ (b & (d >> 2)));
287 D ^= ((b & (c >> 2)) ^ ((a ^ b) & (d >> 2)));
288 }
289
290 {
291 a = A;
292 b = B;
293 c = C;
294 d = D;
295
296 A = ((a & (a >> 4)) ^ (b & (b >> 4)));
297 B = ((a & (b >> 4)) ^ (b & ((a ^ b) >> 4)));
298 C ^= ((a & (c >> 4)) ^ (b & (d >> 4)));
299 D ^= ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));
300 }
301
302 {
303 a = A;
304 b = B;
305 c = C;
306 d = D;
307
308 A = ((a & (a >> 8)) ^ (b & (b >> 8)));
309 B = ((a & (b >> 8)) ^ (b & ((a ^ b) >> 8)));
310 C ^= ((a & (c >> 8)) ^ (b & (d >> 8)));
311 D ^= ((b & (c >> 8)) ^ ((a ^ b) & (d >> 8)));
312 }
313
314 {
315 a = A;
316 b = B;
317 c = C;
318 d = D;
319
320 C ^= ((a & (c >> 16)) ^ (b & (d >> 16)));
321 D ^= ((b & (c >> 16)) ^ ((a ^ b) & (d >> 16)));
322 }
323
324 // Undo transformation prefix scan
325 a = C ^ (C >> 1);
326 b = D ^ (D >> 1);
327
328 // Recover index bits
329 i0 = x ^ y;
330 i1 = b | (0xFFFFFFFFULL ^ (i0 | a));
331
332 return uint64_interleave_2(i0, i1);
333}
334
335/*
336 * This macro is based on PG_FREE_IF_COPY, except that it accepts two pointers.
337 * See PG_FREE_IF_COPY comment in src/include/fmgr.h in postgres source code
338 * for more details.
339 */
340#define POSTGIS_FREE_IF_COPY_P(ptrsrc, ptrori) \
341 do \
342 { \
343 if ((Pointer)(ptrsrc) != (Pointer)(ptrori)) \
344 pfree(ptrsrc); \
345 } while (0)
#define LW_FALSE
Definition liblwgeom.h:94
#define COLLECTIONTYPE
Definition liblwgeom.h:108
#define COMPOUNDTYPE
Definition liblwgeom.h:110
#define CURVEPOLYTYPE
Definition liblwgeom.h:111
#define MULTILINETYPE
Definition liblwgeom.h:106
#define MULTISURFACETYPE
Definition liblwgeom.h:113
#define LINETYPE
Definition liblwgeom.h:103
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define TINTYPE
Definition liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
#define POLYGONTYPE
Definition liblwgeom.h:104
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:114
#define CIRCSTRINGTYPE
Definition liblwgeom.h:109
#define MULTICURVETYPE
Definition liblwgeom.h:112
#define TRIANGLETYPE
Definition liblwgeom.h:115
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:75
static double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition lwinline.h:33
static uint64_t uint32_hilbert(uint32_t px, uint32_t py)
Definition lwinline.h:256
static const POINT3D * getPoint3d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT3D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:109
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition lwinline.h:141
static const POINT4D * getPoint4d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT4D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:121
static int lwcircstring_is_empty(const LWCIRCSTRING *circ)
Definition lwinline.h:161
static int lwpoly_is_empty(const LWPOLY *poly)
Definition lwinline.h:167
static size_t ptarray_point_size(const POINTARRAY *pa)
Definition lwinline.h:56
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition lwinline.h:127
static int lwcollection_is_empty(const LWCOLLECTION *col)
Definition lwinline.h:181
static uint64_t uint64_interleave_2(uint64_t x, uint64_t y)
Definition lwinline.h:237
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:199
static int lwline_is_empty(const LWLINE *line)
Definition lwinline.h:155
static int lwtriangle_is_empty(const LWTRIANGLE *triangle)
Definition lwinline.h:173
static double distance3d_sqr_pt_pt(const POINT3D *p1, const POINT3D *p2)
Definition lwinline.h:42
static int lwpoint_is_empty(const LWPOINT *point)
Definition lwinline.h:149
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:97
POINTARRAY * points
Definition liblwgeom.h:507
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
uint8_t type
Definition liblwgeom.h:462
POINTARRAY * points
Definition liblwgeom.h:483
POINTARRAY * point
Definition liblwgeom.h:471
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
POINTARRAY * points
Definition liblwgeom.h:495
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
double z
Definition liblwgeom.h:402
double x
Definition liblwgeom.h:402
double y
Definition liblwgeom.h:402
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427
uint8_t * serialized_pointlist
Definition liblwgeom.h:434