This is an automated email from the git hooks/post-receive script. sf pushed a commit to annotated tag v1.33 in repository mapcode.
commit 41c123cb4afc24901e960822275a61ef7f918b12 Author: Rijn Buve <[email protected]> Date: Sun Aug 24 20:09:54 2014 +0200 Fixed major bug in transformation --- mapcode.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 189 insertions(+), 23 deletions(-) diff --git a/mapcode.c b/mapcode.c index 9b40973..9217166 100644 --- a/mapcode.c +++ b/mapcode.c @@ -8,6 +8,7 @@ #include "mapcoder/mapcoder.c" static const double PI = 3.14159265358979323846; +static const int RESULTS_MAX = 64; static void usage(const char* appName) { printf("Usage: \n"); @@ -45,12 +46,13 @@ static void usage(const char* appName) { * (x, y, z) point on a sphere with a radius of 1. */ static void unitToLatLonDegXYZ( - const double unit, double* latDeg, double* lonDeg, double* x, double* y, double* z) { + const double unit1, const double unit2, + double* latDeg, double* lonDeg, double* x, double* y, double* z) { // Calculate uniformly distributed 3D point on sphere (radius = 1.0): // http://mathproofs.blogspot.co.il/2005/04/uniform-random-distribution-on-sphere.html - const double theta0 = (2.0 * PI) * unit; - const double theta1 = acos(1.0 - (2.0 * unit)); + const double theta0 = (2.0 * PI) * unit1; + const double theta1 = acos(1.0 - (2.0 * unit2)); *x = sin(theta0) * sin(theta1); *y = cos(theta0) * sin(theta1); *z = cos(theta1); @@ -61,8 +63,8 @@ static void unitToLatLonDegXYZ( const double lonRad = atan2(*y, *x); // Convert radians to degrees. - *latDeg = latRad * (180.0 / PI); - *lonDeg = lonRad * (180.0 / PI); + *latDeg = isnan(latRad) ? 90.0 : (latRad * (180.0 / PI)); + *lonDeg = isnan(lonRad) ? 180.0 : (lonRad * (180.0 / PI)); } int main(const int argc, const char** argv) @@ -82,7 +84,7 @@ int main(const int argc, const char** argv) // Decode: [-d | --decode] <default-territory> <mapcode> [<mapcode> ...] // ------------------------------------------------------------------ if (argc < 4) { - printf("error: incorrect number of arguments\n\n"); + fprintf(stderr, "error: incorrect number of arguments\n\n"); usage(appName); return -1; } @@ -94,7 +96,7 @@ int main(const int argc, const char** argv) for (int i = 3; i < argc; ++i) { int err = mc2coord(&lat, &lon, argv[i], context); if (err != 0) { - printf("error: cannot decode '%s' (default territory='%s')\n", argv[i], argv[2]); + fprintf(stderr, "error: cannot decode '%s' (default territory='%s')\n", argv[i], argv[2]); return -1; } printf("%f %f\n", lat, lon); @@ -106,7 +108,7 @@ int main(const int argc, const char** argv) // Encode: [-e | --encode] <lat:-90..90> <lon:-180..180> [territory]> // ------------------------------------------------------------------ if ((argc != 4) && (argc != 5)) { - printf("error: incorrect number of arguments\n\n"); + fprintf(stderr, "error: incorrect number of arguments\n\n"); usage(appName); return -1; } @@ -117,10 +119,11 @@ int main(const int argc, const char** argv) if (argc == 5) { context = text2tc(argv[4], 0); } - const char* results[32]; + const char* results[RESULTS_MAX]; const int nrResults = coord2mc(results, lat, lon, context); if (nrResults <= 0) { - printf("error: cannot encode lat=%s, lon=%s (default territory=%d)\n", argv[2], argv[3], context); + fprintf(stderr, "error: cannot encode lat=%s, lon=%s (default territory=%d)\n", + argv[2], argv[3], context); return -1; } for (int i = 0; i < nrResults; ++i) { @@ -135,7 +138,7 @@ int main(const int argc, const char** argv) // Generate uniform test set: [-r | --random] <nrPoints> [<seed>] // ------------------------------------------------------------------ if ((argc < 3) || (argc > 4)) { - printf("error: incorrect number of arguments\n\n"); + fprintf(stderr, "error: incorrect number of arguments\n\n"); usage(appName); return -1; } @@ -152,40 +155,55 @@ int main(const int argc, const char** argv) } else { if (argc > 3) { - printf("error: cannot specify seed for -g/--grid\n\n"); + fprintf(stderr, "error: cannot specify seed for -g/--grid\n\n"); usage(appName); return -1; } } - const char* results[32]; + const char* results[RESULTS_MAX]; int context = 0; - double walker = 0.0; - const double increment = 1.0 / nrPoints; - + int gridX = 0; + int gridY = 0; + int line = round(sqrt(nrPoints)); for (int i = 0; i < nrPoints; ++i) { - double lat; double lon; double x; double y; double z; - double unit = (random ? (((double) rand()) / RAND_MAX) : walker); + double unit1; + double unit2; + + if (random) { + unit1 = ((double) rand()) / RAND_MAX; + unit2 = ((double) rand()) / RAND_MAX; + } + else { + unit1 = ((double) gridX) / line; + unit2 = ((double) gridY) / line; - unitToLatLonDegXYZ(unit, &lat, &lon, &x, &y, &z); + if (gridX < line) { + ++gridX; + } + else { + gridX = 0; + ++gridY; + } + } + unitToLatLonDegXYZ(unit1, unit2, &lat, &lon, &x, &y, &z); const int nrResults = coord2mc(results, lat, lon, context); if (nrResults <= 0) { - printf("error: cannot encode lat=%f, lon=%f)\n", lat, lon); + fprintf(stderr, "error: cannot encode lat=%f, lon=%f)\n", lat, lon); return -1; } printf("%d %lf %lf %lf %lf %lf\n", nrResults, lat, lon, x, y, z); - for (int i = 0; i < nrResults; ++i) { - printf("%s %s\n", results[(i * 2) + 1], results[(i * 2)]); + for (int j = 0; j < nrResults; ++j) { + printf("%s %s\n", results[(j * 2) + 1], results[(j * 2)]); } printf("\n"); - walker += increment; } } else { @@ -198,3 +216,151 @@ int main(const int argc, const char** argv) } return 0; } + +/** + * This program can encode and decode Mapcodes. It can also generate reference Mapcodes, + * lat/lon pairs and their corresponding (x, y, z) coordinates. + * + * If you'd like to visualize the generated points, you can use "Processing" from + * processing.org with the following Processing (Java) source code: + * + + --------------------------------------------------------------------------- + // Visualize 3D points. + // + // Copyright (C) 2014, TomTom BV + // Rijn Buve, 2014-08-24 + + final String DATA_FILE = "/Users/rijn/tmp/x"; + + final int N = 100000; + final int C = 150; + final int D = 1; + final boolean DRAW_LAT_LON = true; + final boolean STAR_SHAPE = true; + + float posX; + float posY; + float posZ; + float rotX = 1.2; + float rotY = 0; + float rotZ = 0.9; + + float[] lat = new float[N]; + float[] lon = new float[N]; + + float[] px = new float[N]; + float[] py = new float[N]; + float[] pz = new float[N]; + + int total; + + void setup() { + size(650, 550, P3D); + posX = width / 2.0; + posY = height / 2.0; + posZ = 0.0; + total = 0; + BufferedReader reader = createReader(DATA_FILE); + try { + while (true) { + String line = reader.readLine(); + if (line == null) { + break; + } + + // Parse line. + String[] items = split(line, " "); + int nrItems = Integer.parseInt(items[0]); + lat[total] = Float.parseFloat(items[1]) / 90.0; + lon[total] = Float.parseFloat(items[2]) / 180.0; + px[total] = Float.parseFloat(items[3]); + py[total] = Float.parseFloat(items[4]); + pz[total] = Float.parseFloat(items[5]); + + // Skip codes. + for (int i = 0; i < nrItems; ++i) { + reader.readLine(); + } + reader.readLine(); + ++total; + } + } + catch (IOException e) { + e.printStackTrace(); + } + finally { + try { + reader.close(); + } + catch (IOException e) { + // Ignored. + } + } + } + + void draw() { + clear(); + translate(posX, posY, posZ); + rotateX(rotX); + rotateY(rotY); + rotateZ(rotZ); + + // Draw sphere. + stroke(255, 0, 0, 50); + fill(255, 0, 0, 50); + sphere(C * 0.95); + stroke(255, 0, 0, 255); + + // Draw poles. + line(0, 0, -C - 200, 0, 0, C + 200); + + // Draw sphere dots. + stroke(255, 255, 255, 200); + for (int i = 0; i < total; ++i) { + float x = C * px[i]; + float y = C * py[i]; + float z = C * pz[i]; + if (STAR_SHAPE) { + line(x - D, y , z, x + D, y, z); + line(x, y - D , z, x, y + D, z); + } + line(x, y , z - D, x, y, z + D); + } + + if (DRAW_LAT_LON) { + + // Draw lat/lon bounds. + stroke(0, 255, 255, 200); + line(C + 5, -C - 50, C + 5, C + 5, -C - 50, -C - 5); + line(C + 5, -C - 50, -C - 5, -C - 5, -C - 50, -C - 5); + line(-C - 5, -C - 50, -C - 5, -C - 5, -C - 50, C + 5); + line(-C - 5, -C - 50, C + 5, C + 5, -C - 50, C + 5); + + // Draw lat/lon dots. + stroke(255, 255, 0, 200); + for (int i = 0; i < total; ++i) { + float x = C * lon[i]; + float y = -C - 51; + float z = C * lat[i]; + if (STAR_SHAPE) { + line(x - D , y, z, x + D, y, z); + line(x , y - D, z, x, y + D, z); + } + line(x , y, z - D, x, y, z + D); + } + } + + if (mousePressed) { + rotX += 0.01; + rotY -= 0.0016; + rotZ += 0.0043; + } + } + --------------------------------------------------------------------------- + * + * Have fun! + * + * Rijn Buve, August 2014. + */ + -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapcode.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

