99
1010static const double PI = 3.14159265358979323846 ;
1111static const int RESULTS_MAX = 64 ;
12+ static const int SHOW_PROGRESS = 250 ;
1213
1314static void usage (const char * appName ) {
1415 printf ("MAPCODE (C library version %s)\n" , mapcode_cversion );
@@ -25,11 +26,13 @@ static void usage(const char* appName) {
2526 printf (" Encode a lat/lon to a Mapcode. If the territory code is specified, the\n" );
2627 printf (" encoding will only succeeed if the lat/lon is located in the territory.\n" );
2728 printf ("\n" );
28- printf (" %s [-g | --grid] <nrPoints> [<seed>]\n" , appName );
29+ printf (" %s [-b | --boundaries]\n" , appName );
30+ printf (" %s [-g | --grid] <nrPoints>\n" , appName );
2931 printf (" %s [-r | --random] <nrPoints> [<seed>]\n" , appName );
3032 printf ("\n" );
31- printf (" Create a test set of a number of a grid or random uniformly distributed\n" );
32- printf (" lat/lon pairs, (x, y, z) points and the Mapcode aliases.\n" );
33+ printf (" Create a test set of lat/lon pairs based on the Mapcode boundaries database\n" );
34+ printf (" as a fixed 3D grid or random uniformly distributed set of lat/lons with their\n" );
35+ printf (" (x, y, z) coordinates and all Mapcode aliases.\n" );
3336 printf ("\n" );
3437 printf (" The output format is:\n" );
3538 printf (" <number-of-aliases> <lat-deg> <lon-deg> <x> <y> <z>\n" );
@@ -46,30 +49,67 @@ static void usage(const char* appName) {
4649 printf (" and the (x, y, z) coordinates are placed on a sphere with radius 1.\n" );
4750}
4851
52+ static double radToDeg (double rad ){
53+ return (rad / PI ) * 180.0 ;
54+ }
55+
56+ static double degToRad (double deg ){
57+ return (deg / 180.0 ) * PI ;
58+ }
59+
4960/**
5061 * Given a single number between 0..1, generate a latitude, longitude (in degrees) and a 3D
5162 * (x, y, z) point on a sphere with a radius of 1.
5263 */
53- static void unitToLatLonDegXYZ (
54- const double unit1 , const double unit2 ,
55- double * latDeg , double * lonDeg , double * x , double * y , double * z ) {
64+ static void unitToLatLonDeg (
65+ const double unit1 , const double unit2 , double * latDeg , double * lonDeg ) {
5666
5767 // Calculate uniformly distributed 3D point on sphere (radius = 1.0):
5868 // http://mathproofs.blogspot.co.il/2005/04/uniform-random-distribution-on-sphere.html
5969 const double theta0 = (2.0 * PI ) * unit1 ;
6070 const double theta1 = acos (1.0 - (2.0 * unit2 ));
61- * x = sin (theta0 ) * sin (theta1 );
62- * y = cos (theta0 ) * sin (theta1 );
63- * z = cos (theta1 );
71+ double x = sin (theta0 ) * sin (theta1 );
72+ double y = cos (theta0 ) * sin (theta1 );
73+ double z = cos (theta1 );
6474
6575 // Convert Carthesian 3D point into lat/lon (radius = 1.0):
6676 // http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates
67- const double latRad = asin (* z );
68- const double lonRad = atan2 (* y , * x );
77+ const double latRad = asin (z );
78+ const double lonRad = atan2 (y , x );
6979
7080 // Convert radians to degrees.
71- * latDeg = isnan (latRad ) ? 90.0 : (latRad * (180.0 / PI ));
72- * lonDeg = isnan (lonRad ) ? 180.0 : (lonRad * (180.0 / PI ));
81+ * latDeg = isnan (latRad ) ? 90.0 : radToDeg (latRad );
82+ * lonDeg = isnan (lonRad ) ? 180.0 : radToDeg (lonRad );
83+ }
84+
85+ static void convertLatLonToXYZ (double latDeg , double lonDeg , double * x , double * y , double * z ) {
86+ double latRad = degToRad (latDeg );
87+ double lonRad = degToRad (lonDeg );
88+ * x = cos (latRad ) * cos (lonRad );
89+ * y = cos (latRad ) * sin (lonRad );
90+ * z = sin (latRad );
91+ }
92+
93+ static int printMapcodes (double lat , double lon , int iShowError ) {
94+ const char * results [RESULTS_MAX ];
95+ int context = 0 ;
96+ const int nrResults = coord2mc (results , lat , lon , context );
97+ if (nrResults <= 0 ) {
98+ if (iShowError ) {
99+ fprintf (stderr , "error: cannot encode lat=%f, lon=%f)\n" , lat , lon );
100+ }
101+ return -1 ;
102+ }
103+ double x ;
104+ double y ;
105+ double z ;
106+ convertLatLonToXYZ (lat , lon , & x , & y , & z );
107+ printf ("%d %lf %lf %lf %lf %lf\n" , nrResults , lat , lon , x , y , z );
108+ for (int j = 0 ; j < nrResults ; ++ j ) {
109+ printf ("%s %s\n" , results [(j * 2 ) + 1 ], results [(j * 2 )]);
110+ }
111+ printf ("\n" );
112+ return nrResults ;
73113}
74114
75115int main (const int argc , const char * * argv )
@@ -135,6 +175,76 @@ int main(const int argc, const char** argv)
135175 printf ("%s %s\n" , results [(i * 2 ) + 1 ], results [(i * 2 )]);
136176 }
137177 }
178+ else if ((strcmp (cmd , "-b" ) == 0 ) || (strcmp (cmd , "--boundaries" ) == 0 )) {
179+
180+ // ------------------------------------------------------------------
181+ // Generate a test set based on the Mapcode boundaries.
182+ // ------------------------------------------------------------------
183+ if (argc != 2 ) {
184+ fprintf (stderr , "error: incorrect number of arguments\n\n" );
185+ usage (appName );
186+ return -1 ;
187+ }
188+ for (int i = 0 ; i < NR_RECS ; ++ i ) {
189+ long minLonE6 ;
190+ long maxLonE6 ;
191+ long minLatE6 ;
192+ long maxLatE6 ;
193+ double minLon ;
194+ double maxLon ;
195+ double minLat ;
196+ double maxLat ;
197+ double lat ;
198+ double lon ;
199+
200+ get_boundaries (i , & minLonE6 , & minLatE6 , & maxLonE6 , & maxLatE6 );
201+ minLon = ((double ) minLonE6 ) / 1.0E6 ;
202+ maxLon = ((double ) maxLonE6 ) / 1.0E6 ;
203+ minLat = ((double ) minLatE6 ) / 1.0E6 ;
204+ maxLat = ((double ) maxLatE6 ) / 1.0E6 ;
205+
206+ // Try center.
207+ lat = (maxLat - minLat ) / 2.0 ;
208+ lon = (maxLon - minLon ) / 2.0 ;
209+
210+ // Try center.
211+ printMapcodes (lat , lon , 0 );
212+
213+ // Try corners.
214+ printMapcodes (minLat , minLon , 0 );
215+ printMapcodes (minLat , maxLon , 0 );
216+ printMapcodes (maxLat , minLon , 0 );
217+ printMapcodes (maxLat , maxLon , 0 );
218+
219+ // Try JUST inside.
220+ double factor = 1.0 ;
221+ for (int j = 1 ; j < 6 ; ++ j ) {
222+
223+ double d = 1.0 / factor ;
224+ printMapcodes (minLat + d , minLon + d , 0 );
225+ printMapcodes (minLat + d , maxLon - d , 0 );
226+ printMapcodes (maxLat - d , minLon + d , 0 );
227+ printMapcodes (maxLat - d , maxLon - d , 0 );
228+
229+ // Try JUST outside.
230+ printMapcodes (minLat - d , minLon - d , 0 );
231+ printMapcodes (minLat - d , maxLon + d , 0 );
232+ printMapcodes (maxLat + d , minLon - d , 0 );
233+ printMapcodes (maxLat + d , maxLon + d , 0 );
234+ factor = factor * 10.0 ;
235+ }
236+
237+ // Try 22m outside.
238+ printMapcodes (minLat - 22 , (maxLon - minLon ) / 2 , 0 );
239+ printMapcodes (minLat - 22 , (maxLon - minLon ) / 2 , 0 );
240+ printMapcodes (maxLat + 22 , (maxLon - minLon ) / 2 , 0 );
241+ printMapcodes (maxLat + 22 , (maxLon - minLon ) / 2 , 0 );
242+
243+ if ((i % SHOW_PROGRESS ) == 0 ) {
244+ fprintf (stderr , "Processed %d of %d regions...\r" , i , NR_RECS );
245+ }
246+ }
247+ }
138248 else if ((strcmp (cmd , "-g" ) == 0 ) || (strcmp (cmd , "--grid" ) == 0 ) ||
139249 (strcmp (cmd , "-r" ) == 0 ) || (strcmp (cmd , "--random" ) == 0 )) {
140250
@@ -177,18 +287,12 @@ int main(const int argc, const char** argv)
177287 double lonLargestNrOfResults = 0.0 ;
178288 int totalNrOfResults = 0 ;
179289
180- const char * results [RESULTS_MAX ];
181- int context = 0 ;
182-
183290 int gridX = 0 ;
184291 int gridY = 0 ;
185292 int line = round (sqrt (nrPoints ));
186293 for (int i = 0 ; i < nrPoints ; ++ i ) {
187294 double lat ;
188295 double lon ;
189- double x ;
190- double y ;
191- double z ;
192296 double unit1 ;
193297 double unit2 ;
194298
@@ -209,25 +313,19 @@ int main(const int argc, const char** argv)
209313 }
210314 }
211315
212- unitToLatLonDegXYZ (unit1 , unit2 , & lat , & lon , & x , & y , & z );
213- const int nrResults = coord2mc (results , lat , lon , context );
214- if (nrResults <= 0 ) {
215- fprintf (stderr , "error: cannot encode lat=%f, lon=%f)\n" , lat , lon );
216- return -1 ;
217- }
316+ unitToLatLonDeg (unit1 , unit2 , & lat , & lon );
317+ const int nrResults = printMapcodes (lat , lon , 1 );
218318 if (nrResults > largestNrOfResults ) {
219319 largestNrOfResults = nrResults ;
220320 latLargestNrOfResults = lat ;
221321 lonLargestNrOfResults = lon ;
222322 }
223323 totalNrOfResults += nrResults ;
224- printf ("%d %lf %lf %lf %lf %lf\n" , nrResults , lat , lon , x , y , z );
225- for (int j = 0 ; j < nrResults ; ++ j ) {
226- printf ("%s %s\n" , results [(j * 2 ) + 1 ], results [(j * 2 )]);
324+ if ((i % SHOW_PROGRESS ) == 0 ) {
325+ fprintf (stderr , "Created %d of %d 3D %s data points...\r" , i , nrPoints , random ? "random" : "grid" );
227326 }
228- printf ("\n" );
229327 }
230- fprintf (stderr , "Statistics :\n" );
328+ fprintf (stderr , "\nStatistics :\n" );
231329 fprintf (stderr , "Total number of 3D points generated = %d\n" , nrPoints );
232330 fprintf (stderr , "Total number of Mapcodes generated = %d\n" , totalNrOfResults );
233331 fprintf (stderr , "Average number of Mapcodes per 3D point = %f\n" , ((float ) totalNrOfResults ) / ((float ) nrPoints ));
0 commit comments