Locate a point along the point array defining a geographic line.
369{
375 uint32_t i, seg = 0;
376 int use_sphere = (
s->a ==
s->b ? 1 : 0);
377 int hasz;
378 double za = 0.0, zb = 0.0;
380 length,
381 seglength = 0.0,
382 partlength = 0.0,
383 totlength = 0.0;
384
385
387
388
390 {
391 double mindist = 0.0;
393 {
396
398
399 if ( ! use_sphere || mindist > 0.95 * tolerance )
400 {
402 }
403 }
404 if ( mindistout ) *mindistout = mindist;
405 return 0.0;
406 }
407
408
410
411
414
415
416 for ( i = 1; i < pa->
npoints; i++ )
417 {
418 double d;
421
423
425 {
427 nearest = b;
428 seg = i - 1;
429 }
430
431 if ( d < tolerance )
432 {
433
434 if ( use_sphere )
435 {
436 break;
437 }
438
439 else if ( d < tolerance * 0.95 )
440 {
441 break;
442 }
443
444 else
445 {
447
448 if ( d < tolerance )
449 break;
450 }
451 }
453 }
454
455 if ( mindistout ) *mindistout =
distance;
456
457
459
460
463 if ( hasz )
465
466
467 for ( i = 1; i < pa->
npoints; i++ )
468 {
471 if ( hasz )
473
474
477
478 else
480
481
482 if ( hasz )
483 length = sqrt( (zb-za)*(zb-za) + length*length );
484
485
486 totlength += length;
487
488
489 if (i - 1 < seg)
490 partlength += length;
491 else if (i - 1 == seg)
492
493 seglength = length;
494
495
496 a = b;
497 za = zb;
498 }
499
500
503
504
505
506
509
510
512
513
516
517 else
519
520 if ( hasz )
521 {
522
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);
527
530 length = sqrt( (zb-za)*(zb-za) + length*length );
531 }
532
533
534 partlength += length;
535
536
537
538 if ( partlength == 0 || totlength == 0 )
539 return 0.0;
540
541
543 if ( seg == 0 &&
p2d_same(&proj, p) )
544 return 0.0;
545
546
549 return 1.0;
550
551
552 double result = partlength / totlength;
555 }
else if (
result > 1.0 ) {
557 }
559}
char result[OUT_DOUBLE_BUFFER_SIZE]
#define FLAGS_GET_Z(flags)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
int p2d_same(const POINT2D *p1, const POINT2D *p2)
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
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 edge_distance_to_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POINT *gp, GEOGRAPHIC_POINT *closest)
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,...
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.