temporal_granularity.py 7.2 KB

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