t.vect.what.strds.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ############################################################################
  4. #
  5. # MODULE: t.vect.what.strds
  6. # AUTHOR(S): Soeren Gebbert
  7. #
  8. # PURPOSE: Store raster map values at spatial and temporal positions of vector points as vector attributes.
  9. # COPYRIGHT: (C) 2011-2017 by the GRASS Development Team
  10. #
  11. # This program is free software; you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation; either version 2 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # This program is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU General Public License for more details.
  20. #
  21. #############################################################################
  22. #%module
  23. #% description: Stores raster map values at spatial and temporal positions of vector points as vector attributes.
  24. #% keyword: temporal
  25. #% keyword: sampling
  26. #% keyword: vector
  27. #% keyword: time
  28. #%end
  29. #%option G_OPT_STVDS_INPUT
  30. #%end
  31. #%option G_OPT_STRDS_INPUT
  32. #% key: strds
  33. #%end
  34. #%option
  35. #% key: column
  36. #% type: string
  37. #% label: Name of the vector column to be created and to store sampled raster values
  38. #% description: The use of a column name forces t.vect.what.rast to sample only values from the first map found in an interval. Otherwise the raster map names are used as column names
  39. #% required: no
  40. #% multiple: no
  41. #%end
  42. #%option
  43. #% key: method
  44. #% type: string
  45. #% description: Aggregate operation to be performed on the raster maps
  46. #% required: yes
  47. #% multiple: no
  48. #% options: disabled,average,count,median,mode,minimum,min_raster,maximum,max_raster,stddev,range,sum,variance,diversity,slope,offset,detcoeff,quart1,quart3,perc90,quantile,skewness,kurtosis
  49. #% answer: disabled
  50. #%end
  51. #%option G_OPT_DB_WHERE
  52. #%end
  53. #%option G_OPT_T_WHERE
  54. #% key: t_where
  55. #%end
  56. #%option G_OPT_T_SAMPLE
  57. #%end
  58. import os
  59. import grass.script as grass
  60. import grass.script.raster as raster
  61. from grass.exceptions import CalledModuleError
  62. ############################################################################
  63. def main():
  64. # lazy imports
  65. import grass.temporal as tgis
  66. # Get the options
  67. input = options["input"]
  68. strds = options["strds"]
  69. where = options["where"]
  70. column = options["column"]
  71. method = options["method"]
  72. tempwhere = options["t_where"]
  73. sampling = options["sampling"]
  74. if where == "" or where == " " or where == "\n":
  75. where = None
  76. # Make sure the temporal database exists
  77. tgis.init()
  78. # We need a database interface
  79. dbif = tgis.SQLDatabaseInterfaceConnection()
  80. dbif.connect()
  81. sp = tgis.open_old_stds(input, "stvds", dbif)
  82. strds_sp = tgis.open_old_stds(strds, "strds", dbif)
  83. if strds_sp.get_temporal_type() != sp.get_temporal_type():
  84. dbif.close()
  85. grass.fatal(_("Input and aggregation dataset must "
  86. "have the same temporal type"))
  87. # Check if intervals are present in the sample dataset
  88. if sp.get_temporal_type() == "absolute":
  89. map_time = sp.absolute_time.get_map_time()
  90. else:
  91. map_time = sp.relative_time.get_map_time()
  92. if map_time != "interval":
  93. dbif.close()
  94. grass.fatal(_("All registered maps of the space time vector "
  95. "dataset must have time intervals"))
  96. rows = sp.get_registered_maps("name,layer,mapset,start_time,end_time",
  97. tempwhere, "start_time", dbif)
  98. if not rows:
  99. dbif.close()
  100. grass.fatal(_("Space time vector dataset <%s> is empty") % sp.get_id())
  101. # Sample the raster dataset with the vector dataset and run v.what.rast
  102. for row in rows:
  103. start = row["start_time"]
  104. end = row["end_time"]
  105. vectmap = row["name"] + "@" + row["mapset"]
  106. layer = row["layer"]
  107. raster_maps = tgis.collect_map_names(
  108. strds_sp, dbif, start, end, sampling)
  109. aggreagated_map_name = None
  110. if raster_maps:
  111. # Aggregation
  112. if method != "disabled" and len(raster_maps) > 1:
  113. # Generate the temporary map name
  114. aggreagated_map_name = "aggreagated_map_name_" + \
  115. str(os.getpid())
  116. new_map = tgis.aggregate_raster_maps(raster_maps,
  117. aggreagated_map_name,
  118. start, end, 0, method,
  119. False, dbif)
  120. aggreagated_map_name = aggreagated_map_name + "_0"
  121. if new_map is None:
  122. continue
  123. # We overwrite the raster_maps list
  124. raster_maps = (new_map.get_id(), )
  125. for rastermap in raster_maps:
  126. if column:
  127. col_name = column
  128. else:
  129. # Create a new column with the SQL compliant
  130. # name of the sampled raster map
  131. col_name = rastermap.split("@")[0].replace(".", "_")
  132. coltype = "DOUBLE PRECISION"
  133. # Get raster type
  134. rasterinfo = raster.raster_info(rastermap)
  135. if rasterinfo["datatype"] == "CELL":
  136. coltype = "INT"
  137. try:
  138. if layer:
  139. grass.run_command("v.db.addcolumn",
  140. map=vectmap, layer=layer,
  141. column="%s %s" % (col_name, coltype),
  142. overwrite=grass.overwrite())
  143. else:
  144. grass.run_command("v.db.addcolumn", map=vectmap,
  145. column="%s %s" % (col_name, coltype),
  146. overwrite=grass.overwrite())
  147. except CalledModuleError:
  148. dbif.close()
  149. grass.fatal(_("Unable to add column %s to vector map <%s>")
  150. % (col_name, vectmap))
  151. # Call v.what.rast
  152. try:
  153. if layer:
  154. grass.run_command("v.what.rast", map=vectmap,
  155. layer=layer, raster=rastermap,
  156. column=col_name, where=where)
  157. else:
  158. grass.run_command("v.what.rast", map=vectmap,
  159. raster=rastermap, column=col_name,
  160. where=where)
  161. except CalledModuleError:
  162. dbif.close()
  163. grass.fatal(_("Unable to run v.what.rast for vector map "
  164. "<%s> and raster map <%s>") % (vectmap,
  165. rastermap))
  166. if aggreagated_map_name:
  167. try:
  168. grass.run_command("g.remove", flags='f', type='raster',
  169. name=aggreagated_map_name)
  170. except CalledModuleError:
  171. dbif.close()
  172. grass.fatal(_("Unable to remove raster map <%s>")
  173. % (aggreagated_map_name))
  174. # Use the first map in case a column names was provided
  175. if column:
  176. break
  177. dbif.close()
  178. if __name__ == "__main__":
  179. options, flags = grass.parser()
  180. main()