[GRASS-SVN] r49074 - grass/trunk/lib/python/temporal

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Nov 3 09:00:10 EDT 2011


Author: huhabla
Date: 2011-11-03 06:00:10 -0700 (Thu, 03 Nov 2011)
New Revision: 49074

Modified:
   grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
   grass/trunk/lib/python/temporal/space_time_datasets_tools.py
Log:
Sampling of datasets is now more fine grain and more specific


Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2011-11-03 12:37:25 UTC (rev 49073)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2011-11-03 13:00:10 UTC (rev 49074)
@@ -339,31 +339,96 @@
 
         return True
 
-    def sample_by_dataset_topology_simple(self, stds, dbif=None):
+    def sample_by_dataset_topology(self, stds, method=None, dbif=None):
         """Sample this space time dataset with the temporal topology of a second space time dataset
 
-           Only the start time of the registered maps of the dataset is considered. So that maps with end time 
-           in a sample granule are not listed.
+           The sample dataset must have "interval" as temporal map type, so all sample maps have valid interval time.
         
            Return all registered maps as ordered (by start_time) object list with 
            "gap" map objects (id==None). Each list entry is a list of map objects
-           which are potentially located in each granule of the second space time dataset.
+           which are potentially located in temporal relation to the actual granule of the second space time dataset.
 
+           Each entry in the object list is a dict. The actual sampler map and its temporal enxtent (the actual granule) and
+           the list of samples are stored:
+
+           list = self.sample_by_dataset_topology(stds=sampler, method=["during","overlap","contain","equal"])    
+           for entry in list:
+               granule = entry["granule"]
+               maplist = entry["samples"]
+               for map in maplist:
+                   map.select()
+                   map.print_info()
+
            A valid temporal topology (no overlapping or inclusion allowed) is needed to get correct results. 
     
-           The sample dataset must have "interval" as temporal map type, so all sample maps have valid interval time.
-
            Gaps between maps are identified as unregistered maps with id==None.
 
-           The objects are initialized with the id and the temporal extent (temporal type, start time, end time).
+           The map objects are initialized with the id and the temporal extent of the granule (temporal type, start time, end time).
            In case more map informations are needed, use the select() method for each listed object.
 
            @param stds: The space time dataset to be used for temporal sampling
+           @param method: This option specifies what sample method should be used. In case the registered maps are of temporal point type,
+                          only the start time is used for sampling. In case of mixed of interval data the user can chose between:
+                          * start: Select maps of which the start time is located in the selection granule
+                            map    :        s
+                            granule:  s-----------------e
+
+                            map    :        s--------------------e
+                            granule:  s-----------------e
+
+                            map    :        s--------e
+                            granule:  s-----------------e
+
+                          * during: Select maps which are temporal during the selection granule
+                            map    :     s-----------e
+                            granule:  s-----------------e
+
+                          * overlap: Select maps which temporal overlap the selection granule
+                            map    :     s-----------e
+                            granule:        s-----------------e
+
+                            map    :     s-----------e
+                            granule:  s----------e
+
+                          * contain: Select maps which temporally contain the selection granule
+                            map    :  s-----------------e
+                            granule:     s-----------e
+
+                          * equal: Select maps which temporally equal to the selection granule
+                            map    :  s-----------e
+                            granule:  s-----------e
+
+                          All these methods can be combined. Method must be of type tuple including the identification strings.
            @param dbif: The database interface to be used
 
            In case nothing found None is returned
         """
 
+        use_start = False
+        use_during = False
+        use_overlap = False
+        use_contain = False
+        use_equal = False
+
+        # Inititalize the methods
+        if method:
+            for name in method:
+                if name == "start":
+                    use_start = True
+                if name == "during":
+                    use_during = True
+                if name == "overlap":
+                    use_overlap = True
+                if name == "contain":
+                    use_contain = True
+                if name == "equal":
+                    use_equal = True
+        else:
+            use_during = True
+            use_overlap = True
+            use_contain = True
+            use_equal = True
+
         if self.get_temporal_type() != stds.get_temporal_type():
             core.error(_("The space time datasets must be of the same temporal type"))
             return None
@@ -372,6 +437,13 @@
             core.error(_("The temporal map type of the sample dataset must be interval"))
             return None
 
+        # In case points of time are available, disable the interval specific methods
+        if self.get_map_time() == "point":
+            use_start = True
+            use_during = False
+            use_overlap = False
+            use_contain = False
+            use_equal = False
 
         connect = False
 
