inline void pixelToDegree(const double shift, double &x, double &y) { const double b = shift / 2.0; x = (x - b) / shift * 360.0; // FIXME needs to be simplified const double g = (y - b) / -(shift / (2 * M_PI)) / detail::DEGREE_TO_RAD; static_assert(detail::DEGREE_TO_RAD / (2 * M_PI) - 1 / 360. < 0.0001, ""); y = static_cast<double>(yToLat(g)); }
/** * compute an approximative distance to a segment. Useful to estimate * distance to a gate. * Parameters: lat/long of point, then lat and long of A & B defining the * segment, and pointers to lat/long of closest point */ double distance_to_line_dichotomy_xing(double latitude, double longitude, double latitude_a, double longitude_a, double latitude_b, double longitude_b, double *x_latitude, double *x_longitude){ double p1_latitude, p1_longitude, p2_latitude, p2_longitude; double ortho_p1, ortho_p2; double limit; limit = PI/(180*60*1852); // 1m precision #ifdef DEBUG printf("Longitude A: %.2f Longitude B: .%2f\n", radToDeg(longitude_a), radToDeg(longitude_b)); #endif /* DEBUG */ if (fabs(longitude_a - longitude_b) > PI) { if (longitude_a > longitude_b) { if (longitude_a > 0.0) { longitude_a -= TWO_PI; } else { longitude_b += TWO_PI; } } else { if (longitude_b > 0.0) { longitude_b -= TWO_PI; } else { longitude_a += TWO_PI; } } } #ifdef DEBUG printf("AB NORM: Longitude A: %.2f Longitude B: %2f\n", radToDeg(longitude_a), radToDeg(longitude_b)); printf("Point: Longitude: %.2f\n", radToDeg(longitude)); #endif /* DEBUG */ p1_latitude = latitude_a; p1_longitude = longitude_a; p2_latitude = latitude_b; p2_longitude = longitude_b; ortho_p1 = ortho_distance(latitude, longitude, p1_latitude, p1_longitude); ortho_p2 = ortho_distance(latitude, longitude, p2_latitude, p2_longitude); // ending test on distance between two points. while (__distance((p1_latitude-p2_latitude), (p1_longitude-p2_longitude)) > limit) { if (ortho_p1 < ortho_p2) { p2_longitude = (p1_longitude+p2_longitude)/2; p2_latitude = yToLat((latToY(p1_latitude)+latToY(p2_latitude))/2); } else { p1_longitude = (p1_longitude+p2_longitude)/2; p1_latitude = yToLat((latToY(p1_latitude)+latToY(p2_latitude))/2); } ortho_p1 = ortho_distance(latitude, longitude, p1_latitude, p1_longitude); ortho_p2 = ortho_distance(latitude, longitude, p2_latitude, p2_longitude); } if (ortho_p1 < ortho_p2) { *x_latitude = p1_latitude; *x_longitude = p1_longitude; return ortho_p1; } *x_latitude = p2_latitude; *x_longitude = p2_longitude; return ortho_p2; }
/** * compute an approximative distance to a segment. Useful to estimate * distance to a gate. It is at best an approximation, as the intersection * algorithm is not valid for long distances * Parameters: lat/long of point, then lat and long of A & B defining the * segment */ double distance_to_line_ratio_xing(double latitude, double longitude, double latitude_a, double longitude_a, double latitude_b, double longitude_b, double *x_latitude, double *x_longitude, double *ab_ratio) { double dist_a, dist_b, max_dist, ab_dist, t_dist; double ortho_a, ortho_b; double t_latitude; double longitude_x, latitude_x, intersect; double longitude_y, latitude_y; double xing_latitude, xing_longitude; ortho_a = ortho_distance(latitude, longitude, latitude_a, longitude_a); ortho_b = ortho_distance(latitude, longitude, latitude_b, longitude_b); t_latitude = latToY(latitude); latitude_a = latToY(latitude_a); latitude_b = latToY(latitude_b); /* some normalization */ /* normalize the line */ #ifdef DEBUG printf("Longitude A: %.2f Longitude B: .%2f\n", radToDeg(longitude_a), radToDeg(longitude_b)); #endif /* DEBUG */ if (fabs(longitude_a - longitude_b) > PI) { if (longitude_a > longitude_b) { if (longitude_a > 0.0) { longitude_a -= TWO_PI; } else { longitude_b += TWO_PI; } } else { if (longitude_b > 0.0) { longitude_b -= TWO_PI; } else { longitude_a += TWO_PI; } } } #ifdef DEBUG printf("AB NORM: Longitude A: %.2f Longitude B: %2f\n", radToDeg(longitude_a), radToDeg(longitude_b)); printf("Point: Longitude: %.2f\n", radToDeg(longitude)); #endif /* DEBUG */ /* then the point */ if ((fabs(longitude-longitude_a)>PI) && (fabs(longitude-longitude_b)>PI)) { if (longitude < longitude_a) { longitude += TWO_PI; } else { longitude -= TWO_PI; } } #ifdef DEBUG printf("Point NORM: Longitude: %.2f\n", radToDeg(longitude)); #endif /* DEBUG */ dist_a = __distance((t_latitude-latitude_a), (longitude-longitude_a)); dist_b = __distance((t_latitude-latitude_b), (longitude-longitude_b)); ab_dist = __distance((latitude_a-latitude_b),(longitude_a-longitude_b)); max_dist = fmax(dist_a, dist_b); /* we construct a line form the point, orthogonal to the segment, long of at least max_dist */ latitude_x = t_latitude + (longitude_a - longitude_b) * max_dist / ab_dist; longitude_x = longitude + (latitude_b - latitude_a) * max_dist / ab_dist; latitude_y = t_latitude + (longitude_b - longitude_a) * max_dist / ab_dist; longitude_y = longitude + (latitude_a - latitude_b) * max_dist / ab_dist; #ifdef DEBUG printf("Intersect point: Latitude X: %.2f, Longitude X: %.2f\n", radToDeg(yToLat(latitude_x)), radToDeg(longitude_x)); printf("Intersect point: Latitude Y: %.2f, Longitude Y: %.2f\n", radToDeg(yToLat(latitude_y)), radToDeg(longitude_y)); #endif /* DEBUG */ intersect = __intersects_no_norm(latitude_a, longitude_a, latitude_b, longitude_b, latitude_y, longitude_y, latitude_x, longitude_x, &xing_latitude, &xing_longitude); if (intersect>=INTER_MIN_LIMIT && intersect<=INTER_MAX_LIMIT) { *x_latitude = yToLat(xing_latitude); *x_longitude = xing_longitude; #ifdef DEBUG printf("Intersect point: Latitude X: %.2f\n", radToDeg(*x_latitude)); printf("Intersect point: Longitude Y: %.2f\n", radToDeg(*x_longitude)); printf("Orig point: Latitude X: %.2f\n", radToDeg(latitude)); printf("Orig point: Longitude Y: %.2f\n", radToDeg(longitude)); #endif /* DEBUG */ t_dist = ortho_distance(latitude, longitude, *x_latitude, *x_longitude); #ifdef DEBUG printf("Min dist: %.3f, found dist: %.3f\n", max_dist, t_dist); printf("Ortho_a: %.3f, Ortho_b: %.3f\n", ortho_a, ortho_b); #endif /* DEBUG */ if (t_dist < ortho_a && t_dist < ortho_b) { *ab_ratio = intersect; return t_dist; } } if (ortho_a < ortho_b) { *x_latitude = yToLat(latitude_a); *x_longitude = longitude_a; *ab_ratio = -1.0; return ortho_a; } *x_latitude = yToLat(latitude_b); *x_longitude = longitude_b; *ab_ratio = -2.0; return ortho_b; }
inline FloatCoordinate toWGS84(const FloatCoordinate &mercator_coordinate) { return {mercator_coordinate.lon, yToLat(static_cast<double>(mercator_coordinate.lat))}; }