58
58
#include <stdlib.h>
59
59
#include <string.h>
60
60
#include <unistd.h>
61
+ #include <math.h>
61
62
#include <grass/gis.h>
62
63
#include <grass/raster.h>
63
64
#include <grass/gprojects.h>
64
65
#include <grass/glocale.h>
66
+ #include <grass/parson.h>
65
67
#include "r.proj.h"
66
68
67
69
/* modify this table to add new methods */
@@ -132,14 +134,17 @@ int main(int argc, char **argv)
132
134
* indbase , /* name of input database */
133
135
* interpol , /* interpolation method */
134
136
* memory , /* amount of memory for cache */
135
- * res ; /* resolution of target map */
137
+ * res , /* resolution of target map */
138
+ * format ; /* output format */
136
139
137
140
#ifdef HAVE_PROJ_H
138
141
struct Option * pipeline ; /* name of custom PROJ pipeline */
139
142
#endif
140
143
struct Cell_head incellhd , /* cell header of input map */
141
144
outcellhd ; /* and output map */
142
145
146
+ enum OutputFormat outputFormat ;
147
+
143
148
G_gisinit (argv [0 ]);
144
149
145
150
module = G_define_module ();
@@ -195,6 +200,13 @@ int main(int argc, char **argv)
195
200
res -> description = _ ("Resolution of output raster map" );
196
201
res -> guisection = _ ("Target" );
197
202
203
+ format = G_define_standard_option (G_OPT_F_FORMAT );
204
+ format -> options = "plain,shell,json" ;
205
+ format -> descriptions = _ ("plain;Human readable text output;"
206
+ "shell;shell script style text output;"
207
+ "json;JSON (JavaScript Object Notation);" );
208
+ format -> guisection = _ ("Print" );
209
+
198
210
#ifdef HAVE_PROJ_H
199
211
pipeline = G_define_option ();
200
212
pipeline -> key = "pipeline" ;
@@ -222,8 +234,10 @@ int main(int argc, char **argv)
222
234
223
235
gprint_bounds = G_define_flag ();
224
236
gprint_bounds -> key = 'g' ;
225
- gprint_bounds -> description = _ ("Print input map's bounds in the current "
226
- "projection and exit (shell style)" );
237
+ gprint_bounds -> description =
238
+ _ ("[DEPRECATED] Print input map's bounds in the current "
239
+ "projection and exit (shell style). This flag is obsolete and will "
240
+ "be removed in a future release. Use format=shell instead." );
227
241
gprint_bounds -> guisection = _ ("Print" );
228
242
229
243
/* The parser checks if the map already exists in current mapset,
@@ -234,6 +248,28 @@ int main(int argc, char **argv)
234
248
if (G_parser (argc , argv ))
235
249
exit (EXIT_FAILURE );
236
250
251
+ if (strcmp (format -> answer , "json" ) == 0 ) {
252
+ outputFormat = JSON ;
253
+ }
254
+ else if (strcmp (format -> answer , "shell" ) == 0 ) {
255
+ outputFormat = SHELL ;
256
+ }
257
+ else {
258
+ outputFormat = PLAIN ;
259
+ }
260
+
261
+ if (outputFormat != PLAIN && !print_bounds -> answer && !list -> answer ) {
262
+ G_fatal_error (
263
+ _ ("The format option can only be used with -%c or -%c flags" ),
264
+ print_bounds -> key , list -> key );
265
+ }
266
+
267
+ if (gprint_bounds -> answer ) {
268
+ G_warning (_ ("Flag 'g' is deprecated and will be removed in a future "
269
+ "release. Please use format=shell instead." ));
270
+ outputFormat = SHELL ;
271
+ }
272
+
237
273
/* get the method */
238
274
for (method = 0 ; (ipolname = menu [method ].name ); method ++ )
239
275
if (strcmp (ipolname , interpol -> answer ) == 0 )
@@ -246,7 +282,7 @@ int main(int argc, char **argv)
246
282
247
283
mapname = outmap -> answer ? outmap -> answer : inmap -> answer ;
248
284
if (mapname && !list -> answer && !overwrite && !print_bounds -> answer &&
249
- ! gprint_bounds -> answer && G_find_raster (mapname , G_mapset ()))
285
+ outputFormat != SHELL && G_find_raster (mapname , G_mapset ()))
250
286
G_fatal_error (_ ("option <%s>: <%s> exists. To overwrite, use the "
251
287
"--overwrite flag" ),
252
288
"output" , mapname );
@@ -261,8 +297,8 @@ int main(int argc, char **argv)
261
297
#endif
262
298
G_get_window (& outcellhd );
263
299
264
- if (gprint_bounds -> answer && !print_bounds -> answer )
265
- print_bounds -> answer = gprint_bounds -> answer ;
300
+ if (outputFormat == SHELL && !print_bounds -> answer )
301
+ print_bounds -> answer = 1 ;
266
302
curr_proj = G_projection ();
267
303
268
304
/* Get projection info for output mapset */
@@ -297,15 +333,47 @@ int main(int argc, char **argv)
297
333
if (list -> answer ) {
298
334
int i ;
299
335
char * * srclist ;
336
+ JSON_Array * maps_array = NULL ;
337
+ JSON_Value * maps_value = NULL ;
338
+
339
+ if (outputFormat == JSON ) {
340
+ maps_value = json_value_init_array ();
341
+ if (maps_value == NULL ) {
342
+ G_fatal_error (
343
+ _ ("Failed to initialize JSON array. Out of memory?" ));
344
+ }
345
+ maps_array = json_array (maps_value );
346
+ }
300
347
301
348
G_verbose_message (_ ("Checking project <%s> mapset <%s>" ),
302
349
inlocation -> answer , setname );
303
350
srclist = G_list (G_ELEMENT_RASTER , G_getenv_nofatal ("GISDBASE" ),
304
351
G_getenv_nofatal ("LOCATION_NAME" ), setname );
305
352
for (i = 0 ; srclist [i ]; i ++ ) {
306
- fprintf (stdout , "%s\n" , srclist [i ]);
353
+ switch (outputFormat ) {
354
+ case SHELL :
355
+ case PLAIN :
356
+ fprintf (stdout , "%s\n" , srclist [i ]);
357
+ break ;
358
+
359
+ case JSON :
360
+ json_array_append_string (maps_array , srclist [i ]);
361
+ break ;
362
+ }
363
+ }
364
+ if (outputFormat == JSON ) {
365
+ char * serialized_string = NULL ;
366
+ serialized_string = json_serialize_to_string_pretty (maps_value );
367
+ if (serialized_string == NULL ) {
368
+ G_fatal_error (_ ("Failed to initialize pretty JSON string." ));
369
+ }
370
+ puts (serialized_string );
371
+ json_free_serialized_string (serialized_string );
372
+ json_value_free (maps_value );
373
+ }
374
+ else {
375
+ fflush (stdout );
307
376
}
308
- fflush (stdout );
309
377
exit (EXIT_SUCCESS ); /* leave r.proj after listing */
310
378
}
311
379
@@ -378,6 +446,9 @@ int main(int argc, char **argv)
378
446
ocols = outcellhd .cols ;
379
447
380
448
if (print_bounds -> answer ) {
449
+ JSON_Value * root_value = NULL ;
450
+ JSON_Object * root_object = NULL ;
451
+
381
452
G_message (_ ("Input map <%s@%s> in project <%s>:" ), inmap -> answer ,
382
453
setname , inlocation -> answer );
383
454
@@ -407,17 +478,73 @@ int main(int argc, char **argv)
407
478
G_format_easting (ieast , east_str , curr_proj );
408
479
G_format_easting (iwest , west_str , curr_proj );
409
480
410
- if (gprint_bounds -> answer ) {
411
- fprintf (stdout , "n=%s s=%s w=%s e=%s rows=%d cols=%d\n" , north_str ,
412
- south_str , west_str , east_str , irows , icols );
481
+ if (outputFormat == JSON ) {
482
+ root_value = json_value_init_object ();
483
+ if (root_value == NULL ) {
484
+ G_fatal_error (
485
+ _ ("Failed to initialize JSON object. Out of memory?" ));
486
+ }
487
+ root_object = json_object (root_value );
413
488
}
414
- else {
489
+
490
+ switch (outputFormat ) {
491
+ case PLAIN :
415
492
fprintf (stdout , "Source cols: %d\n" , icols );
416
493
fprintf (stdout , "Source rows: %d\n" , irows );
417
494
fprintf (stdout , "Local north: %s\n" , north_str );
418
495
fprintf (stdout , "Local south: %s\n" , south_str );
419
496
fprintf (stdout , "Local west: %s\n" , west_str );
420
497
fprintf (stdout , "Local east: %s\n" , east_str );
498
+ break ;
499
+
500
+ case SHELL :
501
+ fprintf (stdout , "n=%s s=%s w=%s e=%s rows=%d cols=%d\n" , north_str ,
502
+ south_str , west_str , east_str , irows , icols );
503
+ break ;
504
+
505
+ case JSON :
506
+ if (isfinite (inorth )) {
507
+ json_object_set_number (root_object , "north" , inorth );
508
+ }
509
+ else {
510
+ json_object_set_null (root_object , "north" );
511
+ }
512
+
513
+ if (isfinite (isouth )) {
514
+ json_object_set_number (root_object , "south" , isouth );
515
+ }
516
+ else {
517
+ json_object_set_null (root_object , "south" );
518
+ }
519
+
520
+ if (isfinite (iwest )) {
521
+ json_object_set_number (root_object , "west" , iwest );
522
+ }
523
+ else {
524
+ json_object_set_null (root_object , "west" );
525
+ }
526
+
527
+ if (isfinite (ieast )) {
528
+ json_object_set_number (root_object , "east" , ieast );
529
+ }
530
+ else {
531
+ json_object_set_null (root_object , "east" );
532
+ }
533
+
534
+ json_object_set_number (root_object , "rows" , irows );
535
+ json_object_set_number (root_object , "cols" , icols );
536
+ break ;
537
+ }
538
+
539
+ if (outputFormat == JSON ) {
540
+ char * serialized_string = NULL ;
541
+ serialized_string = json_serialize_to_string_pretty (root_value );
542
+ if (serialized_string == NULL ) {
543
+ G_fatal_error (_ ("Failed to initialize pretty JSON string." ));
544
+ }
545
+ puts (serialized_string );
546
+ json_free_serialized_string (serialized_string );
547
+ json_value_free (root_value );
421
548
}
422
549
423
550
exit (EXIT_SUCCESS );
0 commit comments