PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ LWGEOM_line_substring()

Datum LWGEOM_line_substring ( PG_FUNCTION_ARGS  )

Definition at line 475 of file lwgeom_functions_analytic.c.

476 {
477  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
478  double from = PG_GETARG_FLOAT8(1);
479  double to = PG_GETARG_FLOAT8(2);
480  LWGEOM *olwgeom;
481  POINTARRAY *ipa, *opa;
482  GSERIALIZED *ret;
483  int type = gserialized_get_type(geom);
484 
485  if ( from < 0 || from > 1 )
486  {
487  elog(ERROR,"line_interpolate_point: 2nd arg isn't within [0,1]");
488  PG_RETURN_NULL();
489  }
490 
491  if ( to < 0 || to > 1 )
492  {
493  elog(ERROR,"line_interpolate_point: 3rd arg isn't within [0,1]");
494  PG_RETURN_NULL();
495  }
496 
497  if ( from > to )
498  {
499  elog(ERROR, "2nd arg must be smaller then 3rd arg");
500  PG_RETURN_NULL();
501  }
502 
503  if ( type == LINETYPE )
504  {
506 
507  if ( lwgeom_is_empty((LWGEOM*)iline) )
508  {
509  /* TODO return empty line */
510  lwline_release(iline);
511  PG_FREE_IF_COPY(geom, 0);
512  PG_RETURN_NULL();
513  }
514 
515  ipa = iline->points;
516 
517  opa = ptarray_substring(ipa, from, to, 0);
518 
519  if ( opa->npoints == 1 ) /* Point returned */
520  olwgeom = (LWGEOM *)lwpoint_construct(iline->srid, NULL, opa);
521  else
522  olwgeom = (LWGEOM *)lwline_construct(iline->srid, NULL, opa);
523 
524  }
525  else if ( type == MULTILINETYPE )
526  {
527  LWMLINE *iline;
528  uint32_t i = 0, g = 0;
529  int homogeneous = LW_TRUE;
530  LWGEOM **geoms = NULL;
531  double length = 0.0, sublength = 0.0, minprop = 0.0, maxprop = 0.0;
532 
534 
535  if ( lwgeom_is_empty((LWGEOM*)iline) )
536  {
537  /* TODO return empty collection */
538  lwmline_release(iline);
539  PG_FREE_IF_COPY(geom, 0);
540  PG_RETURN_NULL();
541  }
542 
543  /* Calculate the total length of the mline */
544  for ( i = 0; i < iline->ngeoms; i++ )
545  {
546  LWLINE *subline = (LWLINE*)iline->geoms[i];
547  if ( subline->points && subline->points->npoints > 1 )
548  length += ptarray_length_2d(subline->points);
549  }
550 
551  geoms = lwalloc(sizeof(LWGEOM*) * iline->ngeoms);
552 
553  /* Slice each sub-geometry of the multiline */
554  for ( i = 0; i < iline->ngeoms; i++ )
555  {
556  LWLINE *subline = (LWLINE*)iline->geoms[i];
557  double subfrom = 0.0, subto = 0.0;
558 
559  if ( subline->points && subline->points->npoints > 1 )
560  sublength += ptarray_length_2d(subline->points);
561 
562  /* Calculate proportions for this subline */
563  minprop = maxprop;
564  maxprop = sublength / length;
565 
566  /* This subline doesn't reach the lowest proportion requested
567  or is beyond the highest proporton */
568  if ( from > maxprop || to < minprop )
569  continue;
570 
571  if ( from <= minprop )
572  subfrom = 0.0;
573  if ( to >= maxprop )
574  subto = 1.0;
575 
576  if ( from > minprop && from <= maxprop )
577  subfrom = (from - minprop) / (maxprop - minprop);
578 
579  if ( to < maxprop && to >= minprop )
580  subto = (to - minprop) / (maxprop - minprop);
581 
582 
583  opa = ptarray_substring(subline->points, subfrom, subto, 0);
584  if ( opa && opa->npoints > 0 )
585  {
586  if ( opa->npoints == 1 ) /* Point returned */
587  {
588  geoms[g] = (LWGEOM *)lwpoint_construct(SRID_UNKNOWN, NULL, opa);
589  homogeneous = LW_FALSE;
590  }
591  else
592  {
593  geoms[g] = (LWGEOM *)lwline_construct(SRID_UNKNOWN, NULL, opa);
594  }
595  g++;
596  }
597 
598 
599 
600  }
601  /* If we got any points, we need to return a GEOMETRYCOLLECTION */
602  if ( ! homogeneous )
604 
605  olwgeom = (LWGEOM*)lwcollection_construct(type, iline->srid, NULL, g, geoms);
606  }
607  else
608  {
609  elog(ERROR,"line_substring: 1st arg isn't a line");
610  PG_RETURN_NULL();
611  }
612 
613  ret = geometry_serialize(olwgeom);
614  lwgeom_free(olwgeom);
615  PG_FREE_IF_COPY(geom, 0);
616  PG_RETURN_POINTER(ret);
617 
618 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: g_serialized.c:86
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:170
#define LW_FALSE
Definition: liblwgeom.h:77
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
POINTARRAY * ptarray_substring(POINTARRAY *pa, double d1, double d2, double tolerance)
@d1 start location (distance from start / total distance) @d2 end location (distance from start / tot...
Definition: ptarray.c:1060
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
#define MULTILINETYPE
Definition: liblwgeom.h:89
#define LINETYPE
Definition: liblwgeom.h:86
void lwline_release(LWLINE *lwline)
Definition: lwline.c:134
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition: ptarray.c:1689
void lwmline_release(LWMLINE *lwline)
Definition: lwmline.c:32
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition: lwgeom.c:242
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
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
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
void * lwalloc(size_t size)
Definition: lwutil.c:229
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
if(!(yy_init))
type
Definition: ovdump.py:41
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
int32_t srid
Definition: liblwgeom.h:402
POINTARRAY * points
Definition: liblwgeom.h:425
uint32_t npoints
Definition: liblwgeom.h:374
unsigned int uint32_t
Definition: uthash.h:78

References COLLECTIONTYPE, geometry_serialize(), LWMLINE::geoms, gserialized_get_type(), if(), LINETYPE, LW_FALSE, LW_TRUE, lwalloc(), lwcollection_construct(), lwgeom_as_lwline(), lwgeom_as_lwmline(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_is_empty(), lwline_construct(), lwline_release(), lwmline_release(), lwpoint_construct(), MULTILINETYPE, LWMLINE::ngeoms, POINTARRAY::npoints, LWLINE::points, ptarray_length_2d(), ptarray_substring(), LWLINE::srid, LWMLINE::srid, SRID_UNKNOWN, and ovdump::type.

Here is the call graph for this function: