mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
[processing][grass] Fix grass vector algs don't work with memory layers
Fixes broken grass algs inside models (fixes #18662)
This commit is contained in:
parent
f928e3dde9
commit
8ba762a630
@ -6,6 +6,7 @@ qgis_composermapgridtest
|
|||||||
qgis_composerutils
|
qgis_composerutils
|
||||||
ProcessingGrass7AlgorithmsImageryTest
|
ProcessingGrass7AlgorithmsImageryTest
|
||||||
ProcessingGrass7AlgorithmsRasterTest
|
ProcessingGrass7AlgorithmsRasterTest
|
||||||
|
ProcessingGrass7AlgorithmsVectorTest
|
||||||
PyQgsAppStartup
|
PyQgsAppStartup
|
||||||
|
|
||||||
# temporary during processing refactoring
|
# temporary during processing refactoring
|
||||||
|
@ -60,7 +60,8 @@ from qgis.core import (Qgis,
|
|||||||
QgsProcessingParameterFile,
|
QgsProcessingParameterFile,
|
||||||
QgsProcessingParameterFolderDestination,
|
QgsProcessingParameterFolderDestination,
|
||||||
QgsProcessingOutputHtml,
|
QgsProcessingOutputHtml,
|
||||||
QgsProcessingUtils)
|
QgsProcessingUtils,
|
||||||
|
QgsVectorLayer)
|
||||||
from qgis.utils import iface
|
from qgis.utils import iface
|
||||||
|
|
||||||
from processing.core.ProcessingConfig import ProcessingConfig
|
from processing.core.ProcessingConfig import ProcessingConfig
|
||||||
@ -761,7 +762,17 @@ class Grass7Algorithm(QgsProcessingAlgorithm):
|
|||||||
:param external: use v.external (v.in.ogr if False).
|
:param external: use v.external (v.in.ogr if False).
|
||||||
"""
|
"""
|
||||||
layer = self.parameterAsVectorLayer(parameters, name, context)
|
layer = self.parameterAsVectorLayer(parameters, name, context)
|
||||||
self.loadVectorLayer(name, layer, external)
|
if layer is None or layer.dataProvider().name() != 'ogr':
|
||||||
|
# parameter is not a vector layer or not an OGR layer - try to convert to a source compatible with
|
||||||
|
# grass OGR inputs and extract selection if required
|
||||||
|
path = self.parameterAsCompatibleSourceLayerPath(parameters, name, context,
|
||||||
|
QgsVectorFileWriter.supportedFormatExtensions(),
|
||||||
|
feedback=feedback)
|
||||||
|
ogr_layer = QgsVectorLayer(path, '', 'ogr')
|
||||||
|
self.loadVectorLayer(name, ogr_layer, external)
|
||||||
|
else:
|
||||||
|
# already an ogr layer source
|
||||||
|
self.loadVectorLayer(name, layer, external)
|
||||||
|
|
||||||
def loadVectorLayer(self, name, layer, external=False):
|
def loadVectorLayer(self, name, layer, external=False):
|
||||||
"""
|
"""
|
||||||
@ -771,7 +782,6 @@ class Grass7Algorithm(QgsProcessingAlgorithm):
|
|||||||
:param layer: QgsMapLayer for the vector layer.
|
:param layer: QgsMapLayer for the vector layer.
|
||||||
:param external: use v.external (v.in.ogr if False).
|
:param external: use v.external (v.in.ogr if False).
|
||||||
"""
|
"""
|
||||||
# TODO: support selections
|
|
||||||
# TODO: support multiple input formats
|
# TODO: support multiple input formats
|
||||||
if external is None:
|
if external is None:
|
||||||
external = ProcessingConfig.getSetting(
|
external = ProcessingConfig.getSetting(
|
||||||
|
@ -13,5 +13,6 @@ IF(ENABLE_TESTS)
|
|||||||
ADD_PYTHON_TEST(ProcessingGdalAlgorithmsTest GdalAlgorithmsTest.py)
|
ADD_PYTHON_TEST(ProcessingGdalAlgorithmsTest GdalAlgorithmsTest.py)
|
||||||
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsImageryTest Grass7AlgorithmsImageryTest.py)
|
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsImageryTest Grass7AlgorithmsImageryTest.py)
|
||||||
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsRasterTest Grass7AlgorithmsRasterTest.py)
|
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsRasterTest Grass7AlgorithmsRasterTest.py)
|
||||||
|
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsVectorTest Grass7AlgorithmsVectorTest.py)
|
||||||
ADD_PYTHON_TEST(ProcessingSagaAlgorithmsTest SagaAlgorithmsTest.py)
|
ADD_PYTHON_TEST(ProcessingSagaAlgorithmsTest SagaAlgorithmsTest.py)
|
||||||
ENDIF(ENABLE_TESTS)
|
ENDIF(ENABLE_TESTS)
|
||||||
|
168
python/plugins/processing/tests/Grass7AlgorithmsVectorTest.py
Normal file
168
python/plugins/processing/tests/Grass7AlgorithmsVectorTest.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
***************************************************************************
|
||||||
|
Grass7AlgorithmsVectorTest.py
|
||||||
|
-----------------------------
|
||||||
|
Date : April 2018
|
||||||
|
Copyright : (C) 2018 by Nyall Dawson
|
||||||
|
Email : nyall dot dawson 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__ = 'Nyall Dawson'
|
||||||
|
__date__ = 'March 2018'
|
||||||
|
__copyright__ = '(C) 2018, Nyall Dawson'
|
||||||
|
|
||||||
|
# This will get replaced with a git SHA1 when you do a git archive
|
||||||
|
|
||||||
|
__revision__ = ':%H$'
|
||||||
|
|
||||||
|
import AlgorithmsTestBase
|
||||||
|
|
||||||
|
import nose2
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
|
||||||
|
from qgis.core import (QgsVectorLayer,
|
||||||
|
QgsApplication,
|
||||||
|
QgsFeature,
|
||||||
|
QgsGeometry,
|
||||||
|
QgsPointXY,
|
||||||
|
QgsProcessingContext,
|
||||||
|
QgsProject,
|
||||||
|
QgsProcessingFeedback,
|
||||||
|
QgsProcessingFeatureSourceDefinition)
|
||||||
|
from qgis.testing import (
|
||||||
|
start_app,
|
||||||
|
unittest
|
||||||
|
)
|
||||||
|
from processing.algs.grass7.Grass7Utils import Grass7Utils
|
||||||
|
|
||||||
|
|
||||||
|
class TestGrass7AlgorithmsVectorTest(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
start_app()
|
||||||
|
from processing.core.Processing import Processing
|
||||||
|
Processing.initialize()
|
||||||
|
cls.cleanup_paths = []
|
||||||
|
|
||||||
|
assert Grass7Utils.installedVersion()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
from processing.core.Processing import Processing
|
||||||
|
Processing.deinitialize()
|
||||||
|
for path in cls.cleanup_paths:
|
||||||
|
shutil.rmtree(path)
|
||||||
|
|
||||||
|
def test_definition_file(self):
|
||||||
|
return 'grass7_algorithms_vector_tests.yaml'
|
||||||
|
|
||||||
|
def testMemoryLayerInput(self):
|
||||||
|
# create a memory layer and add to project and context
|
||||||
|
layer = QgsVectorLayer("Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer",
|
||||||
|
"testmem", "memory")
|
||||||
|
self.assertTrue(layer.isValid())
|
||||||
|
pr = layer.dataProvider()
|
||||||
|
f = QgsFeature()
|
||||||
|
f.setAttributes(["test", 123])
|
||||||
|
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
|
||||||
|
f2 = QgsFeature()
|
||||||
|
f2.setAttributes(["test2", 457])
|
||||||
|
f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200)))
|
||||||
|
self.assertTrue(pr.addFeatures([f, f2]))
|
||||||
|
self.assertEqual(layer.featureCount(), 2)
|
||||||
|
QgsProject.instance().addMapLayer(layer)
|
||||||
|
context = QgsProcessingContext()
|
||||||
|
context.setProject(QgsProject.instance())
|
||||||
|
|
||||||
|
alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer')
|
||||||
|
self.assertIsNotNone(alg)
|
||||||
|
temp_file = '/tmp/grass_output.shp'
|
||||||
|
parameters ={'input':'testmem',
|
||||||
|
'type':[0,1,4],
|
||||||
|
'distance':1,
|
||||||
|
'angle':0,
|
||||||
|
'scale':1,
|
||||||
|
'tolerance':0.01,
|
||||||
|
'-s':False,
|
||||||
|
'-c':False,
|
||||||
|
'-t':False,
|
||||||
|
'output':temp_file,
|
||||||
|
'GRASS_SNAP_TOLERANCE_PARAMETER':-1,'GRASS_MIN_AREA_PARAMETER':0.0001,'GRASS_OUTPUT_TYPE_PARAMETER':0}
|
||||||
|
feedback = QgsProcessingFeedback()
|
||||||
|
|
||||||
|
results, ok = alg.run(parameters, context, feedback)
|
||||||
|
self.assertTrue(ok)
|
||||||
|
self.assertTrue(os.path.exists(temp_file))
|
||||||
|
|
||||||
|
# make sure that layer has correct features
|
||||||
|
res = QgsVectorLayer(temp_file, 'res')
|
||||||
|
self.assertTrue(res.isValid())
|
||||||
|
self.assertEqual(res.featureCount(), 2)
|
||||||
|
|
||||||
|
QgsProject.instance().removeMapLayer(layer)
|
||||||
|
|
||||||
|
def testFeatureSourceInput(self):
|
||||||
|
# create a memory layer and add to project and context
|
||||||
|
layer = QgsVectorLayer("Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer",
|
||||||
|
"testmem", "memory")
|
||||||
|
self.assertTrue(layer.isValid())
|
||||||
|
pr = layer.dataProvider()
|
||||||
|
f = QgsFeature()
|
||||||
|
f.setAttributes(["test", 123])
|
||||||
|
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
|
||||||
|
f2 = QgsFeature()
|
||||||
|
f2.setAttributes(["test2", 457])
|
||||||
|
f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200)))
|
||||||
|
self.assertTrue(pr.addFeatures([f, f2]))
|
||||||
|
self.assertEqual(layer.featureCount(), 2)
|
||||||
|
|
||||||
|
# select first feature
|
||||||
|
layer.selectByIds([next(layer.getFeatures()).id()])
|
||||||
|
self.assertEqual(len(layer.selectedFeatureIds()), 1)
|
||||||
|
|
||||||
|
QgsProject.instance().addMapLayer(layer)
|
||||||
|
context = QgsProcessingContext()
|
||||||
|
context.setProject(QgsProject.instance())
|
||||||
|
|
||||||
|
alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer')
|
||||||
|
self.assertIsNotNone(alg)
|
||||||
|
temp_file = '/tmp/grass_output.shp'
|
||||||
|
parameters = {'input': QgsProcessingFeatureSourceDefinition('testmem', True),
|
||||||
|
'type': [0, 1, 4],
|
||||||
|
'distance': 1,
|
||||||
|
'angle': 0,
|
||||||
|
'scale': 1,
|
||||||
|
'tolerance': 0.01,
|
||||||
|
'-s': False,
|
||||||
|
'-c': False,
|
||||||
|
'-t': False,
|
||||||
|
'output': temp_file,
|
||||||
|
'GRASS_SNAP_TOLERANCE_PARAMETER': -1, 'GRASS_MIN_AREA_PARAMETER': 0.0001,
|
||||||
|
'GRASS_OUTPUT_TYPE_PARAMETER': 0}
|
||||||
|
feedback = QgsProcessingFeedback()
|
||||||
|
|
||||||
|
results, ok = alg.run(parameters, context, feedback)
|
||||||
|
self.assertTrue(ok)
|
||||||
|
self.assertTrue(os.path.exists(temp_file))
|
||||||
|
|
||||||
|
# make sure that layer has correct features
|
||||||
|
res = QgsVectorLayer(temp_file, 'res')
|
||||||
|
self.assertTrue(res.isValid())
|
||||||
|
self.assertEqual(res.featureCount(), 1)
|
||||||
|
|
||||||
|
QgsProject.instance().removeMapLayer(layer)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
nose2.main()
|
20
python/plugins/processing/tests/testdata/grass7_algorithms_vector_tests.yaml
vendored
Normal file
20
python/plugins/processing/tests/testdata/grass7_algorithms_vector_tests.yaml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# See ../README.md for a description of the file format
|
||||||
|
|
||||||
|
tests:
|
||||||
|
|
||||||
|
# v.* modules
|
||||||
|
# - algorithm: grass7:r.plane
|
||||||
|
# name: GRASS7 r.plane
|
||||||
|
# params:
|
||||||
|
# GRASS_REGION_PARAMETER: 344500.0,358400.0,6682800.0,6693700.0
|
||||||
|
# azimuth: 125
|
||||||
|
# dip: 45
|
||||||
|
# easting: 351610
|
||||||
|
# elevation: 50
|
||||||
|
# northing: 6688312
|
||||||
|
# type: 1
|
||||||
|
# results:
|
||||||
|
# output:
|
||||||
|
# hash: a9326678c39b6f925e7f22f6e79a48217100071cc8af85d675f28462
|
||||||
|
# type: rasterhash
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user