[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