Skip to content

Commit

Permalink
[processing] turn keep n biggest parts script into normal algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Feb 5, 2018
1 parent 54167bc commit 15a185d
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 49 deletions.
5 changes: 0 additions & 5 deletions python/plugins/processing/algs/qgis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
FILE(GLOB PY_FILES *.py)
FILE(GLOB HELP_FILES help/*.rst)
FILE(GLOB SCRIPT_FILES scripts/*.*)

ADD_SUBDIRECTORY(ui)

PLUGIN_INSTALL(processing algs/qgis ${PY_FILES})
PLUGIN_INSTALL(processing algs/qgis/help ${HELP_FILES})
PLUGIN_INSTALL(processing algs/qgis/scripts ${SCRIPT_FILES})
107 changes: 107 additions & 0 deletions python/plugins/processing/algs/qgis/KeepNBiggestParts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
KeepNBiggestParts.py
---------------------
Date : July 2014
Copyright : (C) 2014 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__ = 'July 2014'
__copyright__ = '(C) 2014, Victor Olaya'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

from operator import itemgetter


from qgis.core import (QgsGeometry,
QgsFeatureSink,
QgsProcessing,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm


class KeepNBiggestParts(QgisAlgorithm):

POLYGONS = 'POLYGONS'
PARTS = 'PARTS'
OUTPUT = 'OUTPUT'

def group(self):
return self.tr('Vector geometry')

def groupId(self):
return 'vectorgeometry'

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.POLYGONS,
self.tr('Polygons'), [QgsProcessing.TypeVectorPolygon]))
self.addParameter(QgsProcessingParameterNumber(self.PARTS,
self.tr('Parts to keep'),
QgsProcessingParameterNumber.Integer,
1, False, 1))
self.addParameter(
QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Parts'), QgsProcessing.TypeVectorPolygon))

def name(self):
return 'keepnbiggestparts'

def displayName(self):
return self.tr('Keep N biggest parts')

def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.POLYGONS, context)
parts = self.parameterAsInt(parameters, self.PARTS, context)

fields = source.fields()
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, feat in enumerate(features):
if feedback.isCanceled():
break

geom = feat.geometry()
if geom.isMultipart():
out_feature = feat
geoms = geom.asGeometryCollection()
geom_area = [(i, geoms[i].area()) for i in range(len(geoms))]
geom_area.sort(key=itemgetter(1))
if parts == 1:
out_feature.setGeometry(geoms[geom_area[-1][0]])
elif parts > len(geoms):
out_feature.setGeometry(geom)
else:
out_feature.setGeometry(geom)
geomres = [geoms[i].asPolygon() for i, a in geom_area[-1 * parts:]]
out_feature.setGeometry(QgsGeometry.fromMultiPolygonXY(geomres))
sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
else:
sink.addFeature(feat, QgsFeatureSink.FastInsert)

feedback.setProgress(int(current * total))

return {self.OUTPUT: dest_id}
2 changes: 2 additions & 0 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
from .ImportIntoPostGIS import ImportIntoPostGIS
from .ImportIntoSpatialite import ImportIntoSpatialite
from .Intersection import Intersection
from .KeepNBiggestParts import KeepNBiggestParts
from .LinesToPolygons import LinesToPolygons
from .MinimumBoundingGeometry import MinimumBoundingGeometry
from .NearestNeighbourAnalysis import NearestNeighbourAnalysis
Expand Down Expand Up @@ -200,6 +201,7 @@ def getAlgs(self):
ImportIntoPostGIS(),
ImportIntoSpatialite(),
Intersection(),
KeepNBiggestParts(),
LinesToPolygons(),
MinimumBoundingGeometry(),
NearestNeighbourAnalysis(),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ biggest_parts.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>-1</gml:Y></gml:coord>
<gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:biggest_parts fid="multipolys.0">
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,1 2,2 3,2 3,3 4,3 4,1 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
<ogr:Bname>Test</ogr:Bname>
<ogr:Bintval>1</ogr:Bintval>
<ogr:Bfloatval>0.123</ogr:Bfloatval>
</ogr:biggest_parts>
</gml:featureMember>
<gml:featureMember>
<ogr:biggest_parts fid="multipolys.1">
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>7,-1 8,-1 8,3 7,3 7,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
<ogr:Bname xsi:nil="true"/>
<ogr:Bintval xsi:nil="true"/>
<ogr:Bfloatval xsi:nil="true"/>
</ogr:biggest_parts>
</gml:featureMember>
<gml:featureMember>
<ogr:biggest_parts fid="multipolys.2">
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>0,0 0,1 1,1 1,0 0,0</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
<ogr:Bname>Test</ogr:Bname>
<ogr:Bintval>2</ogr:Bintval>
<ogr:Bfloatval>-0.123</ogr:Bfloatval>
</ogr:biggest_parts>
</gml:featureMember>
<gml:featureMember>
<ogr:biggest_parts fid="multipolys.3">
<ogr:Bname>Test</ogr:Bname>
<ogr:Bintval>3</ogr:Bintval>
<ogr:Bfloatval>0</ogr:Bfloatval>
</ogr:biggest_parts>
</gml:featureMember>
</ogr:FeatureCollection>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="biggest_parts" type="ogr:biggest_parts_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="biggest_parts_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:MultiPolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="Bname" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Bintval" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Bfloatval" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:decimal">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
12 changes: 12 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4676,3 +4676,15 @@ tests:
OUTPUT:
name: expected/removed_duplicated_nodes_line.gml
type: vector

- algorithm: qgis:keepnbiggestparts
name: Keep N biggest parts
params:
PARTS: 1
POLYGONS:
name: multipolys.gml
type: vector
results:
OUTPUT:
name: expected/biggest_parts.gml
type: vector

0 comments on commit 15a185d

Please sign in to comment.