// Converts a WMS tile coordinate (z,x,y) into a mercator bounding box inline void xyzToMercator( const int x, const int y, const int z, double &minx, double &miny, double &maxx, double &maxy) { xyzToWGS84(x, y, z, minx, miny, maxx, maxy); minx = static_cast<double>(clamp(util::FloatLongitude(minx))) * DEGREE_TO_PX; miny = latToY(clamp(util::FloatLatitude(miny))) * DEGREE_TO_PX; maxx = static_cast<double>(clamp(util::FloatLongitude(maxx))) * DEGREE_TO_PX; maxy = latToY(clamp(util::FloatLatitude(maxy))) * DEGREE_TO_PX; }
inline double degreeToPixel(FloatLatitude lat, unsigned zoom) { const double shift = (1u << zoom) * TILE_SIZE; const double b = shift / 2.0; const double y = b * (1. - latToY(lat) / 180.); return y; }
void planetEtchApp::initCities() { ofxCsv csv; csv.loadFile(ofToDataPath("allcities.csv")); numCities = csv.numRows; cities = new city[numCities]; unsigned long cityIndex = 0; float x; float y; for(int i=0; i<numCities; i++) { /*cout << endl << csv.data[i][0] << endl; cout << "pop = " << csv.data[i][COL_POP] << endl; cout << "x = " << csv.data[i][COL_X] << endl; cout << "y = " << csv.data[i][COL_Y] << endl; */ //x = adjustX(ofToFloat(csv.data[i][COL_X])); //y = adjustY(ofToFloat(csv.data[i][COL_Y])); x = ofToFloat(csv.data[i][OUTPUT_COL_LNG]); y = ofToFloat(csv.data[i][OUTPUT_COL_LAT]); x = lngToX(x); y = latToY(y); x = adjustX(x); y = adjustY(y); /* cout << "x = "; cout << x; cout << endl; cout << "y = "; cout << y; cout << endl; */ string countryString = csv.getString(i, OUTPUT_COL_COUNTRY); unsigned long hashID = hash(countryString.c_str()); float pop = ofToFloat(csv.data[i][OUTPUT_COL_POP]); (cities+i)->setVars( /*CANVAS_WIDTH/4 + x/2*/x, y, pop, hashID); // pop not used right now //(cities+i)->setVars( /*CANVAS_WIDTH/4 + x/2*/x, y, ofToFloat(csv.data[i][COL_POP]), ofToInt(csv.data[i][COL_COUNTRY])); // pop not used right now } csv.clear(); }
inline double latToYapprox(const FloatLatitude latitude) { if (latitude < FloatLatitude(-70.) || latitude > FloatLatitude(70.)) return latToY(latitude); // Approximate the inverse Gudermannian function with the Padé approximant [11/11]: deg → deg // Coefficients are computed for the argument range [-70°,70°] by Remez algorithm |err|_∞=3.387e-12 const auto x = static_cast<double>(latitude); return horner(x, 0.00000000000000000000000000e+00, 1.00000000000089108431373566e+00, 2.34439410386997223035693483e-06, -3.21291701673364717170998957e-04, -6.62778508496089940141103135e-10, 3.68188055470304769936079078e-08, 6.31192702320492485752941578e-14, -1.77274453235716299127325443e-12, -2.24563810831776747318521450e-18, 3.13524754818073129982475171e-17, 2.09014225025314211415458228e-23, -9.82938075991732185095509716e-23) / horner(x, 1.00000000000000000000000000e+00, 2.34439410398970701719081061e-06, -3.72061271627251952928813333e-04, -7.81802389685429267252612620e-10, 5.18418724186576447072888605e-08, 9.37468561198098681003717477e-14, -3.30833288607921773936702558e-12, -4.78446279888774903983338274e-18, 9.32999229169156878168234191e-17, 9.17695141954265959600965170e-23, -8.72130728982012387640166055e-22, -3.23083224835967391884404730e-28); }
/** * 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; }