PostGIS  2.3.8dev-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 void
141 {
142  if ( lwline_is_empty(line) ) return;
143  ptarray_reverse(line->points);
144 }
145 
146 LWLINE *
147 lwline_segmentize2d(LWLINE *line, double dist)
148 {
149  POINTARRAY *segmentized = ptarray_segmentize2d(line->points, dist);
150  if ( ! segmentized ) return NULL;
151  return lwline_construct(line->srid, NULL, segmentized);
152 }
153 
154 /* check coordinate equality */
155 char
156 lwline_same(const LWLINE *l1, const LWLINE *l2)
157 {
158  return ptarray_same(l1->points, l2->points);
159 }
160 
161 /*
162  * Construct a LWLINE from an array of point and line geometries
163  * LWLINE dimensions are large enough to host all input dimensions.
164  */
165 LWLINE *
166 lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
167 {
168  int i;
169  int hasz = LW_FALSE;
170  int hasm = LW_FALSE;
171  POINTARRAY *pa;
172  LWLINE *line;
173  POINT4D pt;
174  LWPOINTITERATOR* it;
175 
176  /*
177  * Find output dimensions, check integrity
178  */
179  for (i=0; i<ngeoms; i++)
180  {
181  if ( FLAGS_GET_Z(geoms[i]->flags) ) hasz = LW_TRUE;
182  if ( FLAGS_GET_M(geoms[i]->flags) ) hasm = LW_TRUE;
183  if ( hasz && hasm ) break; /* Nothing more to learn! */
184  }
185 
186  /*
187  * ngeoms should be a guess about how many points we have in input.
188  * It's an underestimate for lines and multipoints */
189  pa = ptarray_construct_empty(hasz, hasm, ngeoms);
190 
191  for ( i=0; i < ngeoms; i++ )
192  {
193  LWGEOM *g = geoms[i];
194 
195  if ( lwgeom_is_empty(g) ) continue;
196 
197  if ( g->type == POINTTYPE )
198  {
199  lwpoint_getPoint4d_p((LWPOINT*)g, &pt);
200  ptarray_append_point(pa, &pt, LW_TRUE);
201  }
202  else if ( g->type == LINETYPE )
203  {
204  /*
205  * Append the new line points, de-duplicating against the previous points.
206  * Duplicated points internal to the linestring are untouched.
207  */
208  ptarray_append_ptarray(pa, ((LWLINE*)g)->points, -1);
209  }
210  else if ( g->type == MULTIPOINTTYPE )
211  {
212  it = lwpointiterator_create(g);
213  while(lwpointiterator_next(it, &pt))
214  {
215  ptarray_append_point(pa, &pt, LW_TRUE);
216  }
218  }
219  else
220  {
221  ptarray_free(pa);
222  lwerror("lwline_from_ptarray: invalid input type: %s", lwtype_name(g->type));
223  return NULL;
224  }
225  }
226 
227  if ( pa->npoints > 0 )
228  line = lwline_construct(srid, NULL, pa);
229  else {
230  /* Is this really any different from the above ? */
231  ptarray_free(pa);
232  line = lwline_construct_empty(srid, hasz, hasm);
233  }
234 
235  return line;
236 }
237 
238 /*
239  * Construct a LWLINE from an array of LWPOINTs
240  * LWLINE dimensions are large enough to host all input dimensions.
241  */
242 LWLINE *
243 lwline_from_ptarray(int srid, uint32_t npoints, LWPOINT **points)
244 {
245  int i;
246  int hasz = LW_FALSE;
247  int hasm = LW_FALSE;
248  POINTARRAY *pa;
249  LWLINE *line;
250  POINT4D pt;
251 
252  /*
253  * Find output dimensions, check integrity
254  */
255  for (i=0; i<npoints; i++)
256  {
257  if ( points[i]->type != POINTTYPE )
258  {
259  lwerror("lwline_from_ptarray: invalid input type: %s", lwtype_name(points[i]->type));
260  return NULL;
261  }
262  if ( FLAGS_GET_Z(points[i]->flags) ) hasz = LW_TRUE;
263  if ( FLAGS_GET_M(points[i]->flags) ) hasm = LW_TRUE;
264  if ( hasz && hasm ) break; /* Nothing more to learn! */
265  }
266 
267  pa = ptarray_construct_empty(hasz, hasm, npoints);
268 
269  for ( i=0; i < npoints; i++ )
270  {
271  if ( ! lwpoint_is_empty(points[i]) )
272  {
273  lwpoint_getPoint4d_p(points[i], &pt);
274  ptarray_append_point(pa, &pt, LW_TRUE);
275  }
276  }
277 
278  if ( pa->npoints > 0 )
279  line = lwline_construct(srid, NULL, pa);
280  else
281  line = lwline_construct_empty(srid, hasz, hasm);
282 
283  return line;
284 }
285 
286 /*
287  * Construct a LWLINE from a LWMPOINT
288  */
289 LWLINE *
290 lwline_from_lwmpoint(int srid, const LWMPOINT *mpoint)
291 {
292  uint32_t i;
293  POINTARRAY *pa = NULL;
294  LWGEOM *lwgeom = (LWGEOM*)mpoint;
295  POINT4D pt;
296 
297  char hasz = lwgeom_has_z(lwgeom);
298  char hasm = lwgeom_has_m(lwgeom);
299  uint32_t npoints = mpoint->ngeoms;
300 
301  if ( lwgeom_is_empty(lwgeom) )
302  {
303  return lwline_construct_empty(srid, hasz, hasm);
304  }
305 
306  pa = ptarray_construct(hasz, hasm, npoints);
307 
308  for (i=0; i < npoints; i++)
309  {
310  getPoint4d_p(mpoint->geoms[i]->point, 0, &pt);
311  ptarray_set_point4d(pa, i, &pt);
312  }
313 
314  LWDEBUGF(3, "lwline_from_lwmpoint: constructed pointarray for %d points", mpoint->ngeoms);
315 
316  return lwline_construct(srid, NULL, pa);
317 }
318 
323 LWPOINT*
324 lwline_get_lwpoint(const LWLINE *line, int where)
325 {
326  POINT4D pt;
327  LWPOINT *lwpoint;
328  POINTARRAY *pa;
329 
330  if ( lwline_is_empty(line) || where < 0 || where >= line->points->npoints )
331  return NULL;
332 
334  pt = getPoint4d(line->points, where);
335  ptarray_append_point(pa, &pt, LW_TRUE);
336  lwpoint = lwpoint_construct(line->srid, NULL, pa);
337  return lwpoint;
338 }
339 
340 
341 int
342 lwline_add_lwpoint(LWLINE *line, LWPOINT *point, int where)
343 {
344  POINT4D pt;
345  getPoint4d_p(point->point, 0, &pt);
346 
347  if ( ptarray_insert_point(line->points, &pt, where) != LW_SUCCESS )
348  return LW_FAILURE;
349 
350  /* Update the bounding box */
351  if ( line->bbox )
352  {
355  }
356 
357  return LW_SUCCESS;
358 }
359 
360 
361 
362 LWLINE *
363 lwline_removepoint(LWLINE *line, uint32_t index)
364 {
365  POINTARRAY *newpa;
366  LWLINE *ret;
367 
368  newpa = ptarray_removePoint(line->points, index);
369 
370  ret = lwline_construct(line->srid, NULL, newpa);
371  lwgeom_add_bbox((LWGEOM *) ret);
372 
373  return ret;
374 }
375 
376 /*
377  * Note: input will be changed, make sure you have permissions for this.
378  */
379 void
380 lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
381 {
382  ptarray_set_point4d(line->points, index, newpoint);
383  /* Update the box, if there is one to update */
384  if ( line->bbox )
385  {
386  lwgeom_drop_bbox((LWGEOM*)line);
387  lwgeom_add_bbox((LWGEOM*)line);
388  }
389 }
390 
395 LWLINE*
396 lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
397 {
398  int i = 0;
399  int hasm = 0, hasz = 0;
400  int npoints = 0;
401  double length = 0.0;
402  double length_so_far = 0.0;
403  double m_range = m_end - m_start;
404  double m;
405  POINTARRAY *pa = NULL;
406  POINT3DZ p1, p2;
407 
408  if ( lwline->type != LINETYPE )
409  {
410  lwerror("lwline_construct_from_lwline: only line types supported");
411  return NULL;
412  }
413 
414  hasz = FLAGS_GET_Z(lwline->flags);
415  hasm = 1;
416 
417  /* Null points or npoints == 0 will result in empty return geometry */
418  if ( lwline->points )
419  {
420  npoints = lwline->points->npoints;
421  length = ptarray_length_2d(lwline->points);
422  getPoint3dz_p(lwline->points, 0, &p1);
423  }
424 
425  pa = ptarray_construct(hasz, hasm, npoints);
426 
427  for ( i = 0; i < npoints; i++ )
428  {
429  POINT4D q;
430  POINT2D a, b;
431  getPoint3dz_p(lwline->points, i, &p2);
432  a.x = p1.x;
433  a.y = p1.y;
434  b.x = p2.x;
435  b.y = p2.y;
436  length_so_far += distance2d_pt_pt(&a, &b);
437  if ( length > 0.0 )
438  m = m_start + m_range * length_so_far / length;
439  /* #3172, support (valid) zero-length inputs */
440  else if ( length == 0.0 && npoints > 1 )
441  m = m_start + m_range * i / (npoints-1);
442  else
443  m = 0.0;
444  q.x = p2.x;
445  q.y = p2.y;
446  q.z = p2.z;
447  q.m = m;
448  ptarray_set_point4d(pa, i, &q);
449  p1 = p2;
450  }
451 
452  return lwline_construct(lwline->srid, NULL, pa);
453 }
454 
455 LWGEOM*
456 lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
457 {
458  POINTARRAY* npts = ptarray_remove_repeated_points_minpoints(lwline->points, tolerance, 2);
459 
460  LWDEBUGF(3, "%s: npts %p", __func__, npts);
461 
462  return (LWGEOM*)lwline_construct(lwline->srid,
463  lwline->bbox ? gbox_copy(lwline->bbox) : 0,
464  npts);
465 }
466 
467 int
469 {
470  if (FLAGS_GET_Z(line->flags))
471  return ptarray_is_closed_3d(line->points);
472 
473  return ptarray_is_closed_2d(line->points);
474 }
475 
476 int
478 {
479  POINT3DM p;
480  int i, n;
481  double m = -1 * FLT_MAX;
482 
483  if ( ! FLAGS_GET_M(line->flags) ) {
484  lwnotice("Line does not have M dimension");
485  return LW_FALSE;
486  }
487 
488  n = line->points->npoints;
489  if ( n < 2 ) return LW_TRUE; /* empty or single-point are "good" */
490 
491  for (i=0; i<n; ++i) {
492  getPoint3dm_p(line->points, i, &p);
493  if ( p.m <= m ) {
494  lwnotice("Measure of vertex %d (%g) not bigger than measure of vertex %d (%g)",
495  i, p.m, i-1, m);
496  return LW_FALSE;
497  }
498  m = p.m;
499  }
500 
501  return LW_TRUE;
502 }
503 
504 
505 LWLINE*
506 lwline_force_dims(const LWLINE *line, int hasz, int hasm)
507 {
508  POINTARRAY *pdims = NULL;
509  LWLINE *lineout;
510 
511  /* Return 2D empty */
512  if( lwline_is_empty(line) )
513  {
514  lineout = lwline_construct_empty(line->srid, hasz, hasm);
515  }
516  else
517  {
518  pdims = ptarray_force_dims(line->points, hasz, hasm);
519  lineout = lwline_construct(line->srid, NULL, pdims);
520  }
521  lineout->type = line->type;
522  return lineout;
523 }
524 
525 int lwline_is_empty(const LWLINE *line)
526 {
527  if ( !line->points || line->points->npoints < 1 )
528  return LW_TRUE;
529  return LW_FALSE;
530 }
531 
532 
534 {
535  assert(line);
536  if ( ! line->points )
537  return 0;
538  return line->points->npoints;
539 }
540 
541 LWLINE* lwline_simplify(const LWLINE *iline, double dist, int preserve_collapsed)
542 {
543  static const int minvertices = 2; /* TODO: allow setting this */
544  LWLINE *oline;
545  POINTARRAY *pa;
546 
547  LWDEBUG(2, "function called");
548 
549  /* Skip empty case */
550  if( lwline_is_empty(iline) )
551  return NULL;
552 
553  pa = ptarray_simplify(iline->points, dist, minvertices);
554  if ( ! pa ) return NULL;
555 
556  /* Make sure single-point collapses have two points */
557  if ( pa->npoints == 1 )
558  {
559  /* Make sure single-point collapses have two points */
560  if ( preserve_collapsed )
561  {
562  POINT4D pt;
563  getPoint4d_p(pa, 0, &pt);
564  ptarray_append_point(pa, &pt, LW_TRUE);
565  }
566  /* Return null for collapse */
567  else
568  {
569  ptarray_free(pa);
570  return NULL;
571  }
572  }
573 
574  oline = lwline_construct(iline->srid, NULL, pa);
575  oline->type = iline->type;
576  return oline;
577 }
578 
579 double lwline_length(const LWLINE *line)
580 {
581  if ( lwline_is_empty(line) )
582  return 0.0;
583  return ptarray_length(line->points);
584 }
585 
586 double lwline_length_2d(const LWLINE *line)
587 {
588  if ( lwline_is_empty(line) )
589  return 0.0;
590  return ptarray_length_2d(line->points);
591 }
592 
593 
594 
595 LWLINE* lwline_grid(const LWLINE *line, const gridspec *grid)
596 {
597  LWLINE *oline;
598  POINTARRAY *opa;
599 
600  opa = ptarray_grid(line->points, grid);
601 
602  /* Skip line3d with less then 2 points */
603  if ( opa->npoints < 2 ) return NULL;
604 
605  /* TODO: grid bounding box... */
606  oline = lwline_construct(line->srid, NULL, opa);
607 
608  return oline;
609 }
610 
void ptarray_set_point4d(POINTARRAY *pa, int n, const POINT4D *p4d)
Definition: lwgeom_api.c:549
int lwline_is_trajectory(const LWLINE *line)
Definition: lwline.c:477
double x
Definition: liblwgeom.h:351
#define LINETYPE
Definition: liblwgeom.h:85
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:438
uint8_t type
Definition: liblwgeom.h:417
double z
Definition: liblwgeom.h:333
double y
Definition: liblwgeom.h:333
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
double m
Definition: liblwgeom.h:351
LWLINE * lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwline.c:166
GBOX * bbox
Definition: liblwgeom.h:419
POINTARRAY * ptarray_clone(const POINTARRAY *ptarray)
Clone a POINTARRAY object.
Definition: ptarray.c:658
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
double x
Definition: liblwgeom.h:333
LWGEOM * lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
Definition: lwline.c:456
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:89
int lwline_is_closed(const LWLINE *line)
Definition: lwline.c:468
void printLWLINE(LWLINE *line)
Definition: lwline.c:88
void lwfree(void *mem)
Definition: lwutil.c:242
int npoints
Definition: liblwgeom.h:370
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition: ptarray.c:707
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:330
#define MULTIPOINTTYPE
Definition: liblwgeom.h:87
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it&#39;s 3d)
Definition: ptarray.c:1645
#define LW_SUCCESS
Definition: liblwgeom.h:79
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:420
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
LWLINE * lwline_construct_empty(int srid, char hasz, char hasm)
Definition: lwline.c:64
LWLINE * lwline_from_ptarray(int srid, uint32_t npoints, LWPOINT **points)
Definition: lwline.c:243
int lwline_is_empty(const LWLINE *line)
Definition: lwline.c:525
void lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
Definition: lwline.c:380
int getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *point)
Definition: lwgeom_api.c:382
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
The old function nessecary for ptarray_segmentize2d in ptarray.c.
Definition: measures.c:2315
int32_t srid
Definition: liblwgeom.h:420
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&#39;t already there) interpolating the measure betwe...
Definition: lwline.c:396
POINTARRAY * point
Definition: liblwgeom.h:410
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition: ptarray.c:694
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:849
LWPOINTITERATOR * lwpointiterator_create(const LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM*.
Definition: lwiterator.c:244
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:599
#define LW_FAILURE
Definition: liblwgeom.h:78
double x
Definition: liblwgeom.h:327
void lwline_release(LWLINE *lwline)
Definition: lwline.c:134
void lwpointiterator_destroy(LWPOINTITERATOR *s)
Free all memory associated with the iterator.
Definition: lwiterator.c:269
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
POINT4D getPoint4d(const POINTARRAY *pa, int n)
Definition: lwgeom_api.c:229
double lwline_length(const LWLINE *line)
Definition: lwline.c:579
int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point)
Definition: lwgeom_api.c:332
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:262
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, then a duplicate point will not be added.
Definition: ptarray.c:156
#define LW_FALSE
Definition: liblwgeom.h:76
double m
Definition: liblwgeom.h:345
uint8_t flags
Definition: liblwgeom.h:368
LWLINE * lwline_grid(const LWLINE *line, const gridspec *grid)
Definition: lwline.c:595
char lwline_same(const LWLINE *l1, const LWLINE *l2)
Definition: lwline.c:156
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
LWLINE * lwline_from_lwmpoint(int srid, const LWMPOINT *mpoint)
Definition: lwline.c:290
LWLINE * lwline_clone(const LWLINE *g)
Definition: lwline.c:102
LWPOINT * lwline_get_lwpoint(const LWLINE *line, int where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition: lwline.c:324
void lwline_reverse(LWLINE *line)
Definition: lwline.c:140
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
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition: lwpoint.c:57
LWPOINT ** geoms
Definition: liblwgeom.h:469
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:634
POINTARRAY * ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm)
Definition: ptarray.c:1035
LWLINE * lwline_clone_deep(const LWLINE *g)
Definition: lwline.c:118
double y
Definition: liblwgeom.h:327
int ptarray_insert_point(POINTARRAY *pa, const POINT4D *p, int where)
Insert a point into an existing POINTARRAY.
Definition: ptarray.c:96
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:139
int lwline_add_lwpoint(LWLINE *line, LWPOINT *point, int where)
Add a LWPOINT to an LWLINE.
Definition: lwline.c:342
double z
Definition: liblwgeom.h:351
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
double ptarray_length(const POINTARRAY *pts)
Find the 3d/2d length of the given POINTARRAY (depending on its dimensionality)
Definition: ptarray.c:1673
POINTARRAY * ptarray_simplify(POINTARRAY *inpts, double epsilon, unsigned int minpts)
Definition: ptarray.c:1554
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:147
LWLINE * lwline_removepoint(LWLINE *line, uint32_t index)
Definition: lwline.c:363
void printPA(POINTARRAY *pa)
Definition: lwgeom_api.c:611
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
Definition: ptarray.c:484
POINTARRAY * ptarray_remove_repeated_points_minpoints(const POINTARRAY *in, double tolerance, int minpoints)
Definition: ptarray.c:1437
int lwline_count_vertices(LWLINE *line)
Definition: lwline.c:533
POINTARRAY * ptarray_grid(const POINTARRAY *pa, const gridspec *grid)
Definition: ptarray.c:1843
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
int lwpoint_is_empty(const LWPOINT *point)
Definition: lwpoint.c:273
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition: lwgeom.c:612
void ptarray_reverse(POINTARRAY *pa)
Definition: ptarray.c:343
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:140
LWLINE * lwline_segmentize2d(LWLINE *line, double dist)
Definition: lwline.c:147
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:385
LWLINE * lwline_force_dims(const LWLINE *line, int hasz, int hasm)
Definition: lwline.c:506
uint8_t type
Definition: liblwgeom.h:395
void lwline_free(LWLINE *line)
Definition: lwline.c:76
type
Definition: ovdump.py:41
double lwline_length_2d(const LWLINE *line)
Definition: lwline.c:586
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
Definition: ptarray.c:562
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:111
void * lwalloc(size_t size)
Definition: lwutil.c:227
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:1310
double y
Definition: liblwgeom.h:351
int ngeoms
Definition: liblwgeom.h:467
uint8_t flags
Definition: liblwgeom.h:418
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
LWLINE * lwline_simplify(const LWLINE *iline, double dist, int preserve_collapsed)
Definition: lwline.c:541
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:151
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:856
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:102
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:244
#define FLAGS_SET_READONLY(flags, value)
Definition: liblwgeom.h:149
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
POINTARRAY * points
Definition: liblwgeom.h:421
Snap to grid.