1"""
2Functions to open or create 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
13(C) 2012-2014 by the GRASS Development Team
14This program is free software under the GNU General Public
15License (>=v2). Read the file COPYING that comes with GRASS
16for details.
17
18:authors: Soeren Gebbert
19"""
20from .core import init_dbif, get_current_mapset, get_tgis_message_interface
21from .factory import dataset_factory
22from .abstract_map_dataset import AbstractMapDataset
23
24###############################################################################
25
26
27def open_old_stds(name, type, dbif=None):
28    """This function opens an existing space time dataset and return the
29       created and initialized object of the specified type.
30
31       This function will call exit() or raise a
32       grass.pygrass.messages.FatalError in case the type is wrong,
33       or the space time dataset was not found.
34
35       :param name: The name of the space time dataset, if the name does not
36                    contain the mapset (name@mapset) then the current mapset
37                    will be used to identifiy the space time dataset
38       :param type: The type of the space time dataset (strd, str3ds, stvds,
39                    raster, vector, raster3d)
40       :param dbif: The optional database interface to be used
41
42       :return: New stds object
43
44    """
45    mapset = get_current_mapset()
46    msgr = get_tgis_message_interface()
47
48    # Check if the dataset name contains the mapset as well
49    if name.find("@") < 0:
50        id = name + "@" + mapset
51    else:
52        id = name
53
54    if type == "strds" or type == "rast" or type == "raster":
55        sp = dataset_factory("strds", id)
56    elif type == "str3ds" or type == "raster3d" or type == "rast3d" or type == "raster_3d":
57        sp = dataset_factory("str3ds", id)
58    elif type == "stvds" or type == "vect" or type == "vector":
59        sp = dataset_factory("stvds", id)
60    else:
61        msgr.fatal(_("Unknown type: %s") % (type))
62
63    dbif, connected = init_dbif(dbif)
64
65    if not sp.is_in_db(dbif):
66        dbif.close()
67        msgr.fatal(_("Space time %(sp)s dataset <%(name)s> not found") %
68                   {'sp': sp.get_new_map_instance(None).get_type(),
69                    'name': name})
70
71    # Read content from temporal database
72    sp.select(dbif)
73    if connected:
74        dbif.close()
75
76    return sp
77
78###############################################################################
79
80
81def check_new_stds(name, type, dbif=None, overwrite=False):
82    """Check if a new space time dataset of a specific type can be created
83
84       :param name: The name of the new space time dataset
85       :param type: The type of the new space time dataset (strd, str3ds,
86                    stvds, raster, vector, raster3d)
87       :param dbif: The temporal database interface to be used
88       :param overwrite: Flag to allow overwriting
89
90       :return: A space time dataset object that must be filled with
91               content before insertion in the temporal database
92
93       This function will raise a FatalError in case of an error.
94    """
95
96    # Get the current mapset to create the id of the space time dataset
97
98    mapset = get_current_mapset()
99    msgr = get_tgis_message_interface()
100
101    if name.find("@") < 0:
102        id = name + "@" + mapset
103    else:
104        n, m = name.split("@")
105        if mapset != m:
106            msgr.fatal(_("Space time datasets can only be created in the "
107                         "current mapset"))
108        id = name
109
110    if type == "strds" or type == "rast" or type == "raster":
111        sp = dataset_factory("strds", id)
112    elif type == "str3ds" or type == "raster3d" or type == "rast3d "or type == "raster_3d":
113        sp = dataset_factory("str3ds", id)
114    elif type == "stvds" or type == "vect" or type == "vector":
115        sp = dataset_factory("stvds", id)
116    else:
117        msgr.error(_("Unknown type: %s") % (type))
118        return None
119
120    dbif, connected = init_dbif(dbif)
121
122    if sp.is_in_db(dbif) and overwrite is False:
123        msgr.fatal(_("Space time %(sp)s dataset <%(name)s> is already in the"
124                     " database. Use the overwrite flag.") % {
125                   'sp': sp.get_new_map_instance(None).get_type(),
126                   'name': name})
127    if connected:
128        dbif.close()
129
130    return sp
131
132###############################################################################
133
134
135def open_new_stds(name, type, temporaltype, title, descr, semantic,
136                  dbif=None, overwrite=False):
137    """Create a new space time dataset of a specific type
138
139       :param name: The name of the new space time dataset
140       :param type: The type of the new space time dataset (strd, str3ds,
141                    stvds, raster, vector, raster3d)
142       :param temporaltype: The temporal type (relative or absolute)
143       :param title: The title
144       :param descr: The dataset description
145       :param semantic: Semantical information
146       :param dbif: The temporal database interface to be used
147       :param overwrite: Flag to allow overwriting
148
149       :return: The new created space time dataset
150
151       This function will raise a FatalError in case of an error.
152    """
153    dbif, connected = init_dbif(dbif)
154    msgr = get_tgis_message_interface()
155    sp = check_new_stds(name, type, dbif, overwrite)
156
157    if sp.is_in_db(dbif):
158        msgr.warning(_("Overwriting space time %(sp)s dataset <%(name)s> and "
159                       "unregistering all maps") % {
160                     'sp': sp.get_new_map_instance(None).get_type(),
161                     'name': name})
162        id = sp.get_id()
163        sp.delete(dbif)
164        sp = sp.get_new_instance(id)
165
166    msgr.verbose(_("Creating a new space time %s dataset") %
167                 sp.get_new_map_instance(None).get_type())
168
169    sp.set_initial_values(temporal_type=temporaltype, semantic_type=semantic,
170                          title=title, description=descr)
171
172    sp.insert(dbif)
173
174    if connected:
175        dbif.close()
176
177    return sp
178
179############################################################################
180
181
182def check_new_map_dataset(name, layer=None, type="raster",
183                          overwrite=False, dbif=None):
184    """Check if a new map dataset of a specific type can be created in
185        the temporal database
186
187       :param name: The name of the new map dataset
188       :param layer: The layer of the new map dataset
189       :param type: The type of the new map dataset (raster, vector, raster3d)
190       :param dbif: The temporal database interface to be used
191       :param overwrite: Flag to allow overwriting
192
193       :return: A map dataset object
194
195       This function will raise a FatalError in case of an error.
196    """
197    mapset = get_current_mapset()
198    msgr = get_tgis_message_interface()
199
200    dbif, connected = init_dbif(dbif)
201    map_id = AbstractMapDataset.build_id(name, mapset, layer)
202
203    new_map = dataset_factory(type, map_id)
204    # Check if new map is in the temporal database
205    if new_map.is_in_db(dbif):
206        if not overwrite:
207            if connected:
208                dbif.close()
209            msgr.fatal(_("Map <%s> is already in temporal database,"
210                         " use overwrite flag to overwrite") % (map_id))
211
212    if connected:
213        dbif.close()
214
215    return new_map
216
217############################################################################
218
219
220def open_new_map_dataset(name, layer=None, type="raster",
221                         temporal_extent=None, overwrite=False,
222                         dbif=None):
223    """Create a new map dataset object of a specific type that can be
224        registered in the temporal database
225
226       :param name: The name of the new map dataset
227       :param layer: The layer of the new map dataset
228       :param type: The type of the new map dataset (raster, vector, raster3d)
229       :param dbif: The temporal database interface to be used
230       :param overwrite: Flag to allow overwriting
231
232       :return: A map dataset object
233
234    """
235
236    mapset = get_current_mapset()
237
238    dbif, connected = init_dbif(dbif)
239    new_map = check_new_map_dataset(name, layer, type, overwrite, dbif)
240
241    # Check if new map is in the temporal database
242    if new_map.is_in_db(dbif):
243        # Remove the existing temporal database entry
244        map_id = new_map.get_id()
245        new_map.delete(dbif)
246        new_map = new_map.get_new_instance(map_id)
247
248    if temporal_extent:
249        new_map.set_temporal_extent(temporal_extent)
250
251    if connected:
252        dbif.close()
253
254    return new_map
255