PostGIS  2.2.7dev-r@@SVN_REVISION@@
LWMLINE* lwmline_measured_from_lwmline ( const LWMLINE lwmline,
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.

Definition at line 42 of file lwmline.c.

References LWMLINE::flags, FLAGS_GET_Z, LWMLINE::geoms, if(), lwalloc(), lwcollection_construct(), lwcollection_construct_empty(), lwerror(), lwgeom_is_empty(), lwline_measured_from_lwline(), MULTILINETYPE, LWMLINE::ngeoms, POINTARRAY::npoints, LWLINE::points, ptarray_length_2d(), LWMLINE::srid, and LWMLINE::type.

Referenced by ST_AddMeasure().

43 {
44  int i = 0;
45  int hasm = 0, hasz = 0;
46  double length = 0.0, length_so_far = 0.0;
47  double m_range = m_end - m_start;
48  LWGEOM **geoms = NULL;
49 
50  if ( lwmline->type != MULTILINETYPE )
51  {
52  lwerror("lwmline_measured_from_lmwline: only multiline types supported");
53  return NULL;
54  }
55 
56  hasz = FLAGS_GET_Z(lwmline->flags);
57  hasm = 1;
58 
59  /* Calculate the total length of the mline */
60  for ( i = 0; i < lwmline->ngeoms; i++ )
61  {
62  LWLINE *lwline = (LWLINE*)lwmline->geoms[i];
63  if ( lwline->points && lwline->points->npoints > 1 )
64  {
65  length += ptarray_length_2d(lwline->points);
66  }
67  }
68 
69  if ( lwgeom_is_empty((LWGEOM*)lwmline) )
70  {
71  return (LWMLINE*)lwcollection_construct_empty(MULTILINETYPE, lwmline->srid, hasz, hasm);
72  }
73 
74  geoms = lwalloc(sizeof(LWGEOM*) * lwmline->ngeoms);
75 
76  for ( i = 0; i < lwmline->ngeoms; i++ )
77  {
78  double sub_m_start, sub_m_end;
79  double sub_length = 0.0;
80  LWLINE *lwline = (LWLINE*)lwmline->geoms[i];
81 
82  if ( lwline->points && lwline->points->npoints > 1 )
83  {
84  sub_length = ptarray_length_2d(lwline->points);
85  }
86 
87  sub_m_start = (m_start + m_range * length_so_far / length);
88  sub_m_end = (m_start + m_range * (length_so_far + sub_length) / length);
89 
90  geoms[i] = (LWGEOM*)lwline_measured_from_lwline(lwline, sub_m_start, sub_m_end);
91 
92  length_so_far += sub_length;
93  }
94 
95  return (LWMLINE*)lwcollection_construct(lwmline->type, lwmline->srid, NULL, lwmline->ngeoms, geoms);
96 }
LWLINE * lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
Add a measure dimension to a line, interpolating linearly from the start to the end value...
Definition: lwline.c:367
uint8_t type
Definition: liblwgeom.h:461
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:30
int npoints
Definition: liblwgeom.h:355
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition: ptarray.c:1645
int ngeoms
Definition: liblwgeom.h:465
uint8_t flags
Definition: liblwgeom.h:462
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:124
LWLINE ** geoms
Definition: liblwgeom.h:467
void * lwalloc(size_t size)
Definition: lwutil.c:199
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:1297
#define MULTILINETYPE
Definition: liblwgeom.h:74
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:81
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74
if(!(yy_init))
Definition: lwin_wkt_lex.c:863
int32_t srid
Definition: liblwgeom.h:464
POINTARRAY * points
Definition: liblwgeom.h:406

Here is the call graph for this function:

Here is the caller graph for this function: