Final Report
Title: Add JSON output to different tools in C for GRASS
Organization : GRASS under OSGeo
Student Name: Nishant Bansal
Mentor Name: Anna Petrasova, Corey White, Vaclav Petras
Program: Google Summer of Code 2025
Abstract
During my GSoC project, I addressed the challenge that most GRASS tools produced only plain text output, forcing users to write custom parsing code for Python-based workflows. The task was to make these tools more data-science friendly by adding structured output formats. To achieve this, I extended the use of the Parson library to implement consistent JSON output across multiple modules, refined the JSON structure introduced in the previous GSoC, and added optional support for SHELL and CSV outputs where appropriate. I developed comprehensive Python test cases, ensured backward compatibility, and provided documentation with practical examples such as loading JSON into pandas.
The state of integration BEFORE the start of GSoC
Before the start of GSoC, the integration of GRASS with data science workflows was limited due to several challenges. The JSON outputs introduced in the previous GSoC contained nested hierarchies, making them difficult to use directly with libraries such as pandas or in data science workflows. While some tools already supported JSON (e.g., r.univar , r.info , v.distance , g.region , v.to.db , r.profile , v.what ), many important modules lacked JSON support, including r3.info , g.mapset , r.what.color , g.version , i.group , g.list , r.regression.line , r.stats.quantile , r.volume , m.measure and many more. Moreover, there was no clear documentation of the JSON schema or guidance on how to parse and utilize these outputs effectively in python or pandas , which made it difficult for users to understand the use cases and integrate GRASS outputs into data science workflows.
The state of integration AFTER GSoC
After GSoC, the integration state of JSON and alternative output formats in GRASS has significantly improved. I refactored the JSON structures for tools such as r.univar , r.info , v.distance , g.region , v.to.db , r.profile , v.what , and others, removing unnecessary nesting introduced during the previous GSoC. This makes their outputs much easier to consume directly in Python or with pandas . In addition, JSON support has been extended to many essential and frequently used modules, including r3.info , g.mapset , r.what.color , g.version , i.group , g.list , r.regression.line , r.stats.quantile , r.volume , m.measure , and many more. I also added detailed documentation of the JSON schema and provided examples showing how to parse and use these outputs effectively with Python and pandas.
Enhancements made per tool
r.univar: Simplified JSON structure for univariate statistics, removed unnecessary hierarchy, and added new output format options (CSV, shell).r.what.color: Added JSON support for querying raster map colors, with a Python parsing example.g.mapset: Added JSON support for reporting the current mapset, with a Python example.r.info: Updated JSON structure for raster map metadata, removing hierarchy for easier parsing. Additionally, added PLAIN and SHELL output formats for easier parsing and integration.g.region: Simplified JSON output for geographic region boundaries, with examples.g.version: Added JSON support for GRASS version information, with examples.i.group: Added JSON support for listing imagery groups, with examples.r.stats: Added JSON and CSV support for raster area statistics, with Python and CLI examples.v.distance: Refined JSON schema for nearest element queries, with pandas integration example.g.list: Added JSON support for listing GRASS database files, with Python example.v.to.db: Updated JSON schema for printing vector attribute values, with Python example.r.profile: Simplified JSON output, added CSV support, and included a matplotlib example for profile visualization.r.regression.line: Updated JSON schema for linear regression between rasters, with Python parsing example.r.stats.quantile: Updated JSON schema for category quantiles, with Python example.r.volume: Added JSON support for raster volume calculations, fixed missing headers in CSV output, and provided pandas examples.db.columns: Added JSON output for listing database table columns, with Python example.m.measure: Added JSON output for measuring lengths and areas, with Python example.db.connect: Added JSON output for DB connection info, with Python example.r.regression.multi: Added JSON output for multiple regression between rasters, with Python example.v.db.connect: Added JSON output for vector map attribute connections, with Python example.g.findfile: Added JSON output for GRASS database file search, with Python example.r3.info: Added JSON output for 3D raster map info, with Python example. Additionally, added PLAIN and SHELL output formats for easier parsing and integration.v.what.rast: Added JSON output for extracting raster values at vector points, with pandas integration example.r.distance: Added JSON and CSV support for locating closest points between raster objects, with pandas and CLI examples.v.class: Added JSON and CSV support for attribute data, with pandas and CLI examples.v.what: Migrated from manually written JSON to Parson-based JSON output, simplified schema, and provided Python parsing examples.
All these changes were accompanied by regression tests to ensure that new JSON/CSV/SHELL/PLAIN output options do not break existing functionality. Additionally, I introduced comprehensive Python test cases for these outputs, making the enhancements reliable and future-proof. During this work, I also fixed several bugs in modules such as r.stats, r3.info, v.what.rast, and v.class, strengthening the stability of GRASS as a whole.
Conclusion
To sum up, I’m glad to have met the three core objectives of my project with the constant support of my mentors:
- Brought JSON output to several important modules, added regression tests, and ensured reliable future test coverage.
- Enhanced the JSON schema introduced in last year’s GSoC by reducing unnecessary hierarchy, making it more consistent across tools, and providing Python/Pandas examples for practical use.
- Expanded CSV and SHELL output formats to additional tools where they could bring value.
This journey has been both rewarding and educational, and I’m grateful for the opportunity to contribute to GRASS through GSoC 2025. I especially want to thank Anna Petrasova and the GRASS Development Team for their guidance and support. I’m excited to keep building on this work and further extend JSON and other features in the future.
Future Work
There is significant scope to extend structured output support across GRASS tools. In particular, future efforts should focus on:
- Expanding JSON output to additional modules, with details tracked here: GRASS JSON Outputs Project.
- Refining and standardizing the JSON schema to better support complex workflows and integrations.
- Exploring and implementing other output formats (e.g., SHELL, CSV, PLAIN) where they can improve usability.
Log of Pull Requests
Below is a list of pull requests submitted to the GRASS repository during GSoC 2025:
| Pull Request | Description | Date | Status |
|---|---|---|---|
| #5688 | r.univar: Fix JSON structure | May 20, 2025 | Merged |
| #5773 | r.what.color: Add test file | May 25, 2025 | Merged |
| #5775 | g.mapset: Add test file | May 26, 2025 | Merged |
| #5784 | r.info: Add Python example | May 28, 2025 | Closed |
| #5785 | g.region: Add Python example | May 28, 2025 | Merged |
| #5810 | g.mapset: Add JSON support | June 2, 2025 | Merged |
| #5821 | r.univar: Fix uninitialized zone_value | June 3, 2025 | Merged |
| #5822 | r.what.color: Add JSON support | June 3, 2025 | Merged |
| #5842 | r.info: Update test file | June 5, 2025 | Merged |
| #5859 | r.info: Improve interface | June 7, 2025 | Merged |
| #5863 | g.version: Add JSON support | June 9, 2025 | Merged |
| #5870 | i.group: Add JSON support | June 10, 2025 | Merged |
| #5879 | r.stats: Add test file | June 12, 2025 | Merged |
| #5892 | r.stats: Add tests for JSON output | June 14, 2025 | Merged |
| #5898 | v.distance: Update JSON format | June 16, 2025 | Merged |
| #5900 | r.stats: fix uninitialised window value | June 17, 2025 | Merged |
| #5906 | g.list: Add test file | June 17, 2025 | Merged |
| #5921 | g.list: Add JSON support | June 20, 2025 | Merged |
| #5929 | g.region: Update JSON format | June 21, 2025 | Merged |
| #5946 | v.to.db: Update JSON format | June 23, 2025 | Merged |
| #5962 | r.profile: Update JSON format | June 25, 2025 | Merged |
| #5966 | r.univar: Add shell and CSV format | June 25, 2025 | Merged |
| #5990 | r.regression.line: Add test file | June 30, 2025 | Merged |
| #5993 | r.regression.line: Add JSON support | June 30, 2025 | Merged |
| #6002 | r.stats.quantile: Add test file | July 1, 2025 | Merged |
| #6007 | r.stats.quantile: Add JSON support | July 1, 2025 | Merged |
| #6027 | r.volume: Add test file | July 4, 2025 | Merged |
| #6036 | r.volume: Add JSON support | July 6, 2025 | Merged |
| #6042 | db.columns: Add JSON support | July 7, 2025 | Merged |
| #6051 | m.measure: Add test file | July 10, 2025 | Merged |
| #6052 | db.connect: Add test file | July 10, 2025 | Merged |
| #6053 | m.measure: Add JSON support | July 11, 2025 | Merged |
| #6059 | db.connect: Add JSON support | July 12, 2025 | Merged |
| #6066 | r.regression.multi: Add test file | July 15, 2025 | Merged |
| #6067 | v.db.connect: Add test file | July 15, 2025 | Merged |
| #6075 | r.regression.multi: Add JSON support | July 18, 2025 | Merged |
| #6077 | v.db.connect: Add JSON support | July 19, 2025 | Merged |
| #6091 | g.findfile: Add JSON support | July 21, 2025 | Merged |
| #6098 | r3.info: Add test file | July 22, 2025 | Merged |
| #6103 | r3.info: Add JSON support | July 23, 2025 | Merged |
| #6109 | v.what.rast: Add test file | July 24, 2025 | Merged |
| #6132 | v.category: Use CSV format instead of shell format | July 28, 2025 | Merged |
| #6133 | r.stats: add CSV support | July 28, 2025 | Merged |
| #6134 | r.volume: add csv column headers | July 28, 2025 | Merged |
| #6140 | v.what.rast: Add JSON support | July 29, 2025 | Merged |
| #6145 | r.profile: Add CSV support | July 30, 2025 | Merged |
| #6150 | r.distance: Update existing test cases | August 1, 2025 | Merged |
| #6204 | r.distance: Add JSON and CSV support | August 12, 2025 | Merged |
| #6205 | v.class: Add more test cases and fix out-of-bounds bug | August 12, 2025 | Merged |
| #6210 | v.class: Add JSON and CSV support | August 15, 2025 | Merged |
| #6252 | v.what: Update JSON output format | August 23, 2025 | Open |
Additional Links
| Ttile | Link |
|---|---|
| Project Wiki Page | Add JSON output to different tools in C for GRASS |
| Public Repository | GitHub Fork |
| Personal Wiki Page | Link |
| Contributions | Pull Requests |
– Nishant Bansal