Skip to content
Permalink
Browse files

Merge branch 'processing-makevalid'

  • Loading branch information
alexbruy committed Feb 7, 2017
2 parents 11f0836 + d3003de commit 94a263995ba3510a6f0636a956e8453e10430983
@@ -383,7 +383,7 @@ qgis:polygonstolines: >

qgis:spatialiteexecutesql: >
This algorithm performs a SQL database query on a Spatialite database.

qgis:postgisexecutesql: >
This algorithm performs a SQL database query on a PostGIS database connected to QGIS.

@@ -514,7 +514,7 @@ qgis:snappointstogrid: >

qgis:splitwithlines: >
This algorithm splits the lines or polygons in one layer using the lines in another layer to define the breaking points. Intersection between geometries in both layers are considered as split points.

Output will contain multi geometries for split features.

qgis:splitvectorlayer: >
@@ -571,16 +571,20 @@ qgis:zonalstatistics:

qgis:rastercalculator: >
This algorithm allows to perform algebraic operations using raster layers.

The resulting layer will have its values computed according to an expression. The expression can contain numerical values, operators and references to any of the layers in the current project. The following functions are also supported:

- sin(), cos(), tan(), atan2(), ln(), log10()

The extent and cellsize can be defined by the user. If the extent is not specified, the minimum extent that covers the input layers will be used. If the cell size is not specified, the minimum cell size of all input layers will be used.

The cell size is assumed to be the same in both X and Y axes.

Layers are referred by their name as displayed in the layer list and the number of the band to use (based on 1), using the pattern 'layer_name@band number'. For instance, the first band from a layer named DEM will be referred as DEM@1.

When using the calculator in the batch interface or from the console, the files to use have to be specified. The corresponding layers are referred using the base name of the file (without the full path). For instance, is using a layer at path/to/my/rasterfile.tif, the first band of that layer will be referred as rasterfile.tif@1.


qgis:fixgeometries: >
This algorithm attempts to create a valid representation of a given invalid geometry without losing any of the input vertices. Already-valid geometries are returned without further intervention. Always outputs multi-geometry layer.

NOTE: M values will be dropped from the output.
@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
FixGeometry.py
-----------------------
Date : January 2017
Copyright : (C) 2017 by Alexander Bruy
Email : alexander dot bruy 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__ = 'Alexander Bruy'
__date__ = 'January 2017'
__copyright__ = '(C) 2017, Alexander Bruy'

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

__revision__ = '$Format:%H$'

from qgis.core import QgsWkbTypes

from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.outputs import OutputVector
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.tools import dataobjects, vector


class FixGeometry(GeoAlgorithm):

INPUT = 'INPUT'
OUTPUT = 'OUTPUT'

def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Fix geometries')
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools')
self.tags = self.tr('repair,invalid,geometry')

self.addParameter(ParameterVector(self.INPUT,
self.tr('Input Layer'),
[dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_LINE]))
self.addOutput(OutputVector(self.OUTPUT,
self.tr('Layer with fixed geometries')))

def processAlgorithm(self, feedback):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT))

writer = self.getOutputFromName(
self.OUTPUT).getVectorWriter(
layer.fields(),
QgsWkbTypes.multiType(layer.wkbType()),
layer.crs())

features = vector.features(layer)
if len(features) == 0:
raise GeoAlgorithmExecutionException(self.tr('There are no features in the input layer'))

total = 100.0 / len(features)
for current, inputFeature in enumerate(features):
outputFeature = inputFeature
if inputFeature.geometry():
outputGeometry = inputFeature.geometry().makeValid()
if not outputGeometry:
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
'makeValid failed for feature {}'.format(inputFeature.id()))

if outputGeometry.wkbType() == QgsWkbTypes.Unknown or QgsWkbTypes.flatType(outputGeometry.geometry().wkbType()) == QgsWkbTypes.GeometryCollection:
tmpGeometries = outputGeometry.asGeometryCollection()
for g in tmpGeometries:
if g.type() == inputFeature.geometry().type():
try:
g.convertToMultiType()
outputFeature.setGeometry(QgsGeometry(g))
writer.addFeature(outputFeature)
except:
pass
feedback.setProgress(int(current * total))
continue

outputGeometry.convertToMultiType()
outputFeature.setGeometry(outputGeometry)

writer.addFeature(outputFeature)
feedback.setProgress(int(current * total))

del writer
@@ -184,6 +184,7 @@
from .ServiceAreaFromLayer import ServiceAreaFromLayer
from .TruncateTable import TruncateTable
from .Polygonize import Polygonize
from .FixGeometry import FixGeometry

pluginPath = os.path.normpath(os.path.join(
os.path.split(os.path.dirname(__file__))[0], os.pardir))
@@ -252,7 +253,8 @@ def __init__(self):
RasterCalculator(), Heatmap(), Orthogonalize(),
ShortestPathPointToPoint(), ShortestPathPointToLayer(),
ShortestPathLayerToPoint(), ServiceAreaFromPoint(),
ServiceAreaFromLayer(), TruncateTable(), Polygonize()
ServiceAreaFromLayer(), TruncateTable(), Polygonize(),
FixGeometry()
]

if hasMatplotlib:
@@ -0,0 +1,16 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>valid</Name>
<ElementPath>valid</ElementPath>
<!--MULTIPOLYGON-->
<GeometryType>6</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>1</FeatureCount>
<ExtentXMin>122.17632</ExtentXMin>
<ExtentXMax>122.19038</ExtentXMax>
<ExtentYMin>-8.60636</ExtentYMin>
<ExtentYMax>-8.59579</ExtentYMax>
</DatasetSpecificInfo>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>122.1763203897661</gml:X><gml:Y>-8.606355050987483</gml:Y></gml:coord>
<gml:coord><gml:X>122.1903768142314</gml:X><gml:Y>-8.595792419886385</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:valid fid="invalidgeometries.0">
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>122.186446688291,-8.60019485107161 122.188508041037,-8.60212999854704 122.186395514816,-8.60635505098748 122.183795482545,-8.60261750459786 122.186446688291,-8.60019485107161</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>122.176320389766,-8.60123623745388 122.179976685147,-8.59774244408966 122.183895970553,-8.59830234200473 122.176320389766,-8.60123623745388</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>122.186446688291,-8.60019485107161 122.184526741622,-8.59839245215742 122.183895970553,-8.59830234200473 122.190376814231,-8.59579241988638 122.188508041037,-8.59831120114895 122.186446688291,-8.60019485107161</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
</ogr:valid>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -2300,6 +2300,17 @@ tests:
name: expected/zonal_statistics.gml
type: vector

- algorithm: qgis:fixgeometries
name: Fix geometries
params:
INPUT:
name: invalidgeometries.gml
type: vector
results:
OUTPUT:
name: expected/valid.gml
type: vector

- algorithm: qgis:polygonize
name: Polygonize
params:

0 comments on commit 94a2639

Please sign in to comment.
You can’t perform that action at this time.