PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwline.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) 2012 Sandro Santilli <strk@kbt.io>
22 * Copyright (C) 2001-2006 Refractions Research Inc.
23 *
24 **********************************************************************/
25
26
27/* basic LWLINE functions */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include "liblwgeom_internal.h"
33#include "lwgeom_log.h"
34
35
36
37/*
38 * Construct a new LWLINE. points will *NOT* be copied
39 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
40 */
41LWLINE *
42lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
43{
44 LWLINE *result = (LWLINE *)lwalloc(sizeof(LWLINE));
46 result->flags = points->flags;
47 FLAGS_SET_BBOX(result->flags, bbox?1:0);
48 result->srid = srid;
49 result->points = points;
50 result->bbox = bbox;
51 return result;
52}
53
54LWLINE *
55lwline_construct_empty(int32_t srid, char hasz, char hasm)
56{
57 LWLINE *result = lwalloc(sizeof(LWLINE));
58 result->type = LINETYPE;
59 result->flags = lwflags(hasz,hasm,0);
60 result->srid = srid;
61 result->points = ptarray_construct_empty(hasz, hasm, 1);
62 result->bbox = NULL;
63 return result;
64}
65
66
67void lwline_free (LWLINE *line)
68{
69 if ( ! line ) return;
70
71 if ( line->bbox )
72 lwfree(line->bbox);
73 if ( line->points )
74 ptarray_free(line->points);
75 lwfree(line);
76}
77
78
80{
81 lwnotice("LWLINE {");
82 lwnotice(" ndims = %i", (int)FLAGS_NDIMS(line->flags));
83 lwnotice(" srid = %i", (int)line->srid);
84 printPA(line->points);
85 lwnotice("}");
86}
87
88/* @brief Clone LWLINE object. Serialized point lists are not copied.
89 *
90 * @see ptarray_clone
91 */
92LWLINE *
94{
95 LWLINE *ret = lwalloc(sizeof(LWLINE));
96
97 LWDEBUGF(2, "lwline_clone called with %p", g);
98
99 memcpy(ret, g, sizeof(LWLINE));
100
101 ret->points = ptarray_clone(g->points);
102
103 if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
104 return ret;
105}
106
107/* Deep clone LWLINE object. POINTARRAY *is* copied. */
108LWLINE *
110{
111 LWLINE *ret = lwalloc(sizeof(LWLINE));
112
113 LWDEBUGF(2, "lwline_clone_deep called with %p", g);
114 memcpy(ret, g, sizeof(LWLINE));
115
116 if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
117 if ( g->points ) ret->points = ptarray_clone_deep(g->points);
119
120 return ret;
121}
122
123
124void
126{
128}
129
130
131LWLINE *
132lwline_segmentize2d(const LWLINE *line, double dist)
133{
134 POINTARRAY *segmentized = ptarray_segmentize2d(line->points, dist);
135 if ( ! segmentized ) return NULL;
136 return lwline_construct(line->srid, NULL, segmentized);
137}
138
139/* check coordinate equality */
140char
141lwline_same(const LWLINE *l1, const LWLINE *l2)
142{
143 return ptarray_same(l1->points, l2->points);
144}
145
146/*
147 * Construct a LWLINE from an array of point and line geometries
148 * LWLINE dimensions are large enough to host all input dimensions.
149 */
150LWLINE *
151lwline_from_lwgeom_array(int32_t srid, uint32_t ngeoms, LWGEOM **geoms)
152{
153 uint32_t i;
154 int hasz = LW_FALSE;
155 int hasm = LW_FALSE;
156 POINTARRAY *pa;
157 LWLINE *line;
158 POINT4D pt;
159 LWPOINTITERATOR* it;
160
161 /*
162 * Find output dimensions, check integrity
163 */
164 for (i=0; i<ngeoms; i++)
165 {
166 if ( FLAGS_GET_Z(geoms[i]->flags) ) hasz = LW_TRUE;
167 if ( FLAGS_GET_M(geoms[i]->flags) ) hasm = LW_TRUE;
168 if ( hasz && hasm ) break; /* Nothing more to learn! */
169 }
170
171 /*
172 * ngeoms should be a guess about how many points we have in input.
173 * It's an underestimate for lines and multipoints */
174 pa = ptarray_construct_empty(hasz, hasm, ngeoms);
175
176 for ( i=0; i < ngeoms; i++ )
177 {
178 LWGEOM *g = geoms[i];
179
180 if ( lwgeom_is_empty(g) ) continue;
181
182 if ( g->type == POINTTYPE )
183 {
186 }
187 else if ( g->type == LINETYPE )
188 {
189 /*
190 * Append the new line points, de-duplicating against the previous points.
191 * Duplicated points internal to the linestring are untouched.
192 */
193 ptarray_append_ptarray(pa, ((LWLINE*)g)->points, -1);
194 }
195 else if ( g->type == MULTILINETYPE )
196 {
197 LWMLINE *mline = lwgeom_as_lwmline(g);
198 for ( uint32_t j = 0; j < mline->ngeoms; j++ )
199 {
200 LWLINE *line = mline->geoms[j];
201 if (lwline_is_empty(line)) continue;
202 ptarray_append_ptarray(pa, line->points, -1);
203 }
204 }
205 else if ( g->type == MULTIPOINTTYPE )
206 {
208 while(lwpointiterator_next(it, &pt))
209 {
211 }
213 }
214 else
215 {
216 ptarray_free(pa);
217 lwerror("lwline_from_ptarray: invalid input type: %s", lwtype_name(g->type));
218 return NULL;
219 }
220 }
221
222 if ( pa->npoints > 0 )
223 line = lwline_construct(srid, NULL, pa);
224 else {
225 /* Is this really any different from the above ? */
226 ptarray_free(pa);
227 line = lwline_construct_empty(srid, hasz, hasm);
228 }
229
230 return line;
231}
232
233/*
234 * Construct a LWLINE from an array of LWPOINTs
235 * LWLINE dimensions are large enough to host all input dimensions.
236 */
237LWLINE *
238lwline_from_ptarray(int32_t srid, uint32_t npoints, LWPOINT **points)
239{
240 uint32_t i;
241 int hasz = LW_FALSE;
242 int hasm = LW_FALSE;
243 POINTARRAY *pa;
244 LWLINE *line;
245 POINT4D pt;
246
247 /*
248 * Find output dimensions, check integrity
249 */
250 for (i=0; i<npoints; i++)
251 {
252 if ( points[i]->type != POINTTYPE )
253 {
254 lwerror("lwline_from_ptarray: invalid input type: %s", lwtype_name(points[i]->type));
255 return NULL;
256 }
257 if ( FLAGS_GET_Z(points[i]->flags) ) hasz = LW_TRUE;
258 if ( FLAGS_GET_M(points[i]->flags) ) hasm = LW_TRUE;
259 if ( hasz && hasm ) break; /* Nothing more to learn! */
260 }
261
262 pa = ptarray_construct_empty(hasz, hasm, npoints);
263
264 for ( i=0; i < npoints; i++ )
265 {
266 if ( ! lwpoint_is_empty(points[i]) )
267 {
268 lwpoint_getPoint4d_p(points[i], &pt);
270 }
271 }
272
273 if ( pa->npoints > 0 )
274 line = lwline_construct(srid, NULL, pa);
275 else
276 line = lwline_construct_empty(srid, hasz, hasm);
277
278 return line;
279}
280
281/*
282 * Construct a LWLINE from a LWMPOINT
283 */
284LWLINE *
285lwline_from_lwmpoint(int32_t srid, const LWMPOINT *mpoint)
286{
287 uint32_t i;
288 POINTARRAY *pa = NULL;
289 LWGEOM *lwgeom = (LWGEOM*)mpoint;
290 POINT4D pt;
291
292 char hasz = lwgeom_has_z(lwgeom);
293 char hasm = lwgeom_has_m(lwgeom);
294 uint32_t npoints = mpoint->ngeoms;
295
296 if ( lwgeom_is_empty(lwgeom) )
297 {
298 return lwline_construct_empty(srid, hasz, hasm);
299 }
300
301 pa = ptarray_construct(hasz, hasm, npoints);
302
303 for (i=0; i < npoints; i++)
304 {
305 getPoint4d_p(mpoint->geoms[i]->point, 0, &pt);
306 ptarray_set_point4d(pa, i, &pt);
307 }
308
309 LWDEBUGF(3, "lwline_from_lwmpoint: constructed pointarray for %d points", mpoint->ngeoms);
310
311 return lwline_construct(srid, NULL, pa);
312}
313
318LWPOINT*
319lwline_get_lwpoint(const LWLINE *line, uint32_t where)
320{
321 POINT4D pt;
322 LWPOINT *lwpoint;
323 POINTARRAY *pa;
324
325 if ( lwline_is_empty(line) || where >= line->points->npoints )
326 return NULL;
327
329 pt = getPoint4d(line->points, where);
331 lwpoint = lwpoint_construct(line->srid, NULL, pa);
332 return lwpoint;
333}
334
335
336int
337lwline_add_lwpoint(LWLINE *line, LWPOINT *point, uint32_t where)
338{
339 POINT4D pt;
340 getPoint4d_p(point->point, 0, &pt);
341
342 if ( ptarray_insert_point(line->points, &pt, where) != LW_SUCCESS )
343 return LW_FAILURE;
344
345 /* Update the bounding box */
346 if ( line->bbox )
347 {
349 }
350
351 return LW_SUCCESS;
352}
353
354
355
356LWLINE *
357lwline_removepoint(LWLINE *line, uint32_t index)
358{
359 POINTARRAY *newpa;
360 LWLINE *ret;
361
362 newpa = ptarray_removePoint(line->points, index);
363
364 ret = lwline_construct(line->srid, NULL, newpa);
365 lwgeom_add_bbox((LWGEOM *) ret);
366
367 return ret;
368}
369
370/*
371 * Note: input will be changed, make sure you have permissions for this.
372 */
373void
374lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
375{
376 ptarray_set_point4d(line->points, index, newpoint);
377 /* Update the box, if there is one to update */
378 if ( line->bbox )
379 {
381 }
382}
383
388LWLINE*
389lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
390{
391 int i = 0;
392 int hasm = 0, hasz = 0;
393 int npoints = 0;
394 double length = 0.0;
395 double length_so_far = 0.0;
396 double m_range = m_end - m_start;
397 double m;
398 POINTARRAY *pa = NULL;
399 POINT3DZ p1, p2;
400
401 if ( lwline->type != LINETYPE )
402 {
403 lwerror("lwline_construct_from_lwline: only line types supported");
404 return NULL;
405 }
406
407 hasz = FLAGS_GET_Z(lwline->flags);
408 hasm = 1;
409
410 /* Null points or npoints == 0 will result in empty return geometry */
411 if ( lwline->points )
412 {
413 npoints = lwline->points->npoints;
414 length = ptarray_length_2d(lwline->points);
415 getPoint3dz_p(lwline->points, 0, &p1);
416 }
417
418 pa = ptarray_construct(hasz, hasm, npoints);
419
420 for ( i = 0; i < npoints; i++ )
421 {
422 POINT4D q;
423 POINT2D a, b;
424 getPoint3dz_p(lwline->points, i, &p2);
425 a.x = p1.x;
426 a.y = p1.y;
427 b.x = p2.x;
428 b.y = p2.y;
429 length_so_far += distance2d_pt_pt(&a, &b);
430 if ( length > 0.0 )
431 m = m_start + m_range * length_so_far / length;
432 /* #3172, support (valid) zero-length inputs */
433 else if ( length == 0.0 && npoints > 1 )
434 m = m_start + m_range * i / (npoints-1);
435 else
436 m = 0.0;
437 q.x = p2.x;
438 q.y = p2.y;
439 q.z = p2.z;
440 q.m = m;
441 ptarray_set_point4d(pa, i, &q);
442 p1 = p2;
443 }
444
445 return lwline_construct(lwline->srid, NULL, pa);
446}
447
448LWGEOM*
449lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
450{
451 return lwgeom_remove_repeated_points((LWGEOM*)lwline, tolerance);
452}
453
454int
456{
457 if (FLAGS_GET_Z(line->flags))
458 return ptarray_is_closed_3d(line->points);
459
460 return ptarray_is_closed_2d(line->points);
461}
462
463int
465{
466 if (!FLAGS_GET_M(line->flags))
467 {
468 lwnotice("Line does not have M dimension");
469 return LW_FALSE;
470 }
471
472 uint32_t n = line->points->npoints;
473
474 if (n < 2)
475 return LW_TRUE; /* empty or single-point are "good" */
476
477 double m = -1 * FLT_MAX;
478 for (uint32_t i = 0; i < n; ++i)
479 {
480 POINT3DM p;
481 if (!getPoint3dm_p(line->points, i, &p))
482 return LW_FALSE;
483 if (p.m <= m)
484 {
485 lwnotice(
486 "Measure of vertex %d (%g) not bigger than measure of vertex %d (%g)", i, p.m, i - 1, m);
487 return LW_FALSE;
488 }
489 m = p.m;
490 }
491
492 return LW_TRUE;
493}
494
495LWLINE*
496lwline_force_dims(const LWLINE *line, int hasz, int hasm, double zval, double mval)
497{
498 POINTARRAY *pdims = NULL;
499 LWLINE *lineout;
500
501 /* Return 2D empty */
502 if( lwline_is_empty(line) )
503 {
504 lineout = lwline_construct_empty(line->srid, hasz, hasm);
505 }
506 else
507 {
508 pdims = ptarray_force_dims(line->points, hasz, hasm, zval, mval);
509 lineout = lwline_construct(line->srid, NULL, pdims);
510 }
511 lineout->type = line->type;
512 return lineout;
513}
514
515uint32_t lwline_count_vertices(const LWLINE *line)
516{
517 assert(line);
518 if ( ! line->points )
519 return 0;
520 return line->points->npoints;
521}
522
523double lwline_length(const LWLINE *line)
524{
525 if ( lwline_is_empty(line) )
526 return 0.0;
527 return ptarray_length(line->points);
528}
529
530double lwline_length_2d(const LWLINE *line)
531{
532 if ( lwline_is_empty(line) )
533 return 0.0;
534 return ptarray_length_2d(line->points);
535}
536
537
538POINTARRAY* lwline_interpolate_points(const LWLINE *line, double length_fraction, char repeat) {
539 POINT4D pt;
540 uint32_t i;
541 uint32_t points_to_interpolate;
542 uint32_t points_found = 0;
543 double length;
544 double length_fraction_increment = length_fraction;
545 double length_fraction_consumed = 0;
546 char has_z = (char) lwgeom_has_z(lwline_as_lwgeom(line));
547 char has_m = (char) lwgeom_has_m(lwline_as_lwgeom(line));
548 const POINTARRAY* ipa = line->points;
549 POINTARRAY* opa;
550
551 /* Empty.InterpolatePoint == Point Empty */
552 if ( lwline_is_empty(line) )
553 {
554 return ptarray_construct_empty(has_z, has_m, 0);
555 }
556
557 /* If distance is one of the two extremes, return the point on that
558 * end rather than doing any computations
559 */
560 if ( length_fraction == 0.0 || length_fraction == 1.0 )
561 {
562 if ( length_fraction == 0.0 )
563 getPoint4d_p(ipa, 0, &pt);
564 else
565 getPoint4d_p(ipa, ipa->npoints-1, &pt);
566
567 opa = ptarray_construct(has_z, has_m, 1);
568 ptarray_set_point4d(opa, 0, &pt);
569
570 return opa;
571 }
572
573 /* Interpolate points along the line */
574 length = ptarray_length_2d(ipa);
575 points_to_interpolate = repeat ? (uint32_t) floor(1 / length_fraction) : 1;
576 opa = ptarray_construct(has_z, has_m, points_to_interpolate);
577
578 const POINT2D* p1 = getPoint2d_cp(ipa, 0);
579 for ( i = 0; i < ipa->npoints - 1 && points_found < points_to_interpolate; i++ )
580 {
581 const POINT2D* p2 = getPoint2d_cp(ipa, i+1);
582 double segment_length_frac = distance2d_pt_pt(p1, p2) / length;
583
584 /* If our target distance is before the total length we've seen
585 * so far. create a new point some distance down the current
586 * segment.
587 */
588 while ( length_fraction < length_fraction_consumed + segment_length_frac && points_found < points_to_interpolate )
589 {
590 POINT4D p1_4d = getPoint4d(ipa, i);
591 POINT4D p2_4d = getPoint4d(ipa, i+1);
592
593 double segment_fraction = (length_fraction - length_fraction_consumed) / segment_length_frac;
594 interpolate_point4d(&p1_4d, &p2_4d, &pt, segment_fraction);
595 ptarray_set_point4d(opa, points_found++, &pt);
596 length_fraction += length_fraction_increment;
597 }
598
599 length_fraction_consumed += segment_length_frac;
600
601 p1 = p2;
602 }
603
604 /* Return the last point on the line. This shouldn't happen, but
605 * could if there's some floating point rounding errors. */
606 if (points_found < points_to_interpolate) {
607 getPoint4d_p(ipa, ipa->npoints - 1, &pt);
608 ptarray_set_point4d(opa, points_found, &pt);
609 }
610
611 return opa;
612}
613
614extern LWPOINT *
616{
617 double length, slength, tlength;
618 POINTARRAY *ipa;
619 POINT4D pt;
620 int nsegs, i;
621 LWGEOM *geom = lwline_as_lwgeom(line);
622 int has_z = lwgeom_has_z(geom);
623 int has_m = lwgeom_has_m(geom);
624 ipa = line->points;
625
626 /* Empty.InterpolatePoint == Point Empty */
627 if (lwline_is_empty(line))
628 {
629 return lwpoint_construct_empty(line->srid, has_z, has_m);
630 }
631
632 /* If distance is one of the two extremes, return the point on that
633 * end rather than doing any expensive computations
634 */
635 if (distance == 0.0 || distance == 1.0)
636 {
637 if (distance == 0.0)
638 getPoint4d_p(ipa, 0, &pt);
639 else
640 getPoint4d_p(ipa, ipa->npoints - 1, &pt);
641
642 return lwpoint_make(line->srid, has_z, has_m, &pt);
643 }
644
645 /* Interpolate a point on the line */
646 nsegs = ipa->npoints - 1;
647 length = ptarray_length(ipa);
648 tlength = 0;
649 for (i = 0; i < nsegs; i++)
650 {
651 POINT4D p1, p2;
652 POINT4D *p1ptr = &p1, *p2ptr = &p2; /* don't break
653 * strict-aliasing rules
654 */
655
656 getPoint4d_p(ipa, i, &p1);
657 getPoint4d_p(ipa, i + 1, &p2);
658
659 /* Find the relative length of this segment */
660 slength = distance3d_pt_pt((POINT3D *)p1ptr, (POINT3D *)p2ptr) / length;
661
662 /* If our target distance is before the total length we've seen
663 * so far. create a new point some distance down the current
664 * segment.
665 */
666 if (distance < tlength + slength)
667 {
668 double dseg = (distance - tlength) / slength;
669 interpolate_point4d(&p1, &p2, &pt, dseg);
670 return lwpoint_make(line->srid, has_z, has_m, &pt);
671 }
672 tlength += slength;
673 }
674
675 /* Return the last point on the line. This shouldn't happen, but
676 * could if there's some floating point rounding errors. */
677 getPoint4d_p(ipa, ipa->npoints - 1, &pt);
678 return lwpoint_make(line->srid, has_z, has_m, &pt);
679}
680
681extern LWLINE *
682lwline_extend(const LWLINE *line, double distance_forward, double distance_backward)
683{
684 POINTARRAY *pa, *opa;
685 POINT4D p00, p01, p10, p11;
686 POINT4D p_start, p_end;
687 uint32_t i;
688 bool forward = false, backward = false;
689
690 if (distance_forward < 0 || distance_backward < 0)
691 lwerror("%s: distances must be non-negative", __func__);
692
693 if (!line || lwline_is_empty(line) || lwline_count_vertices(line) < 2)
694 {
695 lwerror("%s: line must have at least two points", __func__);
696 }
697
698 pa = line->points;
699 if (distance_backward > 0.0)
700 {
701 i = 0;
702 /* Get two distinct points at start of pointarray */
703 getPoint4d_p(pa, i++, &p00);
704 getPoint4d_p(pa, i, &p01);
705 while(p4d_same(&p00, &p01))
706 {
707 if (i == pa->npoints - 1)
708 {
709 lwerror("%s: line must have at least two distinct points", __func__);
710 }
711 i++;
712 getPoint4d_p(pa, i, &p01);
713 }
714 project_pt_pt(&p01, &p00, distance_backward, &p_start);
715 backward = true;
716 }
717
718 if (distance_forward > 0.0)
719 {
720 i = pa->npoints - 1;
721 /* Get two distinct points at end of pointarray */
722 getPoint4d_p(pa, i--, &p10);
723 getPoint4d_p(pa, i, &p11);
724 while(p4d_same(&p10, &p11))
725 {
726 if (i == 0)
727 {
728 lwerror("%s: line must have at least two distinct points", __func__);
729 }
730 i--;
731 getPoint4d_p(pa, i, &p11);
732 }
733 project_pt_pt(&p11, &p10, distance_forward, &p_end);
734 forward = true;
735 }
736
738
739 if (backward)
740 {
741 ptarray_append_point(opa, &p_start, true);
742 }
743 ptarray_append_ptarray(opa, pa, -1.0);
744 if (forward)
745 {
746 ptarray_append_point(opa, &p_end, true);
747 }
748 return lwline_construct(line->srid, NULL, opa);
749}
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition gbox.c:438
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
Definition lwgeom.c:735
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition lwpoint.c:57
POINT4D getPoint4d(const POINTARRAY *pa, uint32_t n)
Definition lwgeom_api.c:107
#define LW_FALSE
Definition liblwgeom.h:94
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition measures.c:2344
int ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance)
Append a POINTARRAY, pa2 to the end of an existing POINTARRAY, pa1.
Definition ptarray.c:177
#define LW_FAILURE
Definition liblwgeom.h:96
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition ptarray.c:723
LWPOINTITERATOR * lwpointiterator_create(const LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM*.
Definition lwiterator.c:243
#define MULTILINETYPE
Definition liblwgeom.h:106
int lwpointiterator_next(LWPOINTITERATOR *s, POINT4D *p)
Attempts to assign the next point in the iterator to p, and advances the iterator to the next point.
Definition lwiterator.c:210
#define LINETYPE
Definition liblwgeom.h:103
void interpolate_point4d(const POINT4D *A, const POINT4D *B, POINT4D *I, double F)
Find interpolation point I between point A and point B so that the len(AI) == len(AB)*F and I falls o...
Definition lwgeom_api.c:646
#define LW_SUCCESS
Definition liblwgeom.h:97
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition lwpoint.c:129
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
#define FLAGS_SET_BBOX(flags, value)
Definition liblwgeom.h:174
void printPA(POINTARRAY *pa)
Definition lwgeom_api.c:440
void lwpointiterator_destroy(LWPOINTITERATOR *s)
Free all memory associated with the iterator.
Definition lwiterator.c:268
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition ptarray.c:1975
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:962
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
void * lwalloc(size_t size)
Definition lwutil.c:227
int ptarray_insert_point(POINTARRAY *pa, const POINT4D *p, uint32_t where)
Insert a point into an existing POINTARRAY.
Definition ptarray.c:85
double distance3d_pt_pt(const POINT3D *p1, const POINT3D *p2)
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
Definition lwgeom_api.c:215
void lwfree(void *mem)
Definition lwutil.c:248
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:367
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition lwgeom.c:279
POINTARRAY * ptarray_segmentize2d(const POINTARRAY *ipa, double dist)
Returns a modified POINTARRAY so that no segment is longer than the given distance (computed using 2d...
Definition ptarray.c:413
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoint.c:151
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
Definition ptarray.c:582
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:166
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition lwgeom_api.c:125
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
LWPOINT * lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p)
Definition lwpoint.c:206
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_FALSE,...
Definition ptarray.c:147
#define FLAGS_SET_READONLY(flags, value)
Definition liblwgeom.h:176
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition ptarray.c:710
lwflags_t lwflags(int hasz, int hasm, int geodetic)
Construct a new flags bitmask.
Definition lwutil.c:477
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
int getPoint3dm_p(const POINTARRAY *pa, uint32_t n, POINT3DM *point)
Definition lwgeom_api.c:268
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition lwgeom.c:496
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition lwgeom.c:969
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition lwgeom_api.c:369
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition lwgeom.c:723
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
Definition ptarray.c:51
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition ptarray.c:643
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition lwgeom.c:1562
int p4d_same(const POINT4D *p1, const POINT4D *p2)
Definition lwalgorithm.c:32
int lwline_is_empty(const LWLINE *line)
double ptarray_length(const POINTARRAY *pts)
Find the 3d/2d length of the given POINTARRAY (depending on its dimensionality)
Definition ptarray.c:2003
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
Definition ptarray.c:484
int lwpoint_is_empty(const LWPOINT *point)
int ptarray_has_z(const POINTARRAY *pa)
Definition ptarray.c:37
int project_pt_pt(const POINT4D *A, const POINT4D *B, double distance, POINT4D *R)
Azimuth is angle in radians from vertical axis.
Definition measures.c:2445
POINTARRAY * ptarray_clone(const POINTARRAY *ptarray)
Clone a POINTARRAY object.
Definition ptarray.c:674
POINTARRAY * ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm, double zval, double mval)
Definition ptarray.c:1188
int ptarray_has_m(const POINTARRAY *pa)
Definition ptarray.c:44
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
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 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
double lwline_length_2d(const LWLINE *line)
Definition lwline.c:530
LWPOINT * lwline_interpolate_point_3d(const LWLINE *line, double distance)
Interpolate one point along a line in 3D.
Definition lwline.c:615
LWLINE * lwline_from_lwgeom_array(int32_t srid, uint32_t ngeoms, LWGEOM **geoms)
Definition lwline.c:151
POINTARRAY * lwline_interpolate_points(const LWLINE *line, double length_fraction, char repeat)
Interpolate one or more points along a line.
Definition lwline.c:538
LWLINE * lwline_force_dims(const LWLINE *line, int hasz, int hasm, double zval, double mval)
Definition lwline.c:496
LWLINE * lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
Re-write the measure coordinate (or add one, if it isn't already there) interpolating the measure bet...
Definition lwline.c:389
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition lwline.c:319
int lwline_is_closed(const LWLINE *line)
Definition lwline.c:455
uint32_t lwline_count_vertices(const LWLINE *line)
Definition lwline.c:515
void lwline_release(LWLINE *lwline)
Definition lwline.c:125
void lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
Definition lwline.c:374
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwline.c:42
LWLINE * lwline_clone_deep(const LWLINE *g)
Definition lwline.c:109
LWLINE * lwline_extend(const LWLINE *line, double distance_forward, double distance_backward)
Extend the ends of a line.
Definition lwline.c:682
LWGEOM * lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
Definition lwline.c:449
void printLWLINE(LWLINE *line)
Definition lwline.c:79
LWLINE * lwline_clone(const LWLINE *g)
Definition lwline.c:93
LWLINE * lwline_segmentize2d(const LWLINE *line, double dist)
Definition lwline.c:132
double lwline_length(const LWLINE *line)
Definition lwline.c:523
char lwline_same(const LWLINE *l1, const LWLINE *l2)
Definition lwline.c:141
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwline.c:55
LWLINE * lwline_removepoint(LWLINE *line, uint32_t index)
Definition lwline.c:357
int lwline_is_trajectory(const LWLINE *line)
Definition lwline.c:464
void lwline_free(LWLINE *line)
Definition lwline.c:67
LWLINE * lwline_from_ptarray(int32_t srid, uint32_t npoints, LWPOINT **points)
Definition lwline.c:238
LWLINE * lwline_from_lwmpoint(int32_t srid, const LWMPOINT *mpoint)
Definition lwline.c:285
int lwline_add_lwpoint(LWLINE *line, LWPOINT *point, uint32_t where)
Add a LWPOINT to an LWLINE.
Definition lwline.c:337
static double distance(double x1, double y1, double x2, double y2)
Definition lwtree.c:1032
uint8_t type
Definition liblwgeom.h:462
lwflags_t flags
Definition liblwgeom.h:485
GBOX * bbox
Definition liblwgeom.h:482
POINTARRAY * points
Definition liblwgeom.h:483
uint8_t type
Definition liblwgeom.h:486
int32_t srid
Definition liblwgeom.h:484
LWLINE ** geoms
Definition liblwgeom.h:547
uint32_t ngeoms
Definition liblwgeom.h:552
uint32_t ngeoms
Definition liblwgeom.h:538
LWPOINT ** geoms
Definition liblwgeom.h:533
POINTARRAY * point
Definition liblwgeom.h:471
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
double m
Definition liblwgeom.h:408
double z
Definition liblwgeom.h:396
double x
Definition liblwgeom.h:396
double y
Definition liblwgeom.h:396
double m
Definition liblwgeom.h:414
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427