1"""
2Sampling functions for space time datasets
3
4Usage:
5
6.. code-block:: python
7
8    import grass.temporal as tgis
9
10    tgis.register_maps_in_space_time_dataset(type, name, maps)
11
12(C) 2012-2013 by the GRASS Development Team
13This program is free software under the GNU General Public
14License (>=v2). Read the file COPYING that comes with GRASS
15for details.
16
17:authors: Soeren Gebbert
18"""
19from __future__ import print_function
20from .core import get_current_mapset, get_tgis_message_interface, SQLDatabaseInterfaceConnection
21from .datetime_math import time_delta_to_relative_time
22from .factory import dataset_factory
23
24
25def sample_stds_by_stds_topology(intype, sampletype, inputs, sampler, header,
26                                 separator, method, spatial=False,
27                                 print_only=True):
28    """Sample the input space time datasets with a sample
29       space time dataset, return the created map matrix and optionally
30       print the result to stdout
31
32        In case multiple maps are located in the current granule,
33        the map names are separated by comma.
34
35        In case a layer is present, the names map ids are extended
36        in this form: "name:layer@mapset"
37
38        Attention: Do not use the comma as separator for printing
39
40        :param intype: Type of the input space time dataset (strds, stvds or
41                       str3ds)
42        :param sampletype: Type of the sample space time datasets (strds,
43                           stvds or str3ds)
44        :param inputs: Name or comma separated names of space time datasets or
45                       a list of map names
46        :param sampler: Name of a space time dataset used for temporal sampling
47        :param header: Set True to print column names
48        :param separator: The field separator character between the columns
49        :param method: The method to be used for temporal sampling
50                       (start,during,contain,overlap,equal) as comma separated
51                       string or as a list of methods
52        :param spatial: Perform spatial overlapping check
53        :param print_only: If set True (default) then the result of the
54                           sampling will be printed to stdout, if set to False
55                           the resulting map matrix will be returned.
56
57        :return: The map matrix or None if nothing found
58    """
59    mapset = get_current_mapset()
60    msgr = get_tgis_message_interface()
61
62    # Make a method list
63    if not issubclass(type(method), type([])):
64        method = method.split(",")
65
66    # Split the inputs
67    if not issubclass(type(inputs), type([])):
68        inputs = inputs.split(",")
69
70    sts = []
71
72    for input in inputs:
73        if input.find("@") >= 0:
74            id = input
75        else:
76            id = input + "@" + mapset
77
78        st = dataset_factory(intype, id)
79        sts.append(st)
80
81    if sampler.find("@") >= 0:
82        sid = sampler
83    else:
84        sid = sampler + "@" + mapset
85
86    sst = dataset_factory(sampletype, sid)
87
88    dbif = SQLDatabaseInterfaceConnection()
89    dbif.connect()
90
91    for st in sts:
92        if st.is_in_db(dbif) is False:
93            msgr.fatal(_("Dataset <%s> not found in temporal database")
94                       % (st.get_id()))
95        st.select(dbif)
96
97    if sst.is_in_db(dbif) is False:
98        msgr.fatal(_("Dataset <%s> not found in temporal database") % (sid))
99
100    sst.select(dbif)
101
102    if separator is None or separator == "" or separator.find(",") >= 0:
103        separator = " | "
104
105    mapmatrizes = []
106    for st in sts:
107        mapmatrix = st.sample_by_dataset(sst, method, spatial, dbif)
108        if mapmatrix and len(mapmatrix) > 0:
109            mapmatrizes.append(mapmatrix)
110
111    if len(mapmatrizes) > 0:
112
113        # Simply return the map matrix
114        if not print_only:
115            dbif.close()
116            return mapmatrizes
117
118        if header:
119            string = ""
120            string += "%s%s" % (sst.get_id(), separator)
121            for st in sts:
122                string += "%s%s" % (st.get_id(), separator)
123            string += "%s%s" % ("start_time", separator)
124            string += "%s%s" % ("end_time", separator)
125            string += "%s%s" % ("interval_length", separator)
126            string += "%s" % ("distance_from_begin")
127            print(string)
128
129        first_time, dummy = mapmatrizes[0][0]["granule"].get_temporal_extent_as_tuple()
130
131        for i in range(len(mapmatrizes[0])):
132            mapname_list = []
133            for mapmatrix in mapmatrizes:
134                mapnames = ""
135                count = 0
136                entry = mapmatrix[i]
137                for sample in entry["samples"]:
138                    if count == 0:
139                        mapnames += str(sample.get_id())
140                    else:
141                        mapnames += ",%s" % str(sample.get_id())
142                    count += 1
143                mapname_list.append(mapnames)
144
145            entry = mapmatrizes[0][i]
146            map = entry["granule"]
147
148            start, end = map.get_temporal_extent_as_tuple()
149            if end:
150                delta = end - start
151            else:
152                delta = None
153            delta_first = start - first_time
154
155            if map.is_time_absolute():
156                if end:
157                    delta = time_delta_to_relative_time(delta)
158                delta_first = time_delta_to_relative_time(delta_first)
159
160            string = ""
161            string += "%s%s" % (map.get_id(), separator)
162            for mapnames in mapname_list:
163                string += "%s%s" % (mapnames, separator)
164            string += "%s%s" % (start, separator)
165            string += "%s%s" % (end, separator)
166            string += "%s%s" % (delta, separator)
167            string += "%s" % (delta_first)
168            print(string)
169
170    dbif.close()
171    if len(mapmatrizes) > 0:
172        return mapmatrizes
173
174    return None
175