temporal_granularity.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. """!@package grass.temporal
  2. @brief GRASS Python scripting module (temporal GIS functions)
  3. Temporal GIS related functions to be used in temporal GIS Python library package.
  4. Usage:
  5. @code
  6. import grass.temporal as tgis
  7. tgis.compute_relative_time_granularity(maps)
  8. ...
  9. @endcode
  10. (C) 2008-2011 by the GRASS Development Team
  11. This program is free software under the GNU General Public
  12. License (>=v2). Read the file COPYING that comes with GRASS
  13. for details.
  14. @author Soeren Gebbert
  15. """
  16. from abstract_dataset import *
  17. from datetime_math import *
  18. ###############################################################################
  19. def compute_relative_time_granularity(maps):
  20. """ Compute the relative granularity"""
  21. # The interval time must be scaled to days resolution
  22. granularity = None
  23. delta = []
  24. # First we compute the timedelta of the intervals
  25. for map in maps:
  26. start, end = map.get_valid_time()
  27. if start and end:
  28. t = abs(end - start)
  29. delta.append(int(t))
  30. # Compute the timedelta of the gaps
  31. for i in range(len(maps)):
  32. if i < len(maps) - 1:
  33. relation = maps[i + 1].temporal_relation(maps[i])
  34. if relation == "after":
  35. start1, end1 = maps[i].get_valid_time()
  36. start2, end2 = maps[i + 1].get_valid_time()
  37. # Gaps are between intervals, intervals and points, points and points
  38. if end1 and start2:
  39. t = abs(end1 - start2)
  40. delta.append(int(t))
  41. if not end1 and start2:
  42. t = abs(start1 - start2)
  43. delta.append(int(t))
  44. delta.sort()
  45. ulist = list(set(delta))
  46. if len(ulist) > 1:
  47. # Find greatest common divisor
  48. granularity = gcd_list(ulist)
  49. elif len(ulist) == 1:
  50. granularity = ulist[0]
  51. else:
  52. granularity = 0
  53. return granularity
  54. ###############################################################################
  55. def compute_absolute_time_granularity(maps):
  56. has_seconds = False
  57. has_minutes = False
  58. has_hours = False
  59. has_days = False
  60. has_months = False
  61. has_years = False
  62. use_seconds = False
  63. use_minutes = False
  64. use_hours = False
  65. use_days = False
  66. use_months = False
  67. use_years = False
  68. delta = []
  69. datetime_delta = []
  70. # First we compute the timedelta of the intervals
  71. for map in maps:
  72. start, end = map.get_valid_time()
  73. if start and end:
  74. delta.append(end - start)
  75. datetime_delta.append(compute_datetime_delta(start, end))
  76. # Compute the timedelta of the gaps
  77. for i in range(len(maps)):
  78. if i < len(maps) - 1:
  79. relation = maps[i + 1].temporal_relation(maps[i])
  80. if relation == "after":
  81. start1, end1 = maps[i].get_valid_time()
  82. start2, end2 = maps[i + 1].get_valid_time()
  83. # Gaps are between intervals, intervals and points, points and points
  84. if end1 and start2:
  85. delta.append(end1 - start2)
  86. datetime_delta.append(compute_datetime_delta(end1, start2))
  87. if not end1 and start2:
  88. delta.append(start2 - start1)
  89. datetime_delta.append(compute_datetime_delta(start1, start2))
  90. # Check what changed
  91. dlist = []
  92. for d in datetime_delta:
  93. if d.has_key("second") and d["second"] > 0:
  94. has_seconds = True
  95. if d.has_key("minute") and d["minute"] > 0:
  96. has_minutes = True
  97. if d.has_key("hour") and d["hour"] > 0:
  98. has_hours = True
  99. if d.has_key("day") and d["day"] > 0:
  100. has_days = True
  101. if d.has_key("month") and d["month"] > 0:
  102. has_months = True
  103. if d.has_key("year") and d["year"] > 0:
  104. has_years = True
  105. # Create a list with a single time unit only
  106. if has_seconds:
  107. for d in datetime_delta:
  108. if d.has_key("second"):
  109. dlist.append(d["second"])
  110. elif d.has_key("minute"):
  111. dlist.append(d["minute"] * 60)
  112. elif d.has_key("hour"):
  113. dlist.append(d["hour"] * 3600)
  114. elif d.has_key("day"):
  115. dlist.append(d["day"] * 24 * 3600)
  116. else:
  117. dlist.append(d["max_days"] * 24 * 3600)
  118. use_seconds = True
  119. elif has_minutes:
  120. for d in datetime_delta:
  121. if d.has_key("minute"):
  122. dlist.append(d["minute"])
  123. elif d.has_key("hour"):
  124. dlist.append(d["hour"] * 60)
  125. elif d.has_key("day"):
  126. dlist.append(d["day"] * 24 * 60)
  127. else:
  128. dlist.append(d["max_days"] * 24 * 60)
  129. use_minutes = True
  130. elif has_hours:
  131. for d in datetime_delta:
  132. if d.has_key("hour"):
  133. dlist.append(d["hour"])
  134. elif d.has_key("day"):
  135. dlist.append(d["day"] * 24)
  136. else:
  137. dlist.append(d["max_days"] * 24)
  138. use_hours = True
  139. elif has_days:
  140. for d in datetime_delta:
  141. if d.has_key("day"):
  142. dlist.append(d["day"])
  143. else:
  144. dlist.append(d["max_days"])
  145. use_days = True
  146. elif has_months:
  147. for d in datetime_delta:
  148. if d.has_key("month"):
  149. dlist.append(d["month"])
  150. elif d.has_key("year"):
  151. dlist.append(d["year"] * 12)
  152. use_months = True
  153. elif has_years:
  154. for d in datetime_delta:
  155. if d.has_key("year"):
  156. dlist.append(d["year"])
  157. use_years = True
  158. dlist.sort()
  159. ulist = list(set(dlist))
  160. if len(ulist) == 0:
  161. return None
  162. if len(ulist) > 1:
  163. # Find greatest common divisor
  164. granularity = gcd_list(ulist)
  165. else:
  166. granularity = ulist[0]
  167. if use_seconds:
  168. return "%i seconds" % granularity
  169. elif use_minutes:
  170. return "%i minutes" % granularity
  171. elif use_hours:
  172. return "%i hours" % granularity
  173. elif use_days:
  174. return "%i days" % granularity
  175. elif use_months:
  176. return "%i months" % granularity
  177. elif use_years:
  178. return "%i years" % granularity
  179. return None
  180. ###############################################################################
  181. # http://akiscode.com/articles/gcd_of_a_list.shtml
  182. # Copyright (c) 2010 Stephen Akiki
  183. # MIT License (Means you can do whatever you want with this)
  184. # See http://www.opensource.org/licenses/mit-license.php
  185. # Error Codes:
  186. # None
  187. def gcd(a,b):
  188. """ The Euclidean Algorithm """
  189. a = abs(a)
  190. b = abs(b)
  191. while a:
  192. a, b = b%a, a
  193. return b
  194. ###############################################################################
  195. def gcd_list(list):
  196. """ Finds the GCD of numbers in a list.
  197. Input: List of numbers you want to find the GCD of
  198. E.g. [8, 24, 12]
  199. Returns: GCD of all numbers
  200. """
  201. return reduce(gcd, list)