123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- ############################################################################
- #
- # MODULE: v.to.lines (former v.polytoline)
- # AUTHOR(S): Luca Delucchi
- # point support added by Markus Neteler
- #
- # PURPOSE: Converts polygons and points to lines
- # COPYRIGHT: (C) 2013-2014 by the GRASS Development Team
- #
- # This program is free software under the GNU General Public
- # License (version 2). Read the file COPYING that comes with GRASS
- # for details.
- # TODO
- # support centroids (treat as points)?
- #############################################################################
- #%module
- #% description: Converts vector polygons or points to lines.
- #% keyword: vector
- #% keyword: geometry
- #% keyword: area
- #% keyword: line
- #% keyword: point
- #%end
- #%option G_OPT_V_INPUT
- #%end
- #%option G_OPT_V_OUTPUT
- #%end
- #%option
- #% key: method
- #% type: string
- #% description: Method used for point interpolation
- #% options: delaunay
- #% answer: delaunay
- #% guisection: Area
- #%end
- import grass.script as grass
- from grass.script.utils import decode
- from grass.exceptions import CalledModuleError
- import os
- def main():
- # Get the options
- input = options["input"]
- input_name = input.split('@')[0]
- output = options["output"]
- method = options["method"]
- min_cat = None
- max_cat = None
- point = None
- overwrite = grass.overwrite()
- quiet = True
- if grass.verbosity() > 2:
- quiet = False
- in_info = grass.vector_info(input)
- # check for wild mixture of vector types
- if in_info['points'] > 0 and in_info['boundaries'] > 0:
- grass.fatal(_("The input vector map contains both polygons and points,"
- " cannot handle mixed types"))
- pid = os.getpid()
- # process points via triangulation, then exit
- if in_info['points'] > 0:
- point = True
- layer = 1 # hardcoded for now
- out_temp = '{inp}_point_tmp_{pid}'.format(inp=input_name, pid=pid)
- if method == 'delaunay':
- grass.message(_("Processing point data (%d points found)...") % in_info['points'])
- grass.run_command('v.delaunay', input=input, layer=layer,
- output=out_temp, quiet=quiet)
- grass.run_command('v.db.addtable', map=out_temp, quiet=True)
- input = out_temp
- in_info = grass.vector_info(input)
- # process areas
- if in_info['areas'] == 0 and in_info['boundaries'] == 0:
- grass.fatal(_("The input vector map does not contain polygons"))
- out_type = '{inp}_type_{pid}'.format(inp=input_name, pid=pid)
- input_tmp = '{inp}_tmp_{pid}'.format(inp=input_name, pid=pid)
- remove_names = "%s,%s" % (out_type, input_tmp)
- grass.message(_("Processing area data (%d areas found)...") % in_info['areas'])
- try:
- grass.run_command('v.category', layer="2", type='boundary',
- option='add', input=input, out=input_tmp,
- quiet=quiet)
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=input_tmp, quiet=quiet)
- grass.fatal(_("Error creating layer 2"))
- try:
- grass.run_command('v.db.addtable', map=input_tmp, layer="2",
- columns="left integer,right integer",
- quiet=quiet)
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=input_tmp, quiet=quiet)
- grass.fatal(_("Error creating new table for layer 2"))
- try:
- grass.run_command('v.to.db', map=input_tmp, option="sides",
- columns="left,right", layer="2", quiet=quiet)
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=input_tmp, quiet=quiet)
- grass.fatal(_("Error populating new table for layer 2"))
- try:
- grass.run_command('v.type', input=input_tmp, output=out_type,
- from_type='boundary', to_type='line',
- quiet=quiet, layer="2")
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=remove_names, quiet=quiet)
- grass.fatal(_("Error converting polygon to line"))
- report = grass.read_command('v.category', flags='g', input=out_type,
- option='report', quiet=quiet)
- report = decode(report).split('\n')
- for r in report:
- if r.find('centroid') != -1:
- min_cat = report[0].split()[-2]
- max_cat = report[0].split()[-1]
- break
- if min_cat and max_cat:
- try:
- grass.run_command('v.edit', map=out_type, tool='delete',
- type='centroid', layer=2, quiet=quiet,
- cats='{mi}-{ma}'.format(mi=min_cat, ma=max_cat))
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=remove_names, quiet=quiet)
- grass.fatal(_("Error removing centroids"))
- try:
- try:
- # TODO: fix magic numbers for layer here and there
- grass.run_command('v.db.droptable', map=out_type, layer=1,
- flags='f', quiet=True)
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=remove_names, quiet=quiet)
- grass.fatal(_("Error removing table from layer 1"))
- # TODO: when this except is happaning, it seems that never, so it seems wrong
- except:
- grass.warning(_("No table for layer %d" % 1))
- try:
- grass.run_command('v.category', input=out_type, option='transfer',
- output=output, layer="2,1", quiet=quiet,
- overwrite=overwrite)
- except CalledModuleError:
- grass.run_command('g.remove', flags='f', type='vector',
- name=remove_names, quiet=quiet)
- grass.fatal(_("Error adding categories"))
- grass.run_command('g.remove', flags='f', type='vector',
- name=remove_names, quiet=quiet)
- if point:
- grass.run_command('g.remove', flags='f', type='vector',
- name=out_temp, quiet=quiet)
- if __name__ == "__main__":
- options, flags = grass.parser()
- main()
|