PostGIS  2.3.8dev-r@@SVN_REVISION@@

◆ ptarray_segmentize2d()

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).

Every input point is kept. Z and M values for added points (if needed) are set to 0.

Definition at line 420 of file ptarray.c.

References distance2d_pt_pt(), POINTARRAY::flags, FLAGS_GET_M, FLAGS_GET_Z, getPoint4d_p(), LW_FALSE, LW_ON_INTERRUPT, LW_TRUE, POINT4D::m, POINTARRAY::npoints, ptarray_append_point(), ptarray_construct_empty(), ptarray_free(), POINT4D::x, POINT4D::y, and POINT4D::z.

Referenced by lwline_segmentize2d(), and lwpoly_segmentize2d().

421 {
422  double segdist;
423  POINT4D p1, p2;
424  POINT4D pbuf;
425  POINTARRAY *opa;
426  int ipoff=0; /* input point offset */
427  int hasz = FLAGS_GET_Z(ipa->flags);
428  int hasm = FLAGS_GET_M(ipa->flags);
429 
430  pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0;
431 
432  /* Initial storage */
433  opa = ptarray_construct_empty(hasz, hasm, ipa->npoints);
434 
435  /* Add first point */
436  getPoint4d_p(ipa, ipoff, &p1);
437  ptarray_append_point(opa, &p1, LW_FALSE);
438 
439  ipoff++;
440 
441  while (ipoff<ipa->npoints)
442  {
443  /*
444  * We use these pointers to avoid
445  * "strict-aliasing rules break" warning raised
446  * by gcc (3.3 and up).
447  *
448  * It looks that casting a variable address (also
449  * referred to as "type-punned pointer")
450  * breaks those "strict" rules.
451  *
452  */
453  POINT4D *p1ptr=&p1, *p2ptr=&p2;
454 
455  getPoint4d_p(ipa, ipoff, &p2);
456 
457  segdist = distance2d_pt_pt((POINT2D *)p1ptr, (POINT2D *)p2ptr);
458 
459  if (segdist > dist) /* add an intermediate point */
460  {
461  pbuf.x = p1.x + (p2.x-p1.x)/segdist * dist;
462  pbuf.y = p1.y + (p2.y-p1.y)/segdist * dist;
463  if( hasz )
464  pbuf.z = p1.z + (p2.z-p1.z)/segdist * dist;
465  if( hasm )
466  pbuf.m = p1.m + (p2.m-p1.m)/segdist * dist;
467  ptarray_append_point(opa, &pbuf, LW_FALSE);
468  p1 = pbuf;
469  }
470  else /* copy second point */
471  {
472  ptarray_append_point(opa, &p2, (ipa->npoints==2)?LW_TRUE:LW_FALSE);
473  p1 = p2;
474  ipoff++;
475  }
476 
477  LW_ON_INTERRUPT(ptarray_free(opa); return NULL);
478  }
479 
480  return opa;
481 }
double x
Definition: liblwgeom.h:351
double m
Definition: liblwgeom.h:351
int npoints
Definition: liblwgeom.h:370
#define LW_ON_INTERRUPT(x)
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int repeated_points)
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
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
The old function nessecary for ptarray_segmentize2d in ptarray.c.
Definition: measures.c:2315
#define LW_FALSE
Definition: liblwgeom.h:76
uint8_t flags
Definition: liblwgeom.h:368
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:139
double z
Definition: liblwgeom.h:351
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:140
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:330
double y
Definition: liblwgeom.h:351
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:244
Here is the call graph for this function:
Here is the caller graph for this function: