Example scripts from Chapter 6
Open Source GIS: A GRASS GIS Approach
  Markus Neteler, Helena Mitasova
  3. Edition 2007, 426 pages
  Springer, New York
  ISBN-10: 038735767X | ISBN-13: 978-0-387-35767-6 | e-ISBN-13: 978-0-387-68574-8
SQL support in GRASS 6
g.region vect=schools_wake -p
 d.erase
# show all schools in Wake County
 d.vect schools_wake col=red icon=basic/circle siz=5
# show a subset of all elementary schools in Raleigh
 d.vect schools_wake where=”ADDRCITY=’Raleigh’ and GLEVEL=’E'”
DBF driver
# define MAPSET DB connection as DBF (which is the default)
 # use single quotes to avoid variable expansion in the shell
 db.connect driver=dbf \
 database=’$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/’
 # print current connection
 db.connect -p
# copy map from PERMANENT: converts (or keeps in) table to DBF
 g.copy vect=roadsmajor,myroadsmajor
 # show attribute connection
 v.db.connect -p myroadsmajor
# show the DBF tables that can be modified (in current MAPSET)
 db.tables -p
SQLite driver
# use single quotes to avoid variable expansion in the shell
 db.connect driver=sqlite \
 database=’$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite.db’
 db.connect -p
# copy map from PERMANENT, this converts table to SQLite
 g.copy vect=roadsmajor,myroadsmajor
 # show attribute connection
 v.db.connect -p myroadsmajor
# show SQLite tables that can be modified (in current MAPSET)
 db.tables -p
PostgreSQL driver
# create a new database “nc_usa” using PostgreSQL command
 createdb -h localhost nc_usa
# enter PostgreSQL to create a user (‘nc_usa=#’ is the prompt)
 psql -h localhost nc_usa
 nc_usa=# CREATE USER grassuser ENCRYPTED PASSWORD ‘my12sec!’;
 nc_usa=# \q
# define GRASS connection
 db.connect driver=pg database=”host=localhost,dbname=nc_usa”
 # db.login allows to enter the password from above
 db.login user=grassuser
 db.connect -p
# copy map from PERMANENT, this converts table to PostgreSQL
 g.copy vect=roadsmajor,myroadsmajor
 # show attribute connection
 v.db.connect -p myroadsmajor
# show user modifiable PostgreSQL tables (in current MAPSET)
 # (e.g. public.myroadsmajor)
 db.tables -p
MySQL driver
mysql -h localhost
 # create new database “nc_usa” within MySQL (‘mysql>’ is prompt)
 mysql> CREATE DATABASE nc_usa;
 mysql> CREATE USER ‘grassuser’@’localhost’;
 mysql> GRANT ALL PRIVILEGES ON *.* TO ‘grassuser’@’localhost’;
 mysql> SET PASSWORD FOR ‘grassuser’@’localhost’ =
 PASSWORD(‘my12sec!’);
 mysql> quit;
# define GRASS connection
 db.connect driver=mysql database=”host=localhost,dbname=nc_usa”
 # db.login allows to enter the password
 db.login user=grassuser
 db.connect -p
# copy map from PERMANENT, this converts table to MySQL
 g.copy vect=roadsmajor,myroadsmajor
 # show attribute connection
 v.db.connect -p myroadsmajor
# show available MySQL tables
 db.tables -p
unixODBC driver
# define GRASS connection
 db.connect driver=odbc database=myodbcdsn
 # db.login allows to enter the password
 db.login user=myname
 db.connect -p
# copy map from PERMANENT, this converts table to ODBC DBMS
 g.copy vect=roadsmajor,myroadsmajor
 # show attribute connection
 v.db.connect -p myroadsmajor
 # show available ODBC linked tables
 db.tables -p
Converting CSV files and spreadsheet tables to SQL
# convert CSV table into SQLite format and add as table in
 # sqlite.db (adapt path to your settings, input file needs
 # ‘.csv’ extension)
 ogr2ogr -update -f SQLite \
 $HOME/grassdata/nc_spm/sqlite/sqlite.db wake_soil_groups.csv
