abstract_dataset.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. >>> import grass.temporal as tgis
  7. >>> ad = AbstractDataset()
  8. >>> ad.reset(ident="soil@PERMANENT")
  9. Traceback (most recent call last):
  10. File "/usr/lib/python2.7/doctest.py", line 1289, in __run
  11. compileflags, 1) in test.globs
  12. File "<doctest __main__[2]>", line 1, in <module>
  13. ad.reset(ident="soil@PERMANENT")
  14. File "AbstractDataset.py", line 53, in reset
  15. raise ImplementationError("This method must be implemented in the subclasses")
  16. ImplementationError: 'This method must be implemented in the subclasses'
  17. (C) 2008-2011 by the GRASS Development Team
  18. This program is free software under the GNU General Public
  19. License (>=v2). Read the file COPYING that comes with GRASS
  20. for details.
  21. @author Soeren Gebbert
  22. """
  23. import uuid
  24. import copy
  25. from temporal_extent import *
  26. from spatial_extent import *
  27. from metadata import *
  28. class ImplementationError(Exception):
  29. """!Exception raised for the calling of methods that should be implemented in
  30. sub classes.
  31. """
  32. def __init__(self, msg):
  33. self.msg = msg
  34. def __str__(self):
  35. return repr(self.msg)
  36. class AbstractDataset(object):
  37. """!This is the base class for all datasets (raster, vector, raster3d, strds, stvds, str3ds)"""
  38. def reset(self, ident):
  39. """!Reset the internal structure and set the identifier
  40. @param ident: The identifier of the dataset
  41. """
  42. raise ImplementationError("This method must be implemented in the subclasses")
  43. def get_type(self):
  44. """!Return the type of this class"""
  45. raise ImplementationError("This method must be implemented in the subclasses")
  46. def get_new_instance(self, ident):
  47. """!Return a new instance with the type of this class
  48. @param ident: The identifier of the dataset
  49. """
  50. raise ImplementationError("This method must be implemented in the subclasses")
  51. def spatial_overlapping(self, dataset):
  52. """!Return True if the spatial extents are overlapping"""
  53. raise ImplementationError("This method must be implemented in the subclasses")
  54. def spatial_relation(self, dataset):
  55. """Return the spatial relationship between self and dataset"""
  56. raise ImplementationError("This method must be implemented in the subclasses")
  57. def print_info(self):
  58. """!Print information about this class in human readable style"""
  59. raise ImplementationError("This method must be implemented in the subclasses")
  60. def print_shell_info(self):
  61. """!Print information about this class in shell style"""
  62. raise ImplementationError("This method must be implemented in the subclasses")
  63. def print_self(self):
  64. """!Print the content of the internal structure to stdout"""
  65. raise ImplementationError("This method must be implemented in the subclasses")
  66. def set_id(self, ident):
  67. self.base.set_id(ident)
  68. if self.is_time_absolute():
  69. self.absolute_time.set_id(ident)
  70. if self.is_time_relative():
  71. self.relative_time.set_id(ident)
  72. self.spatial_extent.set_id(ident)
  73. self.metadata.set_id(ident)
  74. def get_id(self):
  75. """!Return the unique identifier of the dataset"""
  76. return self.base.get_id()
  77. def get_name(self):
  78. """!Return the name"""
  79. return self.base.get_name()
  80. def get_mapset(self):
  81. """!Return the mapset"""
  82. return self.base.get_mapset()
  83. def get_valid_time(self):
  84. """!Returns a tuple of the start, the end valid time, this can be either datetime or double values
  85. @return A tuple of (start_time, end_time)
  86. """
  87. start = None
  88. end = None
  89. if self.is_time_absolute():
  90. start = self.absolute_time.get_start_time()
  91. end = self.absolute_time.get_end_time()
  92. if self.is_time_relative():
  93. start = self.relative_time.get_start_time()
  94. end = self.relative_time.get_end_time()
  95. return (start, end)
  96. def get_absolute_time(self):
  97. """!Returns a tuple of the start, the end valid time and the timezone of the map
  98. @return A tuple of (start_time, end_time, timezone)
  99. """
  100. start = self.absolute_time.get_start_time()
  101. end = self.absolute_time.get_end_time()
  102. tz = self.absolute_time.get_timezone()
  103. return (start, end, tz)
  104. def get_relative_time(self):
  105. """!Returns the relative time interval (start_time, end_time, unit) or None if not present"""
  106. start = self.relative_time.get_start_time()
  107. end = self.relative_time.get_end_time()
  108. unit = self.relative_time.get_unit()
  109. return (start, end, unit)
  110. def get_relative_time_unit(self):
  111. """!Returns the relative time unit or None if not present"""
  112. unit = self.relative_time.get_unit()
  113. return unit
  114. def check_relative_time_unit(self, unit):
  115. """!Check if unit is of type years, months, days, hours, minutes or seconds
  116. Return True if success or False otherwise
  117. """
  118. # Check unit
  119. units = ["years", "months", "days", "hours", "minutes", "seconds"]
  120. if unit not in units:
  121. return False
  122. return True
  123. def get_temporal_type(self):
  124. """!Return the temporal type of this dataset"""
  125. return self.base.get_ttype()
  126. def get_spatial_extent(self):
  127. """!Return a tuple of spatial extent (north, south, east, west, top, bottom) """
  128. return self.spatial_extent.get_spatial_extent()
  129. def select(self, dbif=None):
  130. """!Select temporal dataset entry from database and fill up the internal structure"""
  131. dbif, connect = init_dbif(dbif)
  132. self.base.select(dbif)
  133. if self.is_time_absolute():
  134. self.absolute_time.select(dbif)
  135. if self.is_time_relative():
  136. self.relative_time.select(dbif)
  137. self.spatial_extent.select(dbif)
  138. self.metadata.select(dbif)
  139. if connect:
  140. dbif.close()
  141. def is_in_db(self, dbif=None):
  142. """!Check if the temporal dataset entry is in the database
  143. @param dbif: The database interface to be used
  144. """
  145. return self.base.is_in_db(dbif)
  146. def delete(self):
  147. """!Delete temporal dataset entry from database if it exists"""
  148. raise ImplementationError("This method must be implemented in the subclasses")
  149. def insert(self, dbif=None, execute=True):
  150. """!Insert temporal dataset entry into database from the internal structure
  151. @param dbif: The database interface to be used
  152. @param execute: If True the SQL statements will be executed.
  153. If False the prepared SQL statements are returned and must be executed by the caller.
  154. """
  155. dbif, connect = init_dbif(dbif)
  156. # Build the INSERT SQL statement
  157. statement = self.base.get_insert_statement_mogrified(dbif)
  158. if self.is_time_absolute():
  159. statement += self.absolute_time.get_insert_statement_mogrified(
  160. dbif)
  161. if self.is_time_relative():
  162. statement += self.relative_time.get_insert_statement_mogrified(
  163. dbif)
  164. statement += self.spatial_extent.get_insert_statement_mogrified(dbif)
  165. statement += self.metadata.get_insert_statement_mogrified(dbif)
  166. if execute:
  167. dbif.execute_transaction(statement)
  168. if connect:
  169. dbif.close()
  170. return ""
  171. if connect:
  172. dbif.close()
  173. return statement
  174. def update(self, dbif=None, execute=True):
  175. """!Update temporal dataset entry of database from the internal structure
  176. excluding None variables
  177. @param dbif: The database interface to be used
  178. @param execute: If True the SQL statements will be executed.
  179. If False the prepared SQL statements are returned and must be executed by the caller.
  180. """
  181. dbif, connect = init_dbif(dbif)
  182. # Build the UPDATE SQL statement
  183. statement = self.base.get_update_statement_mogrified(dbif)
  184. if self.is_time_absolute():
  185. statement += self.absolute_time.get_update_statement_mogrified(
  186. dbif)
  187. if self.is_time_relative():
  188. statement += self.relative_time.get_update_statement_mogrified(
  189. dbif)
  190. statement += self.spatial_extent.get_update_statement_mogrified(dbif)
  191. statement += self.metadata.get_update_statement_mogrified(dbif)
  192. if execute:
  193. dbif.execute_transaction(statement)
  194. if connect:
  195. dbif.close()
  196. return ""
  197. if connect:
  198. dbif.close()
  199. return statement
  200. def update_all(self, dbif=None, execute=True):
  201. """!Update temporal dataset entry of database from the internal structure
  202. and include None variables.
  203. @param dbif: The database interface to be used
  204. @param execute: If True the SQL statements will be executed.
  205. If False the prepared SQL statements are returned and must be executed by the caller.
  206. """
  207. dbif, connect = init_dbif(dbif)
  208. # Build the UPDATE SQL statement
  209. statement = self.base.get_update_all_statement_mogrified(dbif)
  210. if self.is_time_absolute():
  211. statement += self.absolute_time.get_update_all_statement_mogrified(
  212. dbif)
  213. if self.is_time_relative():
  214. statement += self.relative_time.get_update_all_statement_mogrified(
  215. dbif)
  216. statement += self.spatial_extent.get_update_all_statement_mogrified(
  217. dbif)
  218. statement += self.metadata.get_update_all_statement_mogrified(dbif)
  219. if execute:
  220. dbif.execute_transaction(statement)
  221. if connect:
  222. dbif.close()
  223. return ""
  224. if connect:
  225. dbif.close()
  226. return statement
  227. def set_time_to_absolute(self):
  228. self.base.set_ttype("absolute")
  229. def set_time_to_relative(self):
  230. self.base.set_ttype("relative")
  231. def is_time_absolute(self):
  232. if "temporal_type" in self.base.D:
  233. return self.base.get_ttype() == "absolute"
  234. else:
  235. return None
  236. def is_time_relative(self):
  237. if "temporal_type" in self.base.D:
  238. return self.base.get_ttype() == "relative"
  239. else:
  240. return None
  241. def temporal_relation(self, map):
  242. """!Return the temporal relation of this and the provided temporal map"""
  243. if self.is_time_absolute() and map.is_time_absolute():
  244. return self.absolute_time.temporal_relation(map.absolute_time)
  245. if self.is_time_relative() and map.is_time_relative():
  246. return self.relative_time.temporal_relation(map.relative_time)
  247. return None
  248. ###############################################################################
  249. if __name__ == "__main__":
  250. import doctest
  251. doctest.testmod()