I performed a little network analysis with ArcGIS on the Schools in Enschede. Given a shapefile with roads and the school points I obtained the service areas at 1km and 2km from the schools. Can I obtain the same with GRASS?
For those who never heard of GRASS (If you know, you can skip to the fun part).
GRASS is an impressive GIS package with a lot of functionalities. It is designed as an environment where different tools execute GIS computations.
By default all the tools can be executed directly from GRASS command line:
tool op1=val1 op2=val2
or by a GUI:
tool will launch the graphical interface
In this post I always use the command line tool with all the needed options set, but you can perform the same using the GUI.
To import the data:
v.in.ogr -o dsn=NWB_Enschede.shp output=roads
v.in.ogr -o dsn=Schools_corrected.shp output=schools
Notice the -o flag. This is needed because the projection description did not match exactly, nevertheless it was the same. When GRASS finds mismatching projection it shows the PROJ_INFO of both projections (file and project), a little comparison was enough to determine that the projection was apparently the same, so in this case it’s safe to override the check.
While inspecting the data I encountered the first “surprise”. In ArcGIS the road layer has an attribute called “Shape Length” that I use for the network analysis. In this case, there’s no such attribute (automagic by ArcGIS). In GRASS I need to add and populate a LENGTH attribute.
Add a new attribute of type Double:
v.db.addcol map=roads columns=LENGTH Double
Populate the attribute with the length of the road:
v.to.db map=roads option=length units=meters columns=LENGTH
Creating the Network
Everything needed is under
First connect the school points to the road network (this adds new lines):
v.net input=roads points=schools output=network operation=connect thresh=500
GRASS created lines to fully connect the schools to the road network. The schools and roads are joined in a layer called network:
v.category network op=report
Layer/table: 1/network type count min max point 0 0 0 line 7132 1 7004 boundary 0 0 0 centroid 0 0 0 area 0 0 0 all 7132 1 7004 Layer: 2 type count min max point 64 1 64 line 0 0 0 boundary 0 0 0 centroid 0 0 0 area 0 0 0 all 64 1 64
On this result, and with a little bit of inspection, is easy to realize that layer 2 is not assigned to any database (with various information of the schools). But this information is already on our workspace so I’ll connect it. Connecting the layer to the information can be useful in the future.
v.db.connect map=network table=schools layer=2
Now we have the network prepared, let’s get the party started. The network utilities provided by GRASS are:
- Network Maintenance (v.net)
- Allocate Subnets (v.net.alloc)
- Split net (v.net.iso)
- Shortest Path (v.net.path)
- Visibility Network (v.net.visibility)
- Steiner Tree (v.net.steiner)
- Traveling salesman analysis (v.net.salesman)
For this case I’m only interested in
The first one creates sub networks according to nearest centre. The second one can split the network in various distances.
First, let’s see how to allocate the network:
v.net.alloc --overwrite --verbose input=network output=network_alloc ccats=1-63
ouptut are self explanatory. The
ccats sets which schools are used in the allocation, the range 1-63 contains all the schools.
v.category again grass shows the different categories on the newly created layer.
The result looks boring in the map view. That’s because there is no color assigned to each class:
d.vect -c map=network_alloc
-c stands for “
ramdomize randomize colors”.
Now I can see that the allocation worked, the different allocated zones have different colors.
>>Split net by cost
I’m interested to see who is more lucky. And in this situation I define luckiness as a function of closeness to school.
- Less than 1km: You are very lucky! Sleeep!
- 1km~2km: Not the best, not the worst
- 2km~3km: Not the worst, not the best
- More than 3km: I’m sorry, wake up at 6
v.net.iso module with 1000m,2000m and 3000m thresholds:
v.net.iso --overwrite input=network output=network_isolines ccats=1-64 costs=1000,2000,3000 afcolumn=LENGTH abcolumn=LENGTH
ccats (again) represents the schools to use in the analysis.
costs is the isolines to separate (1km,2km,3km).
abcolumn is the dataset column for forward and backward cost.
But this is a general view, I want to know my exact situation. I’m only interested in my school:
v.net.iso --overwrite input=network output=network_isolines_specific ccats=5 costs=1000,2000,3000 afcolumn=LENGTH abcolumn=LENGTH
d.vect -c map=network_isolines_specific
d.vect map=schools type=point where=cat=5 fcolor=9:157:9 icon=basic/circle size=10
First, specific analysis. Second, colorize the network. Third, show only the specific school on the map.
I know I know. Green usually means better, but in this case means less lucky!. That’s the result of the random colors.
I can obtain the same basic result in ArcGIS and GRASS.
It’s just a basic example, in other exercises with ArcGIS I performed a Location-Allocation analysis with Demand points and Facilities to properly decide which new facilities are more suitable, I’m not really sure if that can be done directly with GRASS, but I’m planning to check it out 🙂