Skip to content

v.net: Add JSON output support for nodes operation#6999

Open
tangelll wants to merge 10 commits intoOSGeo:mainfrom
tangelll:main
Open

v.net: Add JSON output support for nodes operation#6999
tangelll wants to merge 10 commits intoOSGeo:mainfrom
tangelll:main

Conversation

@tangelll
Copy link

@tangelll tangelll commented Jan 30, 2026

Description

This PR introduces JSON output support for the v.net module, specifically for the operation=nodes task. This enhancement allows users to programmatically capture network statistics (such as new node counts) for use in automated workflows and testing pipelines.

Changes

  • Core Logic: Integrated G_JSON support in main.c to handle structured output.
  • CLI Arguments: Added a new format parameter to choose between plain (default) and json.
  • Documentation: Updated v.net.md with usage examples and guidelines for JSON output.
  • Testing: Added an automated Python test case in testsuite/test_v_net.py to ensure output consistency.

How to Test

To verify the implementation, you can use the North Carolina sample dataset.

  1. Manual Verification:
# Copy sample data
g.copy vector=streets_wake,my_streets

# Run the module with JSON format for nreport
testsuite % v.net input=my_streets_ready operation=nreport nlayer=2 format=json

#Run the module with JSON format for report
v.net input=streets output=test_vnet operation=report  format=json 

Expected JSON Output :

[
{
"line_cat": 49599,
"start_node_cat": -1,
"end_node_cat": -1
},
...
]

  1. Automated Test Suite: Run the newly added test case:
python3 vector/v.net/testsuite/test_v_net.py

Copying features...
100%
Building topology for vector map test_vnet@PERMANENT...
Registering primitives...
40000
Copying attributes...
Building topology for vector map test_vnet@PERMANENT...
Registering primitives...
50000
v.net complete. 323 lines (network arcs) written to output.

.
Copying features...
100%
Building topology for vector map test_vnet@PERMANENT...
Registering primitives...
40000
Copying attributes...
Building topology for vector map test_vnet@PERMANENT...
Registering primitives...
50000
v.net complete. 156 lines (network arcs) written to output.

.
Copying attributes...
Building topology for vector map test_vnet@PERMANENT...
Registering primitives...
90000
v.net complete. 41813 new points (nodes) written to output.

.v.net complete.
.v.net complete.
.OK

@github-actions github-actions bot added vector Related to vector data processing Python Related code is in Python C Related code is in C module docs markdown Related to markdown, markdown files tests Related to Test Suite labels Jan 30, 2026
opt->tucfield->required = NO;
opt->tucfield->guisection = _("Turntable");

opt->format = G_define_option();
Copy link
Contributor

Choose a reason for hiding this comment

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

Use G_OPT_F_FORMAT standard option.

G_message(_("Copying attributes..."));
if (Vect_copy_tables(In, Out, 0))
if (root_object) {
G_json_object_set_string(root_object, "current_step",
Copy link
Contributor

Choose a reason for hiding this comment

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

These are messages that go to stderr, they are not expected to be in output JSON.

Copy link
Contributor

@petrasovaa petrasovaa left a comment

Choose a reason for hiding this comment

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

To simplify review, could you please post the examples and the output as it was and with the changes you made? Edit the PR description.

@tangelll
Copy link
Author

To simplify review, could you please post the examples and the output as it was and with the changes you made? Edit the PR description.

I’ve updated the PR and reverted the changes in the man folder. Please note that some minor formatting was automatically adjusted by my local pre-commit hooks.

Copy link
Contributor

@petrasovaa petrasovaa left a comment

Choose a reason for hiding this comment

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

Thank you, several things to address:

Please fix the problems in compilation:

main.c: In function ‘main’:
main.c:62:5: warning: ‘output_format’ may be used uninitialized [-Wmaybe-uninitialized]
   62 |     parse_arguments(&opt, &afield, &nfield, &thresh, &act, output_format);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:30:33: note: ‘output_format’ was declared here
   30 |     enum { PLAIN, SHELL, JSON } output_format;
      |                                 ^~~~~~~~~~~~~

Remove the reporting of new nodes, keep the json output for operation=report and nreport only.

Drop the shell format, instead you can add CSV.

Remove any unrelated changes (e.g. you removed several empty lines).

The test misses the report/nreport case.

Thank you!

Comment on lines 124 to 130
opt->format = G_define_standard_option(G_OPT_F_FORMAT);
opt->format->key = "format";
opt->format->type = TYPE_STRING;
opt->format->required = NO;
opt->format->options = "plain,shell,json";
opt->format->answer = "plain";
opt->format->description = _("Output");
Copy link
Contributor

Choose a reason for hiding this comment

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

These are already part of the standard option definition.

Suggested change
opt->format = G_define_standard_option(G_OPT_F_FORMAT);
opt->format->key = "format";
opt->format->type = TYPE_STRING;
opt->format->required = NO;
opt->format->options = "plain,shell,json";
opt->format->answer = "plain";
opt->format->description = _("Output");
opt->format = G_define_standard_option(G_OPT_F_FORMAT);
opt->format->required = NO;
opt->format->options = "plain,shell,json";
opt->format->answer = "plain";
opt->format->description = _("Output");

…porting from stdout. Cleaned up redundant code and added validation tests.
}
fprintf(stdout, "\n");
if (root_arr) {
G_json_object_set_value(G_json_value_get_object(item_val), "lines", lines_val); G_json_array_append_value(root_arr, item_val);
Copy link
Contributor

@petrasovaa petrasovaa Feb 6, 2026

Choose a reason for hiding this comment

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

Use pre-commit to automatically fix the formatting.

except json.JSONDecodeError:
self.fail(f"nreport produced invalid JSON: {output}")

self.assertIsInstance(data, list, "nreport output must be a JSON array")
Copy link
Contributor

Choose a reason for hiding this comment

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

The tests should be more specific that just verifying type of output data.

Generating nodes and getting the result in JSON:

```sh
v.net input=streets operation=nodes format=json -c
Copy link
Contributor

Choose a reason for hiding this comment

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

The example should also show the example output.

def test_nreport_json(self):
"""Test nreport operation JSON output"""
self.runModule("v.net", input="streets", output=self.network, operation="nodes")
output = read_command(
Copy link
Contributor

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C Related code is in C docs markdown Related to markdown, markdown files module Python Related code is in Python tests Related to Test Suite vector Related to vector data processing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants