mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Add native polygonstolines algorithm
This commit is contained in:
parent
8709ab61eb
commit
4c8af20b51
@ -1,130 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
PolygonsToLines.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'
|
||||
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
|
||||
from qgis.core import (QgsApplication,
|
||||
QgsGeometry,
|
||||
QgsGeometryCollection,
|
||||
QgsMultiLineString,
|
||||
QgsMultiCurve,
|
||||
QgsWkbTypes,
|
||||
QgsProcessing)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
|
||||
class PolygonsToLines(QgisFeatureBasedAlgorithm):
|
||||
|
||||
def icon(self):
|
||||
return QgsApplication.getThemeIcon("/algorithms/mAlgorithmPolygonToLine.svg")
|
||||
|
||||
def svgIconPath(self):
|
||||
return QgsApplication.iconPath("/algorithms/mAlgorithmPolygonToLine.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 'polygonstolines'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Polygons to lines')
|
||||
|
||||
def outputName(self):
|
||||
return self.tr('Lines')
|
||||
|
||||
def outputType(self):
|
||||
return QgsProcessing.TypeVectorLine
|
||||
|
||||
def inputLayerTypes(self):
|
||||
return [QgsProcessing.TypeVectorPolygon]
|
||||
|
||||
def outputWkbType(self, input_wkb_type):
|
||||
return self.convertWkbToLines(input_wkb_type)
|
||||
|
||||
def processFeature(self, feature, context, feedback):
|
||||
if feature.hasGeometry():
|
||||
feature.setGeometry(QgsGeometry(self.convertToLines(feature.geometry())))
|
||||
return [feature]
|
||||
|
||||
def supportInPlaceEdit(self, layer):
|
||||
return False
|
||||
|
||||
def convertWkbToLines(self, wkb):
|
||||
multi_wkb = QgsWkbTypes.NoGeometry
|
||||
if QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.Polygon:
|
||||
multi_wkb = QgsWkbTypes.MultiLineString
|
||||
elif QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.CurvePolygon:
|
||||
multi_wkb = QgsWkbTypes.MultiCurve
|
||||
if QgsWkbTypes.hasM(wkb):
|
||||
multi_wkb = QgsWkbTypes.addM(multi_wkb)
|
||||
if QgsWkbTypes.hasZ(wkb):
|
||||
multi_wkb = QgsWkbTypes.addZ(multi_wkb)
|
||||
|
||||
return multi_wkb
|
||||
|
||||
def convertToLines(self, geometry):
|
||||
rings = self.getRings(geometry.constGet())
|
||||
output_wkb = self.convertWkbToLines(geometry.wkbType())
|
||||
out_geom = None
|
||||
if QgsWkbTypes.flatType(output_wkb) == QgsWkbTypes.MultiLineString:
|
||||
out_geom = QgsMultiLineString()
|
||||
else:
|
||||
out_geom = QgsMultiCurve()
|
||||
|
||||
for ring in rings:
|
||||
out_geom.addGeometry(ring)
|
||||
|
||||
return out_geom
|
||||
|
||||
def getRings(self, geometry):
|
||||
rings = []
|
||||
if isinstance(geometry, QgsGeometryCollection):
|
||||
# collection
|
||||
for i in range(geometry.numGeometries()):
|
||||
rings.extend(self.getRings(geometry.geometryN(i)))
|
||||
else:
|
||||
# not collection
|
||||
rings.append(geometry.exteriorRing().clone())
|
||||
for i in range(geometry.numInteriorRings()):
|
||||
rings.append(geometry.interiorRing(i).clone())
|
||||
|
||||
return rings
|
@ -98,7 +98,6 @@ from .PointsLayerFromTable import PointsLayerFromTable
|
||||
from .PointsToPaths import PointsToPaths
|
||||
from .PoleOfInaccessibility import PoleOfInaccessibility
|
||||
from .Polygonize import Polygonize
|
||||
from .PolygonsToLines import PolygonsToLines
|
||||
from .PostGISExecuteSQL import PostGISExecuteSQL
|
||||
from .PostGISExecuteAndLoadSQL import PostGISExecuteAndLoadSQL
|
||||
from .RandomExtract import RandomExtract
|
||||
@ -210,7 +209,6 @@ class QgisAlgorithmProvider(QgsProcessingProvider):
|
||||
PointsToPaths(),
|
||||
PoleOfInaccessibility(),
|
||||
Polygonize(),
|
||||
PolygonsToLines(),
|
||||
PostGISExecuteSQL(),
|
||||
PostGISExecuteAndLoadSQL(),
|
||||
RandomExtract(),
|
||||
|
@ -73,6 +73,7 @@ SET(QGIS_ANALYSIS_SRCS
|
||||
processing/qgsalgorithmorientedminimumboundingbox.cpp
|
||||
processing/qgsalgorithmpackage.cpp
|
||||
processing/qgsalgorithmarrayoffsetlines.cpp
|
||||
processing/qgsalgorithmpolygonstolines.cpp
|
||||
processing/qgsalgorithmpointonsurface.cpp
|
||||
processing/qgsalgorithmprojectpointcartesian.cpp
|
||||
processing/qgsalgorithmpromotetomultipart.cpp
|
||||
|
150
src/analysis/processing/qgsalgorithmpolygonstolines.cpp
Normal file
150
src/analysis/processing/qgsalgorithmpolygonstolines.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/***************************************************************************
|
||||
qgsalgorithmpolygonstolines.cpp
|
||||
---------------------
|
||||
begin : January 2019
|
||||
copyright : (C) 2019 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsalgorithmpolygonstolines.h"
|
||||
#include "qgsgeometrycollection.h"
|
||||
#include "qgscurvepolygon.h"
|
||||
#include "qgscurve.h"
|
||||
#include "qgsmultilinestring.h"
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::name() const
|
||||
{
|
||||
return QStringLiteral( "polygonstolines" );
|
||||
}
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::displayName() const
|
||||
{
|
||||
return QObject::tr( "Polygons to lines" );
|
||||
}
|
||||
|
||||
QStringList QgsPolygonsToLinesAlgorithm::tags() const
|
||||
{
|
||||
return QObject::tr( "line,polygon,convert" ).split( ',' );
|
||||
}
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::group() const
|
||||
{
|
||||
return QObject::tr( "Vector creation" );
|
||||
}
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::groupId() const
|
||||
{
|
||||
return QStringLiteral( "vectorgeometry" );
|
||||
}
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::outputName() const
|
||||
{
|
||||
return QObject::tr( "Lines" );
|
||||
}
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::shortHelpString() const
|
||||
{
|
||||
return QObject::tr( "Converts polygons to lines" );
|
||||
}
|
||||
|
||||
QString QgsPolygonsToLinesAlgorithm::shortDescription() const
|
||||
{
|
||||
return QObject::tr( "Converts polygons to lines." );
|
||||
}
|
||||
|
||||
QgsPolygonsToLinesAlgorithm *QgsPolygonsToLinesAlgorithm::createInstance() const
|
||||
{
|
||||
return new QgsPolygonsToLinesAlgorithm();
|
||||
}
|
||||
|
||||
QList<int> QgsPolygonsToLinesAlgorithm::inputLayerTypes() const
|
||||
{
|
||||
return QList< int >() << QgsProcessing::TypeVectorPolygon;
|
||||
}
|
||||
|
||||
QgsFeatureList QgsPolygonsToLinesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
|
||||
{
|
||||
QgsFeatureList result;
|
||||
QgsFeature feat = feature;
|
||||
if ( feat.hasGeometry() )
|
||||
feat.setGeometry( convertToLines( feat.geometry() ) );
|
||||
|
||||
result << feat;
|
||||
return result;
|
||||
}
|
||||
|
||||
QgsGeometry QgsPolygonsToLinesAlgorithm::convertToLines( const QgsGeometry &geometry ) const
|
||||
{
|
||||
auto rings = extractRings( geometry.constGet() );
|
||||
|
||||
QgsWkbTypes::Type resultType = outWkbType( geometry.wkbType() );
|
||||
|
||||
std::unique_ptr<QgsMultiCurve> lineGeometry;
|
||||
|
||||
if ( QgsWkbTypes::flatType( resultType ) == QgsWkbTypes::MultiLineString )
|
||||
lineGeometry = qgis::make_unique<QgsMultiLineString>();
|
||||
else
|
||||
lineGeometry = qgis::make_unique<QgsMultiCurve>();
|
||||
|
||||
for ( auto ring : qgis::as_const( rings ) )
|
||||
lineGeometry->addGeometry( ring );
|
||||
|
||||
return QgsGeometry( lineGeometry.release() );
|
||||
}
|
||||
|
||||
QgsWkbTypes::Type QgsPolygonsToLinesAlgorithm::outWkbType( QgsWkbTypes::Type polygonWkbType ) const
|
||||
{
|
||||
QgsWkbTypes::Type wkbType = QgsWkbTypes::NoGeometry;
|
||||
|
||||
if ( QgsWkbTypes::singleType( QgsWkbTypes::flatType( polygonWkbType ) ) == QgsWkbTypes::Polygon )
|
||||
wkbType = QgsWkbTypes::MultiLineString;
|
||||
else if ( QgsWkbTypes::singleType( QgsWkbTypes::flatType( polygonWkbType ) ) == QgsWkbTypes::CurvePolygon )
|
||||
wkbType = QgsWkbTypes::MultiCurve;
|
||||
|
||||
if ( QgsWkbTypes::hasM( polygonWkbType ) )
|
||||
wkbType = QgsWkbTypes::addM( wkbType );
|
||||
if ( QgsWkbTypes::hasZ( polygonWkbType ) )
|
||||
wkbType = QgsWkbTypes::addZ( wkbType );
|
||||
|
||||
return wkbType;
|
||||
}
|
||||
|
||||
QList<QgsCurve *> QgsPolygonsToLinesAlgorithm::extractRings( const QgsAbstractGeometry *geom ) const
|
||||
{
|
||||
QList<QgsCurve *> rings;
|
||||
|
||||
if ( QgsGeometryCollection *collection = qgsgeometry_cast<QgsGeometryCollection *>( geom ) )
|
||||
{
|
||||
for ( int i = 0; i < collection->numGeometries(); ++i )
|
||||
{
|
||||
rings.append( extractRings( collection->geometryN( i ) ) );
|
||||
}
|
||||
}
|
||||
else if ( QgsCurvePolygon *polygon = qgsgeometry_cast<QgsCurvePolygon *>( geom ) )
|
||||
{
|
||||
rings.append( polygon->exteriorRing()->clone() );
|
||||
for ( int i = 0; i < polygon->numInteriorRings(); ++i )
|
||||
{
|
||||
rings.append( polygon->interiorRing( i )->clone() );
|
||||
}
|
||||
}
|
||||
|
||||
return rings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///@endcond
|
||||
|
||||
|
63
src/analysis/processing/qgsalgorithmpolygonstolines.h
Normal file
63
src/analysis/processing/qgsalgorithmpolygonstolines.h
Normal file
@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
qgsalgorithmpolygontolines.h
|
||||
---------------------
|
||||
begin : January 2019
|
||||
copyright : (C) 2019 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSALGORITHMPOLYGONSTOLINES_H
|
||||
#define QGSALGORITHMPOLYGONSTOLINES_H
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgsprocessingalgorithm.h"
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
/**
|
||||
* Native convert polygons to lines algorithm
|
||||
*/
|
||||
class QgsPolygonsToLinesAlgorithm : public QgsProcessingFeatureBasedAlgorithm
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
QgsPolygonsToLinesAlgorithm() = default;
|
||||
QString name() const override;
|
||||
QString displayName() const override;
|
||||
QStringList tags() const override;
|
||||
QString group() const override;
|
||||
QString groupId() const override;
|
||||
QString shortHelpString() const override;
|
||||
QString shortDescription() const override;
|
||||
QgsPolygonsToLinesAlgorithm *createInstance() const override SIP_FACTORY;
|
||||
QList<int> inputLayerTypes() const override;
|
||||
|
||||
protected:
|
||||
QString outputName() const override;
|
||||
QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
|
||||
|
||||
private:
|
||||
QgsGeometry convertToLines( const QgsGeometry &geometry ) const;
|
||||
QList<QgsCurve *> extractRings( const QgsAbstractGeometry *geom ) const;
|
||||
QgsWkbTypes::Type outWkbType( QgsWkbTypes::Type polygonWkbType ) const;
|
||||
|
||||
friend class TestQgsProcessingAlgs;
|
||||
};
|
||||
|
||||
///@endcond PRIVATE
|
||||
|
||||
#endif // QGSALGORITHMPOLYGONSTOLINES_H
|
||||
|
||||
|
@ -105,7 +105,7 @@
|
||||
#include "qgsalgorithmvectorize.h"
|
||||
#include "qgsalgorithmwedgebuffers.h"
|
||||
#include "qgsalgorithmzonalhistogram.h"
|
||||
|
||||
#include "qgsalgorithmpolygonstolines.h"
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
@ -243,6 +243,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
|
||||
addAlgorithm( new QgsVariableWidthBufferByMAlgorithm() );
|
||||
addAlgorithm( new QgsWedgeBuffersAlgorithm() );
|
||||
addAlgorithm( new QgsZonalHistogramAlgorithm() );
|
||||
addAlgorithm( new QgsPolygonsToLinesAlgorithm() );
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user