abstract_dataset.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. # -*- coding: utf-8 -*-
  2. """!@package grass.temporal
  3. @brief GRASS Python scripting module (temporal GIS functions)
  4. Temporal GIS related functions to be used in temporal GIS Python library package.
  5. Usage:
  6. @code
  7. import grass.temporal as tgis
  8. ...
  9. @endcode
  10. (C) 2008-2011 by the GRASS Development Team
  11. This program is free software under the GNU General Public
  12. License (>=v2). Read the file COPYING that comes with GRASS
  13. for details.
  14. @author Soeren Gebbert
  15. """
  16. import uuid
  17. import copy
  18. from temporal_extent import *
  19. from spatial_extent import *
  20. from metadata import *
  21. class abstract_dataset(object):
  22. """This is the base class for all datasets (raster, vector, raster3d, strds, stvds, str3ds)"""
  23. def reset(self, ident):
  24. """Reset the internal structure and set the identifier
  25. @param ident: The identifier of the dataset
  26. """
  27. raise IOError("This method must be implemented in the subclasses")
  28. def get_type(self):
  29. """Return the type of this class"""
  30. raise IOError("This method must be implemented in the subclasses")
  31. def get_new_instance(self, ident):
  32. """Return a new instance with the type of this class
  33. @param ident: The identifier of the dataset
  34. """
  35. raise IOError("This method must be implemented in the subclasses")
  36. def print_info(self):
  37. """Print information about this class in human readable style"""
  38. raise IOError("This method must be implemented in the subclasses")
  39. def print_shell_info(self):
  40. """Print information about this class in shell style"""
  41. raise IOError("This method must be implemented in the subclasses")
  42. def print_self(self):
  43. """Print the content of the internal structure to stdout"""
  44. self.base.print_self()
  45. if self.is_time_absolute():
  46. self.absolute_time.print_self()
  47. if self.is_time_relative():
  48. self.relative_time.print_self()
  49. self.spatial_extent.print_self()
  50. self.metadata.print_self()
  51. def get_id(self):
  52. """Return the unique identifier of the dataset"""
  53. return self.base.get_id()
  54. def get_name(self):
  55. """Return the name"""
  56. return self.base.get_name()
  57. def get_mapset(self):
  58. """Return the mapset"""
  59. return self.base.get_mapset()
  60. def build_id(name, mapset, layer=None):
  61. """Build and return the id (primary key) based on name, mapset and layer of a dataset.
  62. @param name: The name of the map
  63. @param mapset: The name of the mapset
  64. @param layer: The name of the layer (optional)
  65. Return None in case the name can not be build (name or mapset are None)
  66. """
  67. if not name or not mapset:
  68. return None
  69. # Make sure to extract the pure mapname
  70. pure_name = name.split("@")[0].split(":")[0]
  71. if layer:
  72. return "%s:%s@%s"%(name, layer, mapset)
  73. else:
  74. return "%s@%s"%(name, mapset)
  75. return None
  76. def get_valid_time(self):
  77. """Returns a tuple of the start, the end valid time, this can be either datetime or double values
  78. @return A tuple of (start_time, end_time)
  79. """
  80. start = None
  81. end = None
  82. if self.is_time_absolute():
  83. start = self.absolute_time.get_start_time()
  84. end = self.absolute_time.get_end_time()
  85. if self.is_time_relative():
  86. start = self.relative_time.get_start_time()
  87. end = self.relative_time.get_end_time()
  88. return (start, end)
  89. def get_absolute_time(self):
  90. """Returns a tuple of the start, the end valid time and the timezone of the map
  91. @return A tuple of (start_time, end_time, timezone)
  92. """
  93. start = self.absolute_time.get_start_time()
  94. end = self.absolute_time.get_end_time()
  95. tz = self.absolute_time.get_timezone()
  96. return (start, end, tz)
  97. def get_relative_time(self):
  98. """Returns the relative time interval (start_time, end_time, unit) or None if not present"""
  99. start = self.relative_time.get_start_time()
  100. end = self.relative_time.get_end_time()
  101. unit = self.relative_time.get_unit()
  102. return (start, end, unit)
  103. def get_relative_time_unit(self):
  104. """Returns the relative time unit or None if not present"""
  105. unit = self.relative_time.get_unit()
  106. return unit
  107. def check_relative_time_unit(self, unit):
  108. """Check if unit is of type years, months, days, hours, minutes or seconds
  109. Return True if success or False otherwise
  110. """
  111. # Check unit
  112. units = ["years","months","days","hours","minutes","seconds"]
  113. if unit not in units:
  114. return False
  115. return True
  116. def get_temporal_type(self):
  117. """Return the temporal type of this dataset"""
  118. return self.base.get_ttype()
  119. def get_spatial_extent(self):
  120. """Return a tuple of spatial extent (north, south, east, west, top, bottom) """
  121. north = self.spatial_extent.get_north()
  122. south = self.spatial_extent.get_south()
  123. east = self.spatial_extent.get_east()
  124. west = self.spatial_extent.get_west()
  125. top = self.spatial_extent.get_top()
  126. bottom = self.spatial_extent.get_bottom()
  127. return (north, south, east, west, top, bottom)
  128. def spatial_overlap(self, dataset):
  129. """Return True if the spatial extents overlap"""
  130. north = self.spatial_extent.overlap(dataset.spatial_extent)
  131. def select(self, dbif=None):
  132. """Select temporal dataset entry from database and fill up the internal structure"""
  133. connect = False
  134. if dbif == None:
  135. dbif = sql_database_interface()
  136. dbif.connect()
  137. connect = True
  138. dbif.cursor.execute("BEGIN TRANSACTION")
  139. self.base.select(dbif)
  140. if self.is_time_absolute():
  141. self.absolute_time.select(dbif)
  142. if self.is_time_relative():
  143. self.relative_time.select(dbif)
  144. self.spatial_extent.select(dbif)
  145. self.metadata.select(dbif)
  146. dbif.cursor.execute("COMMIT TRANSACTION")
  147. if connect:
  148. dbif.close()
  149. def is_in_db(self, dbif=None):
  150. """Check if the temporal dataset entry is in the database"""
  151. return self.base.is_in_db(dbif)
  152. def delete(self):
  153. """Delete temporal dataset entry from database if it exists"""
  154. raise IOError("This method must be implemented in the subclasses")
  155. def insert(self, dbif=None):
  156. """Insert temporal dataset entry into database from the internal structure"""
  157. connect = False
  158. if dbif == None:
  159. dbif = sql_database_interface()
  160. dbif.connect()
  161. connect = True
  162. dbif.cursor.execute("BEGIN TRANSACTION")
  163. self.base.insert(dbif)
  164. if self.is_time_absolute():
  165. self.absolute_time.insert(dbif)
  166. if self.is_time_relative():
  167. self.relative_time.insert(dbif)
  168. self.spatial_extent.insert(dbif)
  169. self.metadata.insert(dbif)
  170. dbif.cursor.execute("COMMIT TRANSACTION")
  171. if connect:
  172. dbif.close()
  173. def update(self, dbif=None):
  174. """Update temporal dataset entry of database from the internal structure
  175. excluding None variables
  176. """
  177. connect = False
  178. if dbif == None:
  179. dbif = sql_database_interface()
  180. dbif.connect()
  181. connect = True
  182. dbif.cursor.execute("BEGIN TRANSACTION")
  183. self.base.update(dbif)
  184. if self.is_time_absolute():
  185. self.absolute_time.update(dbif)
  186. if self.is_time_relative():
  187. self.relative_time.update(dbif)
  188. self.spatial_extent.update(dbif)
  189. self.metadata.update(dbif)
  190. dbif.cursor.execute("COMMIT TRANSACTION")
  191. if connect:
  192. dbif.close()
  193. def update_all(self, dbif=None):
  194. """Update temporal dataset entry of database from the internal structure
  195. and include None varuables.
  196. @param dbif: The database interface to be used
  197. """
  198. connect = False
  199. if dbif == None:
  200. dbif = sql_database_interface()
  201. dbif.connect()
  202. connect = True
  203. dbif.cursor.execute("BEGIN TRANSACTION")
  204. self.base.update_all(dbif)
  205. if self.is_time_absolute():
  206. self.absolute_time.update_all(dbif)
  207. if self.is_time_relative():
  208. self.relative_time.update_all(dbif)
  209. self.spatial_extent.update_all(dbif)
  210. self.metadata.update_all(dbif)
  211. dbif.cursor.execute("COMMIT TRANSACTION")
  212. if connect:
  213. dbif.close()
  214. def set_time_to_absolute(self):
  215. self.base.set_ttype("absolute")
  216. def set_time_to_relative(self):
  217. self.base.set_ttype("relative")
  218. def is_time_absolute(self):
  219. if self.base.D.has_key("temporal_type"):
  220. return self.base.get_ttype() == "absolute"
  221. else:
  222. return None
  223. def is_time_relative(self):
  224. if self.base.D.has_key("temporal_type"):
  225. return self.base.get_ttype() == "relative"
  226. else:
  227. return None
  228. def temporal_relation(self, map):
  229. """Return the temporal relation of this and the provided temporal map"""
  230. if self.is_time_absolute() and map.is_time_absolute():
  231. return self.absolute_time.temporal_relation(map.absolute_time)
  232. if self.is_time_relative() and map.is_time_relative():
  233. return self.relative_time.temporal_relation(map.relative_time)
  234. return None