# or simply
 db.in.ogr wake_soil_groups.csv out=wake_soil_groups
This conversion works for any OGR supported vector format. When listing the available tables, this new table appears, too:
db.tables -p
Null handling example
# copy the map into your MAPSET and check for NULL
 g.copy vect=lakes,mylakes
 v.db.select mylakes
 v.db.select mylakes where=”FTYPE IS NULL”
# display the lakes, show undefined FTYPE lakes in red
 g.region swwake_10m
 d.erase
 d.vect mylakes where=”FTYPE NOT NULL” type=area col=blue
 d.vect mylakes where=”FTYPE IS NULL” type=area col=red
# replace NULL with FTYPE WETLAND
 v.db.update mylakes col=FTYPE value=WETLAND \
 where=”FTYPE IS NULL”
 v.db.select mylakes
Column type converting example (type casts)
v.info -c geodetic_pts
 # copy map into current mapset
 g.copy vect=geodetic_pts,mygeodetic_pts
 v.db.addcol mygeodetic_pts col=”zval double precision”
# the ‘z_value’ col contains ‘N/A’ strings, not to be converted
 v.db.update mygeodetic_pts col=zval \
 qcol=”CAST(z_value AS double precision)” \
 where=”z_value <> ‘N/A'”
 v.info -c mygeodetic_pts
 v.db.select mygeodetic_pts col=Z_VALUE,zval
# fix 0 in ‘zval’ to NULL (orig. ‘N/A’ entries in ‘Z_VALUE’)
 echo “UPDATE mygeodetic_pts SET zval=NULL WHERE zval=0” \
 | db.execute
 v.db.select mygeodetic_pts col=Z_VALUE,zval
Map reclassification
# fetch all counties
 v.db.select geonames_NC \
 where=”POPULATION<>0 and FEATURECOD=’ADM2′”
cat 1
 WHERE FEATURECOD=’ADM2′ AND POPULATION=0
 cat 2
 WHERE FEATURECOD=’ADM2′ AND POPULATION>0 AND POPULATION=1000 AND POPULATION=10000 AND POPULATION=100000 AND POPULATION=500000
v.reclass geonames_NC rules=countypop.cls out=geonames_NC_recl
 v.category geonames_NC_recl op=report
 Layer: 1
 type count min max
 point 104 1 6
 line 0 0 0
 […]
# add new table with one column
 v.db.addtable geonames_NC_recl col=”popclass varchar(50)”
# insert values into table
 v.db.update geonames_NC_recl col=popclass value=”unknown” \
 where=”cat=1″
 v.db.update geonames_NC_recl col=popclass value=”very low” \
 where=”cat=2″
 v.db.update geonames_NC_recl col=popclass value=”low” \
 where=”cat=3″
 v.db.update geonames_NC_recl col=popclass value=”medium” \
 where=”cat=4″
 v.db.update geonames_NC_recl col=popclass value=”high” \
 where=”cat=5″
 v.db.update geonames_NC_recl col=popclass value=”very high”\
 where=”cat=6″
# verify the result and display the reclassified map:
 v.db.select geonames_NC_recl
 v.info geonames_NC_recl
 d.erase
 d.vect nc_state type=area
 d.vect -c geonames_NC_recl where=”popclass<>’unknown'”
Network analysis: Linear reference system (LRS)
# in new MAPSET wolfline_lrs
 db.connect driver=sqlite \
 database=’$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite.db’
 db.connect -p
 db.tables -p
 # … should not show any tables.
# display the available bus route data:
 # several bus lines available
 g.region vect=busroutesall -p n=n+100 s=s-100 res=500 -a
 d.mon x0
 d.vect -c busroutesall
# bus stops for all lines
 d.vect -c busstopsall icon=basic/triangle
# look at the attributes
 v.db.select busstopsall
