PostGIS  2.5.7dev-r@@SVN_REVISION@@
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  */
41 LWLINE *
42 lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
43 {
44  LWLINE *result;
45  result = (LWLINE*) lwalloc(sizeof(LWLINE));
46 
47  LWDEBUG(2, "lwline_construct called.");
48 
49  result->type = LINETYPE;
50 
51  result->flags = points->flags;
52  FLAGS_SET_BBOX(result->flags, bbox?1:0);
53 
54  LWDEBUGF(3, "lwline_construct type=%d", result->type);
55 
56  result->srid = srid;
57  result->points = points;
58  result->bbox = bbox;
59 
60  return result;
61 }
62 
63 LWLINE *
64 lwline_construct_empty(int srid, char hasz, char hasm)
65 {
66  LWLINE *result = lwalloc(sizeof(LWLINE));
67  result->type = LINETYPE;
68  result->flags = gflags(hasz,hasm,0);
69  result->srid = srid;
70  result->points = ptarray_construct_empty(hasz, hasm, 1);
71  result->bbox = NULL;
72  return result;
73 }
74 
75 
76 void lwline_free (LWLINE *line)
77 {
78  if ( ! line ) return;
79 
80  if ( line->bbox )
81  lwfree(line->bbox);
82  if ( line->points )
83  ptarray_free(line->points);
84  lwfree(line);
85 }
86 
87 
88 void printLWLINE(LWLINE *line)
89 {
90  lwnotice("LWLINE {");
91  lwnotice(" ndims = %i", (int)FLAGS_NDIMS(line->flags));
92  lwnotice(" srid = %i", (int)line->srid);
93  printPA(line->points);
94  lwnotice("}");
95 }
96 
97 /* @brief Clone LWLINE object. Serialized point lists are not copied.
98  *
99  * @see ptarray_clone
100  */
101 LWLINE *
103 {
104  LWLINE *ret = lwalloc(sizeof(LWLINE));
105 
106  LWDEBUGF(2, "lwline_clone called with %p", g);
107 
108  memcpy(ret, g, sizeof(LWLINE));
109 
110  ret->points = ptarray_clone(g->points);
111 
112  if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
113  return ret;
114 }
115 
116 /* Deep clone LWLINE object. POINTARRAY *is* copied. */
117 LWLINE *
119 {
120  LWLINE *ret = lwalloc(sizeof(LWLINE));
121 
122  LWDEBUGF(2, "lwline_clone_deep called with %p", g);
123  memcpy(ret, g, sizeof(LWLINE));
124 
125  if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
126  if ( g->points ) ret->points = ptarray_clone_deep(g->points);
127  FLAGS_SET_READONLY(ret->flags,0);
128 
129  return ret;
130 }
131 
132 
133 void
135 {
137 }
138 
139 
140 LWLINE *
141 lwline_segmentize2d(const LWLINE *line, double dist)
142 {
143  POINTARRAY *segmentized = ptarray_segmentize2d(line->points, dist);
144  if ( ! segmentized ) return NULL;
145  return lwline_construct(line->srid, NULL, segmentized);
146 }
147 
148 /* check coordinate equality */
149 char
150 lwline_same(const LWLINE *l1, const LWLINE *l2)
151 {
152  return ptarray_same(l1->points, l2->points);
153 }
154 
155 /*
156  * Construct a LWLINE from an array of point and line geometries
157  * LWLINE dimensions are large enough to host all input dimensions.
158  */
159 LWLINE *
160 lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
161 {
162  uint32_t i;
163  int hasz = LW_FALSE;
164  int hasm = LW_FALSE;
165  POINTARRAY *pa;
166  LWLINE *line;
167  POINT4D pt;
168  LWPOINTITERATOR* it;
169 
170  /*
171  * Find output dimensions, check integrity
172  */
173  for (i=0; i<ngeoms; i++)
174  {
175  if ( FLAGS_GET_Z(geoms[i]->flags) ) hasz = LW_TRUE;
176  if ( FLAGS_GET_M(geoms[i]->flags) ) hasm = LW_TRUE;
177  if ( hasz && hasm ) break; /* Nothing more to learn! */
178  }
179 
180  /*
181  * ngeoms should be a guess about how many points we have in input.
182  * It's an underestimate for lines and multipoints */
183  pa = ptarray_construct_empty(hasz, hasm, ngeoms);
184 
185  for ( i=0; i < ngeoms; i++ )
186  {
187  LWGEOM *g = geoms[i];
188 
189  if ( lwgeom_is_empty(g) ) continue;
190 
191  if ( g->type == POINTTYPE )
192  {
193  lwpoint_getPoint4d_p((LWPOINT*)g, &pt);
194  ptarray_append_point(pa, &pt, LW_TRUE);
195  }
196  else if ( g->type == LINETYPE )
197  {
198  /*
199  * Append the new line points, de-duplicating against the previous points.
200  * Duplicated points internal to the linestring are untouched.
201  */
202  ptarray_append_ptarray(pa, ((LWLINE*)g)->points, -1);
203  }
204  else if ( g->type == MULTIPOINTTYPE )
205  {
206  it = lwpointiterator_create(g);
207  while(lwpointiterator_next(it, &pt))
208  {
209  ptarray_append_point(pa, &pt, LW_TRUE);
210  }
212  }
213  else
214  {
215  ptarray_free(pa);
216  lwerror("lwline_from_ptarray: invalid input type: %s", lwtype_name(g->type));
217  return NULL;
218  }
219  }
220 
221  if ( pa->npoints > 0 )
222  line = lwline_construct(srid, NULL, pa);
223  else {
224  /* Is this really any different from the above ? */
225  ptarray_free(pa);
226  line = lwline_construct_empty(srid, hasz, hasm);
227  }
228 
229  return line;
230 }
231 
232 /*
233  * Construct a LWLINE from an array of LWPOINTs
234  * LWLINE dimensions are large enough to host all input dimensions.
235  */
236 LWLINE *
237 lwline_from_ptarray(int srid, uint32_t npoints, LWPOINT **points)
238 {
239  uint32_t i;
240  int hasz = LW_FALSE;
241  int hasm = LW_FALSE;
242  POINTARRAY *pa;
243  LWLINE *line;
244  POINT4D pt;
245 
246  /*
247  * Find output dimensions, check integrity
248  */
249  for (i=0; i<npoints; i++)
250  {
251  if ( points[i]->type != POINTTYPE )
252  {
253  lwerror("lwline_from_ptarray: invalid input type: %s", lwtype_name(points[i]->type));
254  return NULL;
255  }
256  if ( FLAGS_GET_Z(points[i]->flags) ) hasz = LW_TRUE;
257  if ( FLAGS_GET_M(points[i]->flags) ) hasm = LW_TRUE;
258  if ( hasz && hasm ) break; /* Nothing more to learn! */
259  }
260 
261  pa = ptarray_construct_empty(hasz, hasm, npoints);
262 
263  for ( i=0; i < npoints; i++ )
264  {
265  if ( ! lwpoint_is_empty(points[i]) )
266  {
267  lwpoint_getPoint4d_p(points[i], &pt);
268  ptarray_append_point(pa, &pt, LW_TRUE);
269  }
270  }
271 
272  if ( pa->npoints > 0 )
273  line = lwline_construct(srid, NULL, pa);
274  else
275  line = lwline_construct_empty(srid, hasz, hasm);
276 
277  return line;
278 }
279 
280 /*
281  * Construct a LWLINE from a LWMPOINT
282  */
283 LWLINE *
284 lwline_from_lwmpoint(int srid, const LWMPOINT *mpoint)
285 {
286  uint32_t i;
287  POINTARRAY *pa = NULL;
288  LWGEOM *lwgeom = (LWGEOM*)mpoint;
289  POINT4D pt;
290 
291  char hasz = lwgeom_has_z(lwgeom);
292  char hasm = lwgeom_has_m(lwgeom);
293  uint32_t npoints = mpoint->ngeoms;
294 
295  if ( lwgeom_is_empty(lwgeom) )
296  {
297  return lwline_construct_empty(srid, hasz, hasm);
298  }
299 
300  pa = ptarray_construct(hasz, hasm, npoints);
301 
302  for (i=0; i < npoints; i++)
303  {
304  getPoint4d_p(mpoint->geoms[i]->point, 0, &pt);
305  ptarray_set_point4d(pa, i, &pt);
306  }
307 
308  LWDEBUGF(3, "lwline_from_lwmpoint: constructed pointarray for %d points", mpoint->ngeoms);
309 
310  return lwline_construct(srid, NULL, pa);
311 }
312 
317 LWPOINT*
318 lwline_get_lwpoint(const LWLINE *line, uint32_t where)
319 {
320  POINT4D pt;
321  LWPOINT *lwpoint;
322  POINTARRAY *pa;
323 
324  if ( lwline_is_empty(line) || where >= line->points->npoints )
325  return NULL;
326 
328  pt = getPoint4d(line->points, where);
329  ptarray_append_point(pa, &pt, LW_TRUE);
330  lwpoint = lwpoint_construct(line->srid, NULL, pa);
331  return lwpoint;
332 }
333 
334 
335 int
337 {
338  POINT4D pt;
339  getPoint4d_p(point->point, 0, &pt);
340 
341  if ( ptarray_insert_point(line->points, &pt, where) != LW_SUCCESS )
342  return LW_FAILURE;
343 
344  /* Update the bounding box */
345  if ( line->bbox )
346  {
347  lwgeom_refresh_bbox((LWGEOM*)line);
348  }
349 
350  return LW_SUCCESS;
351 }
352 
353 
354 
355 LWLINE *
357 {
358  POINTARRAY *newpa;
359  LWLINE *ret;
360 
361  newpa = ptarray_removePoint(line->points, index);
362 
363  ret = lwline_construct(line->srid, NULL, newpa);
364  lwgeom_add_bbox((LWGEOM *) ret);
365 
366  return ret;
367 }
368 
369 /*
370  * Note: input will be changed, make sure you have permissions for this.
371  */
372 void
373 lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
374 {
375  ptarray_set_point4d(line->points, index, newpoint);
376  /* Update the box, if there is one to update */
377  if ( line->bbox )
378  {
379  lwgeom_refresh_bbox((LWGEOM*)line);
380  }
381 }
382 
387 LWLINE*
388 lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
389 {
390  int i = 0;
391  int hasm = 0, hasz = 0;
392  int npoints = 0;
393  double length = 0.0;
394  double length_so_far = 0.0;
395  double m_range = m_end - m_start;
396  double m;
397  POINTARRAY *pa = NULL;
398  POINT3DZ p1, p2;
399 
400  if ( lwline->type != LINETYPE )
401  {
402  lwerror("lwline_construct_from_lwline: only line types supported");
403  return NULL;
404  }
405 
406  hasz = FLAGS_GET_Z(lwline->flags);
407  hasm = 1;
408 
409  /* Null points or npoints == 0 will result in empty return geometry */
410  if ( lwline->points )
411  {
412  npoints = lwline->points->npoints;
413  length = ptarray_length_2d(lwline->points);
414  getPoint3dz_p(lwline->points, 0, &p1);
415  }
416 
417  pa = ptarray_construct(hasz, hasm, npoints);
418 
419  for ( i = 0; i < npoints; i++ )
420  {
421  POINT4D q;
422  POINT2D a, b;
423  getPoint3dz_p(lwline->points, i, &p2);
424  a.x = p1.x;
425  a.y = p1.y;
426  b.x = p2.x;
427  b.y = p2.y;
428  length_so_far += distance2d_pt_pt(&a, &b);
429  if ( length > 0.0 )
430  m = m_start + m_range * length_so_far / length;
431  /* #3172, support (valid) zero-length inputs */
432  else if ( length == 0.0 && npoints > 1 )
433  m = m_start + m_range * i / (npoints-1);
434  else
435  m = 0.0;
436  q.x = p2.x;
437  q.y = p2.y;
438  q.z = p2.z;
439  q.m = m;
440  ptarray_set_point4d(pa, i, &q);
441  p1 = p2;
442  }
443 
444  return lwline_construct(lwline->srid, NULL, pa);
445 }
446 
447 LWGEOM*
448 lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
449 {
450  return lwgeom_remove_repeated_points((LWGEOM*)lwline, tolerance);
451 }
452 
453 int
455 {
456  if (FLAGS_GET_Z(line->flags))
457  return ptarray_is_closed_3d(line->points);
458 
459  return ptarray_is_closed_2d(line->points);
460 }
461 
462 int
464 {
465  POINT3DM p;
466  int i, n;
467  double m = -1 * FLT_MAX;
468 
469  if ( ! FLAGS_GET_M(line->flags) ) {
470  lwnotice("Line does not have M dimension");
471  return LW_FALSE;
472  }
473 
474  n = line->points->npoints;
475  if ( n < 2 ) return LW_TRUE; /* empty or single-point are "good" */
476 
477  for (i=0; i<n; ++i) {
478  getPoint3dm_p(line->points, i, &p);
479  if ( p.m <= m ) {
480  lwnotice("Measure of vertex %d (%g) not bigger than measure of vertex %d (%g)",
481  i, p.m, i-1, m);
482  return LW_FALSE;
483  }
484  m = p.m;
485  }
486 
487  return LW_TRUE;
488 }
489 
490 
491 LWLINE*
492 lwline_force_dims(const LWLINE *line, int hasz, int hasm)
493 {
494  POINTARRAY *pdims = NULL;
495  LWLINE *lineout;
496 
497  /* Return 2D empty */
498  if( lwline_is_empty(line) )
499  {
500  lineout = lwline_construct_empty(line->srid, hasz, hasm);
501  }
502  else
503  {
504  pdims = ptarray_force_dims(line->points, hasz, hasm);
505  lineout = lwline_construct(line->srid, NULL, pdims);
506  }
507  lineout->type = line->type;
508  return lineout;
509 }
510 
511 int lwline_is_empty(const LWLINE *line)
512 {
513  if ( !line->points || line->points->npoints < 1 )
514  return LW_TRUE;
515  return LW_FALSE;
516 }
517 
518 
520 {
521  assert(line);
522  if ( ! line->points )
523  return 0;
524  return line->points->npoints;
525 }
526 
527 double lwline_length(const LWLINE *line)
528 {
529  if ( lwline_is_empty(line) )
530  return 0.0;
531  return ptarray_length(line->points);
532 }
533 
534 double lwline_length_2d(const LWLINE *line)
535 {
536  if ( lwline_is_empty(line) )
537  return 0.0;
538  return ptarray_length_2d(line->points);
539 }
540 
541 
542 POINTARRAY* lwline_interpolate_points(const LWLINE *line, double length_fraction, char repeat) {
543  POINT4D pt;
544  uint32_t i;
545  uint32_t points_to_interpolate;
546  uint32_t points_found = 0;
547  double length;
548  double length_fraction_increment = length_fraction;
549  double length_fraction_consumed = 0;
550  char has_z = (char) lwgeom_has_z(lwline_as_lwgeom(line));
551  char has_m = (char) lwgeom_has_m(lwline_as_lwgeom(line));
552  const POINTARRAY* ipa = line->points;
553  POINTARRAY* opa;
554 
555  /* Empty.InterpolatePoint == Point Empty */
556  if ( lwline_is_empty(line) )
557  {
558  return ptarray_construct_empty(has_z, has_m, 0);
559  }
560 
561  /* If distance is one of the two extremes, return the point on that
562  * end rather than doing any computations
563  */
564  if ( length_fraction == 0.0 || length_fraction == 1.0 )
565  {
566  if ( length_fraction == 0.0 )
567  getPoint4d_p(ipa, 0, &pt);
568  else
569  getPoint4d_p(ipa, ipa->npoints-1, &pt);
570 
571  opa = ptarray_construct(has_z, has_m, 1);
572  ptarray_set_point4d(opa, 0, &pt);
573 
574  return opa;
575  }
576 
577  /* Interpolate points along the line */
578  length = ptarray_length_2d(ipa);
579  points_to_interpolate = repeat ? (uint32_t) floor(1 / length_fraction) : 1;
580  opa = ptarray_construct(has_z, has_m, points_to_interpolate);
581 
582  const POINT2D* p1 = getPoint2d_cp(ipa, 0);
583  for ( i = 0; i < ipa->npoints - 1 && points_found < points_to_interpolate; i++ )
584  {
585  const POINT2D* p2 = getPoint2d_cp(ipa, i+1);
586  double segment_length_frac = distance2d_pt_pt(p1, p2) / length;
587 
588  /* If our target distance is before the total length we've seen
589  * so far. create a new point some distance down the current
590  * segment.
591  */
592  while ( length_fraction < length_fraction_consumed + segment_length_frac && points_found < points_to_interpolate )
593  {
594  POINT4D p1_4d = getPoint4d(ipa, i);
595  POINT4D p2_4d = getPoint4d(ipa, i+1);
596 
597  double segment_fraction = (length_fraction - length_fraction_consumed) / segment_length_frac;
598  interpolate_point4d(&p1_4d, &p2_4d, &pt, segment_fraction);
599  ptarray_set_point4d(opa, points_found++, &pt);
600  length_fraction += length_fraction_increment;
601  }
602 
603  length_fraction_consumed += segment_length_frac;
604 
605  p1 = p2;
606  }
607 
608  /* Return the last point on the line. This shouldn't happen, but
609  * could if there's some floating point rounding errors. */
610  if (points_found < points_to_interpolate) {
611  getPoint4d_p(ipa, ipa->npoints - 1, &pt);
612  ptarray_set_point4d(opa, points_found, &pt);
613  }
614 
615  return opa;
616 }
617 
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:433
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
Definition: lwgeom.c:698
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:106
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:330
#define LW_FALSE
Definition: liblwgeom.h:77
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2314
LWPOINTITERATOR * lwpointiterator_create(const LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM*.
Definition: lwiterator.c:244
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:187
#define LW_FAILURE
Definition: liblwgeom.h:79
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition: ptarray.c:708
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:212
#define LINETYPE
Definition: liblwgeom.h:86
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:714
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
Definition: ptarray.c:555
#define LW_SUCCESS
Definition: liblwgeom.h:80
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:148
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:628
void printPA(POINTARRAY *pa)
Definition: lwgeom_api.c:506
void lwpointiterator_destroy(LWPOINTITERATOR *s)
Free all memory associated with the iterator.
Definition: lwiterator.c:269
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:62
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition: lwgeom.c:1503
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition: ptarray.c:1689
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:930
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:140
int ptarray_insert_point(POINTARRAY *pa, const POINT4D *p, uint32_t where)
Insert a point into an existing POINTARRAY.
Definition: ptarray.c:96
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
Definition: lwgeom_api.c:215
void lwfree(void *mem)
Definition: lwutil.c:244
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:152
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:141
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:1393
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition: lwgeom_api.c:123
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:328
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:156
void * lwalloc(size_t size)
Definition: lwutil.c:229
#define FLAGS_SET_READONLY(flags, value)
Definition: liblwgeom.h:150
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition: ptarray.c:695
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
int getPoint3dm_p(const POINTARRAY *pa, uint32_t n, POINT3DM *point)
Definition: lwgeom_api.c:267
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:459
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:937
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition: lwgeom_api.c:435
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition: lwgeom.c:686
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:414
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwgeom_api.c:374
double ptarray_length(const POINTARRAY *pts)
Find the 3d/2d length of the given POINTARRAY (depending on its dimensionality)
Definition: ptarray.c:1717
POINTARRAY * ptarray_clone(const POINTARRAY *ptarray)
Clone a POINTARRAY object.
Definition: ptarray.c:659
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
Definition: ptarray.c:478
int lwpoint_is_empty(const LWPOINT *point)
Definition: lwpoint.c:291
POINTARRAY * ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm)
Definition: ptarray.c:1037
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:177
LWLINE * lwline_removepoint(LWLINE *line, uint32_t index)
Definition: lwline.c:356
double lwline_length_2d(const LWLINE *line)
Definition: lwline.c:534
LWLINE * lwline_force_dims(const LWLINE *line, int hasz, int hasm)
Definition: lwline.c:492
LWLINE * lwline_segmentize2d(const LWLINE *line, double dist)
Definition: lwline.c:141
int lwline_is_empty(const LWLINE *line)
Definition: lwline.c:511
int lwline_is_closed(const LWLINE *line)
Definition: lwline.c:454
void lwline_release(LWLINE *lwline)
Definition: lwline.c:134
LWLINE * lwline_construct_empty(int srid, char hasz, char hasm)
Definition: lwline.c:64
void lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
Definition: lwline.c:373
LWGEOM * lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
Definition: lwline.c:448
POINTARRAY * lwline_interpolate_points(const LWLINE *line, double length_fraction, char repeat)
Interpolate one or more points along a line.
Definition: lwline.c:542
LWLINE * lwline_clone(const LWLINE *g)
Definition: lwline.c:102
LWLINE * lwline_from_lwmpoint(int srid, const LWMPOINT *mpoint)
Definition: lwline.c:284
void printLWLINE(LWLINE *line)
Definition: lwline.c:88
double lwline_length(const LWLINE *line)
Definition: lwline.c:527
LWLINE * lwline_from_ptarray(int srid, uint32_t npoints, LWPOINT **points)
Definition: lwline.c:237
LWLINE * lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
Re-write the measure ordinate (or add one, if it isn't already there) interpolating the measure betwe...
Definition: lwline.c:388
char lwline_same(const LWLINE *l1, const LWLINE *l2)
Definition: lwline.c:150
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
LWLINE * lwline_clone_deep(const LWLINE *g)
Definition: lwline.c:118
int lwline_is_trajectory(const LWLINE *line)
Definition: lwline.c:463
void lwline_free(LWLINE *line)
Definition: lwline.c:76
uint32_t lwline_count_vertices(LWLINE *line)
Definition: lwline.c:519
LWLINE * lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwline.c:160
int lwline_add_lwpoint(LWLINE *line, LWPOINT *point, uint32_t where)
Add a LWPOINT to an LWLINE.
Definition: lwline.c:336
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition: lwline.c:318
type
Definition: ovdump.py:41
uint8_t type
Definition: liblwgeom.h:399
GBOX * bbox
Definition: liblwgeom.h:423
uint8_t flags
Definition: liblwgeom.h:422
POINTARRAY * points
Definition: liblwgeom.h:425
uint8_t type
Definition: liblwgeom.h:421
int32_t srid
Definition: liblwgeom.h:424
uint32_t ngeoms
Definition: liblwgeom.h:471
LWPOINT ** geoms
Definition: liblwgeom.h:473
POINTARRAY * point
Definition: liblwgeom.h:414
double y
Definition: liblwgeom.h:331
double x
Definition: liblwgeom.h:331
double m
Definition: liblwgeom.h:349
double z
Definition: liblwgeom.h:337
double x
Definition: liblwgeom.h:337
double y
Definition: liblwgeom.h:337
double m
Definition: liblwgeom.h:355
double x
Definition: liblwgeom.h:355
double z
Definition: liblwgeom.h:355
double y
Definition: liblwgeom.h:355
uint32_t npoints
Definition: liblwgeom.h:374
uint8_t flags
Definition: liblwgeom.h:372
unsigned int uint32_t
Definition: uthash.h:78