PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ lwline_measured_from_lwline()

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 between the supplied start and end values.

Add a measure dimension to a line, interpolating linearly from the start to the end value.

Definition at line 396 of file lwline.c.

References distance2d_pt_pt(), LWLINE::flags, FLAGS_GET_Z, getPoint3dz_p(), LINETYPE, lwerror(), lwline_construct(), POINT4D::m, POINTARRAY::npoints, LWLINE::points, ptarray_construct(), ptarray_length_2d(), ptarray_set_point4d(), LWLINE::srid, LWLINE::type, POINT2D::x, POINT3DZ::x, POINT4D::x, POINT2D::y, POINT3DZ::y, POINT4D::y, POINT3DZ::z, and POINT4D::z.

Referenced by lwline_locate_along(), lwmline_measured_from_lwmline(), and ST_AddMeasure().

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 }
void ptarray_set_point4d(POINTARRAY *pa, int n, const POINT4D *p4d)
Definition: lwgeom_api.c:437
double x
Definition: liblwgeom.h:352
#define LINETYPE
Definition: liblwgeom.h:86
uint8_t type
Definition: liblwgeom.h:418
double z
Definition: liblwgeom.h:334
double y
Definition: liblwgeom.h:334
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:352
double x
Definition: liblwgeom.h:334
int npoints
Definition: liblwgeom.h:371
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it&#39;s 3d)
Definition: ptarray.c:1692
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
The old function nessecary for ptarray_segmentize2d in ptarray.c.
Definition: measures.c:2317
int32_t srid
Definition: liblwgeom.h:421
double x
Definition: liblwgeom.h:328
int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point)
Definition: lwgeom_api.c:214
double y
Definition: liblwgeom.h:328
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:140
double z
Definition: liblwgeom.h:352
double y
Definition: liblwgeom.h:352
uint8_t flags
Definition: liblwgeom.h:419
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
POINTARRAY * points
Definition: liblwgeom.h:422
Here is the call graph for this function:
Here is the caller graph for this function: