33 * For terms of use refer to http://www.mapcode.com/downloads.html
44 */
55
6+ /**
7+ * This application uses the Mapcode C library to encode and decode Mapcodes.
8+ * It also serves as an example of how to use this library in a C environment.
9+ *
10+ * It also offers additional options to generate "test sets" of coordinates
11+ * and Mapcodes to check other Mapcode implementations against reference data.
12+ *
13+ * These test sets consist of:
14+ *
15+ * - a number of "grid distributed" coordinates, which forms a set of coordinates
16+ * and their Mapcodes, wrapped as a grid around the Earth;
17+ *
18+ * - a number of "random uniformly distributed" coordinates, which forms a set of
19+ * random coordiantes on the surface of Earth; or
20+ *
21+ * - a set which consists of typical Mapcode "boundaries" and "edge cases", based
22+ * on the internal implementation of the boundaries database of the Mapcode
23+ * implementation.
24+ */
25+
626#include <stdio.h>
727#include <math.h>
828#include "mapcoder/mapcoder.c"
929
10- static const double PI = 3.14159265358979323846 ;
11- static const int RESULTS_MAX = 64 ;
12- static const int SHOW_PROGRESS = 125 ;
1330
14- static int largestNrOfResults = 0 ;
15- static double latLargestNrOfResults = 0.0 ;
16- static double lonLargestNrOfResults = 0.0 ;
17- static int totalNrOfResults = 0 ;
1831
32+ /**
33+ * Some global constants to be used.
34+ */
35+ static const double PI = 3.14159265358979323846 ;
36+ static const int RESULTS_MAX = 64 ;
37+ static const int SHOW_PROGRESS = 125 ;
38+
39+
40+
41+ /**
42+ * These statistics are stored globally so they can be updated easily by the
43+ * generateAndOutputMapcodes() method.
44+ */
45+ static int largestNrOfResults = 0 ;
46+ static double latLargestNrOfResults = 0.0 ;
47+ static double lonLargestNrOfResults = 0.0 ;
48+ static int totalNrOfResults = 0 ;
49+
50+
51+
52+ /**
53+ * The usage() method explains how this application can be used. It is called
54+ * whenever a incorrect amount or combination of parameters is entered.
55+ */
1956static void usage (const char * appName ) {
2057 printf ("MAPCODE (C library version %s)\n" , mapcode_cversion );
2158 printf ("Copyright (C) 2014 Stichting Mapcode Foundation\n" );
@@ -48,20 +85,35 @@ static void usage(const char* appName) {
4885 printf (" lat-deg, lon-deg : [-90..90], [-180..180]\n" );
4986 printf (" x, y, z : [-1..1]\n" );
5087 printf ("\n" );
51- printf ("\n stdout: used for outputting 3D point data; stderr: used for statistics." );
52- printf ("\n" );
5388 printf (" The lat/lon pairs will be distributed over the 3D surface of the Earth\n" );
5489 printf (" and the (x, y, z) coordinates are placed on a sphere with radius 1.\n" );
90+ printf (" The (x, y, z) coordinates are primarily meant for visualization of the data set.\n" );
91+ printf ("\n" );
92+ printf ("\n Notes on the use of stdout and stderr:\n" );
93+ printf ("\n stdout: used for outputting 3D point data; stderr: used for statistics." );
94+ printf ("\n You can redirect stdout to a destination file, while stderr will show progress.\n" );
5595}
5696
97+
98+
99+ /**
100+ * The method radToDeg() converts radians to degrees.
101+ */
57102static double radToDeg (double rad ){
58103 return (rad / PI ) * 180.0 ;
59104}
60105
106+
107+
108+ /**
109+ * The method degToRad() converts degrees to radians.
110+ */
61111static double degToRad (double deg ){
62112 return (deg / 180.0 ) * PI ;
63113}
64114
115+
116+
65117/**
66118 * Given a single number between 0..1, generate a latitude, longitude (in degrees) and a 3D
67119 * (x, y, z) point on a sphere with a radius of 1.
@@ -87,6 +139,12 @@ static void unitToLatLonDeg(
87139 * lonDeg = isnan (lonRad ) ? 180.0 : radToDeg (lonRad );
88140}
89141
142+
143+
144+ /**
145+ * The method convertLatLonToXYZ() convertes a lat/lon pair to a (x, y, z) coordinate
146+ * on a sphere with radius 1.
147+ */
90148static void convertLatLonToXYZ (double latDeg , double lonDeg , double * x , double * y , double * z ) {
91149 double latRad = degToRad (latDeg );
92150 double lonRad = degToRad (lonDeg );
@@ -95,7 +153,14 @@ static void convertLatLonToXYZ(double latDeg, double lonDeg, double* x, double*
95153 * z = sin (latRad );
96154}
97155
98- static int printMapcodes (double lat , double lon , int iShowError ) {
156+
157+
158+ /**
159+ * The method printMapcode() generates and outputs Mapcodes for a lat/lon pair.
160+ * If iShowError != 0, then encoding errors are output to stderr, otherwise they
161+ * are ignored.
162+ */
163+ static int generateAndOutputMapcodes (double lat , double lon , int iShowError ) {
99164 const char * results [RESULTS_MAX ];
100165 int context = 0 ;
101166 const int nrResults = coord2mc (results , lat , lon , context );
@@ -124,6 +189,12 @@ static int printMapcodes(double lat, double lon, int iShowError) {
124189 return nrResults ;
125190}
126191
192+
193+
194+ /**
195+ * This is the main() method which is called from the command-line.
196+ * Return code 0 means success. Any other values means some sort of error occurred.
197+ */
127198int main (const int argc , const char * * argv )
128199{
129200 // Provide usage message if no arguments specified.
@@ -228,47 +299,50 @@ int main(const int argc, const char** argv)
228299 lon = (maxLon - minLon ) / 2.0 ;
229300
230301 // Try center.
231- printMapcodes (lat , lon , 0 );
302+ generateAndOutputMapcodes (lat , lon , 0 );
232303
233304 // Try corners.
234- printMapcodes (minLat , minLon , 0 );
235- printMapcodes (minLat , maxLon , 0 );
236- printMapcodes (maxLat , minLon , 0 );
237- printMapcodes (maxLat , maxLon , 0 );
305+ generateAndOutputMapcodes (minLat , minLon , 0 );
306+ generateAndOutputMapcodes (minLat , maxLon , 0 );
307+ generateAndOutputMapcodes (maxLat , minLon , 0 );
308+ generateAndOutputMapcodes (maxLat , maxLon , 0 );
238309
239310 // Try JUST inside.
240311 double factor = 1.0 ;
241312 for (int j = 1 ; j < 6 ; ++ j ) {
242313
243314 double d = 1.0 / factor ;
244- printMapcodes (minLat + d , minLon + d , 0 );
245- printMapcodes (minLat + d , maxLon - d , 0 );
246- printMapcodes (maxLat - d , minLon + d , 0 );
247- printMapcodes (maxLat - d , maxLon - d , 0 );
315+ generateAndOutputMapcodes (minLat + d , minLon + d , 0 );
316+ generateAndOutputMapcodes (minLat + d , maxLon - d , 0 );
317+ generateAndOutputMapcodes (maxLat - d , minLon + d , 0 );
318+ generateAndOutputMapcodes (maxLat - d , maxLon - d , 0 );
248319
249320 // Try JUST outside.
250- printMapcodes (minLat - d , minLon - d , 0 );
251- printMapcodes (minLat - d , maxLon + d , 0 );
252- printMapcodes (maxLat + d , minLon - d , 0 );
253- printMapcodes (maxLat + d , maxLon + d , 0 );
321+ generateAndOutputMapcodes (minLat - d , minLon - d , 0 );
322+ generateAndOutputMapcodes (minLat - d , maxLon + d , 0 );
323+ generateAndOutputMapcodes (maxLat + d , minLon - d , 0 );
324+ generateAndOutputMapcodes (maxLat + d , maxLon + d , 0 );
254325 factor = factor * 10.0 ;
255326 }
256327
257328 // Try 22m outside.
258- printMapcodes (minLat - 22 , (maxLon - minLon ) / 2 , 0 );
259- printMapcodes (minLat - 22 , (maxLon - minLon ) / 2 , 0 );
260- printMapcodes (maxLat + 22 , (maxLon - minLon ) / 2 , 0 );
261- printMapcodes (maxLat + 22 , (maxLon - minLon ) / 2 , 0 );
329+ generateAndOutputMapcodes (minLat - 22 , (maxLon - minLon ) / 2 , 0 );
330+ generateAndOutputMapcodes (minLat - 22 , (maxLon - minLon ) / 2 , 0 );
331+ generateAndOutputMapcodes (maxLat + 22 , (maxLon - minLon ) / 2 , 0 );
332+ generateAndOutputMapcodes (maxLat + 22 , (maxLon - minLon ) / 2 , 0 );
262333
263334 if ((i % SHOW_PROGRESS ) == 0 ) {
264- fprintf (stderr , "Processed %d of %d regions (generated %d Mapcodes)...\r" , i , nrPoints , totalNrOfResults );
335+ fprintf (stderr , "[%d%%] Processed %d of %d regions (generated %d Mapcodes)...\r" ,
336+ (int ) (((float ) i / ((float ) nrPoints )) + 0.5 ),
337+ i , nrPoints , totalNrOfResults );
265338 }
266339 }
267340 fprintf (stderr , "\nStatistics:\n" );
268341 fprintf (stderr , "Total number of 3D points generated = %d\n" , nrPoints );
269342 fprintf (stderr , "Total number of Mapcodes generated = %d\n" , totalNrOfResults );
270343 fprintf (stderr , "Average number of Mapcodes per 3D point = %f\n" , ((float ) totalNrOfResults ) / ((float ) nrPoints ));
271- fprintf (stderr , "Largest number of results for 1 Mapcode = %d at (%f, %f)\n" , largestNrOfResults , latLargestNrOfResults , lonLargestNrOfResults );
344+ fprintf (stderr , "Largest number of results for 1 Mapcode = %d at (%f, %f)\n" ,
345+ largestNrOfResults , latLargestNrOfResults , lonLargestNrOfResults );
272346 }
273347 else if ((strcmp (cmd , "-g" ) == 0 ) || (strcmp (cmd , "--grid" ) == 0 ) ||
274348 (strcmp (cmd , "-r" ) == 0 ) || (strcmp (cmd , "--random" ) == 0 )) {
@@ -339,22 +413,25 @@ int main(const int argc, const char** argv)
339413 }
340414
341415 unitToLatLonDeg (unit1 , unit2 , & lat , & lon );
342- const int nrResults = printMapcodes (lat , lon , 1 );
416+ const int nrResults = generateAndOutputMapcodes (lat , lon , 1 );
343417 if (nrResults > largestNrOfResults ) {
344418 largestNrOfResults = nrResults ;
345419 latLargestNrOfResults = lat ;
346420 lonLargestNrOfResults = lon ;
347421 }
348422 totalNrOfResults += nrResults ;
349423 if ((i % SHOW_PROGRESS ) == 0 ) {
350- fprintf (stderr , "Created %d of %d 3D %s data points (generated %d Mapcodes)...\r" , i , nrPoints , random ? "random" : "grid" , totalNrOfResults );
424+ fprintf (stderr , "[%d%%] Created %d of %d 3D %s data points (generated %d Mapcodes)...\r" ,
425+ (int ) (((float ) i / ((float ) nrPoints )) + 0.5 ),
426+ i , nrPoints , random ? "random" : "grid" , totalNrOfResults );
351427 }
352428 }
353429 fprintf (stderr , "\nStatistics:\n" );
354430 fprintf (stderr , "Total number of 3D points generated = %d\n" , nrPoints );
355431 fprintf (stderr , "Total number of Mapcodes generated = %d\n" , totalNrOfResults );
356432 fprintf (stderr , "Average number of Mapcodes per 3D point = %f\n" , ((float ) totalNrOfResults ) / ((float ) nrPoints ));
357- fprintf (stderr , "Largest number of results for 1 Mapcode = %d at (%f, %f)\n" , largestNrOfResults , latLargestNrOfResults , lonLargestNrOfResults );
433+ fprintf (stderr , "Largest number of results for 1 Mapcode = %d at (%f, %f)\n" ,
434+ largestNrOfResults , latLargestNrOfResults , lonLargestNrOfResults );
358435 }
359436 else {
360437
0 commit comments