abstract_map_dataset.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. """!@package grass.temporal
  2. @brief GRASS Python scripting module (temporal GIS functions)
  3. Temporal GIS related functions to be used in temporal GIS Python library package.
  4. Usage:
  5. @code
  6. import grass.temporal as tgis
  7. ...
  8. @endcode
  9. (C) 2008-2011 by the GRASS Development Team
  10. This program is free software under the GNU General Public
  11. License (>=v2). Read the file COPYING that comes with GRASS
  12. for details.
  13. @author Soeren Gebbert
  14. """
  15. from abstract_dataset import *
  16. ###############################################################################
  17. class abstract_map_dataset(abstract_dataset):
  18. """This is the base class for all maps (raster, vector, raster3d)
  19. providing additional function to set the valid time and the spatial extent.
  20. """
  21. def get_new_stds_instance(self, ident):
  22. """Return a new space time dataset instance in which maps are stored with the type of this class
  23. @param ident: The identifier of the dataset
  24. """
  25. raise IOError("This method must be implemented in the subclasses")
  26. def get_stds_register(self):
  27. """Return the space time dataset register table name in which stds are listed in which this map is registered"""
  28. raise IOError("This method must be implemented in the subclasses")
  29. def set_stds_register(self, name):
  30. """Set the space time dataset register table name.
  31. This table stores all space time datasets in which this map is registered.
  32. @param ident: The name of the register table
  33. """
  34. raise IOError("This method must be implemented in the subclasses")
  35. def set_absolute_time(self, start_time, end_time=None, timezone=None):
  36. """Set the absolute time interval with start time and end time
  37. @param start_time: a datetime object specifying the start time of the map
  38. @param end_time: a datetime object specifying the end time of the map
  39. @param timezone: Thee timezone of the map
  40. """
  41. if start_time != None and not isinstance(start_time, datetime) :
  42. core.fatal(_("Start time must be of type datetime"))
  43. if end_time != None and not isinstance(end_time, datetime) :
  44. core.fatal(_("End time must be of type datetime"))
  45. if start_time != None and end_time != None:
  46. if start_time >= end_time:
  47. core.error(_("End time must be later than start time"))
  48. return False
  49. self.base.set_ttype("absolute")
  50. self.absolute_time.set_start_time(start_time)
  51. self.absolute_time.set_end_time(end_time)
  52. self.absolute_time.set_timezone(timezone)
  53. return True
  54. def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
  55. """Update the absolute time
  56. @param start_time: a datetime object specifying the start time of the map
  57. @param end_time: a datetime object specifying the end time of the map
  58. @param timezone: Thee timezone of the map
  59. """
  60. connect = False
  61. if dbif == None:
  62. dbif = sql_database_interface()
  63. dbif.connect()
  64. connect = True
  65. self.set_absolute_time(start_time, end_time, timezone)
  66. self.absolute_time.update_all(dbif)
  67. self.base.update(dbif)
  68. if connect == True:
  69. dbif.close()
  70. def set_relative_time(self, start_time, end_time=None):
  71. """Set the relative time interval
  72. @param start_time: A double value in days
  73. @param end_time: A double value in days
  74. """
  75. if start_time != None and end_time != None:
  76. if abs(float(start_time)) >= abs(float(end_time)):
  77. core.error(_("End time must be greater than start time"))
  78. return False
  79. self.base.set_ttype("relative")
  80. self.relative_time.set_start_time(float(start_time))
  81. if end_time != None:
  82. self.relative_time.set_end_time(float(end_time))
  83. else:
  84. self.relative_time.set_end_time(None)
  85. return True
  86. def update_relative_time(self, start_time, end_time=None, dbif = None):
  87. """Update the relative time interval
  88. @param start_time: A double value in days
  89. @param end_time: A double value in days
  90. @param dbif: The database interface to be used
  91. """
  92. connect = False
  93. if dbif == None:
  94. dbif = sql_database_interface()
  95. dbif.connect()
  96. connect = True
  97. self.set_relative_time(start_time, end_time)
  98. self.relative_time.update_all(dbif)
  99. self.base.update(dbif)
  100. dbif.connection.commit()
  101. if connect == True:
  102. dbif.close()
  103. def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
  104. """Set the spatial extent of the map
  105. @param north: The northern edge
  106. @param south: The southern edge
  107. @param east: The eastern edge
  108. @param west: The western edge
  109. @param top: The top edge
  110. @param bottom: The bottom ege
  111. """
  112. self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
  113. def delete(self, dbif=None):
  114. """Delete a map entry from database if it exists
  115. Remove dependent entries:
  116. * Remove the map entry in each space time dataset in which this map is registered
  117. * Remove the space time dataset register table
  118. @param dbif: The database interface to be used
  119. """
  120. connect = False
  121. if dbif == None:
  122. dbif = sql_database_interface()
  123. dbif.connect()
  124. connect = True
  125. if self.is_in_db(dbif):
  126. # SELECT all needed informations from the database
  127. self.select(dbif)
  128. # First we unregister from all dependent space time datasets
  129. self.unregister(dbif)
  130. # Remove the strds register table
  131. if self.get_stds_register():
  132. sql = "DROP TABLE " + self.get_stds_register()
  133. #print sql
  134. try:
  135. dbif.cursor.execute(sql)
  136. except:
  137. core.error(_("Unable to remove space time dataset register table <%s>") % (self.get_stds_register()))
  138. core.verbose(_("Delete %s dataset <%s> from temporal database") % (self.get_type(), self.get_id()))
  139. # Delete yourself from the database, trigger functions will take care of dependencies
  140. self.base.delete(dbif)
  141. self.reset(None)
  142. dbif.connection.commit()
  143. if connect == True:
  144. dbif.close()
  145. def unregister(self, dbif=None):
  146. """ Remove the map entry in each space time dataset in which this map is registered
  147. @param dbif: The database interface to be used
  148. """
  149. core.verbose(_("Unregister %s dataset <%s> from space time datasets") % (self.get_type(), self.get_id()))
  150. connect = False
  151. if dbif == None:
  152. dbif = sql_database_interface()
  153. dbif.connect()
  154. connect = True
  155. # Get all datasets in which this map is registered
  156. rows = self.get_registered_datasets(dbif)
  157. # For each stds in which the map is registered
  158. if rows:
  159. for row in rows:
  160. # Create a space time dataset object to remove the map
  161. # from its register
  162. stds = self.get_new_stds_instance(row["id"])
  163. stds.select(dbif)
  164. stds.unregister_map(self, dbif)
  165. # Take care to update the space time dataset after
  166. # the map has been unregistred
  167. stds.update_from_registered_maps(dbif)
  168. dbif.connection.commit()
  169. if connect == True:
  170. dbif.close()
  171. def get_registered_datasets(self, dbif=None):
  172. """Return all space time dataset ids in which this map is registered as
  173. dictionary like rows with column "id" or None if this map is not registered in any
  174. space time dataset.
  175. @param dbif: The database interface to be used
  176. """
  177. connect = False
  178. if dbif == None:
  179. dbif = sql_database_interface()
  180. dbif.connect()
  181. connect = True
  182. rows = None
  183. try:
  184. if self.get_stds_register() != None:
  185. # Select all stds tables in which this map is registered
  186. sql = "SELECT id FROM " + self.get_stds_register()
  187. dbif.cursor.execute(sql)
  188. rows = dbif.cursor.fetchall()
  189. except:
  190. core.error(_("Unable to select space time dataset register table <%s>") % (self.get_stds_register()))
  191. if connect == True:
  192. dbif.close()
  193. return rows