temporal_extent.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  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. # Check single point of time in interval
  138. if map.D["end_time"] == None:
  139. return False
  140. # Check single point of time in interval
  141. if self.D["end_time"] == None:
  142. if self.D["start_time"] > map.D["start_time"] and self.D["start_time"] < map.D["end_time"]:
  143. return True
  144. else:
  145. return False
  146. if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
  147. return True
  148. else:
  149. return False
  150. def contains(self, map):
  151. """Return True if this time object contains the provided time object
  152. A |---------|
  153. B |-------|
  154. """
  155. # Check single point of time in interval
  156. if self.D["end_time"] == None:
  157. return False
  158. # Check single point of time in interval
  159. if map.D["end_time"] == None:
  160. if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["start_time"]:
  161. return True
  162. else:
  163. return False
  164. if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
  165. return True
  166. else:
  167. return False
  168. def equivalent(self, map):
  169. """Return True if this time object is temporal located equivalent the provided time object
  170. A |---------|
  171. B |---------|
  172. """
  173. if self.D["end_time"] == None and map.D["end_time"] == None :
  174. if self.D["start_time"] == map.D["start_time"]:
  175. return True
  176. else:
  177. return False
  178. if self.D["end_time"] == None or map.D["end_time"] == None :
  179. return False
  180. if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] == map.D["end_time"]:
  181. return True
  182. else:
  183. return False
  184. def overlaps(self, map):
  185. """Return True if this time object is temporal overlaps the provided time object
  186. A |---------|
  187. B |---------|
  188. """
  189. if self.D["end_time"] == None or map.D["end_time"] == None :
  190. return False
  191. if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] < map.D["end_time"] and\
  192. self.D["end_time"] > map.D["start_time"]:
  193. return True
  194. else:
  195. return False
  196. def overlapped(self, map):
  197. """Return True if this time object is temporal overlaped by the provided time object
  198. A |---------|
  199. B |---------|
  200. """
  201. if self.D["end_time"] == None or map.D["end_time"] == None :
  202. return False
  203. if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] > map.D["end_time"] and\
  204. self.D["start_time"] < map.D["end_time"]:
  205. return True
  206. else:
  207. return False
  208. def temporal_relation(self, map):
  209. """Returns the temporal relation between temporal objects
  210. Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
  211. """
  212. # First check for correct time
  213. if not self.D.has_key("start_time"):
  214. return None
  215. if not self.D.has_key("end_time"):
  216. return None
  217. if not map.D.has_key("start_time"):
  218. return None
  219. if not map.D.has_key("end_time"):
  220. return None
  221. if self.D["start_time"] == None or map.D["start_time"] == None:
  222. return None
  223. if self.equivalent(map):
  224. return "equivalent"
  225. if self.during(map):
  226. return "during"
  227. if self.contains(map):
  228. return "contains"
  229. if self.overlaps(map):
  230. return "overlaps"
  231. if self.overlapped(map):
  232. return "overlapped"
  233. if self.after(map):
  234. return "after"
  235. if self.before(map):
  236. return "before"
  237. if self.starts(map):
  238. return "starts"
  239. if self.finishes(map):
  240. return "finishes"
  241. if self.started(map):
  242. return "started"
  243. if self.finished(map):
  244. return "finished"
  245. if self.follows(map):
  246. return "follows"
  247. if self.precedes(map):
  248. return "precedes"
  249. return None
  250. def set_id(self, ident):
  251. """Convenient method to set the unique identifier (primary key)"""
  252. self.ident = ident
  253. self.D["id"] = ident
  254. def set_start_time(self, start_time):
  255. """Set the valid start time of the map"""
  256. self.D["start_time"] = start_time
  257. def set_end_time(self, end_time):
  258. """Set the valid end time of the map"""
  259. self.D["end_time"] = end_time
  260. def get_id(self):
  261. """Convenient method to get the unique identifier (primary key)
  262. @return None if not found
  263. """
  264. if self.D.has_key("id"):
  265. return self.D["id"]
  266. else:
  267. return None
  268. def get_start_time(self):
  269. """Get the valid start time of the map
  270. @return None if not found"""
  271. if self.D.has_key("start_time"):
  272. return self.D["start_time"]
  273. else:
  274. return None
  275. def get_end_time(self):
  276. """Get the valid end time of the map
  277. @return None if not found"""
  278. if self.D.has_key("end_time"):
  279. return self.D["end_time"]
  280. else:
  281. return None
  282. def print_info(self):
  283. """Print information about this class in human readable style"""
  284. # 0123456789012345678901234567890
  285. print " | Start time:................. " + str(self.get_start_time())
  286. print " | End time:................... " + str(self.get_end_time())
  287. def print_shell_info(self):
  288. """Print information about this class in shell style"""
  289. print "start_time=" + str(self.get_start_time())
  290. print "end_time=" + str(self.get_end_time())
  291. ###############################################################################
  292. class absolute_temporal_extent(abstract_temporal_extent):
  293. """This is the absolute time class for all maps and spacetime datasets
  294. start_time and end_time must be of type datetime
  295. """
  296. def __init__(self, table=None, ident=None, start_time=None, end_time=None, timezone=None):
  297. abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
  298. self.set_timezone(timezone)
  299. def set_timezone(self, timezone):
  300. """Set the timezone of the map, integer from 1 - 24"""
  301. self.D["timezone"] = timezone
  302. def get_timezone(self):
  303. """Get the timezone of the map
  304. @return None if not found"""
  305. if self.D.has_key("timezone"):
  306. return self.D["timezone"]
  307. else:
  308. return None
  309. def print_info(self):
  310. """Print information about this class in human readable style"""
  311. # 0123456789012345678901234567890
  312. print " +-------------------- Absolute time -----------------------------------------+"
  313. abstract_temporal_extent.print_info(self)
  314. print " | Timezone:................... " + str(self.get_timezone())
  315. def print_shell_info(self):
  316. """Print information about this class in shell style"""
  317. abstract_temporal_extent.print_shell_info(self)
  318. print "timezone=" + str(self.get_timezone())
  319. ###############################################################################
  320. class raster_absolute_time(absolute_temporal_extent):
  321. def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
  322. absolute_temporal_extent.__init__(self, "raster_absolute_time", ident, start_time, end_time, timezone)
  323. class raster3d_absolute_time(absolute_temporal_extent):
  324. def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
  325. absolute_temporal_extent.__init__(self, "raster3d_absolute_time", ident, start_time, end_time, timezone)
  326. class vector_absolute_time(absolute_temporal_extent):
  327. def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
  328. absolute_temporal_extent.__init__(self, "vector_absolute_time", ident, start_time, end_time, timezone)
  329. ###############################################################################
  330. class stds_absolute_time(absolute_temporal_extent):
  331. def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None, map_time=None):
  332. absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
  333. self.set_granularity(granularity)
  334. self.set_map_time(map_time)
  335. def set_granularity(self, granularity):
  336. """Set the granularity of the space time dataset"""
  337. self.D["granularity"] = granularity
  338. def set_map_time(self, map_time):
  339. """Set the type of the map time
  340. Registered maps may have different types of time:
  341. Single point of time "point"
  342. Time intervals "interval"
  343. Or single point and interval time "mixed"
  344. This variable will be set automatically when maps are registered.
  345. """
  346. self.D["map_time"] = map_time
  347. def get_granularity(self):
  348. """Get the granularity of the space time dataset
  349. @return None if not found"""
  350. if self.D.has_key("granularity"):
  351. return self.D["granularity"]
  352. else:
  353. return None
  354. def get_map_time(self):
  355. """Get the type of the map time
  356. Registered maps may have different types of time:
  357. Single point of time "point"
  358. Time intervals "interval"
  359. Or single point and interval time "mixed"
  360. This variable will be set automatically when maps are registered.
  361. """
  362. if self.D.has_key("map_time"):
  363. return self.D["map_time"]
  364. else:
  365. return None
  366. def print_info(self):
  367. """Print information about this class in human readable style"""
  368. absolute_temporal_extent.print_info(self)
  369. # 0123456789012345678901234567890
  370. print " | Granularity:................ " + str(self.get_granularity())
  371. print " | Temporal type of maps:...... " + str(self.get_map_time())
  372. def print_shell_info(self):
  373. """Print information about this class in shell style"""
  374. absolute_temporal_extent.print_shell_info(self)
  375. print "granularity=" + str(self.get_granularity())
  376. print "map_time=" + str(self.get_map_time())
  377. ###############################################################################
  378. class strds_absolute_time(stds_absolute_time):
  379. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  380. stds_absolute_time.__init__(self, "strds_absolute_time", ident, start_time, end_time, granularity, timezone)
  381. class str3ds_absolute_time(stds_absolute_time):
  382. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  383. stds_absolute_time.__init__(self, "str3ds_absolute_time", ident, start_time, end_time, granularity, timezone)
  384. class stvds_absolute_time(stds_absolute_time):
  385. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
  386. stds_absolute_time.__init__(self, "stvds_absolute_time", ident, start_time, end_time, granularity, timezone)
  387. ###############################################################################
  388. class relative_temporal_extent(abstract_temporal_extent):
  389. """This is the relative time class for all maps and spacetime datasets
  390. start_time and end_time must be of type datetime
  391. """
  392. def __init__(self, table=None, ident=None, start_time=None, end_time=None):
  393. abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
  394. def print_info(self):
  395. """Print information about this class in human readable style"""
  396. # 0123456789012345678901234567890
  397. print " +-------------------- Reltive time ------------------------------------------+"
  398. abstract_temporal_extent.print_info(self)
  399. ###############################################################################
  400. class raster_relative_time(relative_temporal_extent):
  401. def __init__(self, ident=None, start_time=None, end_time=None):
  402. relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
  403. class raster3d_relative_time(relative_temporal_extent):
  404. def __init__(self, ident=None, start_time=None, end_time=None):
  405. relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
  406. class vector_relative_time(relative_temporal_extent):
  407. def __init__(self, ident=None, start_time=None, end_time=None):
  408. relative_temporal_extent.__init__(self, "vector_relative_time", ident, start_time, end_time)
  409. ###############################################################################
  410. class stds_relative_time(relative_temporal_extent):
  411. def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, map_time=None):
  412. relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
  413. self.set_granularity(granularity)
  414. self.set_map_time(map_time)
  415. def set_granularity(self, granularity):
  416. """Set the granularity of the space time dataset"""
  417. self.D["granularity"] = granularity
  418. def set_map_time(self, map_time):
  419. """Set the type of the map time
  420. Registered maps may have different types of time:
  421. Single point of time "point"
  422. Time intervals "interval"
  423. Or single point and interval time "mixed"
  424. This variable will be set automatically when maps are registered.
  425. """
  426. self.D["map_time"] = map_time
  427. def get_granularity(self):
  428. """Get the granularity of the space time dataset
  429. @return None if not found"""
  430. if self.D.has_key("granularity"):
  431. return self.D["granularity"]
  432. else:
  433. return None
  434. def get_map_time(self):
  435. """Get the type of the map time
  436. Registered maps may have different types of time:
  437. Single point of time "point"
  438. Time intervals "interval"
  439. Or single point and interval time "mixed"
  440. This variable will be set automatically when maps are registered.
  441. """
  442. if self.D.has_key("map_time"):
  443. return self.D["map_time"]
  444. else:
  445. return None
  446. def print_info(self):
  447. """Print information about this class in human readable style"""
  448. relative_temporal_extent.print_info(self)
  449. # 0123456789012345678901234567890
  450. print " | Granularity:................ " + str(self.get_granularity())
  451. print " | Temporal type of maps:...... " + str(self.get_map_time())
  452. def print_shell_info(self):
  453. """Print information about this class in shell style"""
  454. relative_temporal_extent.print_shell_info(self)
  455. print "granularity=" + str(self.get_granularity())
  456. print "map_time=" + str(self.get_map_time())
  457. ###############################################################################
  458. class strds_relative_time(stds_relative_time):
  459. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  460. stds_relative_time.__init__(self, "strds_relative_time", ident, start_time, end_time, granularity)
  461. class str3ds_relative_time(stds_relative_time):
  462. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  463. stds_relative_time.__init__(self, "str3ds_relative_time", ident, start_time, end_time, granularity)
  464. class stvds_relative_time(stds_relative_time):
  465. def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
  466. stds_relative_time.__init__(self, "stvds_relative_time", ident, start_time, end_time, granularity)