mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Move minimum layer extent calculation to c++
This commit is contained in:
parent
189f804714
commit
ba03f1a13a
@ -152,6 +152,12 @@ class QgsProcessingUtils
|
||||
available in Python bindings as createFeatureSink()
|
||||
%End
|
||||
|
||||
static QgsRectangle combineLayerExtents( const QList< QgsMapLayer *> layers, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
%Docstring
|
||||
Combines the extent of several map ``layers``. If specified, the target ``crs``
|
||||
will be used to transform the layer's extent to the desired output reference system.
|
||||
:rtype: QgsRectangle
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
@ -88,6 +88,9 @@ class ClipByExtent(GdalAlgorithm):
|
||||
noData = self.getParameterValue(self.NO_DATA)
|
||||
opts = self.getParameterValue(self.OPTIONS)
|
||||
projwin = self.getParameterValue(self.PROJWIN)
|
||||
layer = self.getParameterValue(self.INPUT)
|
||||
if not projwin:
|
||||
projwin = QgsProcessingUtils.combineLayerExtents([layer])
|
||||
|
||||
if noData is not None:
|
||||
noData = str(noData)
|
||||
|
@ -69,6 +69,8 @@ class Ogr2OgrClipExtent(GdalAlgorithm):
|
||||
inLayer = self.getParameterValue(self.INPUT_LAYER)
|
||||
ogrLayer = ogrConnectionString(inLayer)[1:-1]
|
||||
clipExtent = self.getParameterValue(self.CLIP_EXTENT)
|
||||
if not clipExtent:
|
||||
clipExtent = QgsProcessingUtils.combineLayerExtents([inLayer])
|
||||
|
||||
output = self.getOutputFromName(self.OUTPUT_LAYER)
|
||||
outFile = output.value
|
||||
|
@ -203,6 +203,8 @@ class Ogr2OgrToPostGis(GdalAlgorithm):
|
||||
simplify = str(self.getParameterValue(self.SIMPLIFY))
|
||||
segmentize = str(self.getParameterValue(self.SEGMENTIZE))
|
||||
spat = self.getParameterValue(self.SPAT)
|
||||
if not spat:
|
||||
spat = QgsProcessingUtils.combineLayerExtents([inLayer])
|
||||
clip = self.getParameterValue(self.CLIP)
|
||||
where = str(self.getParameterValue(self.WHERE))
|
||||
wherestring = '-where "' + where + '"'
|
||||
|
@ -205,6 +205,8 @@ class Ogr2OgrToPostGisList(GdalAlgorithm):
|
||||
simplify = self.getParameterValue(self.SIMPLIFY)
|
||||
segmentize = self.getParameterValue(self.SEGMENTIZE)
|
||||
spat = self.getParameterValue(self.SPAT)
|
||||
if not spat:
|
||||
spat = QgsProcessingUtils.combineLayerExtents([inLayer])
|
||||
clip = self.getParameterValue(self.CLIP)
|
||||
where = self.getParameterValue(self.WHERE)
|
||||
gt = self.getParameterValue(self.GT)
|
||||
|
@ -106,6 +106,8 @@ class rasterize(GdalAlgorithm):
|
||||
inLayer = self.getParameterValue(self.INPUT)
|
||||
noData = self.getParameterValue(self.NO_DATA)
|
||||
rastext = str(self.getParameterValue(self.RAST_EXT))
|
||||
if not rastext:
|
||||
rastext = QgsProcessingUtils.combineLayerExtents([inLayer])
|
||||
opts = self.getParameterValue(self.OPTIONS)
|
||||
out = self.getOutputValue(self.OUTPUT)
|
||||
|
||||
|
@ -104,12 +104,15 @@ class translate(GdalAlgorithm):
|
||||
return self.tr('Raster conversion')
|
||||
|
||||
def getConsoleCommands(self, parameters):
|
||||
inLayer = self.getParameterValue(self.INPUT)
|
||||
out = self.getOutputValue(translate.OUTPUT)
|
||||
outsize = str(self.getParameterValue(self.OUTSIZE))
|
||||
outsizePerc = str(self.getParameterValue(self.OUTSIZE_PERC))
|
||||
noData = self.getParameterValue(self.NO_DATA)
|
||||
expand = self.getParameterFromName(self.EXPAND).options[self.getParameterValue(self.EXPAND)][1]
|
||||
projwin = str(self.getParameterValue(self.PROJWIN))
|
||||
if not projwin:
|
||||
projwin = QgsProcessingUtils.combineLayerExtents([inLayer])
|
||||
crsId = self.getParameterValue(self.SRS)
|
||||
sds = self.getParameterValue(self.SDS)
|
||||
opts = self.getParameterValue(self.OPTIONS)
|
||||
|
@ -122,10 +122,13 @@ class warp(GdalAlgorithm):
|
||||
return self.tr('Raster projections')
|
||||
|
||||
def getConsoleCommands(self, parameters):
|
||||
inLayer = self.getParameterValue(self.INPUT)
|
||||
srccrs = self.getParameterValue(self.SOURCE_SRS)
|
||||
dstcrs = self.getParameterValue(self.DEST_SRS)
|
||||
useRasterExtent = self.getParameterValue(self.USE_RASTER_EXTENT)
|
||||
rasterExtent = self.getParameterValue(self.RASTER_EXTENT)
|
||||
if not rasterExtent:
|
||||
rasterExtent = QgsProcessingUtils.combineLayerExtents([inLayer])
|
||||
extentCrs = self.getParameterValue(self.EXTENT_CRS)
|
||||
opts = self.getParameterValue(self.OPTIONS)
|
||||
noData = self.getParameterValue(self.NO_DATA)
|
||||
|
@ -371,6 +371,9 @@ class Grass7Algorithm(GeoAlgorithm):
|
||||
|
||||
region = \
|
||||
str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER))
|
||||
if not region:
|
||||
region = QgsProcessingUtils.combineLayerExtents(layers)
|
||||
|
||||
regionCoords = region.split(',')
|
||||
command = 'g.region'
|
||||
command += ' n=' + str(regionCoords[3])
|
||||
|
@ -102,6 +102,9 @@ class nviz7(GeoAlgorithm):
|
||||
|
||||
region = \
|
||||
str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER))
|
||||
if not region:
|
||||
region = QgsProcessingUtils.combineLayerExtents(layers)
|
||||
|
||||
regionCoords = region.split(',')
|
||||
command = 'g.region '
|
||||
command += 'n=' + str(regionCoords[3])
|
||||
|
@ -87,6 +87,8 @@ class FindProjection(QgisAlgorithm):
|
||||
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
|
||||
|
||||
extent = self.getParameterValue(self.TARGET_AREA).split(',')
|
||||
if not extent:
|
||||
extent = QgsProcessingUtils.combineLayerExtents([layer])
|
||||
target_crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.TARGET_AREA_CRS))
|
||||
|
||||
target_geom = QgsGeometry.fromRect(QgsRectangle(float(extent[0]), float(extent[2]),
|
||||
|
@ -127,6 +127,8 @@ class RasterCalculator(QgisAlgorithm):
|
||||
|
||||
output = self.getOutputValue(self.OUTPUT)
|
||||
extentValue = self.getParameterValue(self.EXTENT)
|
||||
if not extentValue:
|
||||
extentValue = QgsProcessingUtils.combineLayerExtents(layersValue)
|
||||
|
||||
if extentValue:
|
||||
extent = extentValue.split(',')
|
||||
|
@ -204,6 +204,10 @@ class SagaAlgorithm(GeoAlgorithm):
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Unsupported file format'))
|
||||
|
||||
# TODO - set minimum extent
|
||||
if not extent:
|
||||
extent = QgsProcessingUtils.combineLayerExtents([layer])
|
||||
|
||||
# 2: Set parameters and outputs
|
||||
command = self.undecoratedGroup + ' "' + self.cmdname + '"'
|
||||
command += ' ' + ' '.join(self.hardcodedStrings)
|
||||
|
@ -42,6 +42,7 @@ from qgis.PyQt.QtCore import QCoreApplication
|
||||
from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinateReferenceSystem,
|
||||
QgsExpressionContext, QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope,
|
||||
QgsProject,
|
||||
QgsRectangle,
|
||||
QgsVectorFileWriter,
|
||||
QgsProcessingParameterDefinition)
|
||||
|
||||
@ -356,52 +357,6 @@ class ParameterExtent(Parameter):
|
||||
default = definition.strip()[len('extent') + 1:] or None
|
||||
return ParameterExtent(name, descName, default, isOptional)
|
||||
|
||||
def evaluate(self, alg):
|
||||
if self.flags() & QgsProcessingParameterDefinition.FlagOptional and not bool(self.value):
|
||||
self.value = self.getMinCoveringExtent(alg)
|
||||
|
||||
def getMinCoveringExtent(self, alg):
|
||||
first = True
|
||||
found = False
|
||||
context = dataobjects.createContext()
|
||||
for param in alg.parameters:
|
||||
if param.value:
|
||||
if isinstance(param, (ParameterRaster, ParameterVector)):
|
||||
if isinstance(param.value, (QgsRasterLayer,
|
||||
QgsVectorLayer)):
|
||||
layer = param.value
|
||||
else:
|
||||
layer = QgsProcessingUtils.mapLayerFromString(param.value, context)
|
||||
if layer:
|
||||
found = True
|
||||
self.addToRegion(layer, first)
|
||||
first = False
|
||||
elif isinstance(param, ParameterMultipleInput):
|
||||
layers = param.value.split(';')
|
||||
for layername in layers:
|
||||
layer = QgsProcessingUtils.mapLayerFromString(layername, context)
|
||||
if layer:
|
||||
found = True
|
||||
self.addToRegion(layer, first)
|
||||
first = False
|
||||
if found:
|
||||
return '{},{},{},{}'.format(
|
||||
self.xmin, self.xmax, self.ymin, self.ymax)
|
||||
else:
|
||||
return None
|
||||
|
||||
def addToRegion(self, layer, first):
|
||||
if first:
|
||||
self.xmin = layer.extent().xMinimum()
|
||||
self.xmax = layer.extent().xMaximum()
|
||||
self.ymin = layer.extent().yMinimum()
|
||||
self.ymax = layer.extent().yMaximum()
|
||||
else:
|
||||
self.xmin = min(self.xmin, layer.extent().xMinimum())
|
||||
self.xmax = max(self.xmax, layer.extent().xMaximum())
|
||||
self.ymin = min(self.ymin, layer.extent().yMinimum())
|
||||
self.ymax = max(self.ymax, layer.extent().yMaximum())
|
||||
|
||||
|
||||
class ParameterPoint(Parameter):
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "qgsprocessingutils.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgscsexception.h"
|
||||
#include "qgsprocessingcontext.h"
|
||||
#include "qgsvectorlayerexporter.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
@ -400,3 +401,37 @@ void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString
|
||||
}
|
||||
|
||||
|
||||
QgsRectangle QgsProcessingUtils::combineLayerExtents( const QList<QgsMapLayer *> layers, const QgsCoordinateReferenceSystem &crs )
|
||||
{
|
||||
QgsRectangle extent;
|
||||
Q_FOREACH ( QgsMapLayer *layer, layers )
|
||||
{
|
||||
if ( !layer )
|
||||
continue;
|
||||
|
||||
if ( crs.isValid() )
|
||||
{
|
||||
//transform layer extent to target CRS
|
||||
QgsCoordinateTransform ct( layer->crs(), crs );
|
||||
try
|
||||
{
|
||||
QgsRectangle reprojExtent = ct.transformBoundingBox( layer->extent() );
|
||||
extent.combineExtentWith( reprojExtent );
|
||||
}
|
||||
catch ( QgsCsException & )
|
||||
{
|
||||
// can't reproject... what to do here? hmmm?
|
||||
// let's ignore this layer for now, but maybe we should just use the original extent?
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
extent.combineExtentWith( layer->extent() );
|
||||
}
|
||||
|
||||
}
|
||||
return extent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -180,6 +180,11 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context ) SIP_PYNAME( createFeatureSink );
|
||||
|
||||
/**
|
||||
* Combines the extent of several map \a layers. If specified, the target \a crs
|
||||
* will be used to transform the layer's extent to the desired output reference system.
|
||||
*/
|
||||
static QgsRectangle combineLayerExtents( const QList< QgsMapLayer *> layers, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
|
||||
private:
|
||||
|
||||
|
@ -216,6 +216,7 @@ class TestQgsProcessing: public QObject
|
||||
void parameterVectorLayer();
|
||||
void parameterOutputVectorLayer();
|
||||
void checkParamValues();
|
||||
void combineLayerExtent();
|
||||
|
||||
private:
|
||||
|
||||
@ -2181,5 +2182,39 @@ void TestQgsProcessing::checkParamValues()
|
||||
a.checkParameterVals();
|
||||
}
|
||||
|
||||
void TestQgsProcessing::combineLayerExtent()
|
||||
{
|
||||
QgsRectangle ext = QgsProcessingUtils::combineLayerExtents( QList< QgsMapLayer *>() );
|
||||
QVERIFY( ext.isNull() );
|
||||
|
||||
QString testDataDir = QStringLiteral( TEST_DATA_DIR ) + '/'; //defined in CmakeLists.txt
|
||||
|
||||
QString raster1 = testDataDir + "tenbytenraster.asc";
|
||||
QString raster2 = testDataDir + "landsat.tif";
|
||||
QFileInfo fi1( raster1 );
|
||||
QgsRasterLayer *r1 = new QgsRasterLayer( fi1.filePath(), "R1" );
|
||||
QFileInfo fi2( raster2 );
|
||||
QgsRasterLayer *r2 = new QgsRasterLayer( fi2.filePath(), "R2" );
|
||||
|
||||
ext = QgsProcessingUtils::combineLayerExtents( QList< QgsMapLayer *>() << r1 );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 1535375.000000, 10 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 10 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 10 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 10 );
|
||||
|
||||
ext = QgsProcessingUtils::combineLayerExtents( QList< QgsMapLayer *>() << r1 << r2 );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 781662, 10 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 10 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 3339523, 10 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 10 );
|
||||
|
||||
// with reprojection
|
||||
ext = QgsProcessingUtils::combineLayerExtents( QList< QgsMapLayer *>() << r1 << r2, QgsCoordinateReferenceSystem::fromEpsgId( 3785 ) );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 1995320, 10 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 2008833, 10 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 3523084, 10 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 3536664, 10 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsProcessing )
|
||||
#include "testqgsprocessing.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user