123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- #!/usr/bin/env python3
- ############################################################################
- #
- # 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", 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()
|