97 LWDEBUGF(2,
"lwline_clone called with %p", g);
99 memcpy(ret, g,
sizeof(
LWLINE));
113 LWDEBUGF(2,
"lwline_clone_deep called with %p", g);
114 memcpy(ret, g,
sizeof(
LWLINE));
135 if ( ! segmentized )
return NULL;
164 for (i=0; i<ngeoms; i++)
168 if ( hasz && hasm )
break;
176 for ( i=0; i < ngeoms; i++ )
240 for (i=0; i<npoints; i++)
249 if ( hasz && hasm )
break;
254 for ( i=0; i < npoints; i++ )
284 uint32_t npoints = mpoint->
ngeoms;
293 for (i=0; i < npoints; i++)
299 LWDEBUGF(3,
"lwline_from_lwmpoint: constructed pointarray for %d points", mpoint->
ngeoms);
382 int hasm = 0, hasz = 0;
385 double length_so_far = 0.0;
386 double m_range = m_end - m_start;
393 lwerror(
"lwline_construct_from_lwline: only line types supported");
410 for ( i = 0; i < npoints; i++ )
421 m = m_start + m_range * length_so_far / length;
423 else if ( length == 0.0 && npoints > 1 )
424 m = m_start + m_range * i / (npoints-1);
458 lwnotice(
"Line does not have M dimension");
467 double m = -1 * FLT_MAX;
468 for (uint32_t i = 0; i < n; ++i)
476 "Measure of vertex %d (%g) not bigger than measure of vertex %d (%g)", i, p.
m, i - 1, m);
531 uint32_t points_to_interpolate;
532 uint32_t points_found = 0;
534 double length_fraction_increment = length_fraction;
535 double length_fraction_consumed = 0;
550 if ( length_fraction == 0.0 || length_fraction == 1.0 )
552 if ( length_fraction == 0.0 )
565 points_to_interpolate = repeat ? (uint32_t) floor(1 / length_fraction) : 1;
569 for ( i = 0; i < ipa->
npoints - 1 && points_found < points_to_interpolate; i++ )
578 while ( length_fraction < length_fraction_consumed + segment_length_frac && points_found < points_to_interpolate )
583 double segment_fraction = (length_fraction - length_fraction_consumed) / segment_length_frac;
586 length_fraction += length_fraction_increment;
589 length_fraction_consumed += segment_length_frac;
596 if (points_found < points_to_interpolate) {
607 double length, slength, tlength;
639 for (i = 0; i < nsegs; i++)
642 POINT4D *p1ptr = &p1, *p2ptr = &p2;
658 double dseg = (
distance - tlength) / slength;
678 bool forward =
false, backward =
false;
680 if (distance_forward < 0 || distance_backward < 0)
681 lwerror(
"%s: distances must be non-negative", __func__);
685 lwerror(
"%s: line must have at least two points", __func__);
689 if (distance_backward > 0.0)
699 lwerror(
"%s: line must have at least two distinct points", __func__);
708 if (distance_forward > 0.0)
718 lwerror(
"%s: line must have at least two distinct points", __func__);
char result[OUT_DOUBLE_BUFFER_SIZE]
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
POINT4D getPoint4d(const POINTARRAY *pa, uint32_t n)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
LWPOINTITERATOR * lwpointiterator_create(const LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM*.
int ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance)
Append a POINTARRAY, pa2 to the end of an existing POINTARRAY, pa1.
int ptarray_is_closed_3d(const POINTARRAY *pa)
int lwpointiterator_next(LWPOINTITERATOR *s, POINT4D *p)
Attempts to assign the next point in the iterator to p, and advances the iterator to the next point.
void interpolate_point4d(const POINT4D *A, const POINT4D *B, POINT4D *I, double F)
Find interpolation point I between point A and point B so that the len(AI) == len(AB)*F and I falls o...
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
#define FLAGS_SET_BBOX(flags, value)
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
void printPA(POINTARRAY *pa)
void lwpointiterator_destroy(LWPOINTITERATOR *s)
Free all memory associated with the iterator.
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...
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define FLAGS_GET_Z(flags)
int ptarray_insert_point(POINTARRAY *pa, const POINT4D *p, uint32_t where)
Insert a point into an existing POINTARRAY.
double distance3d_pt_pt(const POINT3D *p1, const POINT3D *p2)
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
#define FLAGS_NDIMS(flags)
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
#define FLAGS_GET_M(flags)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
void ptarray_free(POINTARRAY *pa)
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE,...
void * lwalloc(size_t size)
#define FLAGS_SET_READONLY(flags, value)
int ptarray_is_closed_2d(const POINTARRAY *pa)
lwflags_t lwflags(int hasz, int hasm, int geodetic)
Construct a new flags bitmask.
#define LW_TRUE
Return types for functions with status returns.
int getPoint3dm_p(const POINTARRAY *pa, uint32_t n, POINT3DM *point)
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
POINTARRAY * ptarray_segmentize2d(const POINTARRAY *ipa, double dist)
Returns a modified POINTARRAY so that no segment is longer than the given distance (computed using 2d...
LWPOINT * lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p)
POINTARRAY * ptarray_force_dims(const POINTARRAY *pa, int hasz, int hasm, double zval, double mval)
int p4d_same(const POINT4D *p1, const POINT4D *p2)
int lwline_is_empty(const LWLINE *line)
double ptarray_length(const POINTARRAY *pts)
Find the 3d/2d length of the given POINTARRAY (depending on its dimensionality)
POINTARRAY * ptarray_clone(const POINTARRAY *ptarray)
Clone a POINTARRAY object.
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
int lwpoint_is_empty(const LWPOINT *point)
int ptarray_has_z(const POINTARRAY *pa)
int project_pt_pt(const POINT4D *A, const POINT4D *B, double distance, POINT4D *R)
Azimuth is angle in radians from vertical axis.
int ptarray_has_m(const POINTARRAY *pa)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
LWLINE * lwline_removepoint(LWLINE *line, uint32_t index)
double lwline_length_2d(const LWLINE *line)
LWPOINT * lwline_interpolate_point_3d(const LWLINE *line, double distance)
Interpolate one point along a line in 3D.
LWLINE * lwline_segmentize2d(const LWLINE *line, double dist)
LWLINE * lwline_from_ptarray(int32_t srid, uint32_t npoints, LWPOINT **points)
int lwline_is_closed(const LWLINE *line)
uint32_t lwline_count_vertices(const LWLINE *line)
void lwline_release(LWLINE *lwline)
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
void lwline_setPoint4d(LWLINE *line, uint32_t index, POINT4D *newpoint)
LWGEOM * lwline_remove_repeated_points(const LWLINE *lwline, double tolerance)
POINTARRAY * lwline_interpolate_points(const LWLINE *line, double length_fraction, char repeat)
Interpolate one or more points along a line.
LWLINE * lwline_clone(const LWLINE *g)
void printLWLINE(LWLINE *line)
LWLINE * lwline_from_lwmpoint(int32_t srid, const LWMPOINT *mpoint)
double lwline_length(const LWLINE *line)
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 betwe...
char lwline_same(const LWLINE *l1, const LWLINE *l2)
LWLINE * lwline_extend(const LWLINE *line, double distance_forward, double distance_backward)
Extend the ends of a line.
LWLINE * lwline_force_dims(const LWLINE *line, int hasz, int hasm, double zval, double mval)
LWLINE * lwline_clone_deep(const LWLINE *g)
int lwline_is_trajectory(const LWLINE *line)
void lwline_free(LWLINE *line)
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
LWLINE * lwline_from_lwgeom_array(int32_t srid, uint32_t ngeoms, LWGEOM **geoms)
int lwline_add_lwpoint(LWLINE *line, LWPOINT *point, uint32_t where)
Add a LWPOINT to an LWLINE.
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
static double distance(double x1, double y1, double x2, double y2)