[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