abstract_dataset.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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 spatial_overlapping(self, dataset):
  37. """!Return True if the spatial extents are overlapping"""
  38. raise IOError("This method must be implemented in the subclasses")
  39. def spatial_relation(self, dataset):
  40. """Return the spatial relationship between self and dataset"""
  41. raise IOError("This method must be implemented in the subclasses")
  42. def print_info(self):
  43. """!Print information about this class in human readable style"""
  44. raise IOError("This method must be implemented in the subclasses")
  45. def print_shell_info(self):
  46. """!Print information about this class in shell style"""
  47. raise IOError("This method must be implemented in the subclasses")
  48. def print_self(self):
  49. """!Print the content of the internal structure to stdout"""
  50. self.base.print_self()
  51. if self.is_time_absolute():
  52. self.absolute_time.print_self()
  53. if self.is_time_relative():
  54. self.relative_time.print_self()
  55. self.spatial_extent.print_self()
  56. self.metadata.print_self()
  57. def get_id(self):
  58. """!Return the unique identifier of the dataset"""
  59. return self.base.get_id()
  60. def get_name(self):
  61. """!Return the name"""
  62. return self.base.get_name()
  63. def get_mapset(self):
  64. """!Return the mapset"""
  65. return self.base.get_mapset()
  66. def build_id(name, mapset, layer=None):
  67. """!Build and return the id (primary key) based on name, mapset and layer of a dataset.
  68. @param name: The name of the map
  69. @param mapset: The name of the mapset
  70. @param layer: The name of the layer (optional)
  71. Return None in case the name can not be build (name or mapset are None)
  72. """
  73. if not name or not mapset:
  74. return None
  75. # Make sure to extract the pure mapname
  76. pure_name = name.split("@")[0].split(":")[0]
  77. if layer:
  78. return "%s:%s@%s"%(name, layer, mapset)
  79. else:
  80. return "%s@%s"%(name, mapset)
  81. return None
  82. def get_valid_time(self):
  83. """!Returns a tuple of the start, the end valid time, this can be either datetime or double values
  84. @return A tuple of (start_time, end_time)
  85. """
  86. start = None
  87. end = None
  88. if self.is_time_absolute():
  89. start = self.absolute_time.get_start_time()
  90. end = self.absolute_time.get_end_time()
  91. if self.is_time_relative():
  92. start = self.relative_time.get_start_time()
  93. end = self.relative_time.get_end_time()
  94. return (start, end)
  95. def get_absolute_time(self):
  96. """!Returns a tuple of the start, the end valid time and the timezone of the map
  97. @return A tuple of (start_time, end_time, timezone)
  98. """
  99. start = self.absolute_time.get_start_time()
  100. end = self.absolute_time.get_end_time()
  101. tz = self.absolute_time.get_timezone()
  102. return (start, end, tz)
  103. def get_relative_time(self):
  104. """!Returns the relative time interval (start_time, end_time, unit) or None if not present"""
  105. start = self.relative_time.get_start_time()
  106. end = self.relative_time.get_end_time()
  107. unit = self.relative_time.get_unit()
  108. return (start, end, unit)
  109. def get_relative_time_unit(self):
  110. """!Returns the relative time unit or None if not present"""
  111. unit = self.relative_time.get_unit()
  112. return unit
  113. def check_relative_time_unit(self, unit):
  114. """!Check if unit is of type years, months, days, hours, minutes or seconds
  115. Return True if success or False otherwise
  116. """
  117. # Check unit
  118. units = ["years","months","days","hours","minutes","seconds"]
  119. if unit not in units:
  120. return False
  121. return True
  122. def get_temporal_type(self):
  123. """!Return the temporal type of this dataset"""
  124. return self.base.get_ttype()
  125. def get_spatial_extent(self):
  126. """!Return a tuple of spatial extent (north, south, east, west, top, bottom) """
  127. north = self.spatial_extent.get_north()
  128. south = self.spatial_extent.get_south()
  129. east = self.spatial_extent.get_east()
  130. west = self.spatial_extent.get_west()
  131. top = self.spatial_extent.get_top()
  132. bottom = self.spatial_extent.get_bottom()
  133. return (north, south, east, west, top, bottom)
  134. def select(self, dbif=None):
  135. """!Select temporal dataset entry from database and fill up the internal structure"""
  136. dbif, connect = init_dbif(dbif)
  137. self.base.select(dbif)
  138. if self.is_time_absolute():
  139. self.absolute_time.select(dbif)
  140. if self.is_time_relative():
  141. self.relative_time.select(dbif)
  142. self.spatial_extent.select(dbif)
  143. self.metadata.select(dbif)
  144. if connect:
  145. dbif.close()
  146. def is_in_db(self, dbif=None):
  147. """!Check if the temporal dataset entry is in the database
  148. @param dbif: The database interface to be used
  149. """
  150. return self.base.is_in_db(dbif)
  151. def delete(self):
  152. """!Delete temporal dataset entry from database if it exists"""
  153. raise IOError("This method must be implemented in the subclasses")
  154. def insert(self, dbif=None, execute=True):
  155. """!Insert temporal dataset entry into database from the internal structure
  156. @param dbif: The database interface to be used
  157. @param execute: If True the SQL statements will be executed.
  158. If False the prepared SQL statements are returned and must be executed by the caller.
  159. """
  160. dbif, connect = init_dbif(dbif)
  161. # Build the INSERT SQL statement
  162. statement = self.base.get_insert_statement_mogrified(dbif)
  163. if self.is_time_absolute():
  164. statement += self.absolute_time.get_insert_statement_mogrified(dbif)
  165. if self.is_time_relative():
  166. statement += self.relative_time.get_insert_statement_mogrified(dbif)
  167. statement += self.spatial_extent.get_insert_statement_mogrified(dbif)
  168. statement += self.metadata.get_insert_statement_mogrified(dbif)
  169. if execute == True:
  170. dbif.execute_transaction(statement)
  171. if connect:
  172. dbif.close()
  173. return ""
  174. if connect:
  175. dbif.close()
  176. return statement
  177. def update(self, dbif=None, execute=True):
  178. """!Update temporal dataset entry of database from the internal structure
  179. excluding None variables
  180. @param dbif: The database interface to be used
  181. @param execute: If True the SQL statements will be executed.
  182. If False the prepared SQL statements are returned and must be executed by the caller.
  183. """
  184. dbif, connect = init_dbif(dbif)
  185. # Build the UPDATE SQL statement
  186. statement = self.base.get_update_statement_mogrified(dbif)
  187. if self.is_time_absolute():
  188. statement += self.absolute_time.get_update_statement_mogrified(dbif)
  189. if self.is_time_relative():
  190. statement += self.relative_time.get_update_statement_mogrified(dbif)
  191. statement += self.spatial_extent.get_update_statement_mogrified(dbif)
  192. statement += self.metadata.get_update_statement_mogrified(dbif)
  193. if execute == True:
  194. dbif.execute_transaction(statement)
  195. if connect:
  196. dbif.close()
  197. return ""
  198. if connect:
  199. dbif.close()
  200. return statement
  201. def update_all(self, dbif=None, execute=True):
  202. """!Update temporal dataset entry of database from the internal structure
  203. and include None varuables.
  204. @param dbif: The database interface to be used
  205. @param execute: If True the SQL statements will be executed.
  206. If False the prepared SQL statements are returned and must be executed by the caller.
  207. """
  208. dbif, connect = init_dbif(dbif)
  209. # Build the UPDATE SQL statement
  210. statement = self.base.get_update_all_statement_mogrified(dbif)
  211. if self.is_time_absolute():
  212. statement += self.absolute_time.get_update_all_statement_mogrified(dbif)
  213. if self.is_time_relative():
  214. statement += self.relative_time.get_update_all_statement_mogrified(dbif)
  215. statement += self.spatial_extent.get_update_all_statement_mogrified(dbif)
  216. statement += self.metadata.get_update_all_statement_mogrified(dbif)
  217. if execute == True:
  218. dbif.execute_transaction(statement)
  219. if connect:
  220. dbif.close()
  221. return ""
  222. if connect:
  223. dbif.close()
  224. return statement
  225. def set_time_to_absolute(self):
  226. self.base.set_ttype("absolute")
  227. def set_time_to_relative(self):
  228. self.base.set_ttype("relative")
  229. def is_time_absolute(self):
  230. if self.base.D.has_key("temporal_type"):
  231. return self.base.get_ttype() == "absolute"
  232. else:
  233. return None
  234. def is_time_relative(self):
  235. if self.base.D.has_key("temporal_type"):
  236. return self.base.get_ttype() == "relative"
  237. else:
  238. return None
  239. def temporal_relation(self, map):
  240. """!Return the temporal relation of this and the provided temporal map"""
  241. if self.is_time_absolute() and map.is_time_absolute():
  242. return self.absolute_time.temporal_relation(map.absolute_time)
  243. if self.is_time_relative() and map.is_time_relative():
  244. return self.relative_time.temporal_relation(map.relative_time)
  245. return None