The GRASS GIS Temporal Framework implements temporal GIS functionality at user level and provides additionally an API to implement new spatio-temporal processing modules.
The temporal framework introduces space time datasets to represent time series of raster, 3D raster or vector maps. It provides the following functionalities:
Three related datatypes are available:
Reference: Gebbert, S., Pebesma, E., 2014. TGRASS: A temporal GIS for field based environmental modeling. Environmental Modelling & Software 53, 1-12. http://dx.doi.org/10.1016/j.envsoft.2013.11.001
In [ ]:
import grass.temporal as tgis
import grass.script as gscript
First, we initialize temporal database:
In [ ]:
tgis.init()
Next, we create an empty space-time raster dataset. We specify its name, its type (here: strds), temporal type (absolute, relative), title and description. You can imagine a temporal dataset as a container for selected data which puts them into order, describes their space-time relationships and saves all kind of metadata. The maps themselves remain standard GRASS GIS maps.
In [ ]:
dataset_name = 'temperature'
dataset = tgis.open_new_stds(name=dataset_name, type='strds', temporaltype='absolute',
title="Temperature in Raleigh", descr="Created for test purposes",
semantic='mean', overwrite=True)
Check if the temporal dataset was created:
In [ ]:
# Print some info about the new dataset
dataset.print_shell_info()
Create a set of random maps of temperature using min and max values
In [ ]:
# monthly mean Raleigh temperature
nc_temp_data = {1:[30, 51], 2: [32, 54], 3: [40, 63], 4: [48, 72],
5:[57, 80], 6: [66, 87], 7: [70, 90], 8: [69, 88],
9:[62, 82], 10:[50, 73], 11:[41, 64], 12:[32, 54]}
# list of maps to add into temporal dataset
maps = []
gscript.run_command('g.region', raster='elevation')
for month, values in nc_temp_data.iteritems():
map_name = "temp_{mon}".format(mon=month)
gscript.run_command('r.random.surface', output=map_name, seed=values, high=values[1], overwrite=True)
maps.append(map_name)
print maps
Now we register the created maps within the temporal dataset:
In [ ]:
tgis.register_maps_in_space_time_dataset(type='raster', name=dataset_name, maps=','.join(maps), start='2014-01-01',
increment="1 month", interval=True, update_cmd_list=True)
Next we update the information of temporal dataset and print its metadata:
In [ ]:
dataset.update_from_registered_maps()
dataset.print_shell_info()
During this session you will learn how to extract values for a point from a temporal dataset.
In [ ]:
coors = (638000, 222800.0)
We get the temporal dataset object:
In [ ]:
strds = tgis.open_old_stds(dataset_name, "strds")
Now it is possible to obtain all the registered maps:
In [ ]:
rows = strds.get_registered_maps(columns="name,mapset,start_time,end_time",
where=None, order="start_time")
Get useful info (as name, starting time) about registered maps and query the data using the GRASS GIS command r.what
:
In [ ]:
from collections import OrderedDict
infos = OrderedDict()
for row in rows:
name = row["name"] + "@" + row["mapset"]
values = gscript.read_command('r.what', map=name, coordinates=coors).strip().split('|')
infos[name] = {'date': row["start_time"], 'value': values[3]}
print infos
To write out a CSV file in Python, the CSV module should be used. So, import the CSV and the tempfile modules to then create a new CSV file in the temporal directory:
In [ ]:
import csv
import tempfile
fil = tempfile.NamedTemporaryFile(delete=False)
fil.name = fil.name + '.csv'
print fil.name
Now, for each record read from the temporal dataset, the procedure stores the respective record in the CSV file:
In [ ]:
with open(fil.name, 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=';',
quoting=csv.QUOTE_MINIMAL)
spamwriter.writerow(['Map_name', 'Date', 'Temp'])
for mapp, vals in infos.iteritems():
spamwriter.writerow([mapp, vals['date'].strftime('%Y-%m-%d'), vals['value']])
fil.close()
For verification, we can simply print the CSV file to the terminal using the cat
shell command:
In [ ]:
!cat {fil.name}
To print the data using Matplotlib
some libraries have to be imported first:
In [ ]:
%matplotlib notebook
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
Next we create the list of values for the x and y axes:
In [ ]:
x = []
y = []
for mapp, vals in infos.iteritems():
x.append(vals['date'])
y.append(vals['value'])
print x
print y
Finally we plot the temperature values over time:
In [ ]:
# create the plot
fig, ax = plt.subplots()
# create the plot line
ax.plot(x,y, label='2014 monthly temperature', color='red')
# set the format of X axis label
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
# set the title of graph
plt.title('Monthly temperature');
# add legend and set it lower-center position
ax.legend(loc='lower center')
# fix the position/rotation of X lavel
fig.autofmt_xdate()
# set the label for X and Y axis
ax.set_xlabel('Month')
ax.set_ylabel('Fahrenheit temp')
# show the graph
plt.show()
To remove maps from a temporal dataset (they will not be truly deleted but just unregistered from the temporal dataset), first a map object should be created. Then, using this new dataset object, we remove the selected map(s) using the unregister_map
function:
In [ ]:
remove_map = tgis.RasterDataset('temp_12@{mapset}'.format(mapset=gscript.gisenv()['MAPSET']))
dataset.unregister_map(remove_map)
dataset.update_from_registered_maps()
Removing a space time datasets from temporal database (again, the contained maps remain in GRASS GIS) can be done directly from the same object using the delete
function:
In [ ]:
dataset.delete()
In [ ]: