QGIS/python/plugins/processing/algs/qgis/LinesToPolygons.py
2024-11-29 15:38:02 +01:00

147 lines
4.6 KiB
Python

"""
***************************************************************************
LinesToPolygons.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = "Victor Olaya"
__date__ = "August 2012"
__copyright__ = "(C) 2012, Victor Olaya"
import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (
QgsApplication,
QgsFeature,
QgsGeometry,
QgsGeometryCollection,
QgsPolygon,
QgsMultiPolygon,
QgsMultiSurface,
QgsWkbTypes,
QgsFeatureSink,
QgsProcessing,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingUtils,
)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
from processing.tools import dataobjects, vector
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
class LinesToPolygons(QgisFeatureBasedAlgorithm):
def icon(self):
return QgsApplication.getThemeIcon("/algorithms/mAlgorithmLineToPolygon.svg")
def svgIconPath(self):
return QgsApplication.iconPath("/algorithms/mAlgorithmLineToPolygon.svg")
def tags(self):
return self.tr("line,polygon,convert").split(",")
def group(self):
return self.tr("Vector geometry")
def groupId(self):
return "vectorgeometry"
def __init__(self):
super().__init__()
def name(self):
return "linestopolygons"
def displayName(self):
return self.tr("Lines to polygons")
def outputName(self):
return self.tr("Polygons")
def outputType(self):
return QgsProcessing.SourceType.TypeVectorPolygon
def inputLayerTypes(self):
return [QgsProcessing.SourceType.TypeVectorLine]
def outputWkbType(self, input_wkb_type):
return self.convertWkbToPolygons(input_wkb_type)
def processFeature(self, feature, context, feedback):
if feature.hasGeometry():
feature.setGeometry(QgsGeometry(self.convertToPolygons(feature.geometry())))
if feature.geometry().isEmpty():
feedback.reportError(
self.tr(
"One or more line ignored due to geometry not having a minimum of three vertices."
)
)
return [feature]
def supportInPlaceEdit(self, layer):
return False
def convertWkbToPolygons(self, wkb):
multi_wkb = QgsWkbTypes.Type.NoGeometry
if (
QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb))
== QgsWkbTypes.Type.LineString
):
multi_wkb = QgsWkbTypes.Type.MultiPolygon
elif (
QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb))
== QgsWkbTypes.Type.CompoundCurve
):
multi_wkb = QgsWkbTypes.Type.MultiSurface
if QgsWkbTypes.hasM(wkb):
multi_wkb = QgsWkbTypes.addM(multi_wkb)
if QgsWkbTypes.hasZ(wkb):
multi_wkb = QgsWkbTypes.addZ(multi_wkb)
return multi_wkb
def convertToPolygons(self, geometry):
surfaces = self.getSurfaces(geometry.constGet())
output_wkb = self.convertWkbToPolygons(geometry.wkbType())
out_geom = None
if QgsWkbTypes.flatType(output_wkb) == QgsWkbTypes.Type.MultiPolygon:
out_geom = QgsMultiPolygon()
else:
out_geom = QgsMultiSurface()
for surface in surfaces:
out_geom.addGeometry(surface)
return out_geom
def getSurfaces(self, geometry):
surfaces = []
if isinstance(geometry, QgsGeometryCollection):
# collection
for i in range(geometry.numGeometries()):
surfaces.extend(self.getSurfaces(geometry.geometryN(i)))
else:
# not collection
if geometry.vertexCount() > 2:
surface = QgsPolygon()
surface.setExteriorRing(geometry.clone())
surfaces.append(surface)
return surfaces