Przeglądaj źródła

Added bottom and top to views and separated them in new files. Support for spatio-temporal topology analysis.

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@56014 15284696-431f-4ddb-bdfa-cd5b030d7da7
Soeren Gebbert 12 lat temu
rodzic
commit
082cacaa09

+ 1 - 1
lib/python/temporal/abstract_dataset.py

@@ -91,7 +91,7 @@ class AbstractDataset(SpatialTopologyDatasetConnector, TemporalTopologyDatasetCo
         - finished
        
         To access topological information the spatial, temporal or booth topologies must be build first
-        using the SpatialTopologyBuilder, TemporalTopologyBuilder or SpatioTemporalTopologyBuilder.
+        using the SpatioTemporalTopologyBuilder.
         
         @return the dictionary with relations as keys and number as values or None in case the topology  wasn't build
         """

+ 48 - 19
lib/python/temporal/abstract_space_time_dataset.py

@@ -381,13 +381,16 @@ class AbstractSpaceTimeDataset(AbstractDataset):
 
         return gaps
 
-    def print_temporal_relationships(self, maps=None, dbif=None):
+    def print_spatio_temporal_relationships(self, maps=None, spatial=None, dbif=None):
         """!Print the temporal relation matrix of all registered maps to stdout
 
            The temporal relation matrix includes the temporal relations between
            all registered maps. The relations are strings stored in a list of lists.
 
            @param maps a ordered by start_time list of map objects
+           @param spatial This indicates if the spatial topology is created as well:
+                          spatial can be None (no spatial topology), "2D" using west, east, 
+                          south, north or "3D" using west, east, south, north, bottom, top
            @param dbif The database interface to be used
         """
 
@@ -395,7 +398,8 @@ class AbstractSpaceTimeDataset(AbstractDataset):
             maps = self.get_registered_maps_as_objects(
                 where=None, order="start_time", dbif=dbif)
 
-        print_temporal_topology_relationships(maps)
+        print_spatio_temporal_topology_relationships(maps1=maps, maps2=maps, 
+                                              spatial=spatial, dbif=dbif)
 
     def count_temporal_relations(self, maps=None, dbif=None):
         """!Count the temporal relations between the registered maps.
@@ -521,8 +525,8 @@ class AbstractSpaceTimeDataset(AbstractDataset):
 
            Gaps between maps are identified as unregistered maps with id==None.
 
-           The map objects are initialized with the id and the temporal 
-           extent of the granule (temporal type, start time, end time).
+           The objects are initialized with their id's' and the spatio-temporal extent 
+           (temporal type, start time, end time, west, east, south, north, bottom and top).
            In case more map information are needed, use the select() 
            method for each listed object.
 
@@ -712,7 +716,7 @@ class AbstractSpaceTimeDataset(AbstractDataset):
 
     def get_registered_maps_as_objects_by_granularity(self, gran=None, dbif=None):
         """!Return all registered maps as ordered (by start_time) object list with
-           "gap" map objects (id==None) for temporal topological operations 
+           "gap" map objects (id==None) for spatio-temporal topological operations 
            that require the temporal extent only.
            
            Each list entry is a list of map objects
@@ -729,8 +733,8 @@ class AbstractSpaceTimeDataset(AbstractDataset):
 
            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 objects are initialized with their id's' and the spatio-temporal extent 
+           (temporal type, start time, end time, west, east, south, north, bottom and top).
            In case more map information are needed, use the select() 
            method for each listed object.
 
@@ -899,13 +903,13 @@ class AbstractSpaceTimeDataset(AbstractDataset):
     def get_registered_maps_as_objects_with_gaps(self, where=None, dbif=None):
         """!Return all or a subset of the registered maps as 
            ordered (by start_time) object list with
-           "gap" map objects (id==None) for temporal topological operations 
-           that require the temporal extent only.
+           "gap" map objects (id==None) for spatio-temporal topological operations 
+           that require the spatio-temporal extent only.
 
            Gaps between maps are identified as maps with id==None
 
-           The objects are initialized with the id and the 
-           temporal extent (temporal type, start time, end time).
+           The objects are initialized with their id's' and the spatio-temporal extent 
+           (temporal type, start time, end time, west, east, south, north, bottom and top).
            In case more map information are needed, use the select() 
            method for each listed object.
 
@@ -954,10 +958,10 @@ class AbstractSpaceTimeDataset(AbstractDataset):
     def get_registered_maps_as_objects_with_temporal_topology(self, where=None, order="start_time", 
                                        dbif=None):
         """!Return all or a subset of the registered maps as ordered object list with 
-           temporal topological relationship informations.
+           spatio-temporal topological relationship informations.
 
-           The objects are initialized with their id's' and the temporal extent 
-           (temporal type, start time, end time) and the temporal topological information.
+           The objects are initialized with their id's' and the spatio-temporal extent 
+           (temporal type, start time, end time, west, east, south, north, bottom and top).
            In case more map information are needed, use the select() 
            method for each listed object.
 
@@ -984,10 +988,10 @@ class AbstractSpaceTimeDataset(AbstractDataset):
     def get_registered_maps_as_objects(self, where=None, order="start_time", 
                                        dbif=None):
         """!Return all or a subset of the registered maps as ordered object list for 
-           temporal topological operations that require the temporal extent only
+           spatio-temporal topological operations that require the spatio-temporal extent only
 
-           The objects are initialized with their id's' and the temporal extent 
-           (temporal type, start time, end time).
+           The objects are initialized with their id's' and the spatio-temporal extent 
+           (temporal type, start time, end time, west, east, south, north, bottom and top).
            In case more map information are needed, use the select() 
            method for each listed object.
 
@@ -1004,8 +1008,24 @@ class AbstractSpaceTimeDataset(AbstractDataset):
 
         obj_list = []
 
-        rows = self.get_registered_maps(
-            "id,start_time,end_time", where, order, dbif)
+        # Older temporal databases have no bottom and top columns
+        # in their views so we need a work around to set the full
+        # spatial extent as well
+        has_bt_columns = True
+        try:
+            rows = self.get_registered_maps(
+                "id,start_time,end_time, west,east,south,north,bottom,top", 
+                where, order, dbif)
+        except:
+            try:
+                rows = self.get_registered_maps(
+                    "id,start_time,end_time", 
+                    where, order, dbif)
+                has_bt_columns = False
+                core.warning(_("Old temporal database format. The top and bottom column"\
+                               " is missing in the views, using a work around."))
+            except:
+                raise
 
         if rows is not None:
             for row in rows:
@@ -1015,6 +1035,15 @@ class AbstractSpaceTimeDataset(AbstractDataset):
                 elif self.is_time_relative():
                     map.set_relative_time(row["start_time"], row["end_time"],
                                           self.get_relative_time_unit())
+                # The fast way
+                if has_bt_columns:
+                    map.set_spatial_extent(west=row["west"], east=row["east"],
+                    south=row["south"],north=row["north"], bottom=row["bottom"],
+                    top=row["top"])
+                # The slow work around
+                else:
+                    map.spatial_extent.select(dbif)
+                    
                 obj_list.append(copy.copy(map))
 
         if connected:

+ 46 - 9
lib/python/temporal/core.py

@@ -39,7 +39,7 @@ import copy
 import sys
 import grass.script.core as core
 # Import all supported database backends
-# Ignore import errors sicne they are checked later
+# Ignore import errors since they are checked later
 try:
     import sqlite3
 except ImportError:
@@ -56,15 +56,19 @@ except:
 # It can either be "sqlite" or "pg"
 tgis_backed = None
 
+# The version of the temporal framework
+tgis_version="1.0"
+
+###############################################################################
+
+def get_tgis_version():
+    """!Get the verion number of the temporal framework
+       @return The version number of the temporal framework as string
+    """
+    global tgis_version
+    return tgis_version
+
 
-# This variable specifies if the ctypes interface to the grass 
-# libraries should be used to read map specific data. If set to False
-# the grass scripting library will be used to get map informations.
-# The advantage of the ctypes inteface is speed, the disadvantage is that
-# the GRASS C functions may call G_fatal_error() which exits the process.
-# That is not catchable in Python.
-use_ctypes_map_access = True
-        
 ###############################################################################
 
 def get_temporal_dbmi_init_string():
@@ -93,6 +97,14 @@ def get_temporal_dbmi_init_string():
 
 ###############################################################################
 
+# This variable specifies if the ctypes interface to the grass 
+# libraries should be used to read map specific data. If set to False
+# the grass scripting library will be used to get map informations.
+# The advantage of the ctypes inteface is speed, the disadvantage is that
+# the GRASS C functions may call G_fatal_error() which exits the process.
+# That is not catchable in Python.
+use_ctypes_map_access = True
+
 def set_use_ctypes_map_access(use_ctype = True):
     """!Define the map access method for the temporal GIS library
     
@@ -242,6 +254,13 @@ def init():
         ), "raster3d_metadata_table.sql"), 'r').read()
     vector_metadata_sql = open(os.path.join(
         get_sql_template_path(), "vector_metadata_table.sql"), 'r').read()
+    raster_views_sql = open(os.path.join(
+        get_sql_template_path(), "raster_views.sql"), 'r').read()
+    raster3d_views_sql = open(os.path.join(get_sql_template_path(
+        ), "raster3d_views.sql"), 'r').read()
+    vector_views_sql = open(os.path.join(
+        get_sql_template_path(), "vector_views.sql"), 'r').read()
+
     stds_tables_template_sql = open(os.path.join(
         get_sql_template_path(), "stds_tables_template.sql"), 'r').read()
     strds_metadata_sql = open(os.path.join(
@@ -250,6 +269,12 @@ def init():
         get_sql_template_path(), "str3ds_metadata_table.sql"), 'r').read()
     stvds_metadata_sql = open(os.path.join(
         get_sql_template_path(), "stvds_metadata_table.sql"), 'r').read()
+    strds_views_sql = open(os.path.join(
+        get_sql_template_path(), "strds_views.sql"), 'r').read()
+    str3ds_views_sql = open(os.path.join(
+        get_sql_template_path(), "str3ds_views.sql"), 'r').read()
+    stvds_views_sql = open(os.path.join(
+        get_sql_template_path(), "stvds_views.sql"), 'r').read()
 
     # Create the raster, raster3d and vector tables
     raster_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster")
@@ -281,17 +306,23 @@ def init():
         # Create the global tables for the native grass datatypes
         cursor.executescript(raster_tables_sql)
         cursor.executescript(raster_metadata_sql)
+        cursor.executescript(raster_views_sql)
         cursor.executescript(vector_tables_sql)
         cursor.executescript(vector_metadata_sql)
+        cursor.executescript(vector_views_sql)
         cursor.executescript(raster3d_tables_sql)
         cursor.executescript(raster3d_metadata_sql)
+        cursor.executescript(raster3d_views_sql)
         # Create the tables for the new space-time datatypes
         cursor.executescript(strds_tables_sql)
         cursor.executescript(strds_metadata_sql)
+        cursor.executescript(strds_views_sql)
         cursor.executescript(stvds_tables_sql)
         cursor.executescript(stvds_metadata_sql)
+        cursor.executescript(stvds_views_sql)
         cursor.executescript(str3ds_tables_sql)
         cursor.executescript(str3ds_metadata_sql)
+        cursor.executescript(str3ds_views_sql)
         cursor.executescript(sqlite3_delete_trigger_sql)
     elif tgis_backed == "pg":
         # Connect to database
@@ -301,17 +332,23 @@ def init():
         # Create the global tables for the native grass datatypes
         cursor.execute(raster_tables_sql)
         cursor.execute(raster_metadata_sql)
+        cursor.execute(raster_views_sql)
         cursor.execute(vector_tables_sql)
         cursor.execute(vector_metadata_sql)
+        cursor.execute(vector_views_sql)
         cursor.execute(raster3d_tables_sql)
         cursor.execute(raster3d_metadata_sql)
+        cursor.execute(raster3d_views_sql)
         # Create the tables for the new space-time datatypes
         cursor.execute(strds_tables_sql)
         cursor.execute(strds_metadata_sql)
+        cursor.execute(strds_views_sql)
         cursor.execute(stvds_tables_sql)
         cursor.execute(stvds_metadata_sql)
+        cursor.execute(stvds_views_sql)
         cursor.execute(str3ds_tables_sql)
         cursor.execute(str3ds_metadata_sql)
+        cursor.execute(str3ds_views_sql)
 
     connection.commit()
     cursor.close()

+ 5 - 4
lib/python/temporal/pythontemporallib.dox

@@ -44,8 +44,9 @@ Several "abstract" classes are defined that implement the shared functionality
 of time stamped maps and space time datasets, such as temporal and spatial
 handling and representation:
 
+- python::temporal::spatial_topology_dataset_connector
+- python::temporal::temporal_topology_dataset_connector
 - python::temporal::abstract_dataset
-- python::temporal::abstract_temporal_dataset
 - python::temporal::abstract_map_dataset
 - python::temporal::abstract_space_time_dataset
 
@@ -54,12 +55,12 @@ here:
 
 - python::temporal::space_time_datasets
 
-Helper functions to compute temporal granularity, handling of datetime objects
-and their conversion as well as topology computation are defined in these modules:
+Functions to compute temporal granularity, handling of datetime objects
+and their conversion as well as spatio-temporal topology computation are defined in these modules:
 
 - python::temporal::datetime_math
+- python::temporal::spatio_temporal_relationships
 - python::temporal::temporal_granularity
-- python::temporal::temporal_relationships
 
 Functionality that is shared between different temporal GRASS modules, such as
 map listing, space time dataset creation, map registration and unregistration, 

+ 58 - 12
lib/python/temporal/spatial_extent.py

@@ -634,13 +634,13 @@ class SpatialExtent(SQLDatabaseInterface):
                 eW -= 360.0
 
         # Edges of extent located outside of self are not allowed
-        if E < eW:
+        if E <= eW:
             return False
-        if W > eE:
+        if W >= eE:
             return False
-        if N < eS:
+        if N <= eS:
             return False
-        if S > eN:
+        if S >= eN:
             return False
 
         # First we check that at least one edge of extent meets an edge of self
@@ -1094,23 +1094,42 @@ class SpatialExtent(SQLDatabaseInterface):
     def disjoint_2d(self, extent):
         """!Return True if this extent (A) is disjoint with the provided spatial
         extent (B) in three dimensions.
-        
+
         @verbatim
-          _____ 
+          _____
          |  A  |
-         |_____|       
-         _______ 
+         |_____|
+         _______
         |   B   |
         |_______|
-                     
+
          @endverbatim
-         
+
         @param extent The spatial extent
         @return True or False
         """
 
-        if self.overlapping_2d(extent) or self.meet_2d(extent):
+        if self.is_in_2d(extent):
+            return False
+
+        if self.contain_2d(extent):
+            return False
+
+        if self.cover_2d(extent):
+            return False
+
+        if self.covered_2d(extent):
+            return False
+
+        if self.equivalent_2d(extent):
+            return False
+
+        if self.overlapping_2d(extent):
+            return False
+
+        if  self.meet_2d(extent):
             return False
+
         return True
 
     def disjoint(self, extent):
@@ -1121,8 +1140,27 @@ class SpatialExtent(SQLDatabaseInterface):
         @return True or False
         """
 
-        if self.overlapping(extent) or self.meet(extent):
+        if self.is_in(extent):
+            return False
+
+        if self.contain(extent):
+            return False
+
+        if self.cover(extent):
+            return False
+
+        if self.covered(extent):
+            return False
+
+        if self.equivalent(extent):
+            return False
+
+        if self.overlapping(extent):
             return False
+
+        if  self.meet(extent):
+            return False
+            
         return True
 
     def spatial_relation_2d(self, extent):
@@ -1331,6 +1369,14 @@ class SpatialExtent(SQLDatabaseInterface):
         >>> B = SpatialExtent(north=70, south=30, east=50, west=10, bottom=0, top=50)
         >>> A.spatial_relation(B)
         'meet'
+        >>> A = SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> B = SpatialExtent(north=90, south=81, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation(B)
+        'disjoint'
+        >>> A = SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> B = SpatialExtent(north=90, south=80, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation(B)
+        'meet'
         
         @endcode
         """

Plik diff jest za duży
+ 78 - 59
lib/python/temporal/spatio_temporal_relationships.py


+ 1 - 33
lib/temporal/SQL/raster3d_metadata_table.sql

@@ -1,7 +1,6 @@
 --#############################################################################
 -- This SQL script generates the raster3d metadata table to store 
+-- and metadata for SQL queries and temporal GIS support.
 --
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
@@ -27,44 +26,6 @@ CREATE TABLE  raster3d_metadata (
   FOREIGN KEY (id) REFERENCES  raster3d_base (id) ON DELETE CASCADE
 );
 
-
-CREATE VIEW raster3d_view_abs_time AS SELECT 
-            A1.id, A1.mapset,
-            A1.name, A1.temporal_type,
-            A1.creation_time, 
-            A1.creator,
-	    A2.start_time, A2.end_time, A2.timezone,
-            A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.datatype, A4.cols, A4.rows, A4.depths,
-            A4.nsres, A4.ewres, A4.tbres,
-            A4.min, A4.max,
-	    A4.str3ds_register,
-            A4.number_of_cells
-	    FROM raster3d_base A1, raster3d_absolute_time A2, 
-            raster3d_spatial_extent A3, raster3d_metadata A4 
-	    WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
-
-CREATE VIEW raster3d_view_rel_time AS SELECT 
-            A1.id, A1.mapset,
-            A1.name, A1.temporal_type,
-            A1.creation_time, 
-            A1.creator,
-	    A2.start_time, A2.end_time,
-            A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.datatype, A4.cols, A4.rows, A4.depths,
-            A4.nsres, A4.ewres, A4.tbres,
-            A4.min, A4.max,
-	    A4.str3ds_register,
-            A4.number_of_cells
-	    FROM raster3d_base A1, raster3d_relative_time A2, 
-            raster3d_spatial_extent A3, raster3d_metadata A4 
-	    WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
-
 -- Create a trigger to update the modification time and revision number in case the metadata have been updated 
 
 --CREATE TRIGGER update_raster3d_metadata AFTER UPDATE ON raster3d_metadata 

+ 44 - 0
lib/temporal/SQL/raster3d_views.sql

@@ -0,0 +1,44 @@
+--#############################################################################
+-- This SQL script generates two views to access all map specific tables.
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+
+-- Create the views to access all cols for the absolute and relative time
+
+CREATE VIEW raster3d_view_abs_time AS SELECT 
+            A1.id, A1.mapset,
+            A1.name, A1.temporal_type,
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator,
+            A2.start_time, A2.end_time, A2.timezone,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.datatype, A4.cols, A4.rows, A4.depths,
+            A4.nsres, A4.ewres, A4.tbres,
+            A4.min, A4.max,
+            A4.str3ds_register,
+            A4.number_of_cells
+            FROM raster3d_base A1, raster3d_absolute_time A2, 
+            raster3d_spatial_extent A3, raster3d_metadata A4 
+            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+
+CREATE VIEW raster3d_view_rel_time AS SELECT 
+            A1.id, A1.mapset,
+            A1.name, A1.temporal_type,
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator,
+            A2.start_time, A2.end_time,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.datatype, A4.cols, A4.rows, A4.depths,
+            A4.nsres, A4.ewres, A4.tbres,
+            A4.min, A4.max,
+            A4.str3ds_register,
+            A4.number_of_cells
+            FROM raster3d_base A1, raster3d_relative_time A2, 
+            raster3d_spatial_extent A3, raster3d_metadata A4 
+            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;

+ 1 - 31
lib/temporal/SQL/raster_metadata_table.sql

@@ -1,7 +1,6 @@
 --#############################################################################
 -- This SQL script generates the raster metadata table to store 
+-- and metadata for SQL queries and temporal GIS support. 
 --
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
@@ -25,42 +24,6 @@ CREATE TABLE  raster_metadata (
   FOREIGN KEY (id) REFERENCES  raster_base (id) ON DELETE CASCADE
 );
 
-
-CREATE VIEW raster_view_abs_time AS SELECT 
-            A1.id, A1.mapset,
-            A1.name, A1.temporal_type,
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.timezone,
-            A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.datatype, A4.cols, A4.rows,
-            A4.nsres, A4.ewres, A4.min, A4.max,
-	    A4.strds_register,
-            A4.number_of_cells
-	    FROM raster_base A1, raster_absolute_time A2, 
-            raster_spatial_extent A3, raster_metadata A4 
-	    WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
-
-CREATE VIEW raster_view_rel_time AS SELECT 
-            A1.id, A1.mapset,
-            A1.name, A1.temporal_type,
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time,
-            A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.datatype, A4.cols, A4.rows,
-            A4.nsres, A4.ewres, A4.min, A4.max,
-	    A4.strds_register,
-            A4.number_of_cells
-	    FROM raster_base A1, raster_relative_time A2, 
-            raster_spatial_extent A3, raster_metadata A4 
-	    WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
-
 -- Create a trigger to update the modification time and revision number in case the metadata have been updated 
 -- Uncommented due to performance issues
 --CREATE TRIGGER update_raster_metadata AFTER UPDATE ON raster_metadata 

+ 42 - 0
lib/temporal/SQL/raster_views.sql

@@ -0,0 +1,42 @@
+--#############################################################################
+-- This SQL script generates two views to access all map specific tables.
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+
+-- Create the views to access all cols for the absolute and relative time
+
+CREATE VIEW raster_view_abs_time AS SELECT 
+            A1.id, A1.mapset,
+            A1.name, A1.temporal_type,
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.timezone,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.datatype, A4.cols, A4.rows,
+            A4.nsres, A4.ewres, A4.min, A4.max,
+            A4.strds_register,
+            A4.number_of_cells
+            FROM raster_base A1, raster_absolute_time A2, 
+            raster_spatial_extent A3, raster_metadata A4 
+            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+
+CREATE VIEW raster_view_rel_time AS SELECT 
+            A1.id, A1.mapset,
+            A1.name, A1.temporal_type,
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.datatype, A4.cols, A4.rows,
+            A4.nsres, A4.ewres, A4.min, A4.max,
+            A4.strds_register,
+            A4.number_of_cells
+            FROM raster_base A1, raster_relative_time A2, 
+            raster_spatial_extent A3, raster_metadata A4 
+            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;

+ 1 - 39
lib/temporal/SQL/str3ds_metadata_table.sql

@@ -1,6 +1,5 @@
 --#############################################################################
+-- This SQL script generates the space time 3D raster dataset metadata table.
 --
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
@@ -27,50 +26,6 @@ CREATE TABLE  str3ds_metadata (
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  str3ds_base (id) ON DELETE CASCADE
 );
-
-CREATE VIEW str3ds_view_abs_time AS SELECT 
-            A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.timezone, A2.granularity,
-	    A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.raster3d_register,
-	    A4.number_of_maps, 
-            A4.nsres_min, A4.ewres_min, 
-            A4.nsres_max, A4.ewres_max, 
-            A4.tbres_min, A4.tbres_max, 
-	    A4.min_min, A4.min_max,
-	    A4.max_min, A4.max_max,
-            A4.title, A4.description, A4.command
-	    FROM str3ds_base A1, str3ds_absolute_time A2,  
-            str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
-	    A1.id = A3.id AND A1.id = A4.id;
-
-CREATE VIEW str3ds_view_rel_time AS SELECT 
-            A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.granularity,
-	    A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.raster3d_register,
-	    A4.number_of_maps, 
-            A4.nsres_min, A4.ewres_min, 
-            A4.nsres_max, A4.ewres_max, 
-            A4.tbres_min, A4.tbres_max, 
-	    A4.min_min, A4.min_max,
-	    A4.max_min, A4.max_max,
-            A4.title, A4.description, A4.command
-	    FROM str3ds_base A1, str3ds_relative_time A2,  
-            str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
-	    A1.id = A3.id AND A1.id = A4.id;
-
 
 -- Create a trigger to update the modification time and revision number in case the metadata or timestanps have been updated 
 -- Uncommented due to performance issues

+ 49 - 0
lib/temporal/SQL/str3ds_views.sql

@@ -0,0 +1,49 @@
+--#############################################################################
+-- This SQL script generates the space time 3D raster dataset views.
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- Create the views to access all cols for absolute or relative time
+
+CREATE VIEW str3ds_view_abs_time AS SELECT 
+            A1.id, A1.name, A1.mapset, A1.temporal_type,
+            A1.semantic_type, 
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.timezone, A2.granularity,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.raster3d_register,
+            A4.number_of_maps, 
+            A4.nsres_min, A4.ewres_min, 
+            A4.nsres_max, A4.ewres_max, 
+            A4.tbres_min, A4.tbres_max, 
+            A4.min_min, A4.min_max,
+            A4.max_min, A4.max_max,
+            A4.title, A4.description, A4.command
+            FROM str3ds_base A1, str3ds_absolute_time A2,  
+            str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
+	    A1.id = A3.id AND A1.id = A4.id;
+
+CREATE VIEW str3ds_view_rel_time AS SELECT 
+            A1.id, A1.name, A1.mapset, A1.temporal_type,
+            A1.semantic_type, 
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.granularity,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.raster3d_register,
+            A4.number_of_maps, 
+            A4.nsres_min, A4.ewres_min, 
+            A4.nsres_max, A4.ewres_max, 
+            A4.tbres_min, A4.tbres_max, 
+            A4.min_min, A4.min_max,
+            A4.max_min, A4.max_max,
+            A4.title, A4.description, A4.command
+            FROM str3ds_base A1, str3ds_relative_time A2,  
+            str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
+            A1.id = A3.id AND A1.id = A4.id;

+ 1 - 37
lib/temporal/SQL/strds_metadata_table.sql

@@ -1,6 +1,5 @@
 --#############################################################################
+-- This SQL script generates the space time raster dataset metadata table.
 --
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
@@ -25,48 +24,6 @@ CREATE TABLE  strds_metadata (
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  strds_base (id) ON DELETE CASCADE
 );
-
-CREATE VIEW strds_view_abs_time AS SELECT 
-            A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.timezone, A2.granularity,
-	    A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.raster_register,
-	    A4.number_of_maps, 
-            A4.nsres_min, A4.ewres_min, 
-            A4.nsres_max, A4.ewres_max, 
-	    A4.min_min, A4.min_max,
-	    A4.max_min, A4.max_max,
-            A4.title, A4.description, A4.command	
-	    FROM strds_base A1, strds_absolute_time A2,  
-            strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
-	    A1.id = A3.id AND A1.id = A4.id;
-
-CREATE VIEW strds_view_rel_time AS SELECT 
-            A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.granularity,
-	    A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.raster_register,
-	    A4.number_of_maps, 
-            A4.nsres_min, A4.ewres_min, 
-            A4.nsres_max, A4.ewres_max, 
-	    A4.min_min, A4.min_max,
-	    A4.max_min, A4.max_max,
-            A4.title, A4.description, A4.command
-	    FROM strds_base A1, strds_relative_time A2,  
-            strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
-	    A1.id = A3.id AND A1.id = A4.id;
-
 
 -- Create a trigger to update the modification time and revision number in case the metadata or timestanps have been updated 
 -- Uncommented due to performance issues

+ 47 - 0
lib/temporal/SQL/strds_views.sql

@@ -0,0 +1,47 @@
+--#############################################################################
+-- This SQL script generates the space time raster dataset view.
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- Create the views to access all cols for absolute or relative time
+
+CREATE VIEW strds_view_abs_time AS SELECT 
+            A1.id, A1.name, A1.mapset, A1.temporal_type,
+            A1.semantic_type, 
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.timezone, A2.granularity,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.raster_register,
+            A4.number_of_maps, 
+            A4.nsres_min, A4.ewres_min, 
+            A4.nsres_max, A4.ewres_max, 
+            A4.min_min, A4.min_max,
+            A4.max_min, A4.max_max,
+            A4.title, A4.description, A4.command	
+            FROM strds_base A1, strds_absolute_time A2,  
+            strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
+            A1.id = A3.id AND A1.id = A4.id;
+
+CREATE VIEW strds_view_rel_time AS SELECT 
+            A1.id, A1.name, A1.mapset, A1.temporal_type,
+            A1.semantic_type, 
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.granularity,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.raster_register,
+            A4.number_of_maps, 
+            A4.nsres_min, A4.ewres_min, 
+            A4.nsres_max, A4.ewres_max, 
+            A4.min_min, A4.min_max,
+            A4.max_min, A4.max_max,
+            A4.title, A4.description, A4.command
+            FROM strds_base A1, strds_relative_time A2,  
+            strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
+            A1.id = A3.id AND A1.id = A4.id;

+ 1 - 36
lib/temporal/SQL/stvds_metadata_table.sql

@@ -1,6 +1,5 @@
 --#############################################################################
+-- This SQL script generates the space time vector dataset metadata table.
 --
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
@@ -29,47 +28,6 @@ CREATE TABLE  stvds_metadata (
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  stvds_base (id) ON DELETE CASCADE
 );
-
-CREATE VIEW stvds_view_abs_time AS SELECT 
-            A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.timezone,
-            A2.granularity,
-	    A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.vector_register,
-	    A4.number_of_maps, 
-            A4.title, A4.description, A4.command, A4.points, A4.lines,
-            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
-            A4.primitives, A4.nodes, A4.areas, A4.islands,
-            A4.holes, A4.volumes
-	    FROM stvds_base A1, stvds_absolute_time A2,  
-            stvds_spatial_extent A3, stvds_metadata A4 WHERE A1.id = A2.id AND 
-	    A1.id = A3.id AND A1.id = A4.id;
-
-CREATE VIEW stvds_view_rel_time AS SELECT 
-            A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.granularity,
-	    A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.vector_register,
-	    A4.number_of_maps, 
-            A4.title, A4.description, A4.command, A4.points, A4.lines,
-            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
-            A4.primitives, A4.nodes, A4.areas, A4.islands,
-            A4.holes, A4.volumes
-	    FROM stvds_base A1, stvds_relative_time A2,  
-            stvds_spatial_extent A3, stvds_metadata A4 WHERE A1.id = A2.id AND 
-	    A1.id = A3.id AND A1.id = A4.id;
-
 
 -- Create a trigger to update the modification time and revision number in case the metadata or timestanps have been updated 
 -- Uncommented due to performance issues

+ 46 - 0
lib/temporal/SQL/stvds_views.sql

@@ -0,0 +1,46 @@
+--#############################################################################
+-- This SQL script generates the space time vector dataset view.
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- Create the views to access all columns for absolute or relative time
+
+CREATE VIEW stvds_view_abs_time AS SELECT 
+            A1.id, A1.name, A1.mapset, A1.temporal_type,
+            A1.semantic_type, 
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.timezone,
+            A2.granularity,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.vector_register,
+            A4.number_of_maps, 
+            A4.title, A4.description, A4.command, A4.points, A4.lines,
+            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
+            A4.primitives, A4.nodes, A4.areas, A4.islands,
+            A4.holes, A4.volumes
+            FROM stvds_base A1, stvds_absolute_time A2,  
+            stvds_spatial_extent A3, stvds_metadata A4 WHERE A1.id = A2.id AND 
+            A1.id = A3.id AND A1.id = A4.id;
+
+CREATE VIEW stvds_view_rel_time AS SELECT 
+            A1.id, A1.name, A1.mapset, A1.temporal_type,
+            A1.semantic_type, 
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.granularity,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.vector_register,
+            A4.number_of_maps, 
+            A4.title, A4.description, A4.command, A4.points, A4.lines,
+            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
+            A4.primitives, A4.nodes, A4.areas, A4.islands,
+            A4.holes, A4.volumes
+            FROM stvds_base A1, stvds_relative_time A2,  
+            stvds_spatial_extent A3, stvds_metadata A4 WHERE A1.id = A2.id AND 
+            A1.id = A3.id AND A1.id = A4.id;

+ 0 - 31
lib/temporal/SQL/vector_metadata_table.sql

@@ -29,42 +29,6 @@ CREATE TABLE  vector_metadata (
   FOREIGN KEY (id) REFERENCES  vector_base (id) ON DELETE CASCADE
 );
 
-
-CREATE VIEW vector_view_abs_time AS SELECT 
-            A1.id, A1.mapset,
-            A1.name, A1.layer, A1.temporal_type,
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time, A2.timezone,
-            A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.stvds_register, A4.is_3d, A4.points, A4.lines,
-            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
-            A4.primitives, A4.nodes, A4.areas, A4.islands,
-            A4.holes, A4.volumes
-	    FROM vector_base A1, vector_absolute_time A2, 
-            vector_spatial_extent A3, vector_metadata A4 
-	    WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
-
-CREATE VIEW vector_view_rel_time AS SELECT 
-            A1.id, A1.mapset,
-            A1.name, A1.layer, A1.temporal_type,
-            A1.creation_time, 
-            A1.creator, 
-	    A2.start_time, A2.end_time,
-            A3.north, A3.south, A3.east, A3.west, A3.proj,
-	    A4.stvds_register, A4.is_3d, A4.points, A4.lines,
-            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
-            A4.primitives, A4.nodes, A4.areas, A4.islands,
-            A4.holes, A4.volumes
-	    FROM vector_base A1, vector_relative_time A2, 
-            vector_spatial_extent A3, vector_metadata A4 
-	    WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
-
 -- Create a trigger to update the modification time and revision number in case the metadata or timestanps have been updated 
 -- Uncommented due to performance issues
 --CREATE TRIGGER update_vector_metadata AFTER UPDATE ON vector_metadata 

+ 41 - 0
lib/temporal/SQL/vector_views.sql

@@ -0,0 +1,41 @@
+--#############################################################################
+-- This SQL script generates two views to access all map specific tables.
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- Create the views to access all columns for the absolute and relative time
+
+CREATE VIEW vector_view_abs_time AS SELECT 
+            A1.id, A1.mapset,
+            A1.name, A1.layer, A1.temporal_type,
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time, A2.timezone,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.stvds_register, A4.is_3d, A4.points, A4.lines,
+            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
+            A4.primitives, A4.nodes, A4.areas, A4.islands,
+            A4.holes, A4.volumes
+            FROM vector_base A1, vector_absolute_time A2, 
+            vector_spatial_extent A3, vector_metadata A4 
+            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+
+CREATE VIEW vector_view_rel_time AS SELECT 
+            A1.id, A1.mapset,
+            A1.name, A1.layer, A1.temporal_type,
+            A1.creation_time, 
+-- Uncommented due to performance issues
+--            A1.modification_time, A1.revision, 
+            A1.creator, 
+            A2.start_time, A2.end_time,
+            A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
+            A4.stvds_register, A4.is_3d, A4.points, A4.lines,
+            A4.boundaries, A4.centroids, A4.faces, A4.kernels,
+            A4.primitives, A4.nodes, A4.areas, A4.islands,
+            A4.holes, A4.volumes
+            FROM vector_base A1, vector_relative_time A2, 
+            vector_spatial_extent A3, vector_metadata A4 
+            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;

+ 18 - 4
temporal/t.topology/t.topology.py

@@ -36,6 +36,11 @@
 #% description: Print temporal relationships and exit
 #%end
 
+#%flag
+#% key: s
+#% description: Print spatio-temporal relationships and exit
+#%end
+
 import grass.script as grass
 import grass.temporal as tgis
 
@@ -48,7 +53,8 @@ def main():
     name = options["input"]
     type = options["type"]
     where = options["where"]
-    tmatrix = flags['m']
+    temporal_relations = flags['m']
+    spatio_temporal_relations = flags['s']
 
     # Make sure the temporal database exists
     tgis.init()
@@ -72,9 +78,17 @@ def main():
     # Get ordered map list
     maps = sp.get_registered_maps_as_objects(
         where=where, order="start_time", dbif=None)
-
-    if tmatrix:
-        sp.print_temporal_relationships(maps)
+    
+    spatial = None
+    
+    if spatio_temporal_relations:
+        if sp.get_type() == "strds":
+            spatial = "2D"
+        else:
+            spatial = "3D"
+
+    if temporal_relations or spatio_temporal_relations:
+        sp.print_spatio_temporal_relationships(maps=maps, spatial=spatial)
         return
 
     sp.base.print_info()

+ 6 - 1
temporal/t.topology/test.t.topology.abstime.sh

@@ -12,9 +12,14 @@ r.mapcalc --o expr="prec_3 = rand(0, 320)"
 r.mapcalc --o expr="prec_4 = rand(0, 510)"
 r.mapcalc --o expr="prec_5 = rand(0, 300)"
 r.mapcalc --o expr="prec_6 = rand(0, 650)"
+
+# Different spatial extents
 r.mapcalc --o expr="A = 1"
+g.region s=20 n=70 w=10 e=110 b=10 t=40 res=10 res3=10 -p3 # in A, covered by C
 r.mapcalc --o expr="B = 2"
+g.region s=20 n=80 w=10 e=130 b=10 t=50 res=10 res3=10 -p3 # cover B
 r.mapcalc --o expr="C = 3"
+g.region s=70 n=90 w=10 e=130 b=10 t=50 res=10 res3=10 -p3 # overlap B
 r.mapcalc --o expr="D = 3"
 
 n1=`g.tempfile pid=1 -d` 
@@ -111,7 +116,7 @@ t.topology -m input=precip_abs
 t.register --o type=rast -i input=maps file="${n6}"
 cat "${n6}"
 t.topology    input=maps
-t.topology -m input=maps
+t.topology -ms input=maps
 
 t.remove type=strds input=precip_abs,maps
 t.unregister type=rast file="${n1}"

+ 2 - 2
temporal/t.vect.observe.strds/test.t.vect.observe.strds.layer_bug.sh

@@ -12,7 +12,7 @@ MAP_LIST="map_list.txt"
 rm ${MAP_LIST}
 
 count=1
-while [ $count -lt 500 ]; do
+while [ $count -lt 270 ]; do
     name="test_prec_${count}"
     r.mapcalc --o expr="${name} = ${count}"
     echo ${name} >> ${MAP_LIST}
@@ -36,5 +36,5 @@ t.unregister type=rast file=${MAP_LIST}
 t.remove type=strds input=precip_abs1
 t.remove type=stvds input=prec_observer
 
-g.remove vect=prec_observer
+#g.remove vect=prec_observer
 g.mremove -f rast=test_prec_*