# work on copy
 g.copy vect=busroute1,route1
 g.copy vect=busstopsall,stopsall
# verify map-database connections for SQLite connection
 v.db.connect -p route1
 v.db.connect -p stopsall
# check the selection and extract stops to a new map
 v.db.select stopsall \
 where=”ROUTES LIKE ‘%1%’ AND ROUTES NOT LIKE ‘%11%'”
 v.extract stopsall out=stops1 \
 where=”ROUTES LIKE ‘%1%’ AND ROUTES NOT LIKE ‘%11%'”
v.build.polylines route1 out=route1tmp
# substitute old ‘route1’ with new map (but we lose the table)
 v.category route1tmp out=route1 op=add –o
 g.remove vect=route1tmp
# add table with column to link the route with the bus stop
 v.db.addtable route1 col=”lid integer”
 v.db.update route1 col=lid val=1
 v.db.select route1
 cat|lid
 1|1
v.db.addcol stops1 col=”lid integer”
 v.db.update stops1 col=lid val=1
 v.db.select stops1
 cat|ROUTES|UPDATED|STREET_1|STREET_2|CAMPUS|…
 7|1,5,7a,8,9,A,B|2006/11/14|Dan Allen Dr.||North|…
 […]
# define the order, offsets of the bus stops, preparing table
 v.db.addcol stops1 col=”start_mp double precision, \
 start_off double precision, end_mp double precision,\
 end_off double precision”
# check direction of the vector line for the bus stops order
 g.region vect=route1 n=n+100 s=s-100 -p
 d.erase
 d.vect route1 disp=shape,dir,topo col=grey lcol=blue
 d.vect stops1 disp=attr attr=cat size=10 bgcolor=white
 d.vect stops1 icon=basic/circle fcol=green
# update the attribute column start_mp to indicate order of the bus stops along the bus tour:
 # from node n1 to n2 – line cat 1
 v.db.update stops1 col=start_mp where=”cat=7″ val=1
 v.db.update stops1 col=start_mp where=”cat=13″ val=2
 v.db.update stops1 col=start_mp where=”cat=14″ val=3
 v.db.update stops1 col=start_mp where=”cat=22″ val=4
 v.db.update stops1 col=start_mp where=”cat=83″ val=5
 v.db.update stops1 col=start_mp where=”cat=30″ val=6
 v.db.update stops1 col=start_mp where=”cat=55″ val=7
 v.db.update stops1 col=start_mp where=”cat=56″ val=8
 v.db.update stops1 col=start_mp where=”cat=82″ val=9
 v.db.update stops1 col=start_mp where=”cat=58″ val=10
 v.db.update stops1 col=start_mp where=”cat=38″ val=11
 v.db.update stops1 col=start_mp where=”cat=37″ val=12
 v.db.update stops1 col=start_mp where=”cat=36″ val=13
 v.db.update stops1 col=start_mp where=”cat=35″ val=14
 v.db.update stops1 col=start_mp where=”cat=34″ val=15
 v.db.update stops1 col=start_mp where=”cat=103″ val=16
 v.db.update stops1 col=start_mp where=”cat=31″ val=17
 v.db.update stops1 col=start_mp where=”cat=29″ val=18
 v.db.update stops1 col=start_mp where=”cat=24″ val=19
 v.db.update stops1 col=start_mp where=”cat=28″ val=20
 v.db.update stops1 col=start_mp where=”cat=96″ val=21
 v.db.update stops1 col=start_mp where=”cat=27″ val=22
 v.db.update stops1 col=start_mp where=”cat=60″ val=23
 v.db.update stops1 col=start_mp where=”cat=10″ val=24
 v.db.update stops1 col=start_mp where=”cat=9″ val=25
# verify route
 v.db.select route1
 cat|lid
 1|1
# verify stops
 v.db.select stops1 \
 col=cat,ROUTES,start_mp,start_off,end_mp,end_off,lid
 cat|ROUTES|start_mp|start_off|end_mp|end_off|lid
 7|1,5,7a,8,9,A,B|1||||1
 9|1,4,5,7a,9,A,B|25||||1
 …
 96|1,5,7,7a,8,8a,9,A,B|21||||1
 103|1,A|16||||1
