temporal_extent.py 49 KB

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