About
This one’s about going from GRASS thematic vector polygon data to kml animation that can be viewed on Google Earth. The image is a static screenshot taken from the output Google Earth overlay.
Input Dataset
California Population change into 2100. There is one column with 2000 population numbers. Columns pcyyyy refer to population percentage difference from year 2000 to year yyyy.
v.info -c CountyPop2
Displaying column types/names for database connection of layer 1:
INTEGER|cat
CHARACTER|NAME
INTEGER|NUM
CHARACTER|COUNTY
DOUBLE PRECISION|countynum
DOUBLE PRECISION|p2000
DOUBLE PRECISION|pc2010
DOUBLE PRECISION|pc2015
DOUBLE PRECISION|pc2020
DOUBLE PRECISION|pc2025
DOUBLE PRECISION|pc2030
DOUBLE PRECISION|pc2035
DOUBLE PRECISION|pc2040
DOUBLE PRECISION|pc2045
DOUBLE PRECISION|pc2050
DOUBLE PRECISION|pc2055
DOUBLE PRECISION|pc2060
DOUBLE PRECISION|pc2065
DOUBLE PRECISION|pc2070
DOUBLE PRECISION|pc2075
DOUBLE PRECISION|pc2080
DOUBLE PRECISION|pc2085
DOUBLE PRECISION|pc2090
DOUBLE PRECISION|pc2100
The Script
This shell/GRASS script below can be saved as v.out.kml.sh. Run it using
sh v.out.kml inputvector outputkml
#!/bin/bash
############################################################################
# Apr 2009. Script to create
# a) sequence of GRASS thematic vector displays from one vector dataset, each layer corresponds to a column of the attribute table
# b) sequence of png images from above thematic vectors
# b) write images into a kml file for overlay onto Google Earth
# —-Vishal K. Mehta
# cmd: sh v.out.kml.sh inputvector outputkmlfilename
#####################################################################
#
# get current region settings from thematic map of interest-input file
g.region vect=$1
# Store current environment
OLD_GRASS_WIDTH=$GRASS_WIDTH
OLD_GRASS_HEIGHT=$GRASS_HEIGHT
OLD_GRASS_PNGFILE=$GRASS_PNGFILE
OLD_GRASS_TRANSPARENT=$GRASS_TRANSPARENT
OLD_GRASS_TRUECOLOR=$GRASS_TRUECOLOR
LEGEND_WIDTH=500
LEGEND_HEIGHT=500
LEGEND_TEXT_COLOR=white
BACKGROUND_COLOR=black
#1. create a legend file
#d.thematic.area -l map=CountyPop2 column=pc2100 breaks=20,40,60 colors=cyan,brown,orange,red legendfile=popchange.leg
export GRASS_WIDTH=$LEGEND_WIDTH
export GRASS_HEIGHT=$LEGEND_HEIGHT
export GRASS_BACKGROUNDCOLOR=$BACKGROUND_COLOR
export GRASS_TRANSPARENT=TRUE ##
export GRASS_TRUECOLOR=TRUE ##
export GRASS_PNGFILE=legend.png
d.mon start=PNG
d.mon select=PNG
#2. use d.graph on legend file the legend file popchange.leg is created outside of this code
d.graph input=popchange.leg color=$LEGEND_TEXT_COLOR
#
d.mon stop=PNG
mogrify -transparent black legend.png
# now display the vector thematic layers
# define the driver settings
export GRASS_WIDTH=`g.region -g | grep “cols” | cut -d= -f2`
export GRASS_HEIGHT=`g.region -g | grep “rows” | cut -d= -f2`
export GRASS_TRANSPARENT=TRUE ##
export GRASS_TRUECOLOR=TRUE ##
yr=2010
while [ $yr -lt 2105 ] ; do
echo “yr is $yr ”
#create png images
export GRASS_PNGFILE=pc$yr.png
d.mon start=PNG
d.mon select=PNG
d.thematic.area map=$1 column=pc$yr breaks=20,40,60 colors=cyan,blue,yellow,red
#d.text -b text=”$yr Population” at=50,90 size=4
d.mon stop=PNG
# year 2095 column is non-existent so needs to be skipped
if [ $yr -eq 2090 ]; then yr=$((yr+10)); else yr=$((yr+5)); fi;
done#
# Create the kml file
#TITLE=`r.info -m $GIS_OPT_INPUT | cut -d= -f2`
TITLE=”Population”
NORTH=`g.region -g | grep -m1 “n=” | cut -d= -f2`
SOUTH=`g.region -g | grep -m1 “s=” | cut -d= -f2`
EAST=`g.region -g | grep -m1 “e=” | cut -d= -f2`
WEST=`g.region -g | grep -m1 “w=” | cut -d= -f2`
echo “<?xml version=\”1.0\” encoding=\”UTF-8\”?>” > $2.kml
echo “<kml xmlns=\”http://earth.google.com/kml/2.2\”>” >> $2.kml
# now begins stack of images
echo “<Folder>” >> $2.kml
echo “<open>1</open>” >> $2.kml
echo “<name>California Population Projections</name>” >> $2.kml
echo “<description>Percentage difference from 2000 Population</description>” >> $2.kml
echo “<visibility>1</visibility>” >> $2.kml
echo “<open>0</open>” >> $2.kml
# add legend first
echo “<ScreenOverlay>” >> $2.kml
echo “<name>Legend</name>” >> $2.kml
echo “<Icon>” >> $2.kml
echo “<href>legend.png</href>” >> $2.kml
echo “</Icon>” >> $2.kml
echo “<overlayXY x=\”0\” y=\”1\” xunits=\”fraction\” yunits=\”fraction\”/>” >> $2.kml
echo “<screenXY x=\”0.05\” y=\”0.95\” xunits=\”fraction\” yunits=\”fraction\”/>” >> $2.kml
echo “<rotationXY x=\”0\” y=\”0\” xunits=\”fraction\” yunits=\”fraction\”/>” >> $2.kml
echo “<size x=\”200\” y=\”200\” xunits=\”pixels\” yunits=\”pixels\”/>” >> $2.kml
echo “</ScreenOverlay>” >> $2.kml
echo “<TimeSpan>” >> $2.kml
echo “<begin>2010-01</begin>” >> $2.kml
echo “<end>2100-12</end>” >> $2.kml
echo “</TimeSpan>” >> $2.kml
# start loop for sequence of images
yr=2010
while [ $yr -lt 2105 ] ; do
if [ $yr -eq 2090 ]; then endyr=$((yr+10));
elif [ $yr -eq 2100 ]; then endyr=$((yr));
else endyr=$((yr+5)); fi;
echo “<GroundOverlay>” >> $2.kml
echo “<name>$yr</name>” >> $2.kml
echo “<visibility>1</visibility>” >> $2.kml
echo “<drawOrder>1</drawOrder>” >> $2.kml
echo “<TimeSpan>” >> $2.kml
echo “<begin>$((yr))-01</begin>” >> $2.kml
echo “<end>$((endyr))-12</end>” >> $2.kml
echo “</TimeSpan>” >> $2.kml
echo “<Icon>” >> $2.kml
echo “<href>pc$yr.png</href>” >> $2.kml
echo “</Icon>” >> $2.kml
echo “<LatLonBox>” >> $2.kml
echo “<south>$SOUTH</south>” >> $2.kml
echo “<north>$NORTH</north>” >> $2.kml
echo “<west>$WEST</west>” >> $2.kml
echo “<east>$EAST</east>” >> $2.kml
echo “</LatLonBox>” >> $2.kml
echo “</GroundOverlay>” >> $2.kml
if [ $yr -eq 2090 ]; then yr=$((yr+10)); else yr=$((yr+5)); fi;
done
#
echo “</Folder>” >> $2.kml
echo “</kml>” >> $2.kml
# Restore the environment
export GRASS_WIDTH=$OLD_GRASS_WIDTH
export GRASS_HEIGHT=$OLD_GRASS_HEIGHT
export GRASS_PNGFILE=$OLD_GRASS_PNGFILE
export GRASS_TRANSPARENT=$OLD_GRASS_TRANSPARENT
export GRASS_TRUECOLOR=$OLD_GRASS_TRUECOLOR######END OF SCRIPT#########
Notes/To Do
This script is not fully automated. In particular, the legend specs file is hardcoded.Getting a decent legend for GRASS thematic layers is a Major Pain.
Related posts “thematic maps in GRASS”; “another attempt at animated gif”.
Acknowledgements
David Finlayson‘s r.out.kml script, to convert a single GRASS raster to kml.
RadicaLibre said
Excelent post!! Thanks!!