Add vector data analysis tutorial#136
Conversation
New beginner/intermediate tutorial covering the core vector toolkit: - exploring features and attributes (v.info, v.db.select) - selecting by attribute (v.extract) and by location (v.select) - buffering (v.buffer) and overlaying (v.overlay) layers - counting features per area (v.vect.stats) for a thematic map Worked example uses the North Carolina schools, roads, and ZIP codes, and the grass.tools API (GRASS 8.5). Categories: vector, beginner, intermediate, Python.
veroandreo
left a comment
There was a problem hiding this comment.
The content is ok for an intro tutorial on basic vector operations. All images need to be fixed, though. Black background does not look nice and they are too big. See other suggestions below.
| - **select by attribute** with [v.extract](https://grass.osgeo.org/grass-stable/manuals/v.extract.html), | ||
| - **buffer** features with [v.buffer](https://grass.osgeo.org/grass-stable/manuals/v.buffer.html), | ||
| - **select by location** with [v.select](https://grass.osgeo.org/grass-stable/manuals/v.select.html), | ||
| - combine layers with [v.overlay](https://grass.osgeo.org/grass-stable/manuals/v.overlay.html), and |
There was a problem hiding this comment.
v.overlay combines when we do the union; I would say "perform spatial operations with v.overlay", instead
| - combine layers with [v.overlay](https://grass.osgeo.org/grass-stable/manuals/v.overlay.html), and | ||
| - count features per area with [v.vect.stats](https://grass.osgeo.org/grass-stable/manuals/v.vect.stats.html). | ||
|
|
||
|  |
There was a problem hiding this comment.
I'd remove this image from here as it is generated below.
| ``` | ||
|
|
||
| ```{python} | ||
| attr_map = gj.Map(width=800) |
There was a problem hiding this comment.
Same comment as above regarding images. Also, consider enhancing the scale bar or placing it differently, so it does not overlap the map features.
| area maps with set operations. With `operator=and` we get the **intersection** — the | ||
| part of the road corridor that falls within each ZIP code area. The output keeps the | ||
| attributes of both inputs, so you could, for example, measure how much of each ZIP | ||
| code is within reach of a major road. |
There was a problem hiding this comment.
Would be nice to actually show how to estimate how much area of each ZIP is within reach of a major road.
| A common summary is "how many points fall in each area?" | ||
| [v.vect.stats](https://grass.osgeo.org/grass-stable/manuals/v.vect.stats.html) counts | ||
| the points of one map within the areas of another and writes the result to the area | ||
| map's attribute table. We first copy the ZIP codes with |
There was a problem hiding this comment.
| map's attribute table. We first copy the ZIP codes with | |
| map's attribute table. We first create a copy of the ZIP codes map with |
| - **buffering** (`v.buffer`) and **overlaying** (`v.overlay`) layers, and | ||
| - **counting** points per area (`v.vect.stats`) for a thematic map. | ||
|
|
||
| These operations combine into most vector workflows. To turn results like the |
There was a problem hiding this comment.
| These operations combine into most vector workflows. To turn results like the | |
| The operations described here are common in most vector workflows. To turn results like the |
| [Making Thematic Maps](../thematic_maps/thematic_maps.qmd). To bring raster terrain | ||
| into the analysis, see | ||
| [Visualizing and Modeling Terrain from DEMs in GRASS](../terrain_and_DEMs/GRASS_terrain.qmd). |
There was a problem hiding this comment.
| [Making Thematic Maps](../thematic_maps/thematic_maps.qmd). To bring raster terrain | |
| into the analysis, see | |
| [Visualizing and Modeling Terrain from DEMs in GRASS](../terrain_and_DEMs/GRASS_terrain.qmd). |
As there's no specific suggestion on how to connect this tutorial with the terrain one, I suggest to remove the sentence about raster terrain.
- regenerate figures with white background, smaller size (width 500), and a legible scale bar (white background box) - retitle to "Basic Vector Data Analysis with GRASS" - show the attribute table (v.db.select JSON -> pandas) before selecting on GLEVEL, so the selection is motivated - add an area-within-reach computation (v.to.db + grouped db.select) to the overlay section - reword the v.overlay intro bullet; move the GRASS-version callout below the setup code to avoid stacked callouts - fix the get-started link to the Python quick start - drop the unmotivated terrain cross-link; minor wording fixes
|
Thanks for the thorough review, @veroandreo! I've pushed an update addressing all of it:
Let me know if you'd like any further changes! |
veroandreo
left a comment
There was a problem hiding this comment.
Thanks @Valyrian-Code! Looks much better now, I left some other minor suggestions here and there.
Co-authored-by: Veronica Andreo <veroandreo@gmail.com>
Co-authored-by: Veronica Andreo <veroandreo@gmail.com>
Co-authored-by: Veronica Andreo <veroandreo@gmail.com>
Co-authored-by: Veronica Andreo <veroandreo@gmail.com>
Co-authored-by: Veronica Andreo <veroandreo@gmail.com>
Co-authored-by: Veronica Andreo <veroandreo@gmail.com>
Add the two table outputs the review asked for: the schools attribute table (pandas from v.db.select JSON) and the reach-per-ZIP result (db.select also returns JSON, so the same pandas pattern is reused).
|
Thanks @veroandreo! Pushed the follow-ups:
Ready for another look when you have a moment. |
| records = json.loads( | ||
| tools.v_db_select( | ||
| map="schools_wake", | ||
| columns="NAMESHORT,GLEVEL,ADDRCITY,CORECAPACI", | ||
| format="json", | ||
| ).stdout | ||
| )["records"] |
There was a problem hiding this comment.
pd.DataFrame(tools.v_db_select(...)["records"]).head()
- pass the full path as a single string to gj.init - use .text instead of .stdout for printed output - read JSON results by subscripting the ToolResult directly (tools.v_db_select(...)["records"]) instead of json.loads(...stdout) - move the scale bar to the bottom-right in every figure so it no longer overlays the map
|
Thanks @petrasovaa! Applied the same cleanups here:
I also mirrored the Tools-API changes in the viewshed PR (#135). |
Co-authored-by: Anna Petrasova <kratochanna@gmail.com>
Adds a new beginner/intermediate tutorial on vector data analysis — the tutorial
set currently has no dedicated vector-focused tutorial, so this fills that gap and
covers the operations users reach for most often.
What it covers
Using the North Carolina
schools_wake(points),roadsmajor(lines), andzipcodes_wake(areas), it works through a single "school accessibility" example:v.info,v.db.selectv.extract(the 95 elementary schools)v.buffer(a 500 m road corridor)v.select(the 15 elementary schools within the corridor)v.overlay(road corridor intersected with ZIP areas)v.vect.stats+ ad.vect.thematicchoropleth of schools per ZIPDetails
eval: false).vector,beginner,intermediate,Python.Feedback on scope, the choice of example, or wording is very welcome.