Skip to content

Commit

Permalink
v.distance: add JSON support (#3942)
Browse files Browse the repository at this point in the history
* v.distance: add json support

* add test and documentation

* Update test_v_distance.py
  • Loading branch information
kritibirda26 authored Jan 23, 2025
1 parent a31769d commit 3a8bce8
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 78 deletions.
2 changes: 1 addition & 1 deletion vector/v.distance/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MODULE_TOPDIR = ../..

PGM=v.distance

LIBES = $(VECTORLIB) $(DBMILIB) $(GISLIB) $(MATHLIB)
LIBES = $(VECTORLIB) $(DBMILIB) $(GISLIB) $(MATHLIB) $(PARSONLIB)
DEPENDENCIES = $(VECTORDEP) $(DBMIDEP) $(GISDEP)

EXTRA_INC = $(VECT_INC)
Expand Down
6 changes: 5 additions & 1 deletion vector/v.distance/local_proto.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <grass/vector.h>
#include <grass/dbmi.h>
#include <grass/parson.h>

#ifndef _LOCAL_PROTO_
#define _LOCAL_PROTO_
Expand All @@ -23,6 +24,8 @@
#define TO_ATTR 10 /* attribute of nearest feature */
#define END 11 /* end of list */

enum OutputFormat { PLAIN, JSON };

/* Structure to store info about nearest feature for each category */
typedef struct {
int from_cat; /* category (from) */
Expand Down Expand Up @@ -66,6 +69,7 @@ int line2area(struct Map_info *To, struct line_pnts *Points, int type, int area,
int with_z);

/* print.c */
int print_upload(NEAR *, UPLOAD *, int, dbCatValArray *, dbCatVal *, char *);
int print_upload(NEAR *, UPLOAD *, int, dbCatValArray *, dbCatVal *, char *,
enum OutputFormat, JSON_Object *);

#endif
95 changes: 70 additions & 25 deletions vector/v.distance/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <grass/gis.h>
#include <grass/glocale.h>
#include <grass/vector.h>
#include <grass/parson.h>
#include "local_proto.h"

/* Supported command lines:
Expand Down Expand Up @@ -69,6 +70,7 @@ int main(int argc, char *argv[])
struct Option *out, *max, *min, *table;
struct Option *upload, *column, *to_column;
struct Option *sep;
struct Option *format;
} opt;
struct {
struct Flag *print, *all, *square;
Expand Down Expand Up @@ -112,6 +114,10 @@ int main(int argc, char *argv[])
dbCatValArray cvarr;
dbColumn *column;
char *sep;
enum OutputFormat format;
JSON_Value *root_value, *object_value;
JSON_Array *root_array;
JSON_Object *root_object;

G_gisinit(argv[0]);

Expand Down Expand Up @@ -237,6 +243,9 @@ int main(int argc, char *argv[])
opt.sep = G_define_standard_option(G_OPT_F_SEP);
opt.sep->label = _("Field separator for printing output to stdout");

opt.format = G_define_standard_option(G_OPT_F_FORMAT);
opt.format->guisection = _("Print");

flag.print = G_define_flag();
flag.print->key = 'p';
flag.print->label =
Expand Down Expand Up @@ -293,6 +302,15 @@ int main(int argc, char *argv[])
do_all = flag.all->answer;
print_as_matrix = flag.square->answer;

if (strcmp(opt.format->answer, "json") == 0) {
format = JSON;
root_value = json_value_init_array();
root_array = json_array(root_value);
}
else {
format = PLAIN;
}

if (do_all && update_table)
G_fatal_error(_("Updating the from= table is not supported with -a"));

Expand Down Expand Up @@ -1397,7 +1415,7 @@ int main(int argc, char *argv[])
update_notfound = ncatexist = 0;

/* Update database / print to stdout / create output map */
if (print) { /* print header */
if (print && format == PLAIN) { /* print header */
fprintf(stdout, "from_cat");
if (do_all)
fprintf(stdout, "%sto_cat", sep);
Expand Down Expand Up @@ -1504,35 +1522,51 @@ int main(int argc, char *argv[])
}

if (print) { /* print only */
/*
input and output is the same &&
calculate distances &&
only one upload option given ->
print as a matrix
*/
if (print_as_matrix) {
if (i == 0) {
for (j = 0; j < nfrom; j++) {
if (j == 0)
fprintf(stdout, " ");
fprintf(stdout, "%s%d", sep, Near[j].to_cat);
switch (format) {
case PLAIN:
/*
input and output is the same &&
calculate distances &&
only one upload option given ->
print as a matrix
*/
if (print_as_matrix) {
if (i == 0) {
for (j = 0; j < nfrom; j++) {
if (j == 0)
fprintf(stdout, " ");
fprintf(stdout, "%s%d", sep, Near[j].to_cat);
}
fprintf(stdout, "\n");
}
if (i % nfrom == 0) {
fprintf(stdout, "%d", Near[i].from_cat);
for (j = 0; j < nfrom; j++) {
print_upload(Near, Upload, i + j, &cvarr, catval,
sep, format, NULL);
}
fprintf(stdout, "\n");
}
fprintf(stdout, "\n");
}
if (i % nfrom == 0) {
else {
fprintf(stdout, "%d", Near[i].from_cat);
for (j = 0; j < nfrom; j++) {
print_upload(Near, Upload, i + j, &cvarr, catval, sep);
}
if (do_all)
fprintf(stdout, "%s%d", sep, Near[i].to_cat);
print_upload(Near, Upload, i, &cvarr, catval, sep, format,
NULL);
fprintf(stdout, "\n");
}
}
else {
fprintf(stdout, "%d", Near[i].from_cat);
if (do_all)
fprintf(stdout, "%s%d", sep, Near[i].to_cat);
print_upload(Near, Upload, i, &cvarr, catval, sep);
fprintf(stdout, "\n");
break;
case JSON:
object_value = json_value_init_object();
root_object = json_object(object_value);
json_object_set_number(root_object, "from_cat",
Near[i].from_cat);
json_object_set_number(root_object, "to_cat", Near[i].to_cat);
print_upload(Near, Upload, i, &cvarr, catval, sep, format,
root_object);
json_array_append_value(root_array, object_value);
break;
}
}
else if (create_table) { /* insert new record */
Expand Down Expand Up @@ -1726,6 +1760,17 @@ int main(int argc, char *argv[])
}
}
}

if (format == JSON) {
char *serialized_string = json_serialize_to_string_pretty(root_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(root_value);
}

G_percent(count, count, 1);

if (driver)
Expand Down
Loading

0 comments on commit 3a8bce8

Please sign in to comment.