Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

g.proj: add JSON support #4104

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion general/g.proj/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MODULE_TOPDIR = ../..
PGM = g.proj

EXTRA_INC = $(PROJINC) $(GDALCFLAGS)
LIBES = $(GPROJLIB) $(GISLIB) $(GDALLIBS) $(PROJLIB)
LIBES = $(GPROJLIB) $(GISLIB) $(GDALLIBS) $(PROJLIB) $(PARSONLIB)
DEPENDENCIES = $(GPROJDEP) $(GISDEP)

include $(MODULE_TOPDIR)/include/Make/Module.make
Expand Down
8 changes: 5 additions & 3 deletions general/g.proj/local_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ extern struct Key_Value *projinfo, *projunits, *projepsg;
extern char *projsrid, *projwkt;
extern struct Cell_head cellhd;

enum OutputFormat { PLAIN, SHELL, JSON };

/* input.c */
void input_currloc(void);

Expand All @@ -16,12 +18,12 @@ int input_georef(char *);
#endif

/* output.c */
void print_projinfo(int);
void print_projinfo(enum OutputFormat);
void print_datuminfo(void);
void print_proj4(int);
void print_proj4(int, enum OutputFormat);

#ifdef HAVE_OGR
void print_wkt(int, int);
void print_wkt(int, int, enum OutputFormat);
#endif

/* datumtrans.c */
Expand Down
27 changes: 23 additions & 4 deletions general/g.proj/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct Cell_head cellhd;

int main(int argc, char *argv[])
{
enum OutputFormat outputFormat;
/* TODO: replace most of these flags with an option to select the
* output format */
struct Flag *printinfo, /* Print contents of PROJ_INFO & PROJ_UNITS */
Expand All @@ -53,7 +54,8 @@ int main(int argc, char *argv[])
#endif
*listcodes, /* list codes of given authority */
*datum, /* datum to add (or replace existing datum) */
*dtrans; /* index to datum transform option */
*dtrans, /* index to datum transform option */
*format; /* output format */
struct GModule *module;

int formats;
Expand Down Expand Up @@ -223,9 +225,26 @@ int main(int argc, char *argv[])
location->guisection = _("Create");
location->description = _("Name of new project (location) to create");

format = G_define_standard_option(G_OPT_F_FORMAT);
format->options = "plain,shell,json";
format->descriptions = _("plain;Human readable text output;"
"shell;shell script style text output;"
"json;JSON (JavaScript Object Notation);");
format->guisection = _("Print");

if (G_parser(argc, argv))
exit(EXIT_FAILURE);

if (strcmp(format->answer, "json") == 0) {
outputFormat = JSON;
}
else if ((strcmp(format->answer, "shell") == 0) || shellinfo->answer) {
outputFormat = SHELL;
}
else {
outputFormat = PLAIN;
}

/* Initialisation & Validation */

/* list codes for given authority */
Expand Down Expand Up @@ -326,14 +345,14 @@ int main(int argc, char *argv[])
#endif
}
if (printinfo->answer || shellinfo->answer)
print_projinfo(shellinfo->answer);
print_projinfo(outputFormat);
else if (datuminfo->answer)
print_datuminfo();
else if (printproj4->answer)
print_proj4(dontprettify->answer);
print_proj4(dontprettify->answer, outputFormat);
#ifdef HAVE_OGR
else if (printwkt->answer)
print_wkt(esristyle->answer, dontprettify->answer);
print_wkt(esristyle->answer, dontprettify->answer, outputFormat);
#endif
else if (location->answer)
create_location(location->answer);
Expand Down
146 changes: 115 additions & 31 deletions general/g.proj/output.c
echoix marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -21,64 +21,99 @@
#include <grass/gprojects.h>
#include <grass/glocale.h>
#include <grass/config.h>
#include <grass/parson.h>

#ifdef HAVE_OGR
#include <cpl_csv.h>
#endif

#include "local_proto.h"

static int check_xy(int shell);
static int check_xy(enum OutputFormat);
static void print_json(JSON_Value *);

