[mapcode] 12/32: Fixed major bug in transformation

Stefan Fritsch sf at moszumanska.debian.org
Wed Nov 2 23:27:16 UTC 2016


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 <rijn at buve.nl>
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



More information about the Pkg-grass-devel mailing list