123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- # -*- coding: utf-8 -*-
- """!@package grass.temporal
- @brief GRASS Python scripting module (temporal GIS functions)
- Temporal GIS related functions to be used in temporal GIS Python library package.
- Usage:
- >>> import grass.temporal as tgis
- >>> tmr = tgis.AbstractTemporalDataset()
- (C) 2008-2011 by the GRASS Development Team
- This program is free software under the GNU General Public
- License (>=v2). Read the file COPYING that comes with GRASS
- for details.
- @author Soeren Gebbert
- """
- from abstract_dataset import *
- from datetime_math import *
- class AbstractTemporalDataset(AbstractDataset):
- """!This class implements a temporal topology access structure for an abstract dataset
- This object will be set up by temporal topology creation method provided by the
- TemporallyTopologyBuilder.
- If correctly initialize the calls next() and prev()
- let the user walk temporally forward and backward in time.
- The following temporal relations with access methods are supported:
- * equal
- * follows
- * precedes
- * overlaps
- * overlapped
- * during (including starts, finishes)
- * contains (including started, finished)
- * starts
- * started
- * finishes
- * finished
- @code:
- # We have build the temporal topology and we know the first map
- start = first
- while start:
- # Print all maps this map temporally contains
- dlist = start.get_contains()
- for map in dlist:
- map.print_info()
- start = start.next()
- @endcode
-
- Usage:
-
- @code
-
- >>> tmr = AbstractTemporalDataset()
- >>> tmr.print_topology_info()
- +-------------------- Temporal Topology -------------------------------------+
- >>> tmr.print_topology_shell_info()
-
- @endcode
- """
- def __init__(self):
- AbstractDataset.__init__(self)
- self.reset_topology()
- def reset_topology(self):
- """!Reset any information about temporal topology"""
- self._topology = {}
- self._has_topology = False
-
- def get_number_of_relations(self):
- """! Return a dictionary in which the keys are the relation names and the value
- are the number of relations.
-
- The following relations are available:
- * equal
- * follows
- * precedes
- * overlaps
- * overlapped
- * during (including starts, finishes)
- * contains (including started, finished)
- * starts
- * started
- * finishes
- * finished
-
- To access topological information the temporal topology must be build first
- using the TemporalTopologyBuilder.
-
- @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
- """
- if self._has_topology == False:
- return None
-
- relations = {}
- try:
- relations["equal"] = len(self._topology["EQUAL"])
- except:
- relations["equal"] = 0
- try:
- relations["follows"] = len(self._topology["FOLLOWS"])
- except:
- relations["follows"] = 0
- try:
- relations["precedes"] = len(self._topology["PRECEDES"])
- except:
- relations["precedes"] = 0
- try:
- relations["overlaps"] = len(self._topology["OVERLAPS"])
- except:
- relations["overlaps"] = 0
- try:
- relations["overlapped"] = len(self._topology["OVERLAPPED"])
- except:
- relations["overlapped"] = 0
- try:
- relations["during"] = len(self._topology["DURING"])
- except:
- relations["during"] = 0
- try:
- relations["contains"] = len(self._topology["CONTAINS"])
- except:
- relations["contains"] = 0
- try:
- relations["starts"] = len(self._topology["STARTS"])
- except:
- relations["starts"] = 0
- try:
- relations["started"] = len(self._topology["STARTED"])
- except:
- relations["started"] = 0
- try:
- relations["finishes"] = len(self._topology["FINISHES"])
- except:
- relations["finishes"] = 0
- try:
- relations["finished"] = len(self._topology["FINISHED"])
- except:
- relations["finished"] = 0
-
- return relations
- def set_topology_build_true(self):
- """!Same as name"""
- self._has_topology = True
- def set_topology_build_false(self):
- """!Same as name"""
- self._has_topology = False
- def is_topology_build(self):
- """!Check if the temporal topology was build"""
- return self._has_topology
- def set_next(self, map_):
- """!Set the map that is temporally as closest located after this map.
- Temporally located means that the start time of the "next" map is
- temporally located AFTER the start time of this map, but temporally
- near than other maps of the same dataset.
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- self._topology["NEXT"] = map_
- def set_prev(self, map_):
- """!Set the map that is temporally as closest located before this map.
- Temporally located means that the start time of the "previous" map is
- temporally located BEFORE the start time of this map, but temporally
- near than other maps of the same dataset.
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- self._topology["PREV"] = map_
- def next(self):
- """!Return the map with a start time temporally located after
- the start time of this map, but temporal closer than other maps
- @return A map object or None
- """
- if "NEXT" not in self._topology:
- return None
- return self._topology["NEXT"]
- def prev(self):
- """!Return the map with a start time temporally located before
- the start time of this map, but temporal closer than other maps
- @return A map object or None
- """
- if "PREV" not in self._topology:
- return None
- return self._topology["PREV"]
- def append_equivalent(self, map_):
- """!Append a map with equivalent temporal extent as this map
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "EQUAL" not in self._topology:
- self._topology["EQUAL"] = []
- self._topology["EQUAL"].append(map_)
- def get_equivalent(self):
- """!Return a list of map objects with equivalent temporal extent as this map
- @return A list of map objects or None
- """
- if "EQUAL" not in self._topology:
- return None
- return self._topology["EQUAL"]
- def append_starts(self, map_):
- """!Append a map that this map temporally starts with
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "STARTS" not in self._topology:
- self._topology["STARTS"] = []
- self._topology["STARTS"].append(map_)
- def get_starts(self):
- """!Return a list of map objects that this map temporally starts with
- @return A list of map objects or None
- """
- if "STARTS" not in self._topology:
- return None
- return self._topology["STARTS"]
- def append_started(self, map_):
- """!Append a map that this map temporally started with
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "STARTED" not in self._topology:
- self._topology["STARTED"] = []
- self._topology["STARTED"].append(map_)
- def get_started(self):
- """!Return a list of map objects that this map temporally started with
- @return A list of map objects or None
- """
- if "STARTED" not in self._topology:
- return None
- return self._topology["STARTED"]
- def append_finishes(self, map_):
- """!Append a map that this map temporally finishes with
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "FINISHES" not in self._topology:
- self._topology["FINISHES"] = []
- self._topology["FINISHES"].append(map_)
- def get_finishes(self):
- """!Return a list of map objects that this map temporally finishes with
- @return A list of map objects or None
- """
- if "FINISHES" not in self._topology:
- return None
- return self._topology["FINISHES"]
- def append_finished(self, map_):
- """!Append a map that this map temporally finished with
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "FINISHED" not in self._topology:
- self._topology["FINISHED"] = []
- self._topology["FINISHED"].append(map_)
- def get_finished(self):
- """!Return a list of map objects that this map temporally finished with
- @return A list of map objects or None
- """
- if "FINISHED" not in self._topology:
- return None
- return self._topology["FINISHED"]
- def append_overlaps(self, map_):
- """!Append a map that this map temporally overlaps
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "OVERLAPS" not in self._topology:
- self._topology["OVERLAPS"] = []
- self._topology["OVERLAPS"].append(map_)
- def get_overlaps(self):
- """!Return a list of map objects that this map temporally overlaps
- @return A list of map objects or None
- """
- if "OVERLAPS" not in self._topology:
- return None
- return self._topology["OVERLAPS"]
- def append_overlapped(self, map_):
- """!Append a map that this map temporally overlapped
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "OVERLAPPED" not in self._topology:
- self._topology["OVERLAPPED"] = []
- self._topology["OVERLAPPED"].append(map_)
- def get_overlapped(self):
- """!Return a list of map objects that this map temporally overlapped
- @return A list of map objects or None
- """
- if "OVERLAPPED" not in self._topology:
- return None
- return self._topology["OVERLAPPED"]
- def append_follows(self, map_):
- """!Append a map that this map temporally follows
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "FOLLOWS" not in self._topology:
- self._topology["FOLLOWS"] = []
- self._topology["FOLLOWS"].append(map_)
- def get_follows(self):
- """!Return a list of map objects that this map temporally follows
- @return A list of map objects or None
- """
- if "FOLLOWS" not in self._topology:
- return None
- return self._topology["FOLLOWS"]
- def append_precedes(self, map_):
- """!Append a map that this map temporally precedes
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "PRECEDES" not in self._topology:
- self._topology["PRECEDES"] = []
- self._topology["PRECEDES"].append(map_)
- def get_precedes(self):
- """!Return a list of map objects that this map temporally precedes
- @return A list of map objects or None
- """
- if "PRECEDES" not in self._topology:
- return None
- return self._topology["PRECEDES"]
- def append_during(self, map_):
- """!Append a map that this map is temporally located during
- This includes temporal relationships starts and finishes
- @param map_: This object should be of type
- AbstractMapDataset or derived classes
- """
- if "DURING" not in self._topology:
- self._topology["DURING"] = []
- self._topology["DURING"].append(map_)
- def get_during(self):
- """!Return a list of map objects that this map is temporally located during
- This includes temporally relationships starts and finishes
- @return A list of map objects or None
- """
- if "DURING" not in self._topology:
- return None
- return self._topology["DURING"]
- def append_contains(self, map_):
- """!Append a map that this map temporally contains
- This includes temporal relationships started and finished
- @param map_: This object should be of type AbstractMapDataset
- or derived classes
- """
- if "CONTAINS" not in self._topology:
- self._topology["CONTAINS"] = []
- self._topology["CONTAINS"].append(map_)
- def get_contains(self):
- """!Return a list of map objects that this map temporally contains
- This includes temporal relationships started and finished
- @return A list of map objects or None
- """
- if "CONTAINS" not in self._topology:
- return None
- return self._topology["CONTAINS"]
- def _generate_map_list_string(self, map_list, line_wrap=True):
- count = 0
- string = ""
- for map_ in map_list:
- if line_wrap and count > 0 and count % 3 == 0:
- string += "\n | ............................ "
- count = 0
- if count == 0:
- string += map_.get_id()
- else:
- string += ",%s" % map_.get_id()
- count += 1
- return string
-
- # Set the properties
- equivalent = property(fget=get_equivalent,
- fset=append_equivalent)
- follows = property(fget=get_follows,
- fset=append_follows)
- precedes = property(fget=get_precedes,
- fset=append_precedes)
- overlaps = property(fget=get_overlaps,
- fset=append_overlaps)
- overlapped = property(fget=get_overlapped,
- fset=append_overlapped)
- during = property(fget=get_during,
- fset=append_during)
- contains = property(fget=get_contains,
- fset=append_contains)
- starts = property(fget=get_starts,
- fset=append_starts)
- started = property(fget=get_started,
- fset=append_started)
- finishes = property(fget=get_finishes,
- fset=append_finishes)
- finished = property(fget=get_finished,
- fset=append_finished)
- def print_topology_info(self):
- """!Print information about this class in human readable style"""
- _next = self.next()
- _prev = self.prev()
- _equal = self.get_equivalent()
- _follows = self.get_follows()
- _precedes = self.get_precedes()
- _overlaps = self.get_overlaps()
- _overlapped = self.get_overlapped()
- _during = self.get_during()
- _contains = self.get_contains()
- _starts = self.get_starts()
- _started = self.get_started()
- _finishes = self.get_finishes()
- _finished = self.get_finished()
-
- print " +-------------------- Temporal Topology -------------------------------------+"
- # 0123456789012345678901234567890
- if _next is not None:
- print " | Next: ...................... " + str(_next.get_id())
- if _prev is not None:
- print " | Previous: .................. " + str(_prev.get_id())
- if _equal is not None:
- print " | Equivalent: ................ " + \
- self._generate_map_list_string(_equal)
- if _follows is not None:
- print " | Follows: ................... " + \
- self._generate_map_list_string(_follows)
- if _precedes is not None:
- print " | Precedes: .................. " + \
- self._generate_map_list_string(_precedes)
- if _overlaps is not None:
- print " | Overlaps: .................. " + \
- self._generate_map_list_string(_overlaps)
- if _overlapped is not None:
- print " | Overlapped: ................ " + \
- self._generate_map_list_string(_overlapped)
- if _during is not None:
- print " | During: .................... " + \
- self._generate_map_list_string(_during)
- if _contains is not None:
- print " | Contains: .................. " + \
- self._generate_map_list_string(_contains)
- if _starts is not None:
- print " | Starts:.. .................. " + \
- self._generate_map_list_string(_starts)
- if _started is not None:
- print " | Started:. .................. " + \
- self._generate_map_list_string(_started)
- if _finishes is not None:
- print " | Finishes:................... " + \
- self._generate_map_list_string(_finishes)
- if _finished is not None:
- print " | Finished:................... " + \
- self._generate_map_list_string(_finished)
- def print_topology_shell_info(self):
- """!Print information about this class in shell style"""
- _next = self.next()
- _prev = self.prev()
- _equal = self.get_equivalent()
- _follows = self.get_follows()
- _precedes = self.get_precedes()
- _overlaps = self.get_overlaps()
- _overlapped = self.get_overlapped()
- _during = self.get_during()
- _contains = self.get_contains()
- _starts = self.get_starts()
- _started = self.get_started()
- _finishes = self.get_finishes()
- _finished = self.get_finished()
-
- if _next is not None:
- print "next=" + _next.get_id()
- if _prev is not None:
- print "prev=" + _prev.get_id()
- if _equal is not None:
- print "equivalent=" + self._generate_map_list_string(_equal, False)
- if _follows is not None:
- print "follows=" + self._generate_map_list_string(_follows, False)
- if _precedes is not None:
- print "precedes=" + self._generate_map_list_string(
- _precedes, False)
- if _overlaps is not None:
- print "overlaps=" + self._generate_map_list_string(
- _overlaps, False)
- if _overlapped is not None:
- print "overlapped=" + \
- self._generate_map_list_string(_overlapped, False)
- if _during is not None:
- print "during=" + self._generate_map_list_string(_during, False)
- if _contains is not None:
- print "contains=" + self._generate_map_list_string(
- _contains, False)
- if _starts is not None:
- print "starts=" + \
- self._generate_map_list_string(_starts)
- if _started is not None:
- print "started=" + \
- self._generate_map_list_string(_started)
- if _finishes is not None:
- print "finishes=" + \
- self._generate_map_list_string(_finishes)
- if _finished is not None:
- print "finished=" + \
- self._generate_map_list_string(_finished)
- ###############################################################################
- if __name__ == "__main__":
- import doctest
- doctest.testmod()
|