72 if (
s == NULL ||
s->a ==
s->b )
107 double from,
double to,
117 double length, slength, tlength;
119 uint32_t srid = lwline->
srid;
134 from = length * from;
140 for (i = 0; i < nsegs; i++)
157 if (fabs ( from - ( tlength + slength ) ) <= tolerance)
164 else if (fabs(from - tlength) <= tolerance)
178 else if (from > tlength + slength)
185 dseg = (from - tlength) / slength;
196 if (fabs(to - ( tlength + slength ) ) <= tolerance )
205 else if (fabs(to - tlength) <= tolerance)
214 else if (to > tlength + slength)
223 else if (to < tlength + slength )
225 dseg = (to - tlength) / slength;
234 memcpy(&p1, &p2,
sizeof(
POINT4D));
258 const LWLINE *line,
double length_fraction,
263 uint32_t points_to_interpolate;
264 uint32_t points_found = 0;
266 double length_fraction_increment = length_fraction;
267 double length_fraction_consumed = 0;
276 uint32_t srid = line->
srid;
288 if ( length_fraction == 0.0 || length_fraction == 1.0 )
290 if ( length_fraction == 0.0 )
302 points_to_interpolate = repeat ? (uint32_t) floor(1 / length_fraction) : 1;
307 for ( i = 0; i < ipa->
npoints - 1 && points_found < points_to_interpolate; i++ )
309 double segment_length_frac;
324 while ( length_fraction < length_fraction_consumed + segment_length_frac && points_found < points_to_interpolate )
328 double segment_fraction = (length_fraction - length_fraction_consumed) / segment_length_frac;
331 length_fraction += length_fraction_increment;
334 length_fraction_consumed += segment_length_frac;
342 if (points_found < points_to_interpolate)
376 int use_sphere = (
s->a ==
s->b ? 1 : 0);
378 double za = 0.0, zb = 0.0;
391 double mindist = 0.0;
399 if ( ! use_sphere || mindist > 0.95 * tolerance )
404 if ( mindistout ) *mindistout = mindist;
416 for ( i = 1; i < pa->
npoints; i++ )
439 else if ( d < tolerance * 0.95 )
455 if ( mindistout ) *mindistout =
distance;
467 for ( i = 1; i < pa->
npoints; i++ )
483 length = sqrt( (zb-za)*(zb-za) + length*length );
490 partlength += length;
491 else if (i - 1 == seg)
523 double f = length / seglength;
525 proj4d->
z = p1.
z + ((p2.
z - p1.
z) * f);
526 proj4d->
m = p1.
m + ((p2.
m - p1.
m) * f);
530 length = sqrt( (zb-za)*(zb-za) + length*length );
534 partlength += length;
538 if ( partlength == 0 || totlength == 0 )
543 if ( seg == 0 &&
p2d_same(&proj, p) )
551 return partlength / totlength;
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
LWGEOM * lwmpoint_as_lwgeom(const LWMPOINT *obj)
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
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...
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
#define FLAGS_GET_Z(flags)
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
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.
#define FLAGS_GET_M(flags)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
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,...
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)
LWMPOINT * lwmpoint_construct(int32_t srid, const POINTARRAY *pa)
int lwline_is_empty(const LWLINE *line)
int p2d_same(const POINT2D *p1, const POINT2D *p2)
double longitude_radians_normalize(double lon)
Convert a longitude to the range of -PI,PI.
double latitude_radians_normalize(double lat)
Convert a latitude to the range of -PI/2,PI/2.
int sphere_project(const GEOGRAPHIC_POINT *r, double distance, double azimuth, GEOGRAPHIC_POINT *n)
Given a starting location r, a distance and an azimuth to the new point, compute the location of the ...
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
double ptarray_length_spheroid(const POINTARRAY *pa, const SPHEROID *s)
double sphere_distance(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e)
Given two points on a unit sphere, calculate their distance apart in radians.
double sphere_direction(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e, double d)
Given two points on a unit sphere, calculate the direction from s to e.
double edge_distance_to_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POINT *gp, GEOGRAPHIC_POINT *closest)
void geog2cart(const GEOGRAPHIC_POINT *g, POINT3D *p)
Convert spherical coordinates to cartesian coordinates on unit sphere.
double spheroid_distance(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POINT *b, const SPHEROID *spheroid)
Computes the shortest distance along the surface of the spheroid between two points,...
int spheroid_project(const GEOGRAPHIC_POINT *r, const SPHEROID *spheroid, double distance, double azimuth, GEOGRAPHIC_POINT *g)
Given a location, an azimuth and a distance, computes the location of the projected point.
double spheroid_direction(const GEOGRAPHIC_POINT *r, const GEOGRAPHIC_POINT *s, const SPHEROID *spheroid)
Computes the forward azimuth of the geodesic joining two points on the spheroid, using the inverse ge...
double ptarray_locate_point_spheroid(const POINTARRAY *pa, const POINT4D *p4d, const SPHEROID *s, double tolerance, double *mindistout, POINT4D *proj4d)
Locate a point along the point array defining a geographic line.
LWGEOM * geography_interpolate_points(const LWLINE *line, double length_fraction, const SPHEROID *s, char repeat)
Interpolate a point along a geographic line.
LWGEOM * geography_substring(const LWLINE *lwline, const SPHEROID *s, double from, double to, double tolerance)
Return the part of a line between two fractional locations.
static void interpolate_point4d_spheroid(const POINT4D *p1, const POINT4D *p2, POINT4D *p, const SPHEROID *s, double f)
Find interpolation point p between geography points p1 and p2 so that the len(p1,p) == len(p1,...
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 double distance(double x1, double y1, double x2, double y2)
Two-point great circle segment from a to b.
Point in spherical coordinates on the world.