temporal_extent.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. """!@package grass.temporal
  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. import grass.temporal as tgis
  7. tgis.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, map_time=None):
  321. absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
  322. self.set_granularity(granularity)
  323. self.set_map_time(map_time)
  324. def set_granularity(self, granularity):
  325. """Set the granularity of the space time dataset"""
  326. self.D["granularity"] = granularity
  327. def set_map_time(self, map_time):
  328. """Set the type of the map time
  329. Registered maps may have different types of time:
  330. Single point of time "point"
  331. Time intervals "interval"
  332. Or single point and interval time "mixed"
  333. This variable will be set automatically when maps are registered.
  334. """
  335. self.D["map_time"] = map_time
  336. def get_granularity(self):
  337. """Get the granularity of the space time dataset
  338. @return None if not found"""
  339. if self.D.has_key("granularity"):
  340. return self.D["granularity"]
  341. else:
  342. return None
  343. def get_map_time(self):
  344. """Get the type of the map time
  345. Registered maps may have different types of time:
  346. Single point of time "point"
  347. Time intervals "interval"
  348. Or single point and interval time "mixed"
  349. This variable will be set automatically when maps are registered.
  350. """
  351. if self.D.has_key("map_time"):
  352. return self.D["map_time"]
  353. else:
  354. return None
  355. def print_info(self):
  356. """Print information about this class in human readable style"""
  357. absolute_temporal_extent.print_info(self)
  358. # 0123456789012345678901234567890
  359. print " | Granularity:................ " + str(self.get_granularity())
  360. print " | Temporal type of maps:...... " + str(self.get_map_time())
  361. def print_shell_info(self):
  362. """Print information about this class in shell style"""
  363. absolute_temporal_extent.print_shell_info(self)
  364. print "granularity=" + str(self.get_granularity())
  365. print "map_time=" + str(self.get_map_time())
  366. ###############################################################################
  367. class strds_absolute_time(stds_absolute_time):
  368. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  369. stds_absolute_time.__init__(self, "strds_absolute_time", ident, start_time, end_time, granularity, timezone)
  370. class str3ds_absolute_time(stds_absolute_time):
  371. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  372. stds_absolute_time.__init__(self, "str3ds_absolute_time", ident, start_time, end_time, granularity, timezone)
  373. class stvds_absolute_time(stds_absolute_time):
  374. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  375. stds_absolute_time.__init__(self, "stvds_absolute_time", ident, start_time, end_time, granularity, timezone)
  376. ###############################################################################
  377. class relative_temporal_extent(abstract_temporal_extent):
  378. """This is the relative time class for all maps and spacetime datasets
  379. start_time and end_time must be of type datetime
  380. """
  381. def __init__(self, table=None, ident=None, start_time=None, end_time=None):
  382. abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
  383. def print_info(self):
  384. """Print information about this class in human readable style"""
  385. # 0123456789012345678901234567890
  386. print " +-------------------- Reltive time ------------------------------------------+"
  387. abstract_temporal_extent.print_info(self)
  388. ###############################################################################
  389. class raster_relative_time(relative_temporal_extent):
  390. def __init__(self, ident=None, start_time=None, end_time=None):
  391. relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
  392. class raster3d_relative_time(relative_temporal_extent):
  393. def __init__(self, ident=None, start_time=None, end_time=None):
  394. relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
  395. class vector_relative_time(relative_temporal_extent):
  396. def __init__(self, ident=None, start_time=None, end_time=None):
  397. relative_temporal_extent.__init__(self, "vector_relative_time", ident, start_time, end_time)
  398. ###############################################################################
  399. class stds_relative_time(relative_temporal_extent):
  400. def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, map_time=None):
  401. relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
  402. self.set_granularity(granularity)
  403. self.set_map_time(map_time)
  404. def set_granularity(self, granularity):
  405. """Set the granularity of the space time dataset"""
  406. self.D["granularity"] = granularity
  407. def set_map_time(self, map_time):
  408. """Set the type of the map time
  409. Registered maps may have different types of time:
  410. Single point of time "point"
  411. Time intervals "interval"
  412. Or single point and interval time "mixed"
  413. This variable will be set automatically when maps are registered.
  414. """
  415. self.D["map_time"] = map_time
  416. def get_granularity(self):
  417. """Get the granularity of the space time dataset
  418. @return None if not found"""
  419. if self.D.has_key("granularity"):
  420. return self.D["granularity"]
  421. else:
  422. return None
  423. def get_map_time(self):
  424. """Get the type of the map time
  425. Registered maps may have different types of time:
  426. Single point of time "point"
  427. Time intervals "interval"
  428. Or single point and interval time "mixed"
  429. This variable will be set automatically when maps are registered.
  430. """
  431. if self.D.has_key("map_time"):
  432. return self.D["map_time"]
  433. else:
  434. return None
  435. def print_info(self):
  436. """Print information about this class in human readable style"""
  437. relative_temporal_extent.print_info(self)
  438. # 0123456789012345678901234567890
  439. print " | Granularity:................ " + str(self.get_granularity())
  440. print " | Temporal type of maps:...... " + str(self.get_map_time())
  441. def print_shell_info(self):
  442. """Print information about this class in shell style"""
  443. relative_temporal_extent.print_shell_info(self)
  444. print "granularity=" + str(self.get_granularity())
  445. print "map_time=" + str(self.get_map_time())
  446. ###############################################################################
  447. class strds_relative_time(stds_relative_time):
  448. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  449. stds_relative_time.__init__(self, "strds_relative_time", ident, start_time, end_time, granularity)
  450. class str3ds_relative_time(stds_relative_time):
  451. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  452. stds_relative_time.__init__(self, "str3ds_relative_time", ident, start_time, end_time, granularity)
  453. class stvds_relative_time(stds_relative_time):
  454. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  455. stds_relative_time.__init__(self, "stvds_relative_time", ident, start_time, end_time, granularity)