PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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.
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
#define LW_FALSE
Definition liblwgeom.h:94
#define COLLECTIONTYPE
Definition liblwgeom.h:108
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
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:1211
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition lwpoint.c:129
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:1975
void lwmline_release(LWMLINE *lwline)
Definition lwmline.c:32
void * lwalloc(size_t size)
Definition lwutil.c:227
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwline.c:42
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition lwgeom.c:279
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:207
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
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
int32_t srid
Definition liblwgeom.h:460
uint32_t npoints
Definition liblwgeom.h:427

References COLLECTIONTYPE, LWMLINE::geoms, gserialized_get_type(), 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, and SRID_UNKNOWN.

Here is the call graph for this function: