temporal_extent.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. """!@package grass.script.tgis_temporal_extent
  2. @brief GRASS Python scripting module (temporal GIS functions)
  3. Temporal GIS related temporal extent functions to be used in Python scripts and tgis packages.
  4. Usage:
  5. @code
  6. from grass.script import tgis_temporal_extent as grass
  7. grass.raster_temporal_extent()
  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. from base import *
  17. ###############################################################################
  18. class abstract_temporal_extent(sql_database_interface):
  19. """This is the abstract time base class for relative and absolute time objects"""
  20. def __init__(self, table=None, ident=None, start_time=None, end_time=None):
  21. sql_database_interface.__init__(self, table, ident)
  22. self.set_id(ident)
  23. self.set_start_time(start_time)
  24. self.set_end_time(end_time)
  25. def starts(self, map):
  26. """Return True if this time object starts at the start of the provided time object and finishes within it
  27. A |-----|
  28. B |---------|
  29. """
  30. if self.D["end_time"] == None or map.D["end_time"] == None :
  31. return False
  32. if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
  33. return True
  34. else:
  35. return False
  36. def started(self, map):
  37. """Return True if this time object is started at the start of the provided time object
  38. A |---------|
  39. B |-----|
  40. """
  41. if self.D["end_time"] == None or map.D["end_time"] == None :
  42. return False
  43. if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
  44. return True
  45. else:
  46. return False
  47. def finishes(self, map):
  48. """Return True if this time object finishes at the end and within of the provided time object
  49. A |-----|
  50. B |---------|
  51. """
  52. if self.D["end_time"] == None or map.D["end_time"] == None :
  53. return False
  54. if self.D["end_time"] == map.D["end_time"] and self.D["start_time"] > map.D["start_time"] :
  55. return True
  56. else:
  57. return False
  58. def finished(self, map):
  59. """Return True if this time object finished at the end of the provided time object
  60. A |---------|
  61. B |-----|
  62. """
  63. if self.D["end_time"] == None or map.D["end_time"] == None :
  64. return False
  65. if self.D["end_time"] == map.D["end_time"] and self.D["start_time"] < map.D["start_time"] :
  66. return True
  67. else:
  68. return False
  69. def after(self, map):
  70. """Return True if this time object is temporal located after the provided time object
  71. A |---------|
  72. B |---------|
  73. """
  74. if map.D["end_time"] == None:
  75. if self.D["start_time"] > map.D["start_time"]:
  76. return True
  77. else:
  78. return False
  79. if self.D["start_time"] > map.D["end_time"]:
  80. return True
  81. else:
  82. return False
  83. def before(self, map):
  84. """Return True if this time object is temporal located bevor the provided time object
  85. A |---------|
  86. B |---------|
  87. """
  88. if self.D["end_time"] == None:
  89. if self.D["start_time"] < map.D["start_time"]:
  90. return True
  91. else:
  92. return False
  93. if self.D["end_time"] < map.D["start_time"]:
  94. return True
  95. else:
  96. return False
  97. def adjacent(self, map):
  98. """Return True if this time object is a meeting neighbour the provided time object
  99. A |---------|
  100. B |---------|
  101. A |---------|
  102. B |---------|
  103. """
  104. if self.D["end_time"] == None and map.D["end_time"] == None :
  105. return False
  106. if (self.D["start_time"] == map.D["end_time"]) or (self.D["end_time"] == map.D["start_time"]):
  107. return True
  108. else:
  109. return False
  110. def follows(self, map):
  111. """Return True if this time object is temporal follows the provided time object
  112. A |---------|
  113. B |---------|
  114. """
  115. if map.D["end_time"] == None :
  116. return False
  117. if self.D["start_time"] == map.D["end_time"]:
  118. return True
  119. else:
  120. return False
  121. def precedes(self, map):
  122. """Return True if this time object is temporal precedes the provided time object
  123. A |---------|
  124. B |---------|
  125. """
  126. if self.D["end_time"] == None:
  127. return False
  128. if self.D["end_time"] == map.D["start_time"]:
  129. return True
  130. else:
  131. return False
  132. def during(self, map):
  133. """Return True if this time object is temporal located during the provided time object
  134. A |-------|
  135. B |---------|
  136. """
  137. if self.D["end_time"] == None and map.D["end_time"] == None :
  138. return False
  139. # Check single point of time in interval
  140. if self.D["end_time"] == None:
  141. if self.D["start_time"] > map.D["start_time"] and self.D["start_time"] < map.D["end_time"]:
  142. return True
  143. else:
  144. return False
  145. if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
  146. return True
  147. else:
  148. return False
  149. def contains(self, map):
  150. """Return True if this time object contains the provided time object
  151. A |---------|
  152. B |-------|
  153. """
  154. if self.D["end_time"] == None and map.D["end_time"] == None :
  155. return False
  156. # Check single point of time in interval
  157. if map.D["end_time"] == None:
  158. if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["start_time"]:
  159. return True
  160. else:
  161. return False
  162. if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
  163. return True
  164. else:
  165. return False
  166. def equivalent(self, map):
  167. """Return True if this time object is temporal located equivalent the provided time object
  168. A |---------|
  169. B |---------|
  170. """
  171. if self.D["end_time"] == None and map.D["end_time"] == None :
  172. if self.D["start_time"] == map.D["start_time"]:
  173. return True
  174. else:
  175. return False
  176. if self.D["end_time"] == None or map.D["end_time"] == None :
  177. return False
  178. if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] == map.D["end_time"]:
  179. return True
  180. else:
  181. return False
  182. def overlaps(self, map):
  183. """Return True if this time object is temporal overlaps the provided time object
  184. A |---------|
  185. B |---------|
  186. """
  187. if self.D["end_time"] == None or map.D["end_time"] == None :
  188. return False
  189. if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] < map.D["end_time"] and\
  190. self.D["end_time"] > map.D["start_time"]:
  191. return True
  192. else:
  193. return False
  194. def overlapped(self, map):
  195. """Return True if this time object is temporal overlaped by the provided time object
  196. A |---------|
  197. B |---------|
  198. """
  199. if self.D["end_time"] == None or map.D["end_time"] == None :
  200. return False
  201. if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] > map.D["end_time"] and\
  202. self.D["start_time"] < map.D["end_time"]:
  203. return True
  204. else:
  205. return False
  206. def temporal_relation(self, map):
  207. """Returns the temporal relation between temporal objects
  208. Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
  209. """
  210. if self.equivalent(map):
  211. return "equivalent"
  212. if self.during(map):
  213. return "during"
  214. if self.contains(map):
  215. return "contains"
  216. if self.overlaps(map):
  217. return "overlaps"
  218. if self.overlapped(map):
  219. return "overlapped"
  220. if self.after(map):
  221. return "after"
  222. if self.before(map):
  223. return "before"
  224. if self.starts(map):
  225. return "starts"
  226. if self.finishes(map):
  227. return "finishes"
  228. if self.started(map):
  229. return "started"
  230. if self.finished(map):
  231. return "finished"
  232. if self.equivalent(map):
  233. return "equivalent"
  234. if self.follows(map):
  235. return "follows"
  236. if self.precedes(map):
  237. return "precedes"
  238. return None
  239. def set_id(self, ident):
  240. """Convenient method to set the unique identifier (primary key)"""
  241. self.ident = ident
  242. self.D["id"] = ident
  243. def set_start_time(self, start_time):
  244. """Set the valid start time of the map"""
  245. self.D["start_time"] = start_time
  246. def set_end_time(self, end_time):
  247. """Set the valid end time of the map"""
  248. self.D["end_time"] = end_time
  249. def get_id(self):
  250. """Convenient method to get the unique identifier (primary key)
  251. @return None if not found
  252. """
  253. if self.D.has_key("id"):
  254. return self.D["id"]
  255. else:
  256. return None
  257. def get_start_time(self):
  258. """Get the valid start time of the map
  259. @return None if not found"""
  260. if self.D.has_key("start_time"):
  261. return self.D["start_time"]
  262. else:
  263. return None
  264. def get_end_time(self):
  265. """Get the valid end time of the map
  266. @return None if not found"""
  267. if self.D.has_key("end_time"):
  268. return self.D["end_time"]
  269. else:
  270. return None
  271. def print_info(self):
  272. """Print information about this class in human readable style"""
  273. # 0123456789012345678901234567890
  274. print " | Start time:................. " + str(self.get_start_time())
  275. print " | End time:................... " + str(self.get_end_time())
  276. def print_shell_info(self):
  277. """Print information about this class in shell style"""
  278. print "start_time=" + str(self.get_start_time())
  279. print "end_time=" + str(self.get_end_time())
  280. ###############################################################################
  281. class absolute_temporal_extent(abstract_temporal_extent):
  282. """This is the absolute time class for all maps and spacetime datasets
  283. start_time and end_time must be of type datetime
  284. """
  285. def __init__(self, table=None, ident=None, start_time=None, end_time=None, timezone=None):
  286. abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
  287. self.set_timezone(timezone)
  288. def set_timezone(self, timezone):
  289. """Set the timezone of the map, integer from 1 - 24"""
  290. self.D["timezone"] = timezone
  291. def get_timezone(self):
  292. """Get the timezone of the map
  293. @return None if not found"""
  294. if self.D.has_key("timezone"):
  295. return self.D["timezone"]
  296. else:
  297. return None
  298. def print_info(self):
  299. """Print information about this class in human readable style"""
  300. # 0123456789012345678901234567890
  301. print " +-------------------- Absolute time -----------------------------------------+"
  302. abstract_temporal_extent.print_info(self)
  303. print " | Timezone:................... " + str(self.get_timezone())
  304. def print_shell_info(self):
  305. """Print information about this class in shell style"""
  306. abstract_temporal_extent.print_shell_info(self)
  307. print "timezone=" + str(self.get_timezone())
  308. ###############################################################################
  309. class raster_absolute_time(absolute_temporal_extent):
  310. def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
  311. absolute_temporal_extent.__init__(self, "raster_absolute_time", ident, start_time, end_time, timezone)
  312. class raster3d_absolute_time(absolute_temporal_extent):
  313. def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
  314. absolute_temporal_extent.__init__(self, "raster3d_absolute_time", ident, start_time, end_time, timezone)
  315. class vector_absolute_time(absolute_temporal_extent):
  316. def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
  317. absolute_temporal_extent.__init__(self, "vector_absolute_time", ident, start_time, end_time, timezone)
  318. ###############################################################################
  319. class stds_absolute_time(absolute_temporal_extent):
  320. def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  321. absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
  322. self.set_granularity(granularity)
  323. def set_granularity(self, granularity):
  324. """Set the granularity of the space time dataset"""
  325. self.D["granularity"] = granularity
  326. def get_granularity(self):
  327. """Get the granularity of the space time dataset
  328. @return None if not found"""
  329. if self.D.has_key("granularity"):
  330. return self.D["granularity"]
  331. else:
  332. return None
  333. def print_info(self):
  334. """Print information about this class in human readable style"""
  335. absolute_temporal_extent.print_info(self)
  336. # 0123456789012345678901234567890
  337. print " | Granularity:................ " + str(self.get_granularity())
  338. def print_shell_info(self):
  339. """Print information about this class in shell style"""
  340. absolute_temporal_extent.print_shell_info(self)
  341. print "granularity=" + str(self.get_granularity())
  342. ###############################################################################
  343. class strds_absolute_time(stds_absolute_time):
  344. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  345. stds_absolute_time.__init__(self, "strds_absolute_time", ident, start_time, end_time, granularity, timezone)
  346. class str3ds_absolute_time(stds_absolute_time):
  347. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  348. stds_absolute_time.__init__(self, "str3ds_absolute_time", ident, start_time, end_time, granularity, timezone)
  349. class stvds_absolute_time(stds_absolute_time):
  350. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  351. stds_absolute_time.__init__(self, "stvds_absolute_time", ident, start_time, end_time, granularity, timezone)
  352. ###############################################################################
  353. class relative_temporal_extent(abstract_temporal_extent):
  354. """This is the relative time class for all maps and spacetime datasets
  355. start_time and end_time must be of type datetime
  356. """
  357. def __init__(self, table=None, ident=None, start_time=None, end_time=None):
  358. abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
  359. def print_info(self):
  360. """Print information about this class in human readable style"""
  361. # 0123456789012345678901234567890
  362. print " +-------------------- Reltive time ------------------------------------------+"
  363. abstract_temporal_extent.print_info(self)
  364. ###############################################################################
  365. class raster_relative_time(relative_temporal_extent):
  366. def __init__(self, ident=None, start_time=None, end_time=None):
  367. relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
  368. class raster3d_relative_time(relative_temporal_extent):
  369. def __init__(self, ident=None, start_time=None, end_time=None):
  370. relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
  371. class vector_relative_time(relative_temporal_extent):
  372. def __init__(self, ident=None, start_time=None, end_time=None):
  373. relative_temporal_extent.__init__(self, "vector_relative_time", ident, start_time, end_time)
  374. ###############################################################################
  375. class stds_relative_time(relative_temporal_extent):
  376. def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None):
  377. relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
  378. self.set_granularity(granularity)
  379. def set_granularity(self, granularity):
  380. """Set the granularity of the space time dataset"""
  381. self.D["granularity"] = granularity
  382. def get_granularity(self):
  383. """Get the granularity of the space time dataset
  384. @return None if not found"""
  385. if self.D.has_key("granularity"):
  386. return self.D["granularity"]
  387. else:
  388. return None
  389. def print_info(self):
  390. """Print information about this class in human readable style"""
  391. relative_temporal_extent.print_info(self)
  392. # 0123456789012345678901234567890
  393. print " | Granularity:................ " + str(self.get_granularity())
  394. def print_shell_info(self):
  395. """Print information about this class in shell style"""
  396. relative_temporal_extent.print_shell_info(self)
  397. print "granularity=" + str(self.get_granularity())
  398. ###############################################################################
  399. class strds_relative_time(stds_relative_time):
  400. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  401. stds_relative_time.__init__(self, "strds_relative_time", ident, start_time, end_time, granularity)
  402. class str3ds_relative_time(stds_relative_time):
  403. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  404. stds_relative_time.__init__(self, "str3ds_relative_time", ident, start_time, end_time, granularity)
  405. class stvds_relative_time(stds_relative_time):
  406. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  407. stds_relative_time.__init__(self, "stvds_relative_time", ident, start_time, end_time, granularity)