temporal_extent.py 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492
  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. >>> from datetime import datetime
  8. >>> tgis.init()
  9. >>> t = tgis.RasterRelativeTime()
  10. >>> t = tgis.RasterAbsoluteTime()
  11. @endcode
  12. (C) 2008-2011 by the GRASS Development Team
  13. This program is free software under the GNU General Public
  14. License (>=v2). Read the file COPYING that comes with GRASS
  15. for details.
  16. @author Soeren Gebbert
  17. """
  18. from base import *
  19. ###############################################################################
  20. class AbstractTemporalExtent(SQLDatabaseInterface):
  21. """!This is the abstract time base class for relative and absolute time objects
  22. It abstract class implements the interface to absolute and relative time.
  23. Absolute time is represented by datetime time stamps,
  24. relative time is represented by a unit an integer value.
  25. This class implements temporal topology relationships computation
  26. after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic].
  27. Usage:
  28. @code
  29. >>> init()
  30. >>> A = AbstractTemporalExtent(table="raster_absolute_time",
  31. ... ident="soil@PERMANENT", start_time=datetime(2001, 01, 01),
  32. ... end_time=datetime(2005,01,01) )
  33. >>> A.id
  34. 'soil@PERMANENT'
  35. >>> A.start_time
  36. datetime.datetime(2001, 1, 1, 0, 0)
  37. >>> A.end_time
  38. datetime.datetime(2005, 1, 1, 0, 0)
  39. >>> A.print_info()
  40. | Start time:................. 2001-01-01 00:00:00
  41. | End time:................... 2005-01-01 00:00:00
  42. >>> A.print_shell_info()
  43. start_time=2001-01-01 00:00:00
  44. end_time=2005-01-01 00:00:00
  45. >>> # relative time
  46. >>> A = AbstractTemporalExtent(table="raster_absolute_time",
  47. ... ident="soil@PERMANENT", start_time=0, end_time=1 )
  48. >>> A.id
  49. 'soil@PERMANENT'
  50. >>> A.start_time
  51. 0
  52. >>> A.end_time
  53. 1
  54. >>> A.print_info()
  55. | Start time:................. 0
  56. | End time:................... 1
  57. >>> A.print_shell_info()
  58. start_time=0
  59. end_time=1
  60. @endcode
  61. """
  62. def __init__(self, table=None, ident=None, start_time=None, end_time=None):
  63. SQLDatabaseInterface.__init__(self, table, ident)
  64. self.set_id(ident)
  65. self.set_start_time(start_time)
  66. self.set_end_time(end_time)
  67. def intersect(self, extent):
  68. """!Intersect this temporal extent with the provided temporal extent and
  69. return a new temporal extent with the new start and end time
  70. @param extent The temporal extent to intersect with
  71. @return The new temporal extent with start and end time,
  72. or None in case of no intersection
  73. Usage:
  74. @code
  75. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  76. >>> inter = A.intersect(A)
  77. >>> inter.print_info()
  78. | Start time:................. 5
  79. | End time:................... 6
  80. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  81. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  82. >>> inter = A.intersect(B)
  83. >>> inter.print_info()
  84. | Start time:................. 5
  85. | End time:................... 6
  86. >>> inter = B.intersect(A)
  87. >>> inter.print_info()
  88. | Start time:................. 5
  89. | End time:................... 6
  90. >>> A = AbstractTemporalExtent(start_time=3, end_time=6 )
  91. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  92. >>> inter = A.intersect(B)
  93. >>> inter.print_info()
  94. | Start time:................. 5
  95. | End time:................... 6
  96. >>> inter = B.intersect(A)
  97. >>> inter.print_info()
  98. | Start time:................. 5
  99. | End time:................... 6
  100. >>> A = AbstractTemporalExtent(start_time=3, end_time=8 )
  101. >>> B = AbstractTemporalExtent(start_time=5, end_time=6 )
  102. >>> inter = A.intersect(B)
  103. >>> inter.print_info()
  104. | Start time:................. 5
  105. | End time:................... 6
  106. >>> inter = B.intersect(A)
  107. >>> inter.print_info()
  108. | Start time:................. 5
  109. | End time:................... 6
  110. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  111. >>> B = AbstractTemporalExtent(start_time=3, end_time=6 )
  112. >>> inter = A.intersect(B)
  113. >>> inter.print_info()
  114. | Start time:................. 5
  115. | End time:................... 6
  116. >>> inter = B.intersect(A)
  117. >>> inter.print_info()
  118. | Start time:................. 5
  119. | End time:................... 6
  120. >>> A = AbstractTemporalExtent(start_time=5, end_time=None )
  121. >>> B = AbstractTemporalExtent(start_time=3, end_time=6 )
  122. >>> inter = A.intersect(B)
  123. >>> inter.print_info()
  124. | Start time:................. 5
  125. | End time:................... None
  126. >>> inter = B.intersect(A)
  127. >>> inter.print_info()
  128. | Start time:................. 5
  129. | End time:................... None
  130. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  131. >>> B = AbstractTemporalExtent(start_time=3, end_time=4 )
  132. >>> inter = A.intersect(B)
  133. >>> print inter
  134. None
  135. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  136. >>> B = AbstractTemporalExtent(start_time=3, end_time=None )
  137. >>> inter = A.intersect(B)
  138. >>> print inter
  139. None
  140. @endcode
  141. """
  142. relation = self.temporal_relation(extent)
  143. if relation == "after" or relation == "before":
  144. return None
  145. if self.D["end_time"] is None:
  146. return AbstractTemporalExtent(start_time=self.D["start_time"])
  147. if extent.D["end_time"] is None:
  148. return AbstractTemporalExtent(start_time=extent.D["start_time"])
  149. start = None
  150. end = None
  151. if self.D["start_time"] > extent.D["start_time"]:
  152. start = self.D["start_time"]
  153. else:
  154. start = extent.D["start_time"]
  155. if self.D["end_time"] > extent.D["end_time"]:
  156. end = extent.D["end_time"]
  157. else:
  158. end = self.D["end_time"]
  159. if issubclass(type(self), RelativeTemporalExtent):
  160. return RelativeTemporalExtent(start_time=start, end_time=end,
  161. unit=self.get_unit())
  162. elif issubclass(type(self), AbsoluteTemporalExtent):
  163. return AbsoluteTemporalExtent(start_time=start, end_time=end,
  164. timezone=self.get_timezone())
  165. elif issubclass(type(self), AbstractTemporalExtent):
  166. return AbstractTemporalExtent(start_time=start, end_time=end)
  167. def disjoint_union(self, extent):
  168. """!Creates a disjoint union with this temporal extent and the provided one.
  169. Return a new temporal extent with the new start and end time.
  170. @param extent The temporal extent to create a union with
  171. @return The new temporal extent with start and end time
  172. Usage:
  173. @code
  174. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  175. >>> inter = A.intersect(A)
  176. >>> inter.print_info()
  177. | Start time:................. 5
  178. | End time:................... 6
  179. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  180. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  181. >>> inter = A.disjoint_union(B)
  182. >>> inter.print_info()
  183. | Start time:................. 5
  184. | End time:................... 7
  185. >>> inter = B.disjoint_union(A)
  186. >>> inter.print_info()
  187. | Start time:................. 5
  188. | End time:................... 7
  189. >>> A = AbstractTemporalExtent(start_time=3, end_time=6 )
  190. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  191. >>> inter = A.disjoint_union(B)
  192. >>> inter.print_info()
  193. | Start time:................. 3
  194. | End time:................... 7
  195. >>> inter = B.disjoint_union(A)
  196. >>> inter.print_info()
  197. | Start time:................. 3
  198. | End time:................... 7
  199. >>> A = AbstractTemporalExtent(start_time=3, end_time=8 )
  200. >>> B = AbstractTemporalExtent(start_time=5, end_time=6 )
  201. >>> inter = A.disjoint_union(B)
  202. >>> inter.print_info()
  203. | Start time:................. 3
  204. | End time:................... 8
  205. >>> inter = B.disjoint_union(A)
  206. >>> inter.print_info()
  207. | Start time:................. 3
  208. | End time:................... 8
  209. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  210. >>> B = AbstractTemporalExtent(start_time=3, end_time=6 )
  211. >>> inter = A.disjoint_union(B)
  212. >>> inter.print_info()
  213. | Start time:................. 3
  214. | End time:................... 8
  215. >>> inter = B.disjoint_union(A)
  216. >>> inter.print_info()
  217. | Start time:................. 3
  218. | End time:................... 8
  219. >>> A = AbstractTemporalExtent(start_time=5, end_time=None )
  220. >>> B = AbstractTemporalExtent(start_time=3, end_time=6 )
  221. >>> inter = A.disjoint_union(B)
  222. >>> inter.print_info()
  223. | Start time:................. 3
  224. | End time:................... 6
  225. >>> inter = B.disjoint_union(A)
  226. >>> inter.print_info()
  227. | Start time:................. 3
  228. | End time:................... 6
  229. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  230. >>> B = AbstractTemporalExtent(start_time=3, end_time=4 )
  231. >>> inter = A.disjoint_union(B)
  232. >>> inter.print_info()
  233. | Start time:................. 3
  234. | End time:................... 8
  235. >>> inter = B.disjoint_union(A)
  236. >>> inter.print_info()
  237. | Start time:................. 3
  238. | End time:................... 8
  239. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  240. >>> B = AbstractTemporalExtent(start_time=3, end_time=None )
  241. >>> inter = A.disjoint_union(B)
  242. >>> inter.print_info()
  243. | Start time:................. 3
  244. | End time:................... 8
  245. >>> inter = B.disjoint_union(A)
  246. >>> inter.print_info()
  247. | Start time:................. 3
  248. | End time:................... 8
  249. >>> A = AbstractTemporalExtent(start_time=5, end_time=None )
  250. >>> B = AbstractTemporalExtent(start_time=3, end_time=8 )
  251. >>> inter = A.disjoint_union(B)
  252. >>> inter.print_info()
  253. | Start time:................. 3
  254. | End time:................... 8
  255. >>> inter = B.disjoint_union(A)
  256. >>> inter.print_info()
  257. | Start time:................. 3
  258. | End time:................... 8
  259. >>> A = AbstractTemporalExtent(start_time=5, end_time=None )
  260. >>> B = AbstractTemporalExtent(start_time=3, end_time=None )
  261. >>> inter = A.disjoint_union(B)
  262. >>> inter.print_info()
  263. | Start time:................. 3
  264. | End time:................... 5
  265. >>> inter = B.disjoint_union(A)
  266. >>> inter.print_info()
  267. | Start time:................. 3
  268. | End time:................... 5
  269. >>> A = RelativeTemporalExtent(start_time=5, end_time=None, unit="years" )
  270. >>> B = RelativeTemporalExtent(start_time=3, end_time=None, unit="years" )
  271. >>> inter = A.disjoint_union(B)
  272. >>> inter.print_info()
  273. +-------------------- Relative time -----------------------------------------+
  274. | Start time:................. 3
  275. | End time:................... 5
  276. | Relative time unit:......... years
  277. >>> inter = B.disjoint_union(A)
  278. >>> inter.print_info()
  279. +-------------------- Relative time -----------------------------------------+
  280. | Start time:................. 3
  281. | End time:................... 5
  282. | Relative time unit:......... years
  283. >>> from datetime import datetime as dt
  284. >>> A = AbsoluteTemporalExtent(start_time=dt(2001,1,10), end_time=dt(2003,1,1))
  285. >>> B = AbsoluteTemporalExtent(start_time=dt(2005,1,10), end_time=dt(2008,1,1))
  286. >>> inter = A.disjoint_union(B)
  287. >>> inter.print_info()
  288. +-------------------- Absolute time -----------------------------------------+
  289. | Start time:................. 2001-01-10 00:00:00
  290. | End time:................... 2008-01-01 00:00:00
  291. >>> inter = B.disjoint_union(A)
  292. >>> inter.print_info()
  293. +-------------------- Absolute time -----------------------------------------+
  294. | Start time:................. 2001-01-10 00:00:00
  295. | End time:................... 2008-01-01 00:00:00
  296. @endcoe
  297. """
  298. start = None
  299. end = None
  300. if self.D["start_time"] < extent.D["start_time"]:
  301. start = self.D["start_time"]
  302. else:
  303. start = extent.D["start_time"]
  304. # End time handling
  305. if self.D["end_time"] is None and extent.D["end_time"] is None:
  306. if self.D["start_time"] > extent.D["start_time"]:
  307. end = self.D["start_time"]
  308. else:
  309. end = extent.D["start_time"]
  310. elif self.D["end_time"] is None:
  311. if self.D["start_time"] > extent.D["end_time"]:
  312. end = self.D["start_time"]
  313. else:
  314. end = extent.D["end_time"]
  315. elif extent.D["end_time"] is None:
  316. if self.D["end_time"] > extent.D["start_time"]:
  317. end = self.D["end_time"]
  318. else:
  319. end = extent.D["start_time"]
  320. elif self.D["end_time"] < extent.D["end_time"]:
  321. end = extent.D["end_time"]
  322. else:
  323. end = self.D["end_time"]
  324. if issubclass(type(self), RelativeTemporalExtent):
  325. return RelativeTemporalExtent(start_time=start, end_time=end,
  326. unit=self.get_unit())
  327. elif issubclass(type(self), AbsoluteTemporalExtent):
  328. return AbsoluteTemporalExtent(start_time=start, end_time=end,
  329. timezone=self.get_timezone())
  330. elif issubclass(type(self), AbstractTemporalExtent):
  331. return AbstractTemporalExtent(start_time=start, end_time=end)
  332. def union(self, extent):
  333. """!Creates a union with this temporal extent and the provided one.
  334. Return a new temporal extent with the new start and end time.
  335. @param extent The temporal extent to create a union with
  336. @return The new temporal extent with start and end time,
  337. or None in case the temporal extents are unrelated (before or after)
  338. @code
  339. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  340. >>> B = AbstractTemporalExtent(start_time=3, end_time=4 )
  341. >>> inter = A.intersect(B)
  342. >>> print inter
  343. None
  344. >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
  345. >>> B = AbstractTemporalExtent(start_time=3, end_time=None )
  346. >>> inter = A.intersect(B)
  347. >>> print inter
  348. None
  349. @endcode
  350. """
  351. relation = self.temporal_relation(extent)
  352. if relation == "after" or relation == "before":
  353. return None
  354. return self.disjoint_union(extent)
  355. def starts(self, extent):
  356. """!Return True if this temporal extent (A) starts at the start of the
  357. provided temporal extent (B) and finishes within it
  358. @verbatim
  359. A |-----|
  360. B |---------|
  361. @endverbatim
  362. @param extent The temporal extent object with which this extent starts
  363. Usage:
  364. @code
  365. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  366. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  367. >>> A.starts(B)
  368. True
  369. >>> B.starts(A)
  370. False
  371. @endcode
  372. """
  373. if self.D["end_time"] is None or extent.D["end_time"] is None:
  374. return False
  375. if self.D["start_time"] == extent.D["start_time"] and \
  376. self.D["end_time"] < extent.D["end_time"]:
  377. return True
  378. else:
  379. return False
  380. def started(self, extent):
  381. """!Return True if this temporal extent (A) started at the start of the
  382. provided temporal extent (B) and finishes after it
  383. @verbatim
  384. A |---------|
  385. B |-----|
  386. @endverbatim
  387. @param extent The temporal extent object with which this extent started
  388. Usage:
  389. @code
  390. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  391. >>> B = AbstractTemporalExtent(start_time=5, end_time=6 )
  392. >>> A.started(B)
  393. True
  394. >>> B.started(A)
  395. False
  396. @endcode
  397. """
  398. if self.D["end_time"] is None or extent.D["end_time"] is None:
  399. return False
  400. if self.D["start_time"] == extent.D["start_time"] and \
  401. self.D["end_time"] > extent.D["end_time"]:
  402. return True
  403. else:
  404. return False
  405. def finishes(self, extent):
  406. """!Return True if this temporal extent (A) starts after the start of the
  407. provided temporal extent (B) and finishes with it
  408. @verbatim
  409. A |-----|
  410. B |---------|
  411. @endverbatim
  412. @param extent The temporal extent object with which this extent finishes
  413. Usage:
  414. @code
  415. >>> A = AbstractTemporalExtent(start_time=6, end_time=7 )
  416. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  417. >>> A.finishes(B)
  418. True
  419. >>> B.finishes(A)
  420. False
  421. @endcode
  422. """
  423. if self.D["end_time"] is None or extent.D["end_time"] is None:
  424. return False
  425. if self.D["end_time"] == extent.D["end_time"] and \
  426. self.D["start_time"] > extent.D["start_time"]:
  427. return True
  428. else:
  429. return False
  430. def finished(self, extent):
  431. """!Return True if this temporal extent (A) starts before the start of the
  432. provided temporal extent (B) and finishes with it
  433. @verbatim
  434. A |---------|
  435. B |-----|
  436. @endverbatim
  437. @param extent The temporal extent object with which this extent finishes
  438. Usage:
  439. @code
  440. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  441. >>> B = AbstractTemporalExtent(start_time=6, end_time=7 )
  442. >>> A.finished(B)
  443. True
  444. >>> B.finished(A)
  445. False
  446. @endcode
  447. """
  448. if self.D["end_time"] is None or extent.D["end_time"] is None:
  449. return False
  450. if self.D["end_time"] == extent.D["end_time"] and \
  451. self.D["start_time"] < extent.D["start_time"]:
  452. return True
  453. else:
  454. return False
  455. def after(self, extent):
  456. """!Return True if this temporal extent (A) is located after the
  457. provided temporal extent (B)
  458. @verbatim
  459. A |---------|
  460. B |---------|
  461. @endverbatim
  462. @param extent The temporal extent object that is located before this extent
  463. Usage:
  464. @code
  465. >>> A = AbstractTemporalExtent(start_time=8, end_time=9 )
  466. >>> B = AbstractTemporalExtent(start_time=6, end_time=7 )
  467. >>> A.after(B)
  468. True
  469. >>> B.after(A)
  470. False
  471. @endcode
  472. """
  473. if extent.D["end_time"] is None:
  474. if self.D["start_time"] > extent.D["start_time"]:
  475. return True
  476. else:
  477. return False
  478. if self.D["start_time"] > extent.D["end_time"]:
  479. return True
  480. else:
  481. return False
  482. def before(self, extent):
  483. """!Return True if this temporal extent (A) is located before the
  484. provided temporal extent (B)
  485. @verbatim
  486. A |---------|
  487. B |---------|
  488. @endverbatim
  489. @param extent The temporal extent object that is located after this extent
  490. Usage:
  491. @code
  492. >>> A = AbstractTemporalExtent(start_time=6, end_time=7 )
  493. >>> B = AbstractTemporalExtent(start_time=8, end_time=9 )
  494. >>> A.before(B)
  495. True
  496. >>> B.before(A)
  497. False
  498. @endcode
  499. """
  500. if self.D["end_time"] is None:
  501. if self.D["start_time"] < extent.D["start_time"]:
  502. return True
  503. else:
  504. return False
  505. if self.D["end_time"] < extent.D["start_time"]:
  506. return True
  507. else:
  508. return False
  509. def adjacent(self, extent):
  510. """!Return True if this temporal extent (A) is a meeting neighbor the
  511. provided temporal extent (B)
  512. @verbatim
  513. A |---------|
  514. B |---------|
  515. A |---------|
  516. B |---------|
  517. @endverbatim
  518. @param extent The temporal extent object that is a meeting neighbor
  519. of this extent
  520. Usage:
  521. @code
  522. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  523. >>> B = AbstractTemporalExtent(start_time=7, end_time=9 )
  524. >>> A.adjacent(B)
  525. True
  526. >>> B.adjacent(A)
  527. True
  528. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  529. >>> B = AbstractTemporalExtent(start_time=3, end_time=5 )
  530. >>> A.adjacent(B)
  531. True
  532. >>> B.adjacent(A)
  533. True
  534. @endcode
  535. """
  536. if self.D["end_time"] is None and extent.D["end_time"] is None:
  537. return False
  538. if (self.D["start_time"] == extent.D["end_time"]) or \
  539. (self.D["end_time"] == extent.D["start_time"]):
  540. return True
  541. else:
  542. return False
  543. def follows(self, extent):
  544. """!Return True if this temporal extent (A) follows the
  545. provided temporal extent (B)
  546. @verbatim
  547. A |---------|
  548. B |---------|
  549. @endverbatim
  550. @param extent The temporal extent object that is the predecessor
  551. of this extent
  552. Usage:
  553. @code
  554. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  555. >>> B = AbstractTemporalExtent(start_time=3, end_time=5 )
  556. >>> A.follows(B)
  557. True
  558. >>> B.follows(A)
  559. False
  560. @endcode
  561. """
  562. if extent.D["end_time"] is None:
  563. return False
  564. if self.D["start_time"] == extent.D["end_time"]:
  565. return True
  566. else:
  567. return False
  568. def precedes(self, extent):
  569. """!Return True if this temporal extent (A) precedes the provided
  570. temporal extent (B)
  571. @verbatim
  572. A |---------|
  573. B |---------|
  574. @endverbatim
  575. @param extent The temporal extent object that is the successor
  576. of this extent
  577. Usage:
  578. @code
  579. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  580. >>> B = AbstractTemporalExtent(start_time=7, end_time=9 )
  581. >>> A.precedes(B)
  582. True
  583. >>> B.precedes(A)
  584. False
  585. @endcode
  586. """
  587. if self.D["end_time"] is None:
  588. return False
  589. if self.D["end_time"] == extent.D["start_time"]:
  590. return True
  591. else:
  592. return False
  593. def during(self, extent):
  594. """!Return True if this temporal extent (A) is located during the provided
  595. temporal extent (B)
  596. @verbatim
  597. A |-------|
  598. B |---------|
  599. @endverbatim
  600. @param extent The temporal extent object that contains this extent
  601. Usage:
  602. @code
  603. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  604. >>> B = AbstractTemporalExtent(start_time=4, end_time=9 )
  605. >>> A.during(B)
  606. True
  607. >>> B.during(A)
  608. False
  609. @endcode
  610. """
  611. # Check single point of time in interval
  612. if extent.D["end_time"] is None:
  613. return False
  614. # Check single point of time in interval
  615. if self.D["end_time"] is None:
  616. if self.D["start_time"] >= extent.D["start_time"] and \
  617. self.D["start_time"] < extent.D["end_time"]:
  618. return True
  619. else:
  620. return False
  621. if self.D["start_time"] > extent.D["start_time"] and \
  622. self.D["end_time"] < extent.D["end_time"]:
  623. return True
  624. else:
  625. return False
  626. def contains(self, extent):
  627. """!Return True if this temporal extent (A) contains the provided
  628. temporal extent (B)
  629. @verbatim
  630. A |---------|
  631. B |-------|
  632. @endverbatim
  633. @param extent The temporal extent object that is located
  634. during this extent
  635. Usage:
  636. @code
  637. >>> A = AbstractTemporalExtent(start_time=4, end_time=9 )
  638. >>> B = AbstractTemporalExtent(start_time=5, end_time=8 )
  639. >>> A.contains(B)
  640. True
  641. >>> B.contains(A)
  642. False
  643. @endcode
  644. """
  645. # Check single point of time in interval
  646. if self.D["end_time"] is None:
  647. return False
  648. # Check single point of time in interval
  649. if extent.D["end_time"] is None:
  650. if self.D["start_time"] <= extent.D["start_time"] and \
  651. self.D["end_time"] > extent.D["start_time"]:
  652. return True
  653. else:
  654. return False
  655. if self.D["start_time"] < extent.D["start_time"] and \
  656. self.D["end_time"] > extent.D["end_time"]:
  657. return True
  658. else:
  659. return False
  660. def equal(self, extent):
  661. """!Return True if this temporal extent (A) is equal to the provided
  662. temporal extent (B)
  663. @verbatim
  664. A |---------|
  665. B |---------|
  666. @endverbatim
  667. @param extent The temporal extent object that is equal
  668. during this extent
  669. Usage:
  670. @code
  671. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  672. >>> B = AbstractTemporalExtent(start_time=5, end_time=6 )
  673. >>> A.equal(B)
  674. True
  675. >>> B.equal(A)
  676. True
  677. @endcode
  678. """
  679. if self.D["end_time"] is None and extent.D["end_time"] is None:
  680. if self.D["start_time"] == extent.D["start_time"]:
  681. return True
  682. else:
  683. return False
  684. if self.D["end_time"] is None or extent.D["end_time"] is None:
  685. return False
  686. if self.D["start_time"] == extent.D["start_time"] and \
  687. self.D["end_time"] == extent.D["end_time"]:
  688. return True
  689. else:
  690. return False
  691. def overlaps(self, extent):
  692. """!Return True if this temporal extent (A) overlapped the provided
  693. temporal extent (B)
  694. @verbatim
  695. A |---------|
  696. B |---------|
  697. @endverbatim
  698. @param extent The temporal extent object that is overlaps
  699. this extent
  700. Usage:
  701. @code
  702. >>> A = AbstractTemporalExtent(start_time=5, end_time=7 )
  703. >>> B = AbstractTemporalExtent(start_time=6, end_time=8 )
  704. >>> A.overlaps(B)
  705. True
  706. >>> B.overlaps(A)
  707. False
  708. >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
  709. >>> B = AbstractTemporalExtent(start_time=6, end_time=8 )
  710. >>> A.overlaps(B)
  711. False
  712. >>> B.overlaps(A)
  713. False
  714. @endcode
  715. """
  716. if self.D["end_time"] is None or extent.D["end_time"] is None:
  717. return False
  718. if self.D["start_time"] < extent.D["start_time"] and \
  719. self.D["end_time"] < extent.D["end_time"] and \
  720. self.D["end_time"] > extent.D["start_time"]:
  721. return True
  722. else:
  723. return False
  724. def overlapped(self, extent):
  725. """!Return True if this temporal extent (A) overlapps the provided
  726. temporal extent (B)
  727. @verbatim
  728. A |---------|
  729. B |---------|
  730. @endverbatim
  731. @param extent The temporal extent object that is overlapped
  732. this extent
  733. Usage:
  734. @code
  735. >>> A = AbstractTemporalExtent(start_time=6, end_time=8 )
  736. >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
  737. >>> A.overlapped(B)
  738. True
  739. >>> B.overlapped(A)
  740. False
  741. >>> A = AbstractTemporalExtent(start_time=6, end_time=8 )
  742. >>> B = AbstractTemporalExtent(start_time=5, end_time=6 )
  743. >>> A.overlapped(B)
  744. False
  745. >>> B.overlapped(A)
  746. False
  747. @endcode
  748. """
  749. if self.D["end_time"] is None or extent.D["end_time"] is None:
  750. return False
  751. if self.D["start_time"] > extent.D["start_time"] and \
  752. self.D["end_time"] > extent.D["end_time"] and \
  753. self.D["start_time"] < extent.D["end_time"]:
  754. return True
  755. else:
  756. return False
  757. def temporal_relation(self, extent):
  758. """!Returns the temporal relation between temporal objects
  759. Temporal relationships are implemented after
  760. [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
  761. The following temporal relationships are supported:
  762. - equal
  763. - during
  764. - contains
  765. - overlaps
  766. - overlapped
  767. - after
  768. - before
  769. - starts
  770. - finishes
  771. - started
  772. - finished
  773. - follows
  774. - precedes
  775. @param extent The temporal extent
  776. @return The name of the temporal relation or None if no relation found
  777. """
  778. # First check for correct time
  779. if "start_time" not in self.D:
  780. return None
  781. if "end_time" not in self.D:
  782. return None
  783. if "start_time" not in extent.D:
  784. return None
  785. if "end_time" not in extent.D:
  786. return None
  787. # Return None if the start_time is undefined
  788. if self.D["start_time"] is None or extent.D["start_time"] is None:
  789. return None
  790. if self.equal(extent):
  791. return "equal"
  792. if self.during(extent):
  793. return "during"
  794. if self.contains(extent):
  795. return "contains"
  796. if self.overlaps(extent):
  797. return "overlaps"
  798. if self.overlapped(extent):
  799. return "overlapped"
  800. if self.after(extent):
  801. return "after"
  802. if self.before(extent):
  803. return "before"
  804. if self.starts(extent):
  805. return "starts"
  806. if self.finishes(extent):
  807. return "finishes"
  808. if self.started(extent):
  809. return "started"
  810. if self.finished(extent):
  811. return "finished"
  812. if self.follows(extent):
  813. return "follows"
  814. if self.precedes(extent):
  815. return "precedes"
  816. return None
  817. def set_id(self, ident):
  818. """!Convenient method to set the unique identifier (primary key)"""
  819. self.ident = ident
  820. self.D["id"] = ident
  821. def set_start_time(self, start_time):
  822. """!Set the valid start time of the extent"""
  823. self.D["start_time"] = start_time
  824. def set_end_time(self, end_time):
  825. """!Set the valid end time of the extent"""
  826. self.D["end_time"] = end_time
  827. def get_id(self):
  828. """!Convenient method to get the unique identifier (primary key)
  829. @return None if not found
  830. """
  831. if "id" in self.D:
  832. return self.D["id"]
  833. else:
  834. return None
  835. def get_start_time(self):
  836. """!Get the valid start time of the extent
  837. @return None if not found"""
  838. if "start_time" in self.D:
  839. return self.D["start_time"]
  840. else:
  841. return None
  842. def get_end_time(self):
  843. """!Get the valid end time of the extent
  844. @return None if not found"""
  845. if "end_time" in self.D:
  846. return self.D["end_time"]
  847. else:
  848. return None
  849. # Set the properties
  850. id = property(fget=get_id, fset=set_id)
  851. start_time = property(fget=get_start_time, fset=set_start_time)
  852. end_time = property(fget=get_end_time, fset=set_end_time)
  853. def print_info(self):
  854. """!Print information about this class in human readable style"""
  855. # 0123456789012345678901234567890
  856. print " | Start time:................. " + str(self.get_start_time())
  857. print " | End time:................... " + str(self.get_end_time())
  858. def print_shell_info(self):
  859. """!Print information about this class in shell style"""
  860. print "start_time=" + str(self.get_start_time())
  861. print "end_time=" + str(self.get_end_time())
  862. ###############################################################################
  863. class AbsoluteTemporalExtent(AbstractTemporalExtent):
  864. """!This is the absolute time class for all maps and spacetime datasets
  865. start_time and end_time must be of type datetime
  866. """
  867. def __init__(self, table=None, ident=None, start_time=None, end_time=None,
  868. timezone=None):
  869. AbstractTemporalExtent.__init__(
  870. self, table, ident, start_time, end_time)
  871. self.set_timezone(timezone)
  872. def set_timezone(self, timezone):
  873. """!Set the timezone of the map, the timezone is of type string.
  874. Timezones are not supported yet, instead the timezone
  875. is set in the datetime string as offset in minutes.
  876. """
  877. self.D["timezone"] = timezone
  878. def get_timezone(self):
  879. """!Get the timezone of the map
  880. Timezones are not supported yet, instead the timezone
  881. is set in the datetime string as offset in minutes.
  882. @return None if not found"""
  883. if "timezone" in self.D:
  884. return self.D["timezone"]
  885. else:
  886. return None
  887. timezone = property(fget=get_timezone, fset=set_timezone)
  888. def print_info(self):
  889. """!Print information about this class in human readable style"""
  890. # 0123456789012345678901234567890
  891. print " +-------------------- Absolute time -----------------------------------------+"
  892. AbstractTemporalExtent.print_info(self)
  893. #print " | Timezone:................... " + str(self.get_timezone())
  894. def print_shell_info(self):
  895. """!Print information about this class in shell style"""
  896. AbstractTemporalExtent.print_shell_info(self)
  897. #print "timezone=" + str(self.get_timezone())
  898. ###############################################################################
  899. class RasterAbsoluteTime(AbsoluteTemporalExtent):
  900. def __init__(self, ident=None, start_time=None, end_time=None,
  901. timezone=None):
  902. AbsoluteTemporalExtent.__init__(self, "raster_absolute_time",
  903. ident, start_time, end_time, timezone)
  904. class Raster3DAbsoluteTime(AbsoluteTemporalExtent):
  905. def __init__(self, ident=None, start_time=None, end_time=None,
  906. timezone=None):
  907. AbsoluteTemporalExtent.__init__(self, "raster3d_absolute_time",
  908. ident, start_time, end_time, timezone)
  909. class VectorAbsoluteTime(AbsoluteTemporalExtent):
  910. def __init__(self, ident=None, start_time=None, end_time=None,
  911. timezone=None):
  912. AbsoluteTemporalExtent.__init__(self, "vector_absolute_time",
  913. ident, start_time, end_time, timezone)
  914. ###############################################################################
  915. class STDSAbsoluteTime(AbsoluteTemporalExtent):
  916. """!This class implements the absolute time extent for space time dataset
  917. In addition to the existing functionality the granularity and the
  918. map_time are added.
  919. Usage:
  920. @code
  921. >>> init()
  922. >>> A = STDSAbsoluteTime(table="strds_absolute_time",
  923. ... ident="strds@PERMANENT", start_time=datetime(2001, 01, 01),
  924. ... end_time=datetime(2005,01,01), granularity="1 days",
  925. ... map_time="interval")
  926. >>> A.id
  927. 'strds@PERMANENT'
  928. >>> A.start_time
  929. datetime.datetime(2001, 1, 1, 0, 0)
  930. >>> A.end_time
  931. datetime.datetime(2005, 1, 1, 0, 0)
  932. >>> A.granularity
  933. '1 days'
  934. >>> A.map_time
  935. 'interval'
  936. >>> A.print_info()
  937. +-------------------- Absolute time -----------------------------------------+
  938. | Start time:................. 2001-01-01 00:00:00
  939. | End time:................... 2005-01-01 00:00:00
  940. | Granularity:................ 1 days
  941. | Temporal type of maps:...... interval
  942. >>> A.print_shell_info()
  943. start_time=2001-01-01 00:00:00
  944. end_time=2005-01-01 00:00:00
  945. granularity=1 days
  946. map_time=interval
  947. @endcode
  948. """
  949. def __init__(self, table=None, ident=None, start_time=None, end_time=None,
  950. granularity=None, timezone=None, map_time=None):
  951. AbsoluteTemporalExtent.__init__(
  952. self, table, ident, start_time, end_time, timezone)
  953. self.set_granularity(granularity)
  954. self.set_map_time(map_time)
  955. def set_granularity(self, granularity):
  956. """!Set the granularity of the space time dataset"""
  957. self.D["granularity"] = granularity
  958. def set_map_time(self, map_time):
  959. """!Set the type of the map time
  960. Registered maps may have different types of time:
  961. - Single point of time "point"
  962. - Time intervals "interval"
  963. - Single point and interval time "mixed"
  964. This variable will be set automatically when maps are registered.
  965. """
  966. self.D["map_time"] = map_time
  967. def get_granularity(self):
  968. """!Get the granularity of the space time dataset
  969. @return None if not found"""
  970. if "granularity" in self.D:
  971. return self.D["granularity"]
  972. else:
  973. return None
  974. def get_map_time(self):
  975. """!Get the type of the map time
  976. Registered maps may have different types of time:
  977. Single point of time "point"
  978. Time intervals "interval"
  979. Or single point and interval time "mixed"
  980. This variable will be set automatically when maps are registered.
  981. """
  982. if "map_time" in self.D:
  983. return self.D["map_time"]
  984. else:
  985. return None
  986. # Properties
  987. granularity = property(fget=get_granularity, fset=set_granularity)
  988. map_time = property(fget=get_map_time, fset=set_map_time)
  989. def print_info(self):
  990. """!Print information about this class in human readable style"""
  991. AbsoluteTemporalExtent.print_info(self)
  992. # 0123456789012345678901234567890
  993. print " | Granularity:................ " + str(self.get_granularity())
  994. print " | Temporal type of maps:...... " + str(self.get_map_time())
  995. def print_shell_info(self):
  996. """!Print information about this class in shell style"""
  997. AbsoluteTemporalExtent.print_shell_info(self)
  998. print "granularity=" + str(self.get_granularity())
  999. print "map_time=" + str(self.get_map_time())
  1000. ###############################################################################
  1001. class STRDSAbsoluteTime(STDSAbsoluteTime):
  1002. def __init__(self, ident=None, start_time=None, end_time=None,
  1003. granularity=None, timezone=None):
  1004. STDSAbsoluteTime.__init__(self, "strds_absolute_time",
  1005. ident, start_time, end_time, granularity, timezone)
  1006. class STR3DSAbsoluteTime(STDSAbsoluteTime):
  1007. def __init__(self, ident=None, start_time=None, end_time=None,
  1008. granularity=None, timezone=None):
  1009. STDSAbsoluteTime.__init__(self, "str3ds_absolute_time",
  1010. ident, start_time, end_time, granularity, timezone)
  1011. class STVDSAbsoluteTime(STDSAbsoluteTime):
  1012. def __init__(self, ident=None, start_time=None, end_time=None,
  1013. granularity=None, timezone=None):
  1014. STDSAbsoluteTime.__init__(self, "stvds_absolute_time",
  1015. ident, start_time, end_time, granularity, timezone)
  1016. ###############################################################################
  1017. class RelativeTemporalExtent(AbstractTemporalExtent):
  1018. """!This is the relative time class for all maps and space time datasets
  1019. start_time and end_time must be of type integer
  1020. Usage:
  1021. @code
  1022. >>> init()
  1023. >>> A = RelativeTemporalExtent(table="raster_relative_time",
  1024. ... ident="soil@PERMANENT", start_time=0, end_time=1, unit="years")
  1025. >>> A.id
  1026. 'soil@PERMANENT'
  1027. >>> A.start_time
  1028. 0
  1029. >>> A.end_time
  1030. 1
  1031. >>> A.unit
  1032. 'years'
  1033. >>> A.print_info()
  1034. +-------------------- Relative time -----------------------------------------+
  1035. | Start time:................. 0
  1036. | End time:................... 1
  1037. | Relative time unit:......... years
  1038. >>> A.print_shell_info()
  1039. start_time=0
  1040. end_time=1
  1041. unit=years
  1042. @endcode
  1043. """
  1044. def __init__(self, table=None, ident=None, start_time=None, end_time=None,
  1045. unit=None):
  1046. AbstractTemporalExtent.__init__(
  1047. self, table, ident, start_time, end_time)
  1048. self.D["unit"] = unit
  1049. def set_unit(self, unit):
  1050. """!Set the unit of the relative time. Valid units are:
  1051. - years
  1052. - months
  1053. - days
  1054. - hours
  1055. - minutes
  1056. - seconds
  1057. """
  1058. self.D["unit"] = unit
  1059. def get_unit(self):
  1060. """!Get the unit of the relative time
  1061. @return None if not found"""
  1062. if "unit" in self.D:
  1063. return self.D["unit"]
  1064. else:
  1065. return None
  1066. def temporal_relation(self, map):
  1067. """!Returns the temporal relation between temporal objects
  1068. Temporal relationships are implemented after
  1069. [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
  1070. """
  1071. # Check units for relative time
  1072. if "unit" not in self.D:
  1073. return None
  1074. if "unit" not in map.D:
  1075. return None
  1076. # Units must be equal
  1077. if self.D["unit"] != map.D["unit"]:
  1078. return None
  1079. return AbstractTemporalExtent.temporal_relation(self, map)
  1080. # Properties
  1081. unit = property(fget=get_unit, fset=set_unit)
  1082. def print_info(self):
  1083. """!Print information about this class in human readable style"""
  1084. # 0123456789012345678901234567890
  1085. print " +-------------------- Relative time -----------------------------------------+"
  1086. AbstractTemporalExtent.print_info(self)
  1087. print " | Relative time unit:......... " + str(self.get_unit())
  1088. def print_shell_info(self):
  1089. """!Print information about this class in shell style"""
  1090. AbstractTemporalExtent.print_shell_info(self)
  1091. print "unit=" + str(self.get_unit())
  1092. ###############################################################################
  1093. class RasterRelativeTime(RelativeTemporalExtent):
  1094. def __init__(self, ident=None, start_time=None, end_time=None,
  1095. unit=None):
  1096. RelativeTemporalExtent.__init__(
  1097. self, "raster_relative_time", ident, start_time, end_time, unit)
  1098. class Raster3DRelativeTime(RelativeTemporalExtent):
  1099. def __init__(self, ident=None, start_time=None, end_time=None,
  1100. unit=None):
  1101. RelativeTemporalExtent.__init__(self,
  1102. "raster3d_relative_time", ident, start_time, end_time, unit)
  1103. class VectorRelativeTime(RelativeTemporalExtent):
  1104. def __init__(self, ident=None, start_time=None, end_time=None,
  1105. unit=None):
  1106. RelativeTemporalExtent.__init__(
  1107. self, "vector_relative_time", ident, start_time, end_time, unit)
  1108. ###############################################################################
  1109. class STDSRelativeTime(RelativeTemporalExtent):
  1110. """!This is the relative time class for all maps and space time datasets
  1111. start_time and end_time must be of type integer
  1112. Usage:
  1113. @code
  1114. >>> init()
  1115. >>> A = STDSRelativeTime(table="strds_relative_time",
  1116. ... ident="strds@PERMANENT", start_time=0, end_time=1, unit="years",
  1117. ... granularity=5, map_time="interval")
  1118. >>> A.id
  1119. 'strds@PERMANENT'
  1120. >>> A.start_time
  1121. 0
  1122. >>> A.end_time
  1123. 1
  1124. >>> A.unit
  1125. 'years'
  1126. >>> A.granularity
  1127. 5
  1128. >>> A.map_time
  1129. 'interval'
  1130. >>> A.print_info()
  1131. +-------------------- Relative time -----------------------------------------+
  1132. | Start time:................. 0
  1133. | End time:................... 1
  1134. | Relative time unit:......... years
  1135. | Granularity:................ 5
  1136. | Temporal type of maps:...... interval
  1137. >>> A.print_shell_info()
  1138. start_time=0
  1139. end_time=1
  1140. unit=years
  1141. granularity=5
  1142. map_time=interval
  1143. @endcode
  1144. """
  1145. def __init__(self, table=None, ident=None, start_time=None, end_time=None,
  1146. unit=None, granularity=None, map_time=None):
  1147. RelativeTemporalExtent.__init__(
  1148. self, table, ident, start_time, end_time, unit)
  1149. self.set_granularity(granularity)
  1150. self.set_map_time(map_time)
  1151. def set_granularity(self, granularity):
  1152. """!Set the granularity of the space time dataset"""
  1153. self.D["granularity"] = granularity
  1154. def set_map_time(self, map_time):
  1155. """!Set the type of the map time
  1156. Registered maps may have different types of time:
  1157. Single point of time "point"
  1158. Time intervals "interval"
  1159. Or single point and interval time "mixed"
  1160. This variable will be set automatically when maps are registered.
  1161. """
  1162. self.D["map_time"] = map_time
  1163. def get_granularity(self):
  1164. """!Get the granularity of the space time dataset
  1165. @return None if not found"""
  1166. if "granularity" in self.D:
  1167. return self.D["granularity"]
  1168. else:
  1169. return None
  1170. def get_map_time(self):
  1171. """!Get the type of the map time
  1172. Registered maps may have different types of time:
  1173. Single point of time "point"
  1174. Time intervals "interval"
  1175. Or single point and interval time "mixed"
  1176. This variable will be set automatically when maps are registered.
  1177. """
  1178. if "map_time" in self.D:
  1179. return self.D["map_time"]
  1180. else:
  1181. return None
  1182. # Properties
  1183. granularity = property(fget=get_granularity, fset=set_granularity)
  1184. map_time = property(fget=get_map_time, fset=set_map_time)
  1185. def print_info(self):
  1186. """!Print information about this class in human readable style"""
  1187. RelativeTemporalExtent.print_info(self)
  1188. # 0123456789012345678901234567890
  1189. print " | Granularity:................ " + str(self.get_granularity())
  1190. print " | Temporal type of maps:...... " + str(self.get_map_time())
  1191. def print_shell_info(self):
  1192. """!Print information about this class in shell style"""
  1193. RelativeTemporalExtent.print_shell_info(self)
  1194. print "granularity=" + str(self.get_granularity())
  1195. print "map_time=" + str(self.get_map_time())
  1196. ###############################################################################
  1197. class STRDSRelativeTime(STDSRelativeTime):
  1198. def __init__(self, ident=None, start_time=None, end_time=None,
  1199. unit=None, granularity=None, map_time=None):
  1200. STDSRelativeTime.__init__(self, "strds_relative_time",
  1201. ident, start_time, end_time, unit, granularity, map_time)
  1202. class STR3DSRelativeTime(STDSRelativeTime):
  1203. def __init__(self, ident=None, start_time=None, end_time=None,
  1204. unit=None, granularity=None, map_time=None):
  1205. STDSRelativeTime.__init__(self, "str3ds_relative_time",
  1206. ident, start_time, end_time, unit, granularity, map_time)
  1207. class STVDSRelativeTime(STDSRelativeTime):
  1208. def __init__(self, ident=None, start_time=None, end_time=None,
  1209. unit=None, granularity=None, map_time=None):
  1210. STDSRelativeTime.__init__(self, "stvds_relative_time",
  1211. ident, start_time, end_time, unit, granularity, map_time)
  1212. ###############################################################################
  1213. if __name__ == "__main__":
  1214. import doctest
  1215. doctest.testmod()