Пример #1
0
static int GeodSolve2() {
  /* Check fix for antipodal prolate bug found 2010-09-04 */
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, 6.4e6, -1/150.0);
  geod_inverse(&g, 0.07476, 0, -0.07476, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 90.00078, 0.5e-5);
  result += checkEquals(azi2, 90.00078, 0.5e-5);
  result += checkEquals(s12, 20106193, 0.5);
  geod_inverse(&g, 0.1, 0, -0.1, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 90.00105, 0.5e-5);
  result += checkEquals(azi2, 90.00105, 0.5e-5);
  result += checkEquals(s12, 20106193, 0.5);
  return result;
}
Пример #2
0
SEXP inversegeodesic(SEXP longitude1, SEXP latitude1, SEXP longitude2, SEXP latitude2, SEXP pa, SEXP pf) {

  PROTECT(latitude1 = coerceVector(latitude1, REALSXP));
  PROTECT(longitude1 = coerceVector(longitude1, REALSXP));
  PROTECT(latitude2 = coerceVector(latitude2, REALSXP));
  PROTECT(longitude2 = coerceVector(longitude2, REALSXP));
  double a = REAL(pa)[0];
  double f = REAL(pf)[0];

  double *lat1, *lon1, *lat2, *lon2, *xr;
  lat1 = REAL(latitude1);
  lon1 = REAL(longitude1);
  lat2 = REAL(latitude2);
  lon2 = REAL(longitude2);

  SEXP r;
  PROTECT( r = allocVector(REALSXP, length(latitude1) ));
  xr = REAL(r);  
   
  double azi1, azi2, s12;
  struct geod_geodesic g;

  geod_init(&g, a, f);
  
  for (int i=0; i < length(latitude1); i++) {
    geod_inverse(&g, lat1[i], lon1[i], lat2[i], lon2[i], &s12, &azi1, &azi2);
    xr[i] = s12;
  }
  
  UNPROTECT(5);
  return r;
}
Пример #3
0
static int GeodSolve6() {
  /* Check fix for volatile sbet12a bug found 2011-06-25 (gcc 4.4.4
   * x86 -O3).  Found again on 2012-03-27 with tdm-mingw32 (g++ 4.6.1). */
  double s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 88.202499451857, 0,
               -88.202499451857, 179.981022032992859592, &s12, nullptr, nullptr);
  result += checkEquals(s12, 20003898.214, 0.5e-3);
  geod_inverse(&g, 89.262080389218, 0,
               -89.262080389218, 179.992207982775375662, &s12, nullptr, nullptr);
  result += checkEquals(s12, 20003925.854, 0.5e-3);
  geod_inverse(&g, 89.333123580033, 0,
               -89.333123580032997687, 179.99295812360148422, &s12, nullptr, nullptr);
  result += checkEquals(s12, 20003926.881, 0.5e-3);
  return result;
}
Пример #4
0
/* Geodesic distance (in meter) between two points with angular 2D coordinates */
double proj_lp_dist (const PJ *P, PJ_COORD a, PJ_COORD b) {
    double s12, azi1, azi2;
    /* Note: the geodesic code takes arguments in degrees */
    geod_inverse (P->geod,
        PJ_TODEG(a.lpz.phi), PJ_TODEG(a.lpz.lam),
        PJ_TODEG(b.lpz.phi), PJ_TODEG(b.lpz.lam),
        &s12, &azi1, &azi2
    );
    return s12;
}
Пример #5
0
static int GeodSolve0() {
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 40.6, -73.8, 49.01666667, 2.55, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 53.47022, 0.5e-5);
  result += checkEquals(azi2, 111.59367, 0.5e-5);
  result += checkEquals(s12, 5853226, 0.5);
  return result;
}
Пример #6
0
static int GeodSolve9() {
  /* Check fix for volatile x bug found 2011-06-25 (gcc 4.4.4 x86 -O3) */
  double s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 56.320923501171, 0,
               -56.320923501171, 179.664747671772880215, &s12, nullptr, nullptr);
  result += checkEquals(s12, 19993558.287, 0.5e-3);
  return result;
}
Пример #7
0
static int GeodSolve4() {
  /* Check fix for short line bug found 2010-05-21 */
  double s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 36.493349428792, 0, 36.49334942879201, .0000008,
               &s12, nullptr, nullptr);
  result += checkEquals(s12, 0.072, 0.5e-3);
  return result;
}
Пример #8
0
/* Geodesic distance (in meter) + fwd and rev azimuth between two points on the ellipsoid */
PJ_COORD proj_geod (const PJ *P, PJ_COORD a, PJ_COORD b) {
    PJ_COORD c;
    /* Note: the geodesic code takes arguments in degrees */
    geod_inverse (P->geod,
        PJ_TODEG(a.lpz.phi), PJ_TODEG(a.lpz.lam),
        PJ_TODEG(b.lpz.phi), PJ_TODEG(b.lpz.lam),
        c.v, c.v+1, c.v+2
    );

    return c;
}
Пример #9
0
static int GeodSolve78() {
  /* An example where the NGS calculator fails to converge */
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 27.2, 0.0, -27.1, 179.5, &s12, &azi1, &azi2);
  result += checkEquals(azi1,  45.82468716758, 0.5e-11);
  result += checkEquals(azi2, 134.22776532670, 0.5e-11);
  result += checkEquals(s12,  19974354.765767, 0.5e-6);
  return result;
}
Пример #10
0
static int GeodSolve59() {
  /* Check for points close with longitudes close to 180 deg apart. */
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 5, 0.00000000000001, 10, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 0.000000000000035, 1.5e-14);
  result += checkEquals(azi2, 179.99999999999996, 1.5e-14);
  result += checkEquals(s12, 18345191.174332713, 5e-9);
  return result;
}
Пример #11
0
static int GeodSolve11() {
  /* Check fix for bet2 = -bet1 bug found 2011-06-25 (Visual Studio
   * 10 rel + debug) */
  double s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 48.522876735459, 0,
               -48.52287673545898293, 179.599720456223079643, &s12, nullptr, nullptr);
  result += checkEquals(s12, 19989144.774, 0.5e-3);
  return result;
}
Пример #12
0
static int GeodSolve10() {
  /* Check fix for adjust tol1_ bug found 2011-06-25 (Visual Studio
   * 10 rel + debug) */
  double s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 52.784459512564, 0,
               -52.784459512563990912, 179.634407464943777557, &s12, nullptr, nullptr);
  result += checkEquals(s12, 19991596.095, 0.5e-3);
  return result;
}
Пример #13
0
static int GeodSolve55() {
  /* Check fix for nan + point on equator or pole not returning all nans in
   * Geodesic::Inverse, found 2015-09-23. */
  double azi1, azi2, s12, nan;
  struct geod_geodesic g;
  int result = 0;
  {
    double minus1 = -1;
    /* cppcheck-suppress wrongmathcall */
    nan = sqrt(minus1);
  }
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, nan, 0, 0, 90, &s12, &azi1, &azi2);
  result += checkNaN(azi1);
  result += checkNaN(azi2);
  result += checkNaN(s12);
  geod_inverse(&g, nan, 0, 90, 9, &s12, &azi1, &azi2);
  result += checkNaN(azi1);
  result += checkNaN(azi2);
  result += checkNaN(s12);
  return result;
}
Пример #14
0
static int GeodSolve76() {
  /* The distance from Wellington and Salamanca (a classic failure of
     Vincenty) */
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, -(41+19/60.0), 174+49/60.0, 40+58/60.0, -(5+30/60.0),
               &s12, &azi1, &azi2);
  result += checkEquals(azi1, 160.39137649664, 0.5e-11);
  result += checkEquals(azi2,  19.50042925176, 0.5e-11);
  result += checkEquals(s12,  19960543.857179, 0.5e-6);
  return result;
}
Пример #15
0
static int GeodSolve12() {
  /* Check fix for inverse geodesics on extreme prolate/oblate
   * ellipsoids Reported 2012-08-29 Stefan Guenther
   * <*****@*****.**>; fixed 2012-10-07 */
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, 89.8, -1.83);
  geod_inverse(&g, 0, 0, -10, 160, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 120.27, 1e-2);
  result += checkEquals(azi2, 105.15, 1e-2);
  result += checkEquals(s12, 266.7, 1e-1);
  return result;
}
Пример #16
0
static int GeodSolve14() {
  /* Check fix for inverse ignoring lon12 = nan */
  double azi1, azi2, s12, nan;
  struct geod_geodesic g;
  int result = 0;
  {
    double minus1 = -1;
    /* cppcheck-suppress wrongmathcall */
    nan = sqrt(minus1);
  }
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 0, 0, 1, nan, &s12, &azi1, &azi2);
  result += checkNaN(azi1);
  result += checkNaN(azi2);
  result += checkNaN(s12);
  return result;
}
Пример #17
0
static int Planimeter15() {
  /* Coverage tests, includes Planimeter15 - Planimeter18 (combinations of
     reverse and sign) + calls to testpoint, testedge, geod_polygonarea. */
  struct geod_geodesic g;
  struct geod_polygon p;
  double lat[] = {2, 1, 3}, lon[] = {1, 2, 3};
  double area, s12, azi1;
  double r = 18454562325.45119,
    a0 = 510065621724088.5093;  /* ellipsoid area */
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_polygon_init(&p, 0);
  geod_polygon_addpoint(&g, &p, lat[0], lon[0]);
  geod_polygon_addpoint(&g, &p, lat[1], lon[1]);
  geod_polygon_testpoint(&g, &p, lat[2], lon[2], 0, 1, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  geod_polygon_testpoint(&g, &p, lat[2], lon[2], 0, 0, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  geod_polygon_testpoint(&g, &p, lat[2], lon[2], 1, 1, &area, nullptr);
  result += checkEquals(area, -r, 0.5);
  geod_polygon_testpoint(&g, &p, lat[2], lon[2], 1, 0, &area, nullptr);
  result += checkEquals(area, a0-r, 0.5);
  geod_inverse(&g, lat[1], lon[1], lat[2], lon[2], &s12, &azi1, nullptr);
  geod_polygon_testedge(&g, &p, azi1, s12, 0, 1, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  geod_polygon_testedge(&g, &p, azi1, s12, 0, 0, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  geod_polygon_testedge(&g, &p, azi1, s12, 1, 1, &area, nullptr);
  result += checkEquals(area, -r, 0.5);
  geod_polygon_testedge(&g, &p, azi1, s12, 1, 0, &area, nullptr);
  result += checkEquals(area, a0-r, 0.5);
  geod_polygon_addpoint(&g, &p, lat[2], lon[2]);
  geod_polygon_compute(&g, &p, 0, 1, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  geod_polygon_compute(&g, &p, 0, 0, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  geod_polygon_compute(&g, &p, 1, 1, &area, nullptr);
  result += checkEquals(area, -r, 0.5);
  geod_polygon_compute(&g, &p, 1, 0, &area, nullptr);
  result += checkEquals(area, a0-r, 0.5);
  geod_polygonarea(&g, lat, lon, 3, &area, nullptr);
  result += checkEquals(area, r, 0.5);
  return result;
}
Пример #18
0
GAIAGEO_DECLARE double
gaiaGeodesicDistance (double a, double b, double rf, double lat1, double lon1,
		      double lat2, double lon2)
{
/*
/ Calculate geodesic distance (in m) 
/ between two points specified by latitude/longitude 
/ (in decimal degrees) 
*/

#if PROJ_GEODESIC
/*
/ using the PROJ.4 own implementation
/
/ requires PROJ.4 >= 4.9.0
/
/ (accepting a patch suggested by Charles Karney <*****@*****.**>
*/
    double s12;
    struct geod_geodesic gd;
    geod_init (&gd, a, 1 / rf);
    geod_inverse (&gd, lat1, lon1, lat2, lon2, &s12, 0, 0);
    return s12;
#else
/*
/ using Vincenty inverse formula for ellipsoids
/
/ based on original JavaScript by (c) Chris Veness 2002-2008 
/ http://www.movable-type.co.uk/scripts/latlong-vincenty.html
/
*/
    double f = 1.0 / rf;
    double L = (lon2 - lon1) * DEG2RAD;
    double U1 = atan ((1.0 - f) * tan (lat1 * DEG2RAD));
    double U2 = atan ((1.0 - f) * tan (lat2 * DEG2RAD));
    double sinU1 = sin (U1);
    double cosU1 = cos (U1);
    double sinU2 = sin (U2);
    double cosU2 = cos (U2);
    double lambda = L;
    double lambdaP;
    double sinLambda;
    double cosLambda;
    double sinSigma;
    double cosSigma;
    double sigma;
    double sinAlpha;
    double cosSqAlpha;
    double cos2SigmaM;
    double C;
    double uSq;
    double A;
    double B;
    double deltaSigma;
    double s;
    int iterLimit = 100;
    do
      {
	  sinLambda = sin (lambda);
	  cosLambda = cos (lambda);
	  sinSigma =
	      sqrt ((cosU2 * sinLambda) * (cosU2 * sinLambda) +
		    (cosU1 * sinU2 -
		     sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 -
						   sinU1 * cosU2 * cosLambda));
	  if (sinSigma == 0.0)
	      return 0.0;	/* co-incident points */
	  cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
	  sigma = atan2 (sinSigma, cosSigma);
	  sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
	  cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
	  cos2SigmaM = cosSigma - 2.0 * sinU1 * sinU2 / cosSqAlpha;
	  if (isnan (cos2SigmaM))
	      cos2SigmaM = 0;	/* equatorial line */
	  C = f / 16.0 * cosSqAlpha * (4.0 + f * (4.0 - 3.0 * cosSqAlpha));
	  lambdaP = lambda;
	  lambda =
	      L + (1.0 - C) * f * sinAlpha * (sigma +
					      C * sinSigma * (cos2SigmaM +
							      C * cosSigma *
							      (-1.0 +
							       2.0 *
							       cos2SigmaM *
							       cos2SigmaM)));
      }
    while (fabs (lambda - lambdaP) > 1e-12 && --iterLimit > 0);
    if (iterLimit == 0)
	return -1.0;		/* formula failed to converge */
    uSq = cosSqAlpha * (a * a - b * b) / (b * b);
    A = 1.0 + uSq / 16384.0 * (4096.0 +
			       uSq * (-768.0 + uSq * (320.0 - 175.0 * uSq)));
    B = uSq / 1024.0 * (256.0 + uSq * (-128.0 + uSq * (74.0 - 47.0 * uSq)));
    deltaSigma =
	B * sinSigma * (cos2SigmaM +
			B / 4.0 * (cosSigma *
				   (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM) -
				   B / 6.0 * cos2SigmaM * (-3.0 +
							   4.0 * sinSigma *
							   sinSigma) * (-3.0 +
									4.0 *
									cos2SigmaM
									*
									cos2SigmaM)));
    s = b * A * (sigma - deltaSigma);
    return s;
#endif /* end Vincenty formula */
}
Пример #19
0
static int GeodSolve33() {
  /* Check max(-0.0,+0.0) issues 2015-08-22 (triggered by bugs in Octave --
   * sind(-0.0) = +0.0 -- and in some version of Visual Studio --
   * fmod(-0.0, 360.0) = +0.0. */
  double azi1, azi2, s12;
  struct geod_geodesic g;
  int result = 0;
  geod_init(&g, wgs84_a, wgs84_f);
  geod_inverse(&g, 0, 0, 0, 179, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 90.00000, 0.5e-5);
  result += checkEquals(azi2, 90.00000, 0.5e-5);
  result += checkEquals(s12, 19926189, 0.5);
  geod_inverse(&g, 0, 0, 0, 179.5, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 55.96650, 0.5e-5);
  result += checkEquals(azi2, 124.03350, 0.5e-5);
  result += checkEquals(s12, 19980862, 0.5);
  geod_inverse(&g, 0, 0, 0, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 0.00000, 0.5e-5);
  result += checkEquals(fabs(azi2), 180.00000, 0.5e-5);
  result += checkEquals(s12, 20003931, 0.5);
  geod_inverse(&g, 0, 0, 1, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 0.00000, 0.5e-5);
  result += checkEquals(fabs(azi2), 180.00000, 0.5e-5);
  result += checkEquals(s12, 19893357, 0.5);
  geod_init(&g, 6.4e6, 0);
  geod_inverse(&g, 0, 0, 0, 179, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 90.00000, 0.5e-5);
  result += checkEquals(azi2, 90.00000, 0.5e-5);
  result += checkEquals(s12, 19994492, 0.5);
  geod_inverse(&g, 0, 0, 0, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 0.00000, 0.5e-5);
  result += checkEquals(fabs(azi2), 180.00000, 0.5e-5);
  result += checkEquals(s12, 20106193, 0.5);
  geod_inverse(&g, 0, 0, 1, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 0.00000, 0.5e-5);
  result += checkEquals(fabs(azi2), 180.00000, 0.5e-5);
  result += checkEquals(s12, 19994492, 0.5);
  geod_init(&g, 6.4e6, -1/300.0);
  geod_inverse(&g, 0, 0, 0, 179, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 90.00000, 0.5e-5);
  result += checkEquals(azi2, 90.00000, 0.5e-5);
  result += checkEquals(s12, 19994492, 0.5);
  geod_inverse(&g, 0, 0, 0, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 90.00000, 0.5e-5);
  result += checkEquals(azi2, 90.00000, 0.5e-5);
  result += checkEquals(s12, 20106193, 0.5);
  geod_inverse(&g, 0, 0, 0.5, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 33.02493, 0.5e-5);
  result += checkEquals(azi2, 146.97364, 0.5e-5);
  result += checkEquals(s12, 20082617, 0.5);
  geod_inverse(&g, 0, 0, 1, 180, &s12, &azi1, &azi2);
  result += checkEquals(azi1, 0.00000, 0.5e-5);
  result += checkEquals(fabs(azi2), 180.00000, 0.5e-5);
  result += checkEquals(s12, 20027270, 0.5);

  return result;
}