v.clip.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # MODULE: v.clip
  5. # AUTHOR: Zofie Cimburova, CTU Prague, Czech Republic
  6. # PURPOSE: Clips vector features
  7. # COPYRIGHT: (C) 2016 Zofie Cimburova
  8. # This program is free software under the GNU General
  9. # Public License (>=v2). Read the file COPYING that
  10. # comes with GRASS for details.
  11. #
  12. #############################################################################
  13. #%module
  14. #% description: Extracts features of input map which overlay features of clip map.
  15. #% keyword: vector
  16. #% keyword: clip
  17. #% keyword: area
  18. #%end
  19. #%option G_OPT_V_INPUT
  20. #% label: Name of vector map to be clipped
  21. #% key: input
  22. #%end
  23. #%option G_OPT_V_INPUT
  24. #% key: clip
  25. #% label: Name of clip vector map
  26. #%end
  27. #%option G_OPT_V_OUTPUT
  28. #% key: output
  29. #%end
  30. #%flag
  31. #% key: d
  32. #% description: Do not dissolve clip map
  33. #%end
  34. #%flag
  35. #% key: r
  36. #% description: Clip by region
  37. #% suppress_required: yes
  38. #% guisection: Region
  39. #%end
  40. # flags -d and -r are mutualy exclusive
  41. # with flag -r, suppress_required: yes, but input and output must be defined
  42. #%rules
  43. #% exclusive: -d, -r
  44. #% requires_all: -r, input, output
  45. #%end
  46. import os
  47. import sys
  48. import atexit
  49. from grass.script import run_command, message, parser
  50. import grass.script as grass
  51. from grass.exceptions import CalledModuleError
  52. TMP = []
  53. def cleanup():
  54. for name in TMP:
  55. try:
  56. grass.run_command('g.remove', flags='f',
  57. type='vector', name=name, quiet=True)
  58. except CalledModuleError as e:
  59. grass.fatal(_("Deleting of temporary layer failed. "
  60. "Check above error messages and "
  61. "see following details:\n%s") % e)
  62. def section_message(msg):
  63. grass.message('{delim}\n{msg}\n{delim}'.format(msg=msg, delim='-' * 80))
  64. def main():
  65. input_map = opt['input']
  66. clip_map = opt['clip']
  67. output_map = opt['output']
  68. flag_dissolve = flg['d']
  69. flag_region = flg['r']
  70. # ======================================== #
  71. # ========== INPUT MAP TOPOLOGY ========== #
  72. # ======================================== #
  73. vinfo = grass.vector_info_topo(input_map)
  74. # ==== only points ==== #
  75. if (vinfo['points'] > 0 and vinfo['lines'] == 0 and vinfo['areas'] == 0):
  76. # ==================================== #
  77. # ========== CLIP BY REGION ========== #
  78. # ==================================== #
  79. if (flag_region):
  80. clip_by_region(input_map, output_map, clip_select)
  81. # ================================== #
  82. # ========== DEFAULT CLIP ========== #
  83. # ================================== #
  84. else:
  85. section_message("Clipping.")
  86. # perform clipping
  87. clip_select(input_map, clip_map, output_map)
  88. # ==== lines, areas, lines + areas ==== #
  89. # ==== points + areas, points + lines, points + areas + lines ==== #
  90. else:
  91. if (vinfo['points'] > 0):
  92. grass.warning("Input map contains multiple geometry, "
  93. "only lines and areas will be clipped.")
  94. # ==================================== #
  95. # ========== CLIP BY REGION ========== #
  96. # ==================================== #
  97. if (flag_region):
  98. clip_by_region(input_map, output_map, clip_overlay)
  99. # ===================================================== #
  100. # ========== CLIP WITHOUT DISSOLVED CLIP MAP ========== #
  101. # ===================================================== #
  102. elif (flag_dissolve):
  103. section_message("Clipping without dissolved clip map.")
  104. clip_overlay(input_map, clip_map, output_map)
  105. # ========================================================== #
  106. # ========== DEFAULT CLIP WITH DISSOLVED CLIP MAP ========== #
  107. # ========================================================== #
  108. else:
  109. section_message("Default clipping with dissolved clip map.")
  110. # setup temporary map
  111. temp_clip_map = '%s_%s' % ("temp", str(os.getpid()))
  112. TMP.append(temp_clip_map)
  113. # dissolve clip_map
  114. grass.run_command('v.dissolve', input=clip_map,
  115. output=temp_clip_map)
  116. # perform clipping
  117. clip_overlay(input_map, temp_clip_map, output_map)
  118. # ======================================== #
  119. # ========== OUTPUT MAP TOPOLOGY========== #
  120. # ======================================== #
  121. vinfo = grass.vector_info_topo(output_map)
  122. if vinfo['primitives'] == 0:
  123. grass.warning("Output map is empty.")
  124. return 0
  125. # clip input map by computational region
  126. # clip_select for points, clip_overlay for areas and lines
  127. def clip_by_region(input_map, output_map, clip_fn):
  128. section_message("Clipping by region.")
  129. # setup temporary map
  130. temp_region_map = '%s_%s' % ("temp", str(os.getpid()))
  131. TMP.append(temp_region_map)
  132. # create a map covering current computational region
  133. grass.run_command('v.in.region', output=temp_region_map)
  134. # perform clipping
  135. clip_fn(input_map, temp_region_map, output_map)
  136. def clip_overlay(input_data, clip_data, out_data):
  137. try:
  138. grass.run_command('v.overlay', ainput=input_data, binput=clip_data,
  139. operator='and', output=out_data, olayer='0,1,0')
  140. except CalledModuleError as e:
  141. grass.fatal(_("Clipping steps failed."
  142. " Check above error messages and"
  143. " see following details:\n%s") % e)
  144. def clip_select(input_data, clip_data, out_data):
  145. try:
  146. grass.run_command('v.select', ainput=input_data, binput=clip_data,
  147. output=out_data, operator='overlap')
  148. except CalledModuleError as e:
  149. grass.fatal(_("Clipping steps failed."
  150. " Check above error messages and"
  151. " see following details:\n%s") % e)
  152. if __name__ == "__main__":
  153. atexit.register(cleanup)
  154. opt, flg = parser()
  155. sys.exit(main())