@@ -383,81 +455,50 @@
         obj_list = []
         sample_maps = stds.get_registered_maps_as_objects_with_gaps(where=None, dbif=dbif)
         
+        for granule in sample_maps:
+            start, end = granule.get_valid_time()
 
-        for sample in sample_maps:
-            start, end = sample.get_valid_time()
+            where = "("
 
-            where = "((start_time >= '%s' and start_time < '%s'))" % (start, end)
-            rows = self.get_registered_maps("id", where, "start_time", dbif)
+            if use_start:
+                where += "(start_time >= '%s' and start_time < '%s') " % (start, end)
 
-            if rows:
-                maplist = []
-                for row in rows:
-                    map = self.get_new_map_instance(row["id"])
+            if use_during:
+                if use_start:
+                    where += " OR "
+                where += "((start_time > '%s' and end_time < '%s') OR " % (start, end)
+                where += "(start_time >= '%s' and end_time < '%s') OR " % (start, end)
+                where += "(start_time > '%s' and end_time <= '%s'))" % (start, end)
 
-                    if self.is_time_absolute():
-                        map.set_absolute_time(start, end)
-                    elif self.is_time_relative():
-                        map.set_relative_time(start, end)
+            if use_overlap:
+                if use_start or use_during:
+                    where += " OR "
 
-                    maplist.append(copy.copy(map))
+                where += "((start_time < '%s' and end_time > '%s' and end_time < '%s') OR " % (start, start, end)
+                where += "(start_time < '%s' and start_time > '%s' and end_time > '%s'))" % (end, start, end)
 
-                obj_list.append(copy.copy(maplist))
+            if use_contain:
+                if use_start or use_during or use_overlap:
+                    where += " OR "
 
-        if connect == True:
-            dbif.close()
+                where += "((start_time < '%s' and end_time > '%s') OR " % (start, end)
+                where += "(start_time <= '%s' and end_time > '%s') OR " % (start, end)
+                where += "(start_time < '%s' and end_time >= '%s'))" % (start, end)
 
-        return obj_list
+            if use_equal:
+                if use_start or use_during or use_overlap or use_contain:
+                    where += " OR "
 
+                where += "(start_time = '%s' and end_time = '%s')" % (start, end)
 
-    def sample_by_dataset_topology(self, stds, dbif=None):
-        """Sample this space time dataset with the temporal topology of a second space time dataset
+            where += ")"
 
-           This dataset and the sample dataset must have "interval" as temporal map type, so all maps have valid interval time.
-        
-           Return all registered maps as ordered (by start_time) object list with 
-           "gap" map objects (id==None). Each list entry is a list of map objects
-           which are potentially located in each granule of the second space time dataset.
+            rows = self.get_registered_maps("id", where, "start_time", dbif)
 
-           A valid temporal topology (no overlapping or inclusion allowed) is needed to get correct results. 
-    
-           Gaps between maps are identified as unregistered maps with id==None.
+            result = {}
+            result["granule"] = granule
+            maplist = None
 
-           The objects are initialized with the id and the temporal extent (temporal type, start time, end time).
-           In case more map informations are needed, use the select() method for each listed object.
-
-           @param stds: The space time dataset to be used for temporal sampling
-           @param dbif: The database interface to be used
-
-           In case nothing found None is returned
-        """
-
-        if self.get_temporal_type() != stds.get_temporal_type():
-            core.error(_("The space time datasets must be of the same temporal type"))
-            return None
-
-        if stds.get_map_time() != "interval":
-            core.error(_("The temporal map type of the sample dataset must be interval"))
-            return None
-
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        obj_list = []
-        sample_maps = stds.get_registered_maps_as_objects_with_gaps(where=None, dbif=dbif)
-        
-
-        for sample in sample_maps:
-            start, end = sample.get_valid_time()
-
-            where = "((start_time >= '%s' and start_time < '%s') OR (start_time <= '%s' and end_time >= '%s') OR (start_time >= '%s' and end_time <= '%s') OR (start_time < '%s' and end_time >= '%s') OR (start_time <= '%s' and end_time > '%s'))" % (start, end, start, end, start, end, end, end, start, start)
-            rows = self.get_registered_maps("id", where, "start_time", dbif)
-
             if rows:
                 maplist = []
                 for row in rows:
@@ -469,9 +510,21 @@
                         map.set_relative_time(start, end)
 
                     maplist.append(copy.copy(map))
