[mapcode] 09/32: Added -g/--grid and -r/--random options

Stefan Fritsch sf at moszumanska.debian.org
Wed Nov 2 23:27:15 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 78bed3db3291a0dc121359f6f0956c0e71753064
Author: Rijn Buve <rijn at buve.nl>
Date:   Thu Aug 21 10:45:04 2014 +0200

    Added -g/--grid and -r/--random options
---
 mapcode.c | 106 +++++++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 73 insertions(+), 33 deletions(-)

diff --git a/mapcode.c b/mapcode.c
index fa54020..3e3d72e 100644
--- a/mapcode.c
+++ b/mapcode.c
@@ -21,19 +21,48 @@ static void usage(const char* appName) {
     printf("       Encode a lat/lon to a Mapcode. If the territory code is specified, the\n");
     printf("       encoding will only succeeed if the lat/lon is located in the territory.\n");
     printf("\n");
-    printf("    %s [-g | --generate] <nrPoints> [<seed>]\n", appName);
+    printf("    %s [-g | --grid] <nrPoints> [<seed>]\n", appName);
+    printf("    %s [-r | --random] <nrPoints> [<seed>]\n", appName);
     printf("\n");
-    printf("       Create a test set of a number of uniformly distributed lat/lon pairs,\n");
-    printf("       3D x/y/z points and their Mapcodes). The output format is:\n");
-    printf("           <nr> <lat> <lon> <x> <y> <z>\n");
-    printf("           <territory> <mapcode>            (repeated 'nr' rtimes)\n");
-    printf("           <1 empty line>\n");
+    printf("       Create a test set of a number of a grid or random uniformly distributed\n");
+    printf("       lat/lon pairs, (x, y, z) points and the Mapcode aliases.\n");
     printf("\n");
-    printf("       The points will be uniformly distributed over the 3D surface of the Earth\n");
-    printf("       rather than using uniformly distributed lat/lon values.\n");
+    printf("       The output format is:\n");
+    printf("           <number-of-aliases> <lat-deg> <lon-deg> <x> <y> <z>\n");
+    printf("           <territory> <mapcode>      (repeated 'number-of-aliases' times)\n");
+    printf("                                      (empty lines and next record)\n");
     printf("       Ranges:\n");
-    printf("           nr > 1    lat = -90..90    lon = -180..180    x,y,z = -1..1\n");
+    printf("           number-of-aliases : >= 1\n");
+    printf("           lat-deg, lon-deg  : [-90..90], [-180..180]\n");
+    printf("           x, y, z           : [-1..1]\n");
     printf("\n");
+    printf("       The lat/lon pairs will be distributed over the 3D surface of the Earth\n");
+    printf("       and the (x, y, z) coordinates are placed on a sphere with radius 1.\n");
+}
+
+/**
+ * Given a single number between 0..1, generate a latitude, longitude (in degrees) and a 3D
+ * (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) {
+
+    // 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));
+    *x = sin(theta0) * sin(theta1);
+    *y = cos(theta0) * sin(theta1);
+    *z = cos(theta1);
+
+    // Convert Carthesian 3D point into lat/lon (radius = 1.0):
+    // http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates
+    const double latRad = asin(*z);
+    const double lonRad = atan2(*y, *x);
+
+    // Convert radians to degrees.
+    *latDeg = latRad * (180.0 / PI);
+    *lonDeg = lonRad * (180.0 / PI);
 }
 
 int main(const int argc, const char** argv)
@@ -53,6 +82,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");
             usage(appName);
             return -1;
         }
@@ -76,6 +106,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");
             usage(appName);
             return -1;
         }
@@ -96,45 +127,53 @@ int main(const int argc, const char** argv)
             printf("%s %s\n", results[(i * 2) + 1], results[(i * 2)]);
         }
     }
-    else if ((strcmp(cmd, "-g") == 0) || (strcmp(cmd, "--generate") == 0)) {
+    else if ((strcmp(cmd, "-g") == 0) || (strcmp(cmd, "--grid") == 0) ||
+        (strcmp(cmd, "-r") == 0) || (strcmp(cmd, "--random") == 0)) {
 
         // ------------------------------------------------------------------
-        // Generate uniform test set: [-g | --generate] <nrPoints> [<seed>]
+        // Generate grid test set:    [-g | --grid]   <nrPoints>
+        // Generate uniform test set: [-r | --random] <nrPoints> [<seed>]
         // ------------------------------------------------------------------
-        if ((argc != 3) && (argc != 4)) {
+        if ((argc < 3) || (argc > 4)) {
+            printf("error: incorrect number of arguments\n\n");
             usage(appName);
             return -1;
         }
         const int nrPoints = atoi(argv[2]);
-
-        if (argc == 4) {
-            const int seed = atoi(argv[3]);
-            srand(seed);
+        int random = (strcmp(cmd, "-r") == 0) || (strcmp(cmd, "--random") == 0);
+        if (random) {
+            if (argc == 4) {
+                const int seed = atoi(argv[3]);
+                srand(seed);
+            }
+            else {
+                srand(time(0));
+            }
         }
         else {
-            srand(time(0));
+            if (argc > 3) {
+                printf("error: cannot specify seed for -g/--grid\n\n");
+                usage(appName);
+                return -1;
+            }
         }
+
         const char* results[32];
         int context = 0;
-        for (int i = 0; i < nrPoints; ++i) {
 
-            // 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 unitRand = ((double) rand()) / RAND_MAX;
-            const double theta0 = (2.0 * PI) * unitRand;
-            const double theta1 = acos(1.0 - (2.0 * unitRand));
-            const double x = sin(theta0) * sin(theta1);
-            const double y = cos(theta0) * sin(theta1);
-            const double z = cos(theta1);
+        double walker = 0.0;
+        const double increment = 1.0 / nrPoints;
+
+        for (int i = 0; i < nrPoints; ++i) {
 
-            // Convert Carthesian 3D point into lat/lon (radius = 1.0):
-            // http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates
-            const double latRad = asin(z);
-            const double lonRad = atan2(y, x);
+            double lat;
+            double lon;
+            double x;
+            double y;
+            double z;
+            double unit = (random ? (((double) rand()) / RAND_MAX) : walker);
 
-            // Convert radians to degrees.
-            const double lat = latRad * (180.0 / PI);
-            const double lon = lonRad * (180.0 / PI);
+            unitToLatLonDegXYZ(unit, &lat, &lon, &x, &y, &z);
 
             const int nrResults = coord2mc(results, lat, lon, context);
             if (nrResults <= 0) {
@@ -146,6 +185,7 @@ int main(const int argc, const char** argv)
                 printf("%s %s\n", results[(i * 2) + 1], results[(i * 2)]);
             }
             printf("\n");
+            walker += increment;
         }
     }
     else {

-- 
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