PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ LWGEOM_line_substring()

Datum LWGEOM_line_substring ( PG_FUNCTION_ARGS  )

Definition at line 509 of file lwgeom_functions_analytic.c.

510 {
511  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
512  double from = PG_GETARG_FLOAT8(1);
513  double to = PG_GETARG_FLOAT8(2);
514  LWGEOM *olwgeom;
515  POINTARRAY *ipa, *opa;
516  GSERIALIZED *ret;
517  int type = gserialized_get_type(geom);
518 
519  if ( from < 0 || from > 1 )
520  {
521  elog(ERROR,"line_interpolate_point: 2nd arg isn't within [0,1]");
522  PG_RETURN_NULL();
523  }
524 
525  if ( to < 0 || to > 1 )
526  {
527  elog(ERROR,"line_interpolate_point: 3rd arg isn't within [0,1]");
528  PG_RETURN_NULL();
529  }
530 
531  if ( from > to )
532  {
533  elog(ERROR, "2nd arg must be smaller then 3rd arg");
534  PG_RETURN_NULL();
535  }
536 
537  if ( type == LINETYPE )
538  {
540 
541  if ( lwgeom_is_empty((LWGEOM*)iline) )
542  {
543  /* TODO return empty line */
544  lwline_release(iline);
545  PG_FREE_IF_COPY(geom, 0);
546  PG_RETURN_NULL();
547  }
548 
549  ipa = iline->points;
550 
551  opa = ptarray_substring(ipa, from, to, 0);
552 
553  if ( opa->npoints == 1 ) /* Point returned */
554  olwgeom = (LWGEOM *)lwpoint_construct(iline->srid, NULL, opa);
555  else
556  olwgeom = (LWGEOM *)lwline_construct(iline->srid, NULL, opa);
557 
558  }
559  else if ( type == MULTILINETYPE )
560  {
561  LWMLINE *iline;
562  uint32_t i = 0, g = 0;
563  int homogeneous = LW_TRUE;
564  LWGEOM **geoms = NULL;
565  double length = 0.0, sublength = 0.0, minprop = 0.0, maxprop = 0.0;
566 
568 
569  if ( lwgeom_is_empty((LWGEOM*)iline) )
570  {
571  /* TODO return empty collection */
572  lwmline_release(iline);
573  PG_FREE_IF_COPY(geom, 0);
574  PG_RETURN_NULL();
575  }
576 
577  /* Calculate the total length of the mline */
578  for ( i = 0; i < iline->ngeoms; i++ )
579  {
580  LWLINE *subline = (LWLINE*)iline->geoms[i];
581  if ( subline->points && subline->points->npoints > 1 )
582  length += ptarray_length_2d(subline->points);
583  }
584 
585  geoms = lwalloc(sizeof(LWGEOM*) * iline->ngeoms);
586 
587  /* Slice each sub-geometry of the multiline */
588  for ( i = 0; i < iline->ngeoms; i++ )
589  {
590  LWLINE *subline = (LWLINE*)iline->geoms[i];
591  double subfrom = 0.0, subto = 0.0;
592 
593  if ( subline->points && subline->points->npoints > 1 )
594  sublength += ptarray_length_2d(subline->points);
595 
596  /* Calculate proportions for this subline */
597  minprop = maxprop;
598  maxprop = sublength / length;
599 
600  /* This subline doesn't reach the lowest proportion requested
601  or is beyond the highest proporton */
602  if ( from > maxprop || to < minprop )
603  continue;
604 
605  if ( from <= minprop )
606  subfrom = 0.0;
607  if ( to >= maxprop )
608  subto = 1.0;
609 
610  if ( from > minprop && from <= maxprop )
611  subfrom = (from - minprop) / (maxprop - minprop);
612 
613  if ( to < maxprop && to >= minprop )
614  subto = (to - minprop) / (maxprop - minprop);
615 
616 
617  opa = ptarray_substring(subline->points, subfrom, subto, 0);
618  if ( opa && opa->npoints > 0 )
619  {
620  if ( opa->npoints == 1 ) /* Point returned */
621  {
622  geoms[g] = (LWGEOM *)lwpoint_construct(SRID_UNKNOWN, NULL, opa);
623  homogeneous = LW_FALSE;
624  }
625  else
626  {
627  geoms[g] = (LWGEOM *)lwline_construct(SRID_UNKNOWN, NULL, opa);
628  }
629  g++;
630  }
631 
632 
633 
634  }
635  /* If we got any points, we need to return a GEOMETRYCOLLECTION */
636  if ( ! homogeneous )
638 
639  olwgeom = (LWGEOM*)lwcollection_construct(type, iline->srid, NULL, g, geoms);
640  }
641  else
642  {
643  elog(ERROR,"line_substring: 1st arg isn't a line");
644  PG_RETURN_NULL();
645  }
646 
647  ret = geometry_serialize(olwgeom);
648  lwgeom_free(olwgeom);
649  PG_FREE_IF_COPY(geom, 0);
650  PG_RETURN_POINTER(ret);
651 
652 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:268
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:118
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:179
#define LW_FALSE
Definition: liblwgeom.h:94
#define COLLECTIONTYPE
Definition: liblwgeom.h:108
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:1083
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
#define MULTILINETYPE
Definition: liblwgeom.h:106
#define LINETYPE
Definition: liblwgeom.h:103
void lwline_release(LWLINE *lwline)
Definition: lwline.c:125
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition: ptarray.c:1840
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
void lwmline_release(LWMLINE *lwline)
Definition: lwmline.c:32
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition: lwgeom.c:251
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
void * lwalloc(size_t size)
Definition: lwutil.c:227
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
if(!(yy_init))
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition: lwinline.h:199
type
Definition: ovdump.py:42
int32_t srid
Definition: liblwgeom.h:460
POINTARRAY * points
Definition: liblwgeom.h:483
uint32_t npoints
Definition: liblwgeom.h:427

References COLLECTIONTYPE, 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: