v.to.lines.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ############################################################################
  4. #
  5. # MODULE: v.to.lines (former v.polytoline)
  6. # AUTHOR(S): Luca Delucchi
  7. # point support added by Markus Neteler
  8. #
  9. # PURPOSE: Converts polygons and points to lines
  10. # COPYRIGHT: (C) 2013-2014 by the GRASS Development Team
  11. #
  12. # This program is free software under the GNU General Public
  13. # License (version 2). Read the file COPYING that comes with GRASS
  14. # for details.
  15. # TODO
  16. # support centroids (treat as points)?
  17. #############################################################################
  18. #%module
  19. #% description: Converts vector polygons or points to lines.
  20. #% keyword: vector
  21. #% keyword: geometry
  22. #% keyword: area
  23. #% keyword: line
  24. #% keyword: point
  25. #%end
  26. #%option G_OPT_V_INPUT
  27. #%end
  28. #%option G_OPT_V_OUTPUT
  29. #%end
  30. #%option
  31. #% key: method
  32. #% type: string
  33. #% description: Method used for point interpolation
  34. #% options: delaunay
  35. #% answer: delaunay
  36. #% guisection: Area
  37. #%end
  38. import grass.script as grass
  39. from grass.script.utils import decode
  40. from grass.exceptions import CalledModuleError
  41. import os
  42. # i18N
  43. import gettext
  44. gettext.install('grassmods', os.path.join(os.getenv("GISBASE"), 'locale'))
  45. def main():
  46. # Get the options
  47. input = options["input"]
  48. input_name = input.split('@')[0]
  49. output = options["output"]
  50. method = options["method"]
  51. min_cat = None
  52. max_cat = None
  53. point = None
  54. overwrite = grass.overwrite()
  55. quiet = True
  56. if grass.verbosity() > 2:
  57. quiet = False
  58. in_info = grass.vector_info(input)
  59. # check for wild mixture of vector types
  60. if in_info['points'] > 0 and in_info['boundaries'] > 0:
  61. grass.fatal(_("The input vector map contains both polygons and points,"
  62. " cannot handle mixed types"))
  63. pid = os.getpid()
  64. # process points via triangulation, then exit
  65. if in_info['points'] > 0:
  66. point = True
  67. layer = 1 # hardcoded for now
  68. out_temp = '{inp}_point_tmp_{pid}'.format(inp=input_name, pid=pid)
  69. if method == 'delaunay':
  70. grass.message(_("Processing point data (%d points found)...") % in_info['points'])
  71. grass.run_command('v.delaunay', input=input, layer=layer,
  72. output=out_temp, quiet=quiet)
  73. grass.run_command('v.db.addtable', map=out_temp, quiet=True)
  74. input = out_temp
  75. in_info = grass.vector_info(input)
  76. # process areas
  77. if in_info['areas'] == 0 and in_info['boundaries'] == 0:
  78. grass.fatal(_("The input vector map does not contain polygons"))
  79. out_type = '{inp}_type_{pid}'.format(inp=input_name, pid=pid)
  80. input_tmp = '{inp}_tmp_{pid}'.format(inp=input_name, pid=pid)
  81. remove_names = "%s,%s" % (out_type, input_tmp)
  82. grass.message(_("Processing area data (%d areas found)...") % in_info['areas'])
  83. try:
  84. grass.run_command('v.category', layer="2", type='boundary',
  85. option='add', input=input, out=input_tmp,
  86. quiet=quiet)
  87. except CalledModuleError:
  88. grass.run_command('g.remove', flags='f', type='vector',
  89. name=input_tmp, quiet=quiet)
  90. grass.fatal(_("Error creating layer 2"))
  91. try:
  92. grass.run_command('v.db.addtable', map=input_tmp, layer="2",
  93. columns="left integer,right integer",
  94. quiet=quiet)
  95. except CalledModuleError:
  96. grass.run_command('g.remove', flags='f', type='vector',
  97. name=input_tmp, quiet=quiet)
  98. grass.fatal(_("Error creating new table for layer 2"))
  99. try:
  100. grass.run_command('v.to.db', map=input_tmp, option="sides",
  101. columns="left,right", layer="2", quiet=quiet)
  102. except CalledModuleError:
  103. grass.run_command('g.remove', flags='f', type='vector',
  104. name=input_tmp, quiet=quiet)
  105. grass.fatal(_("Error populating new table for layer 2"))
  106. try:
  107. grass.run_command('v.type', input=input_tmp, output=out_type,
  108. from_type='boundary', to_type='line',
  109. quiet=quiet, layer="2")
  110. except CalledModuleError:
  111. grass.run_command('g.remove', flags='f', type='vector',
  112. name=remove_names, quiet=quiet)
  113. grass.fatal(_("Error converting polygon to line"))
  114. report = grass.read_command('v.category', flags='g', input=out_type,
  115. option='report', quiet=quiet)
  116. report = decode(report).split('\n')
  117. for r in report:
  118. if r.find('centroid') != -1:
  119. min_cat = report[0].split()[-2]
  120. max_cat = report[0].split()[-1]
  121. break
  122. if min_cat and max_cat:
  123. try:
  124. grass.run_command('v.edit', map=out_type, tool='delete',
  125. type='centroid', layer=2, quiet=quiet,
  126. cats='{mi}-{ma}'.format(mi=min_cat, ma=max_cat))
  127. except CalledModuleError:
  128. grass.run_command('g.remove', flags='f', type='vector',
  129. name=remove_names, quiet=quiet)
  130. grass.fatal(_("Error removing centroids"))
  131. try:
  132. try:
  133. # TODO: fix magic numbers for layer here and there
  134. grass.run_command('v.db.droptable', map=out_type, layer=1,
  135. flags='f', quiet=True)
  136. except CalledModuleError:
  137. grass.run_command('g.remove', flags='f', type='vector',
  138. name=remove_names, quiet=quiet)
  139. grass.fatal(_("Error removing table from layer 1"))
  140. # TODO: when this except is happaning, it seems that never, so it seems wrong
  141. except:
  142. grass.warning(_("No table for layer %d" % 1))
  143. try:
  144. grass.run_command('v.category', input=out_type, option='transfer',
  145. output=output, layer="2,1", quiet=quiet,
  146. overwrite=overwrite)
  147. except CalledModuleError:
  148. grass.run_command('g.remove', flags='f', type='vector',
  149. name=remove_names, quiet=quiet)
  150. grass.fatal(_("Error adding categories"))
  151. grass.run_command('g.remove', flags='f', type='vector',
  152. name=remove_names, quiet=quiet)
  153. if point:
  154. grass.run_command('g.remove', flags='f', type='vector',
  155. name=out_temp, quiet=quiet)
  156. if __name__ == "__main__":
  157. options, flags = grass.parser()
  158. main()