# shift bus stop cat 30 onto the related vector segment
 v.edit stops1 tool=move cats=30 move=18,-12
# redraw to verify updated map
 d.redraw
# find maximum distance between bus stops and route1
 v.distance from=stops1 to=route1 upload=dist column=dummy -p
 # the highest reported value is 44.819408m
# the “start_mp” column is used to indicate the bus stops order
 v.lrs.create in_lines=route1 points=stops1 out=route1_lrs \
 err=lrs_error lidcol=lid pidcol=lid rstable=route1_lrs thre=45
 # the error map should be empty
# verify new LRS table
 db.select route1_lrs
# display complete linear reference system
 d.erase
 # show route and nodes
 d.vect route1 disp=shape,topo col=grey lcol=blue
 d.vect stops1 icon=basic/circle fcol=green
# show bus stop numbers (bottom right labels)
 d.vect stops1 disp=attr attr=cat size=10 bgcolor=white \
 lcol=green yref=top
 # show milepost numbers (top right labels)
 d.vect stops1 disp=attr attr=start_mp size=10 bgcolor=white \
 lcol=red yref=bottom
Querying the LRS
# these coordinates can be retrieved via GPS
 echo “638632|224857” | v.in.ascii out=position
g.region vect=route1 n=n+100 s=s-100 -p
 d.erase
 # show route and nodes
 d.vect route1 disp=shape,topo col=grey lcol=blue
 # show bus stop numbers (bottom right labels)
 d.vect stops1 disp=attr attr=cat size=10 bgcolor=white \
 lcol=green yref=top
 # show milepost numbers (top right labels)
 d.vect stops1 disp=attr attr=start_mp size=10 bgcolor=white \
 lcol=blue yref=bottom
 # show markers
 d.vect stops1 icon=basic/circle fcol=green
 d.vect position col=red icon=basic/marker size=20
v.lrs.where line=route1_lrs point=position rstab=route1_lrs
 pcat|lid|mpost|offset
 1|1|6.000000+134.532728
 [1] points read from input
 [1] positions found
# check to which bus stop the milepost 6 belongs to
 # a) get corresponding bus stop number “upstream”
 v.db.select stops1 col=cat,start_mp where=”start_mp=6″
 cat|start_mp
 30|6
# b) get next bus stop number along the tour
 v.db.select stops1 col=cat,start_mp where=”start_mp=7″
 cat|start_mp
 55|7
# the LRS table contains even more information:
 db.select sql=”SELECT * FROM route1_lrs WHERE start_mp=6″
 rsid|lcat|lid|start_map|end_map|start_mp|start_off|\
 end_mp|end_off|end_type
 6|1|1|1946.147074|2411.275995|6|0|7|0|2
# what is the distance between bus stop 30 and 55
 db.select sql=”SELECT (end_map – start_map) as dist_30_55 \
 FROM route1_lrs WHERE start_mp=6″
 dist_30_55
 465.128921
# distance from our position to bus stop 55 (MP 7)
 db.select sql=”SELECT (end_map – start_map – 134.5) as \
 dist_to_55 FROM route1_lrs WHERE start_mp=6″
 dist_to_55
 330.628921
Visualization of the LRS
v.lrs.label route1_lrs rstable=route1_lrs labels=labels \
 col=red size=50 xoffset=100 output=route1_lrs_labels
g.region vect=route1 n=n+100 s=s-100 -p
 d.erase
 d.vect route1_lrs
 d.vect route1_lrs_labels col=grey type=line
 d.vect stops1 disp=attr attr=cat size=10 bg=white lcol=green \
 yref=bottom
 d.vect stops1 icon=basic/circle fcol=green
 d.labels labels
# simple PNG output
 d.out.file route1_lrs format=png res=2
 display route1_lrs.png



