LinesToPolygons.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. """
  2. ***************************************************************************
  3. LinesToPolygons.py
  4. ---------------------
  5. Date : August 2012
  6. Copyright : (C) 2012 by Victor Olaya
  7. Email : volayaf at gmail dot com
  8. ***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************
  16. """
  17. __author__ = 'Victor Olaya'
  18. __date__ = 'August 2012'
  19. __copyright__ = '(C) 2012, Victor Olaya'
  20. import os
  21. from qgis.PyQt.QtGui import QIcon
  22. from qgis.core import (QgsApplication,
  23. QgsFeature,
  24. QgsGeometry,
  25. QgsGeometryCollection,
  26. QgsPolygon,
  27. QgsMultiPolygon,
  28. QgsMultiSurface,
  29. QgsWkbTypes,
  30. QgsFeatureSink,
  31. QgsProcessing,
  32. QgsProcessingParameterFeatureSource,
  33. QgsProcessingParameterFeatureSink,
  34. QgsProcessingUtils)
  35. from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
  36. from processing.tools import dataobjects, vector
  37. pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
  38. class LinesToPolygons(QgisFeatureBasedAlgorithm):
  39. def icon(self):
  40. return QgsApplication.getThemeIcon("/algorithms/mAlgorithmLineToPolygon.svg")
  41. def svgIconPath(self):
  42. return QgsApplication.iconPath("/algorithms/mAlgorithmLineToPolygon.svg")
  43. def tags(self):
  44. return self.tr('line,polygon,convert').split(',')
  45. def group(self):
  46. return self.tr('Vector geometry')
  47. def groupId(self):
  48. return 'vectorgeometry'
  49. def __init__(self):
  50. super().__init__()
  51. def name(self):
  52. return 'linestopolygons'
  53. def displayName(self):
  54. return self.tr('Lines to polygons')
  55. def outputName(self):
  56. return self.tr('Polygons')
  57. def outputType(self):
  58. return QgsProcessing.TypeVectorPolygon
  59. def inputLayerTypes(self):
  60. return [QgsProcessing.TypeVectorLine]
  61. def outputWkbType(self, input_wkb_type):
  62. return self.convertWkbToPolygons(input_wkb_type)
  63. def processFeature(self, feature, context, feedback):
  64. if feature.hasGeometry():
  65. feature.setGeometry(QgsGeometry(self.convertToPolygons(feature.geometry())))
  66. if feature.geometry().isEmpty():
  67. feedback.reportError(self.tr("One or more line ignored due to geometry not having a minimum of three vertices."))
  68. return [feature]
  69. def supportInPlaceEdit(self, layer):
  70. return False
  71. def convertWkbToPolygons(self, wkb):
  72. multi_wkb = QgsWkbTypes.NoGeometry
  73. if QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.LineString:
  74. multi_wkb = QgsWkbTypes.MultiPolygon
  75. elif QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.CompoundCurve:
  76. multi_wkb = QgsWkbTypes.MultiSurface
  77. if QgsWkbTypes.hasM(wkb):
  78. multi_wkb = QgsWkbTypes.addM(multi_wkb)
  79. if QgsWkbTypes.hasZ(wkb):
  80. multi_wkb = QgsWkbTypes.addZ(multi_wkb)
  81. return multi_wkb
  82. def convertToPolygons(self, geometry):
  83. surfaces = self.getSurfaces(geometry.constGet())
  84. output_wkb = self.convertWkbToPolygons(geometry.wkbType())
  85. out_geom = None
  86. if QgsWkbTypes.flatType(output_wkb) == QgsWkbTypes.MultiPolygon:
  87. out_geom = QgsMultiPolygon()
  88. else:
  89. out_geom = QgsMultiSurface()
  90. for surface in surfaces:
  91. out_geom.addGeometry(surface)
  92. return out_geom
  93. def getSurfaces(self, geometry):
  94. surfaces = []
  95. if isinstance(geometry, QgsGeometryCollection):
  96. # collection
  97. for i in range(geometry.numGeometries()):
  98. surfaces.extend(self.getSurfaces(geometry.geometryN(i)))
  99. else:
  100. # not collection
  101. if geometry.vertexCount() > 2:
  102. surface = QgsPolygon()
  103. surface.setExteriorRing(geometry.clone())
  104. surfaces.append(surface)
  105. return surfaces