abstract_dataset.py 12 KB

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