1""" 2Functions to create space time dataset lists 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-2016 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 GIS 16for details. 17 18:authors: Soeren Gebbert 19""" 20from __future__ import print_function 21from .core import get_tgis_message_interface, get_available_temporal_mapsets, init_dbif 22from .datetime_math import time_delta_to_relative_time 23from .space_time_datasets import RasterDataset 24from .factory import dataset_factory 25from .open_stds import open_old_stds 26import grass.script as gscript 27 28############################################################################### 29 30 31def get_dataset_list(type, temporal_type, columns=None, where=None, 32 order=None, dbif=None): 33 """ Return a list of time stamped maps or space time datasets of a specific 34 temporal type that are registered in the temporal database 35 36 This method returns a dictionary, the keys are the available mapsets, 37 the values are the rows from the SQL database query. 38 39 :param type: The type of the datasets (strds, str3ds, stvds, raster, 40 raster_3d, vector) 41 :param temporal_type: The temporal type of the datasets (absolute, 42 relative) 43 :param columns: A comma separated list of columns that will be selected 44 :param where: A where statement for selected listing without "WHERE" 45 :param order: A comma separated list of columns to order the 46 datasets by category 47 :param dbif: The database interface to be used 48 49 :return: A dictionary with the rows of the SQL query for each 50 available mapset 51 52 .. code-block:: python 53 54 >>> import grass.temporal as tgis 55 >>> tgis.core.init() 56 >>> name = "list_stds_test" 57 >>> sp = tgis.open_stds.open_new_stds(name=name, type="strds", 58 ... temporaltype="absolute", title="title", descr="descr", 59 ... semantic="mean", dbif=None, overwrite=True) 60 >>> mapset = tgis.get_current_mapset() 61 >>> stds_list = tgis.list_stds.get_dataset_list("strds", "absolute", columns="name") 62 >>> rows = stds_list[mapset] 63 >>> for row in rows: 64 ... if row["name"] == name: 65 ... print(True) 66 True 67 >>> stds_list = tgis.list_stds.get_dataset_list("strds", "absolute", columns="name,mapset", where="mapset = '%s'"%(mapset)) 68 >>> rows = stds_list[mapset] 69 >>> for row in rows: 70 ... if row["name"] == name and row["mapset"] == mapset: 71 ... print(True) 72 True 73 >>> check = sp.delete() 74 75 """ 76 id = None 77 sp = dataset_factory(type, id) 78 79 dbif, connected = init_dbif(dbif) 80 81 mapsets = get_available_temporal_mapsets() 82 83 result = {} 84 85 for mapset in mapsets.keys(): 86 87 if temporal_type == "absolute": 88 table = sp.get_type() + "_view_abs_time" 89 else: 90 table = sp.get_type() + "_view_rel_time" 91 92 if columns and columns.find("all") == -1: 93 sql = "SELECT " + str(columns) + " FROM " + table 94 else: 95 sql = "SELECT * FROM " + table 96 97 if where: 98 sql += " WHERE " + where 99 sql += " AND mapset = '%s'" % (mapset) 100 else: 101 sql += " WHERE mapset = '%s'" % (mapset) 102 103 if order: 104 sql += " ORDER BY " + order 105 106 dbif.execute(sql, mapset=mapset) 107 rows = dbif.fetchall(mapset=mapset) 108 109 if rows: 110 result[mapset] = rows 111 112 if connected: 113 dbif.close() 114 115 return result 116 117############################################################################### 118 119 120def list_maps_of_stds(type, input, columns, order, where, separator, 121 method, no_header=False, gran=None, dbif=None, 122 outpath=None): 123 """ List the maps of a space time dataset using different methods 124 125 :param type: The type of the maps raster, raster3d or vector 126 :param input: Name of a space time raster dataset 127 :param columns: A comma separated list of columns to be printed to stdout 128 :param order: A comma separated list of columns to order the 129 maps by category 130 :param where: A where statement for selected listing without "WHERE" 131 e.g: start_time < "2001-01-01" and end_time > "2001-01-01" 132 :param separator: The field separator character between the columns 133 :param method: String identifier to select a method out of cols, 134 comma,delta or deltagaps 135 :param dbif: The database interface to be used 136 137 - "cols" Print preselected columns specified by columns 138 - "comma" Print the map ids ("name@mapset") as comma separated string 139 - "delta" Print the map ids ("name@mapset") with start time, 140 end time, relative length of intervals and the relative 141 distance to the begin 142 - "deltagaps" Same as "delta" with additional listing of gaps. 143 Gaps can be easily identified as the id is "None" 144 - "gran" List map using the granularity of the space time dataset, 145 columns are identical to deltagaps 146 147 :param no_header: Suppress the printing of column names 148 :param gran: The user defined granule to be used if method=gran is 149 set, in case gran=None the granule of the space time 150 dataset is used 151 :param outpath: The path to file where to save output 152 """ 153 154 dbif, connected = init_dbif(dbif) 155 msgr = get_tgis_message_interface() 156 157 sp = open_old_stds(input, type, dbif) 158 159 if separator is None or separator == "": 160 separator = "\t" 161 162 if outpath: 163 outfile = open(outpath, 'w') 164 165 # This method expects a list of objects for gap detection 166 if method == "delta" or method == "deltagaps" or method == "gran": 167 if type == "stvds": 168 columns = "id,name,layer,mapset,start_time,end_time" 169 else: 170 columns = "id,name,mapset,start_time,end_time" 171 if method == "deltagaps": 172 maps = sp.get_registered_maps_as_objects_with_gaps(where=where, 173 dbif=dbif) 174 elif method == "delta": 175 maps = sp.get_registered_maps_as_objects(where=where, 176 order="start_time", 177 dbif=dbif) 178 elif method == "gran": 179 if gran is not None and gran != "": 180 maps = sp.get_registered_maps_as_objects_by_granularity(gran=gran, 181 dbif=dbif) 182 else: 183 maps = sp.get_registered_maps_as_objects_by_granularity(dbif=dbif) 184 185 if no_header is False: 186 string = "" 187 string += "%s%s" % ("id", separator) 188 string += "%s%s" % ("name", separator) 189 if type == "stvds": 190 string += "%s%s" % ("layer", separator) 191 string += "%s%s" % ("mapset", separator) 192 string += "%s%s" % ("start_time", separator) 193 string += "%s%s" % ("end_time", separator) 194 string += "%s%s" % ("interval_length", separator) 195 string += "%s" % ("distance_from_begin") 196 if outpath: 197 outfile.write('{st}\n'.format(st=string)) 198 else: 199 print(string) 200 201 if maps and len(maps) > 0: 202 203 if isinstance(maps[0], list): 204 if len(maps[0]) > 0: 205 first_time, dummy = maps[0][0].get_temporal_extent_as_tuple() 206 else: 207 msgr.warning(_("Empty map list")) 208 return 209 else: 210 first_time, dummy = maps[0].get_temporal_extent_as_tuple() 211 212 for mymap in maps: 213 214 if isinstance(mymap, list): 215 if len(mymap) > 0: 216 map = mymap[0] 217 else: 218 msgr.fatal(_("Empty entry in map list, this should not happen")) 219 else: 220 map = mymap 221 222 start, end = map.get_temporal_extent_as_tuple() 223 if end: 224 delta = end - start 225 else: 226 delta = None 227 delta_first = start - first_time 228 229 if map.is_time_absolute(): 230 if end: 231 delta = time_delta_to_relative_time(delta) 232 delta_first = time_delta_to_relative_time(delta_first) 233 234 string = "" 235 string += "%s%s" % (map.get_id(), separator) 236 string += "%s%s" % (map.get_name(), separator) 237 if type == "stvds": 238 string += "%s%s" % (map.get_layer(), separator) 239 string += "%s%s" % (map.get_mapset(), separator) 240 string += "%s%s" % (start, separator) 241 string += "%s%s" % (end, separator) 242 string += "%s%s" % (delta, separator) 243 string += "%s" % (delta_first) 244 if outpath: 245 outfile.write('{st}\n'.format(st=string)) 246 else: 247 print(string) 248 249 else: 250 # In comma separated mode only map ids are needed 251 if method == "comma": 252 if columns not in ['id', 'name']: 253 columns = "id" 254 255 rows = sp.get_registered_maps(columns, where, order, dbif) 256 257 if not rows: 258 dbif.close() 259 err = "Space time %(sp)s dataset <%(i)s> is empty" 260 if where: 261 err += " or where condition is wrong" 262 gscript.fatal(_(err) % { 263 'sp': sp.get_new_map_instance(None).get_type(), 264 'i': sp.get_id()}) 265 266 if rows: 267 if method == "comma": 268 string = "" 269 count = 0 270 for row in rows: 271 if count == 0: 272 string += row[columns] 273 else: 274 string += ",%s" % row[columns] 275 count += 1 276 if outpath: 277 outfile.write('{st}\n'.format(st=string)) 278 else: 279 print(string) 280 281 elif method == "cols": 282 # Print the column names if requested 283 if no_header is False: 284 output = "" 285 count = 0 286 287 collist = columns.split(",") 288 289 for key in collist: 290 if count > 0: 291 output += separator + str(key) 292 else: 293 output += str(key) 294 count += 1 295 if outpath: 296 outfile.write('{st}\n'.format(st=output)) 297 else: 298 print(output) 299 300 for row in rows: 301 output = "" 302 count = 0 303 for col in row: 304 if count > 0: 305 output += separator + str(col) 306 else: 307 output += str(col) 308 count += 1 309 if outpath: 310 outfile.write('{st}\n'.format(st=output)) 311 else: 312 print(output) 313 if outpath: 314 outfile.close() 315 if connected: 316 dbif.close() 317 318############################################################################### 319 320if __name__ == "__main__": 321 import doctest 322 doctest.testmod() 323