/* print projection information gathered from one of the possible inputs
* in GRASS format */
void print_projinfo(int shell)
void print_projinfo(enum OutputFormat format)
{
int i;
JSON_Value *value;
JSON_Object *object;

if (check_xy(shell))
if (check_xy(format))
return;

if (!shell)
if (format == PLAIN)
fprintf(
stdout,
"-PROJ_INFO-------------------------------------------------\n");

if (format == JSON) {
value = json_value_init_object();
object = json_object(value);
}

for (i = 0; i < projinfo->nitems; i++) {
if (strcmp(projinfo->key[i], "init") == 0)
continue;
if (shell)
switch (format) {
case PLAIN:
fprintf(stdout, "%s=%s\n", projinfo->key[i], projinfo->value[i]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fprintf(stdout, "%s=%s\n", projinfo->key[i], projinfo->value[i]);
fprintf(stdout, "%-11s: %s\n", projinfo->key[i],
projinfo->value[i]);

else
break;
case SHELL:
fprintf(stdout, "%-11s: %s\n", projinfo->key[i],
projinfo->value[i]);
Comment on lines 64 to 65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fprintf(stdout, "%-11s: %s\n", projinfo->key[i],
projinfo->value[i]);
fprintf(stdout, "%s=%s\n", projinfo->key[i], projinfo->value[i]);

break;
case JSON:
json_object_set_string(object, projinfo->key[i],
projinfo->value[i]);
break;
}
}

/* TODO: use projsrid instead */
if (projsrid) {

if (!shell) {
switch (format) {
case PLAIN:
fprintf(stdout, "-PROJ_SRID----------------------------------------"
"---------\n");
fprintf(stdout, "%-11s: %s\n", "SRID", projsrid);
}
else
break;
case SHELL:
fprintf(stdout, "%s=%s\n", "srid", projsrid);
break;
case JSON:
json_object_set_string(object, "srid", projsrid);
break;
}
}

if (projunits) {
if (!shell)
if (format == PLAIN)
fprintf(stdout, "-PROJ_UNITS---------------------------------------"
"---------\n");
for (i = 0; i < projunits->nitems; i++) {
if (shell)
fprintf(stdout, "%s=%s\n", projunits->key[i],
projunits->value[i]);
else
switch (format) {
case PLAIN:
fprintf(stdout, "%-11s: %s\n", projunits->key[i],
projunits->value[i]);
break;
case SHELL:
fprintf(stdout, "%s=%s\n", projunits->key[i],
projunits->value[i]);
break;
case JSON:
json_object_set_string(object, projunits->key[i],
echoix marked this conversation as resolved.
Show resolved Hide resolved
projunits->value[i]);
break;
}
}
}

if (format == JSON) {
print_json(value);
}

return;
}

Expand Down Expand Up @@ -130,13 +165,16 @@ void print_datuminfo(void)
}

/* print input projection information in PROJ format */
void print_proj4(int dontprettify)
void print_proj4(int dontprettify, enum OutputFormat format)
{
struct pj_info pjinfo;
char *i, *projstrmod;
const char *projstr;
const char *unfact;

JSON_Value *value;
JSON_Object *object;

if (check_xy(FALSE))
return;

Expand Down Expand Up @@ -187,25 +225,38 @@ void print_proj4(int dontprettify)
if (!projstrmod)
projstrmod = G_store(projstr);

for (i = projstrmod; *i; i++) {
/* Don't print the first space */
if (i == projstrmod && *i == ' ')
continue;

if (*i == ' ' && *(i + 1) == '+' && !(dontprettify))
fputc('\n', stdout);
else
fputc(*i, stdout);
switch (format) {
case JSON:
value = json_value_init_object();
object = json_object(value);
json_object_set_string(object, "proj4", projstrmod);
print_json(value);
break;
default:
for (i = projstrmod; *i; i++) {
/* Don't print the first space */
if (i == projstrmod && *i == ' ')
continue;

if (*i == ' ' && *(i + 1) == '+' && !(dontprettify))
fputc('\n', stdout);
else
fputc(*i, stdout);
}
fputc('\n', stdout);
break;
}
fputc('\n', stdout);

G_free(projstrmod);

return;
}

#ifdef HAVE_OGR
void print_wkt(int esristyle, int dontprettify)
void print_wkt(int esristyle, int dontprettify, enum OutputFormat format)
{
JSON_Value *value;
JSON_Object *object;
char *outwkt;

if (check_xy(FALSE))
Expand Down Expand Up @@ -277,7 +328,17 @@ void print_wkt(int esristyle, int dontprettify)
#endif

if (outwkt != NULL) {
fprintf(stdout, "%s\n", outwkt);
switch (format) {
case JSON:
value = json_value_init_object();
object = json_object(value);
json_object_set_string(object, "wkt", outwkt);
print_json(value);
break;
default:
fprintf(stdout, "%s\n", outwkt);
break;
}
CPLFree(outwkt);
}
else
Expand All @@ -287,15 +348,38 @@ void print_wkt(int esristyle, int dontprettify)
}
#endif

static int check_xy(int shell)
static int check_xy(enum OutputFormat format)
{
JSON_Value *value;
JSON_Object *object;
if (cellhd.proj == PROJECTION_XY) {
if (shell)
switch (format) {
case SHELL:
fprintf(stdout, "name=xy_location_unprojected\n");
else
break;
case PLAIN:
fprintf(stdout, "XY location (unprojected)\n");
break;
case JSON:
value = json_value_init_object();
object = json_object(value);
json_object_set_string(object, "name", "xy_location_unprojected");
print_json(value);
break;
}
return 1;
}
else
return 0;
}

void print_json(JSON_Value *value)
{
char *serialized_string = json_serialize_to_string_pretty(value);
if (serialized_string == NULL) {
G_fatal_error(_("Failed to initialize pretty JSON string."));
}
puts(serialized_string);
json_free_serialized_string(serialized_string);
json_value_free(value);
}
Loading