+                result["samples"] = maplist
+            else:
+                maplist = []
+                map = self.get_new_map_instance(None)
 
-                obj_list.append(copy.copy(maplist))
+                if self.is_time_absolute():
+                    map.set_absolute_time(start, end)
+                elif self.is_time_relative():
+                    map.set_relative_time(start, end)
 
+                maplist.append(copy.copy(map))
+                result["samples"] = maplist
+
+            obj_list.append(copy.copy(result))
+
         if connect == True:
             dbif.close()
 
@@ -519,7 +572,7 @@
             else:
                 next = start + gran
 
-            where = "((start_time <= '%s' and end_time >= '%s') OR (start_time >= '%s' and end_time <= '%s') OR (start_time < '%s' and end_time >= '%s') OR (start_time <= '%s' and end_time > '%s'))" % (start, end, start, end, end, end, start, start)
+            where += "(start_time >= '%s' and end_time <= '%s') OR " % (start, end)
 
             rows = self.get_registered_maps("id", where, "start_time", dbif)
 

Modified: grass/trunk/lib/python/temporal/space_time_datasets_tools.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets_tools.py	2011-11-03 12:37:25 UTC (rev 49073)
+++ grass/trunk/lib/python/temporal/space_time_datasets_tools.py	2011-11-03 13:00:10 UTC (rev 49074)
@@ -677,15 +677,20 @@
                     print output
 
 
-def sample_stds_by_stds_topology(intype, sampletype, input, sampler, header, separator, use_simple):
+def sample_stds_by_stds_topology(intype, sampletype, input, sampler, header, separator, method):
     """ Sample the input space time dataset with a sample space time dataset and print the result to stdout
 
         In case multiple maps are located in the current granule, the map names are separated by comma.
 
         Attention: Do not use the comma as separator
 
+        @param intype:  Type of the input space time dataset (strds, stvds or str3ds)
+        @param samtype: Type of the sample space time dataset (strds, stvds or str3ds)
         @param input: Name of a space time dataset
         @param sampler: Name of a space time dataset used for temporal sampling
+        @param header: Set True to print column names 
+        @param separator: The field separator character between the columns
+        @param method: The method to be used for sampling (start,during,contain,overlap,equal)
     """
     mapset =  core.gisenv()["MAPSET"]
 
@@ -706,7 +711,6 @@
     dbif = sql_database_interface()
     dbif.connect()
 
-
     if sp.is_in_db(dbif) == False:
         core.fatal(_("Dataset <%s> not found in temporal database") % (id))
 
@@ -719,11 +723,7 @@
     if separator == None or separator == "" or separator.find(",") >= 0:
         separator = " | "
        
-    if use_simple:
-        mapmatrix = sp.sample_by_dataset_topology_simple(ssp, dbif)
-    else:
-        mapmatrix = sp.sample_by_dataset_topology(ssp, dbif)
-    samplerlist = ssp.get_registered_maps_as_objects_with_gaps(dbif=dbif)
+    mapmatrix = sp.sample_by_dataset_topology(ssp, method, dbif)
 
     if mapmatrix and len(mapmatrix) > 0:
 
@@ -737,19 +737,19 @@
             string += "%s"   % ("distance_from_begin")
             print string
 
-        first_time, dummy = mapmatrix[0][0].get_valid_time()
+        first_time, dummy = mapmatrix[0]["granule"].get_valid_time()
 
-        for i in range(len(mapmatrix)):
+        for entry in mapmatrix:
             mapnames = ""
             count = 0
-            for map in mapmatrix[i]:
+            for sample in entry["samples"]:
                 if count == 0:
-                    mapnames += map.get_id()
+                    mapnames += str(sample.get_id())
                 else:
-                    mapnames += ",%s" % map.get_id()
+                    mapnames += ",%s" % str(sample.get_id())
                 count += 1
             
-            map = mapmatrix[i][0]
+            map = entry["granule"]
 
             start, end = map.get_valid_time()
             if end:
@@ -764,7 +764,7 @@
                 delta_first = time_delta_to_relative_time(delta_first)
 
             string = ""
-            string += "%s%s" % (samplerlist[i].get_id(), separator)
+            string += "%s%s" % (map.get_id(), separator)
             string += "%s%s" % (mapnames, separator)
             string += "%s%s" % (start, separator)
             string += "%s%s" % (end, separator)



More information about the grass-commit mailing list