list_stds.py 11 KB

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