[GRASS-SVN] r56633 - in grass/trunk: lib/python/temporal temporal/t.rast.aggregate.ds
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Jun 7 08:25:46 PDT 2013
Author: huhabla
Date: 2013-06-07 08:25:46 -0700 (Fri, 07 Jun 2013)
New Revision: 56633
Modified:
grass/trunk/lib/python/temporal/abstract_dataset.py
grass/trunk/lib/python/temporal/abstract_map_dataset.py
grass/trunk/lib/python/temporal/datetime_math.py
grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py
Log:
Implemented temporal buffering
Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py 2013-06-07 12:58:04 UTC (rev 56632)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py 2013-06-07 15:25:46 UTC (rev 56633)
@@ -527,8 +527,7 @@
return a new temporal extent with the new start and end time.
@param dataset The abstract dataset to create temporal union with
- @return The new temporal extent with start and end time,
- or None in case of no intersection
+ @return The new temporal extent with start and end time
"""
return self.temporal_extent.disjoint_union(dataset.temporal_extent)
Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py 2013-06-07 12:58:04 UTC (rev 56632)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py 2013-06-07 15:25:46 UTC (rev 56633)
@@ -472,6 +472,108 @@
self.write_timestamp_to_grass()
+ def temporal_buffer(self, increment, update=False, dbif=None):
+ """!Create a temporal buffer based on an increment
+
+ For absolute time the increment must be a string of type "integer unit"
+ Unit can be year, years, month, months, day, days, hour, hours, minute,
+ minutes, day or days.
+
+ @param increment This is the increment, a string in case of absolute
+ time or an integer in case of relative time
+ @param update Perform an immediate database update to store the
+ modified temporal extent, otherwise only this object
+ will be modified
+
+ Usage:
+
+ @code
+
+ >>> import grass.temporal as tgis
+ >>> maps = []
+ >>> for i in range(5):
+ ... map = tgis.RasterDataset(None)
+ ... if i%2 == 0:
+ ... check = map.set_relative_time(i, i + 1, 'years')
+ ... else:
+ ... check = map.set_relative_time(i, None, 'years')
+ ... map.temporal_buffer(3)
+ ... maps.append(map)
+ >>> for map in maps:
+ ... map.temporal_extent.print_info()
+ +-------------------- Relative time -----------------------------------------+
+ | Start time:................. -3
+ | End time:................... 4
+ | Relative time unit:......... years
+ +-------------------- Relative time -----------------------------------------+
+ | Start time:................. -2
+ | End time:................... 4
+ | Relative time unit:......... years
+ +-------------------- Relative time -----------------------------------------+
+ | Start time:................. -1
+ | End time:................... 6
+ | Relative time unit:......... years
+ +-------------------- Relative time -----------------------------------------+
+ | Start time:................. 0
+ | End time:................... 6
+ | Relative time unit:......... years
+ +-------------------- Relative time -----------------------------------------+
+ | Start time:................. 1
+ | End time:................... 8
+ | Relative time unit:......... years
+ >>> maps = []
+ >>> for i in range(1,5):
+ ... map = tgis.RasterDataset(None)
+ ... if i%2 == 0:
+ ... check = map.set_absolute_time(datetime(2001,i,1), datetime(2001, i + 1, 1))
+ ... else:
+ ... check = map.set_absolute_time(datetime(2001,i,1), None)
+ ... map.temporal_buffer("7 days")
+ ... maps.append(map)
+ >>> for map in maps:
+ ... map.temporal_extent.print_info()
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2000-12-25 00:00:00
+ | End time:................... 2001-01-08 00:00:00
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2001-01-25 00:00:00
+ | End time:................... 2001-03-08 00:00:00
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2001-02-22 00:00:00
+ | End time:................... 2001-03-08 00:00:00
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2001-03-25 00:00:00
+ | End time:................... 2001-05-08 00:00:00
+
+ @endcode
+ """
+
+ if self.is_time_absolute():
+ start, end, tz = self.get_absolute_time()
+
+ new_start = decrement_datetime_by_string(start, increment)
+ if end == None:
+ new_end = increment_datetime_by_string(start, increment)
+ else:
+ new_end = increment_datetime_by_string(end, increment)
+
+ if update:
+ self.update_absolute_time(new_start, new_end, tz, dbif=dbif)
+ else:
+ self.set_absolute_time(new_start, new_end, tz)
+ else:
+ start, end, unit = self.get_relative_time()
+ new_start = start - increment
+ if end == None:
+ new_end = start + increment
+ else:
+ new_end = end + increment
+
+ if update:
+ self.update_relative_time(new_start, new_end, unit, dbif=dbif)
+ else:
+ self.set_relative_time(new_start, new_end, unit)
+
def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
"""!Set the spatial extent of the map
@@ -659,3 +761,9 @@
dbif.close()
return rows
+
+###############################################################################
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
Modified: grass/trunk/lib/python/temporal/datetime_math.py
===================================================================
--- grass/trunk/lib/python/temporal/datetime_math.py 2013-06-07 12:58:04 UTC (rev 56632)
+++ grass/trunk/lib/python/temporal/datetime_math.py 2013-06-07 15:25:46 UTC (rev 56633)
@@ -4,7 +4,7 @@
Temporal GIS datetime math functions to be used in library functions and modules.
-(C) 2008-2011 by the GRASS Development Team
+(C) 2011-2013 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@@ -44,7 +44,73 @@
###############################################################################
+def decrement_datetime_by_string(mydate, increment, mult=1):
+ """!Return a new datetime object decremented with the provided
+ relative dates specified as string.
+ Additional a multiplier can be specified to multiply the increment
+ before adding to the provided datetime object.
+
+ Usage:
+
+ @code
+
+ >>> dt = datetime(2001, 1, 1, 0, 0, 0)
+ >>> string = "31 days"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(2000, 12, 1, 0, 0)
+
+ >>> dt = datetime(2001, 1, 1, 0, 0, 0)
+ >>> string = "1 month"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(2000, 12, 1, 0, 0)
+
+ >>> dt = datetime(2001, 1, 1, 0, 0, 0)
+ >>> string = "2 month"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(2000, 11, 1, 0, 0)
+
+ >>> dt = datetime(2001, 1, 1, 0, 0, 0)
+ >>> string = "24 months"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(1999, 1, 1, 0, 0)
+
+ >>> dt = datetime(2001, 1, 1, 0, 0, 0)
+ >>> string = "48 months"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(1997, 1, 1, 0, 0)
+
+ >>> dt = datetime(2001, 6, 1, 0, 0, 0)
+ >>> string = "5 months"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(2001, 1, 1, 0, 0)
+
+ >>> dt = datetime(2001, 6, 1, 0, 0, 0)
+ >>> string = "7 months"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(2000, 11, 1, 0, 0)
+
+ >>> dt = datetime(2001, 1, 1, 0, 0, 0)
+ >>> string = "1 year"
+ >>> decrement_datetime_by_string(dt, string)
+ datetime.datetime(2000, 1, 1, 0, 0)
+
+ @endcode
+
+ @param mydate A datetime object to incremented
+ @param increment A string providing increment information:
+ The string may include comma separated values of type seconds,
+ minutes, hours, days, weeks, months and years
+ Example: Increment the datetime 2001-01-01 00:00:00
+ with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+ will result in the datetime 2003-02-18 12:05:00
+ @param mult A multiplier, default is 1
+ @return The new datetime object or none in case of an error
+ """
+ return modify_datetime_by_string(mydate, increment, mult, sign=int(-1))
+
+###############################################################################
+
def increment_datetime_by_string(mydate, increment, mult=1):
"""!Return a new datetime object incremented with the provided
relative dates specified as string.
@@ -110,8 +176,34 @@
with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
will result in the datetime 2003-02-18 12:05:00
@param mult A multiplier, default is 1
+ @return The new datetime object or none in case of an error
"""
+ return modify_datetime_by_string(mydate, increment, mult, sign=int(1))
+###############################################################################
+
+def modify_datetime_by_string(mydate, increment, mult=1, sign=1):
+ """!Return a new datetime object incremented with the provided
+ relative dates specified as string.
+ Additional a multiplier can be specified to multiply the increment
+ before adding to the provided datetime object.
+
+ @param mydate A datetime object to incremented
+ @param increment A string providing increment information:
+ The string may include comma separated values of type seconds,
+ minutes, hours, days, weeks, months and years
+ Example: Increment the datetime 2001-01-01 00:00:00
+ with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+ will result in the datetime 2003-02-18 12:05:00
+ @param mult A multiplier, default is 1
+ @param sign Choose 1 for positive sign (incrementing) or -1 for negative
+ sign (decrementing).
+ @return The new datetime object or none in case of an error
+ """
+ sign = int(sign)
+ if sign != 1 and sign != -1:
+ return None
+
if increment:
seconds = 0
@@ -133,31 +225,30 @@
core.error(_("Wrong increment format: %s") % (increment))
return None
if inc[1].find("seconds") >= 0 or inc[1].find("second") >= 0:
- seconds = mult * int(inc[0])
+ seconds = sign * mult * int(inc[0])
elif inc[1].find("minutes") >= 0 or inc[1].find("minute") >= 0:
- minutes = mult * int(inc[0])
+ minutes = sign * mult * int(inc[0])
elif inc[1].find("hours") >= 0 or inc[1].find("hour") >= 0:
- hours = mult * int(inc[0])
+ hours = sign * mult * int(inc[0])
elif inc[1].find("days") >= 0 or inc[1].find("day") >= 0:
- days = mult * int(inc[0])
+ days = sign * mult * int(inc[0])
elif inc[1].find("weeks") >= 0 or inc[1].find("week") >= 0:
- weeks = mult * int(inc[0])
+ weeks = sign * mult * int(inc[0])
elif inc[1].find("months") >= 0 or inc[1].find("month") >= 0:
- months = mult * int(inc[0])
+ months = sign * mult * int(inc[0])
elif inc[1].find("years") >= 0 or inc[1].find("year") >= 0:
- years = mult * int(inc[0])
+ years = sign * mult * int(inc[0])
else:
core.error(_("Wrong increment format: %s") % (increment))
return None
- return increment_datetime(mydate, years, months, weeks, days, hours, minutes, seconds)
+ return modify_datetime(mydate, years, months, weeks, days, hours, minutes, seconds)
return mydate
###############################################################################
-
-def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0,
+def modify_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0,
minutes=0, seconds=0):
"""!Return a new datetime object incremented with the provided
relative dates and times"""
@@ -189,18 +280,44 @@
try:
dt1 = dt1.replace(year=year + years_to_add, month=residual_months)
except:
- core.fatal(_("Unable to increment the datetime %s. "\
- "Please check that the yearly or monthly increment does not result in wrong number of days."%(mydate)))
+ raise
tdelta_months = dt1 - mydate
+ elif months < 0:
+ # Compute the actual number of days in the month to add as timedelta
+ year = mydate.year
+ month = mydate.month
+ years_to_remove = 0
- if years > 0:
+ all_months = int(months) + int(month)
+ if all_months <= 0:
+ years_to_remove = abs(int(all_months / 12.001))
+ residual_months = all_months + (years_to_remove * 12)
+ years_to_remove += 1
+ else:
+ residual_months = all_months
+
# Make a deep copy of the datetime object
dt1 = copy.copy(mydate)
+
+ # Correct the months
+ if residual_months <= 0:
+ residual_months += 12
+
+ try:
+ dt1 = dt1.replace(year=year - years_to_remove, month=residual_months)
+ except:
+ raise
+
+ tdelta_months = dt1 - mydate
+
+ if years != 0:
+ # Make a deep copy of the datetime object
+ dt1 = copy.copy(mydate)
# Compute the number of days
dt1 = dt1.replace(year=mydate.year + int(years))
tdelta_years = dt1 - mydate
-
+
return mydate + tdelta_seconds + tdelta_minutes + tdelta_hours + \
tdelta_days + tdelta_weeks + tdelta_months + tdelta_years
Modified: grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py
===================================================================
--- grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py 2013-06-07 12:58:04 UTC (rev 56632)
+++ grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py 2013-06-07 15:25:46 UTC (rev 56633)
@@ -121,7 +121,7 @@
"the same temporal type"))
# Check if intervals are present
- if sample.temporal_extent.get_map_time() != "interval":
+ if sampler_sp.temporal_extent.get_map_time() != "interval":
dbif.close()
grass.fatal(_("All registered maps of the aggregation dataset "
"must have time intervals"))
More information about the grass-commit
mailing list