mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Merge pull request #5199 from nyalldawson/extract_by_extent2
[processing] Extent handling improvements
This commit is contained in:
commit
c5ae3a0c98
@ -662,12 +662,40 @@ class QgsProcessingAlgorithm
|
||||
:rtype: QgsCoordinateReferenceSystem
|
||||
%End
|
||||
|
||||
QgsRectangle parameterAsExtent( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context ) const;
|
||||
QgsRectangle parameterAsExtent( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) const;
|
||||
%Docstring
|
||||
Evaluates the parameter with matching ``name`` to a rectangular extent.
|
||||
|
||||
If ``crs`` is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
reprojected so that it is in the specified ``crs``. In this case the extent of the reproject rectangle will be returned.
|
||||
|
||||
.. seealso:: parameterAsExtentGeometry()
|
||||
:rtype: QgsRectangle
|
||||
%End
|
||||
|
||||
QgsGeometry parameterAsExtentGeometry( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
%Docstring
|
||||
Evaluates the parameter with matching ``name`` to a rectangular extent, and returns a geometry covering this extent.
|
||||
|
||||
If ``crs`` is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
reprojected so that it is in the specified ``crs``. Unlike parameterAsExtent(), the reprojected rectangle returned by this function
|
||||
will no longer be a rectangle itself (i.e. this method returns the geometry of the actual reprojected rectangle, while parameterAsExtent() returns
|
||||
just the extent of the reprojected rectangle).
|
||||
|
||||
.. seealso:: parameterAsExtent()
|
||||
:rtype: QgsGeometry
|
||||
%End
|
||||
|
||||
QgsCoordinateReferenceSystem parameterAsExtentCrs( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context );
|
||||
%Docstring
|
||||
Returns the coordinate reference system associated with an extent parameter value.
|
||||
|
||||
.. seealso:: parameterAsExtent()
|
||||
:rtype: QgsCoordinateReferenceSystem
|
||||
%End
|
||||
|
||||
QgsPointXY parameterAsPoint( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context ) const;
|
||||
%Docstring
|
||||
Evaluates the parameter with matching ``name`` to a point.
|
||||
|
@ -534,12 +534,42 @@ class QgsProcessingParameters
|
||||
:rtype: QgsCoordinateReferenceSystem
|
||||
%End
|
||||
|
||||
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context );
|
||||
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
%Docstring
|
||||
Evaluates the parameter with matching ``definition`` to a rectangular extent.
|
||||
|
||||
If ``crs`` is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
reprojected so that it is in the specified ``crs``. In this case the extent of the reproject rectangle will be returned.
|
||||
|
||||
.. seealso:: parameterAsExtentGeometry()
|
||||
.. seealso:: parameterAsExtentCrs()
|
||||
:rtype: QgsRectangle
|
||||
%End
|
||||
|
||||
static QgsGeometry parameterAsExtentGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
%Docstring
|
||||
Evaluates the parameter with matching ``definition`` to a rectangular extent, and returns a geometry covering this extent.
|
||||
|
||||
If ``crs`` is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
reprojected so that it is in the specified ``crs``. Unlike parameterAsExtent(), the reprojected rectangle returned by this function
|
||||
will no longer be a rectangle itself (i.e. this method returns the geometry of the actual reprojected rectangle, while parameterAsExtent() returns
|
||||
just the extent of the reprojected rectangle).
|
||||
|
||||
.. seealso:: parameterAsExtent()
|
||||
.. seealso:: parameterAsExtentCrs()
|
||||
:rtype: QgsGeometry
|
||||
%End
|
||||
|
||||
static QgsCoordinateReferenceSystem parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context );
|
||||
%Docstring
|
||||
Returns the coordinate reference system associated with an extent parameter value.
|
||||
|
||||
.. seealso:: parameterAsExtent()
|
||||
:rtype: QgsCoordinateReferenceSystem
|
||||
%End
|
||||
|
||||
static QgsPointXY parameterAsPoint( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context );
|
||||
%Docstring
|
||||
Evaluates the parameter with matching ``definition`` to a point.
|
||||
|
@ -76,8 +76,8 @@ class CreateConstantRaster(QgisAlgorithm):
|
||||
return self.tr('Create constant raster layer')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
extent = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
|
||||
extent = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
value = self.parameterAsDouble(parameters, self.NUMBER, context)
|
||||
pixelSize = self.parameterAsDouble(parameters, self.PIXEL_SIZE, context)
|
||||
|
||||
|
@ -105,8 +105,8 @@ class GridLine(QgisAlgorithm):
|
||||
hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
|
||||
vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)
|
||||
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
|
||||
width = bbox.width()
|
||||
height = bbox.height()
|
||||
|
@ -113,8 +113,8 @@ class GridPolygon(QgisAlgorithm):
|
||||
hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
|
||||
vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)
|
||||
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
|
||||
width = bbox.width()
|
||||
height = bbox.height()
|
||||
|
@ -94,10 +94,10 @@ class RandomPointsExtent(QgisAlgorithm):
|
||||
return self.tr('Random points in extent')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
|
||||
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
|
||||
crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
|
||||
extent = QgsGeometry().fromRect(bbox)
|
||||
|
||||
|
@ -93,13 +93,12 @@ class RegularPoints(QgisAlgorithm):
|
||||
return self.tr('Regular points')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
extent = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
|
||||
spacing = self.parameterAsDouble(parameters, self.SPACING, context)
|
||||
inset = self.parameterAsDouble(parameters, self.INSET, context)
|
||||
randomize = self.parameterAsBool(parameters, self.RANDOMIZE, context)
|
||||
isSpacing = self.parameterAsBool(parameters, self.IS_SPACING, context)
|
||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||
extent = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
|
||||
fields = QgsFields()
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
|
@ -216,7 +216,10 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
||||
self.tr('<b>Algorithm \'{0}\' starting...</b>').format(self.alg.displayName()), escape_html=False)
|
||||
|
||||
feedback.pushInfo(self.tr('Input parameters:'))
|
||||
feedback.pushCommandInfo(pformat(parameters))
|
||||
display_params = []
|
||||
for k, v in parameters.items():
|
||||
display_params.append("'" + k + "' : " + self.alg.parameterDefinition(k).valueAsPythonString(v, context))
|
||||
feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }')
|
||||
feedback.pushInfo('')
|
||||
start_time = time.time()
|
||||
|
||||
|
22
python/plugins/processing/gui/ExtentSelectionPanel.py
Normal file → Executable file
22
python/plugins/processing/gui/ExtentSelectionPanel.py
Normal file → Executable file
@ -36,7 +36,11 @@ from qgis.gui import QgsMessageBar
|
||||
from qgis.utils import iface
|
||||
from qgis.core import (QgsProcessingUtils,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProject)
|
||||
QgsProcessingParameters,
|
||||
QgsProject,
|
||||
QgsCoordinateReferenceSystem,
|
||||
QgsRectangle,
|
||||
QgsReferencedRectangle)
|
||||
from processing.gui.RectangleMapTool import RectangleMapTool
|
||||
from processing.core.ProcessingConfig import ProcessingConfig
|
||||
from processing.tools.dataobjects import createContext
|
||||
@ -54,6 +58,8 @@ class ExtentSelectionPanel(BASE, WIDGET):
|
||||
|
||||
self.dialog = dialog
|
||||
self.param = param
|
||||
self.crs = QgsProject.instance().crs()
|
||||
|
||||
if self.param.flags() & QgsProcessingParameterDefinition.FlagOptional:
|
||||
if hasattr(self.leText, 'setPlaceholderText'):
|
||||
self.leText.setPlaceholderText(
|
||||
@ -126,7 +132,7 @@ class ExtentSelectionPanel(BASE, WIDGET):
|
||||
(item, ok) = QInputDialog.getItem(self, self.tr('Select extent'),
|
||||
self.tr('Use extent from'), extents, False)
|
||||
if ok:
|
||||
self.setValueFromRect(extentsDict[item]["extent"])
|
||||
self.setValueFromRect(QgsReferencedRectangle(extentsDict[item]["extent"], QgsCoordinateReferenceSystem(extentsDict[item]["authid"])))
|
||||
if extentsDict[item]["authid"] != iface.mapCanvas().mapSettings().destinationCrs().authid():
|
||||
iface.messageBar().pushMessage(self.tr("Warning"),
|
||||
self.tr("The projection of the chosen layer is not the same as canvas projection! The selected extent might not be what was intended."),
|
||||
@ -146,6 +152,10 @@ class ExtentSelectionPanel(BASE, WIDGET):
|
||||
r.xMinimum(), r.xMaximum(), r.yMinimum(), r.yMaximum())
|
||||
|
||||
self.leText.setText(s)
|
||||
try:
|
||||
self.crs = r.crs()
|
||||
except:
|
||||
self.crs = QgsProject.instance().crs()
|
||||
self.tool.reset()
|
||||
canvas = iface.mapCanvas()
|
||||
canvas.setMapTool(self.prevMapTool)
|
||||
@ -155,7 +165,13 @@ class ExtentSelectionPanel(BASE, WIDGET):
|
||||
|
||||
def getValue(self):
|
||||
if str(self.leText.text()).strip() != '':
|
||||
return str(self.leText.text())
|
||||
try:
|
||||
parts = self.leText.text().split(',')
|
||||
parts = [float(p) for p in parts]
|
||||
r = QgsReferencedRectangle(QgsRectangle(parts[0], parts[2], parts[1], parts[3]), self.crs)
|
||||
return r
|
||||
except:
|
||||
return str(self.leText.text())
|
||||
else:
|
||||
return None
|
||||
|
||||
|
32
python/plugins/processing/tests/testdata/expected/extract_by_extent.gfs
vendored
Normal file
32
python/plugins/processing/tests/testdata/expected/extract_by_extent.gfs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<GMLFeatureClassList>
|
||||
<GMLFeatureClass>
|
||||
<Name>extract_by_extent</Name>
|
||||
<ElementPath>extract_by_extent</ElementPath>
|
||||
<!--POLYGON-->
|
||||
<GeometryType>3</GeometryType>
|
||||
<SRSName>EPSG:4326</SRSName>
|
||||
<DatasetSpecificInfo>
|
||||
<FeatureCount>2</FeatureCount>
|
||||
<ExtentXMin>-1.00000</ExtentXMin>
|
||||
<ExtentXMax>6.00000</ExtentXMax>
|
||||
<ExtentYMin>-3.00000</ExtentYMin>
|
||||
<ExtentYMax>3.00000</ExtentYMax>
|
||||
</DatasetSpecificInfo>
|
||||
<PropertyDefn>
|
||||
<Name>name</Name>
|
||||
<ElementPath>name</ElementPath>
|
||||
<Type>String</Type>
|
||||
<Width>5</Width>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>intval</Name>
|
||||
<ElementPath>intval</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>floatval</Name>
|
||||
<ElementPath>floatval</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
30
python/plugins/processing/tests/testdata/expected/extract_by_extent.gml
vendored
Normal file
30
python/plugins/processing/tests/testdata/expected/extract_by_extent.gml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?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>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
|
||||
<gml:coord><gml:X>6</gml:X><gml:Y>3</gml:Y></gml:coord>
|
||||
</gml:Box>
|
||||
</gml:boundedBy>
|
||||
|
||||
<gml:featureMember>
|
||||
<ogr:extract_by_extent fid="polys.0">
|
||||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
|
||||
<ogr:name>aaaaa</ogr:name>
|
||||
<ogr:intval>33</ogr:intval>
|
||||
<ogr:floatval>44.123456</ogr:floatval>
|
||||
</ogr:extract_by_extent>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:extract_by_extent fid="polys.5">
|
||||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
|
||||
<ogr:name>elim</ogr:name>
|
||||
<ogr:intval>2</ogr:intval>
|
||||
<ogr:floatval>3.33</ogr:floatval>
|
||||
</ogr:extract_by_extent>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
32
python/plugins/processing/tests/testdata/expected/extract_by_extent_clip.gfs
vendored
Normal file
32
python/plugins/processing/tests/testdata/expected/extract_by_extent_clip.gfs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<GMLFeatureClassList>
|
||||
<GMLFeatureClass>
|
||||
<Name>extract_by_extent_clip</Name>
|
||||
<ElementPath>extract_by_extent_clip</ElementPath>
|
||||
<!--MULTIPOLYGON-->
|
||||
<GeometryType>6</GeometryType>
|
||||
<SRSName>EPSG:4326</SRSName>
|
||||
<DatasetSpecificInfo>
|
||||
<FeatureCount>2</FeatureCount>
|
||||
<ExtentXMin>-1.00000</ExtentXMin>
|
||||
<ExtentXMax>4.77500</ExtentXMax>
|
||||
<ExtentYMin>-2.38750</ExtentYMin>
|
||||
<ExtentYMax>3.00000</ExtentYMax>
|
||||
</DatasetSpecificInfo>
|
||||
<PropertyDefn>
|
||||
<Name>name</Name>
|
||||
<ElementPath>name</ElementPath>
|
||||
<Type>String</Type>
|
||||
<Width>5</Width>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>intval</Name>
|
||||
<ElementPath>intval</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>floatval</Name>
|
||||
<ElementPath>floatval</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
30
python/plugins/processing/tests/testdata/expected/extract_by_extent_clip.gml
vendored
Normal file
30
python/plugins/processing/tests/testdata/expected/extract_by_extent_clip.gml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?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>-1</gml:X><gml:Y>-2.3875</gml:Y></gml:coord>
|
||||
<gml:coord><gml:X>4.775</gml:X><gml:Y>3</gml:Y></gml:coord>
|
||||
</gml:Box>
|
||||
</gml:boundedBy>
|
||||
|
||||
<gml:featureMember>
|
||||
<ogr:extract_by_extent_clip fid="polys.0">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>aaaaa</ogr:name>
|
||||
<ogr:intval>33</ogr:intval>
|
||||
<ogr:floatval>44.123456</ogr:floatval>
|
||||
</ogr:extract_by_extent_clip>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
<ogr:extract_by_extent_clip fid="polys.5">
|
||||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 4.775,1.40833333333333 4.775,-2.3875 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
|
||||
<ogr:name>elim</ogr:name>
|
||||
<ogr:intval>2</ogr:intval>
|
||||
<ogr:floatval>3.33</ogr:floatval>
|
||||
</ogr:extract_by_extent_clip>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
28
python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
vendored
Normal file → Executable file
28
python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
vendored
Normal file → Executable file
@ -3937,4 +3937,30 @@ tests:
|
||||
- name
|
||||
compare:
|
||||
fields:
|
||||
fid: skip
|
||||
fid: skip
|
||||
|
||||
- algorithm: native:extractbyextent
|
||||
name: Extract by extent
|
||||
params:
|
||||
CLIP: false
|
||||
EXTENT: -1.1650000000000003,4.775,-2.444285714285715,3.4171428571428573
|
||||
INPUT:
|
||||
name: polys.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/extract_by_extent.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: native:extractbyextent
|
||||
name: Extract by extent (clipped)
|
||||
params:
|
||||
CLIP: true
|
||||
EXTENT: -1.1650000000000003,4.775,-2.444285714285715,3.4171428571428573
|
||||
INPUT:
|
||||
name: polys.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/extract_by_extent_clip.gml
|
||||
type: vector
|
||||
|
@ -82,6 +82,8 @@ void QgsNativeAlgorithms::loadAlgorithms()
|
||||
addAlgorithm( new QgsMergeLinesAlgorithm() );
|
||||
addAlgorithm( new QgsSmoothAlgorithm() );
|
||||
addAlgorithm( new QgsSimplifyAlgorithm() );
|
||||
addAlgorithm( new QgsExtractByExtentAlgorithm() );
|
||||
addAlgorithm( new QgsExtentToLayerAlgorithm() );
|
||||
}
|
||||
|
||||
void QgsCentroidAlgorithm::initAlgorithm( const QVariantMap & )
|
||||
@ -1811,7 +1813,121 @@ QgsFeature QgsSimplifyAlgorithm::processFeature( const QgsFeature &feature, QgsP
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void QgsExtractByExtentAlgorithm::initAlgorithm( const QVariantMap & )
|
||||
{
|
||||
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
|
||||
addParameter( new QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Extent" ) ) );
|
||||
addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "CLIP" ), QObject::tr( "Clip features to extent" ), false ) );
|
||||
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extracted" ) ) );
|
||||
}
|
||||
|
||||
QString QgsExtractByExtentAlgorithm::shortHelpString() const
|
||||
{
|
||||
return QObject::tr( "This algorithm creates a new vector layer that only contains features which fall within a specified extent. "
|
||||
"Any features which intersect the extent will be included.\n\n"
|
||||
"Optionally, feature geometries can also be clipped to the extent. If this option is selected, then the output "
|
||||
"geometries will automatically be converted to multi geometries to ensure uniform output geometry types." );
|
||||
}
|
||||
|
||||
QgsExtractByExtentAlgorithm *QgsExtractByExtentAlgorithm::createInstance() const
|
||||
{
|
||||
return new QgsExtractByExtentAlgorithm();
|
||||
}
|
||||
|
||||
QVariantMap QgsExtractByExtentAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
|
||||
{
|
||||
std::unique_ptr< QgsFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
|
||||
if ( !featureSource )
|
||||
return QVariantMap();
|
||||
|
||||
QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() );
|
||||
bool clip = parameterAsBool( parameters, QStringLiteral( "CLIP" ), context );
|
||||
|
||||
// if clipping, we force multi output
|
||||
QgsWkbTypes::Type outType = clip ? QgsWkbTypes::multiType( featureSource->wkbType() ) : featureSource->wkbType();
|
||||
|
||||
QString dest;
|
||||
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, featureSource->fields(), outType, featureSource->sourceCrs() ) );
|
||||
|
||||
if ( !sink )
|
||||
return QVariantMap();
|
||||
|
||||
QgsGeometry clipGeom = parameterAsExtentGeometry( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() );
|
||||
|
||||
double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1;
|
||||
QgsFeatureIterator inputIt = featureSource->getFeatures( QgsFeatureRequest().setFilterRect( extent ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
||||
QgsFeature f;
|
||||
int i = -1;
|
||||
while ( inputIt.nextFeature( f ) )
|
||||
{
|
||||
i++;
|
||||
if ( feedback->isCanceled() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( clip )
|
||||
{
|
||||
QgsGeometry g = f.geometry().intersection( clipGeom );
|
||||
g.convertToMultiType();
|
||||
f.setGeometry( g );
|
||||
}
|
||||
|
||||
sink->addFeature( f, QgsFeatureSink::FastInsert );
|
||||
feedback->setProgress( i * step );
|
||||
}
|
||||
|
||||
QVariantMap outputs;
|
||||
outputs.insert( QStringLiteral( "OUTPUT" ), dest );
|
||||
return outputs;
|
||||
}
|
||||
|
||||
|
||||
void QgsExtentToLayerAlgorithm::initAlgorithm( const QVariantMap & )
|
||||
{
|
||||
addParameter( new QgsProcessingParameterExtent( QStringLiteral( "INPUT" ), QObject::tr( "Extent" ) ) );
|
||||
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extent" ), QgsProcessing::TypeVectorPolygon ) );
|
||||
}
|
||||
|
||||
QString QgsExtentToLayerAlgorithm::shortHelpString() const
|
||||
{
|
||||
return QObject::tr( "This algorithm creates a new vector layer that contains a single feature with geometry matching an extent parameter.\n\n"
|
||||
"It can be used in models to convert an extent into a layer which can be used for other algorithms which require "
|
||||
"a layer based input." );
|
||||
}
|
||||
|
||||
QgsExtentToLayerAlgorithm *QgsExtentToLayerAlgorithm::createInstance() const
|
||||
{
|
||||
return new QgsExtentToLayerAlgorithm();
|
||||
}
|
||||
|
||||
QVariantMap QgsExtentToLayerAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
|
||||
{
|
||||
QgsCoordinateReferenceSystem crs = parameterAsExtentCrs( parameters, QStringLiteral( "INPUT" ), context );
|
||||
QgsGeometry geom = parameterAsExtentGeometry( parameters, QStringLiteral( "INPUT" ), context );
|
||||
|
||||
QgsFields fields;
|
||||
fields.append( QgsField( QStringLiteral( "id" ), QVariant::Int ) );
|
||||
|
||||
QString dest;
|
||||
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, QgsWkbTypes::Polygon, crs ) );
|
||||
if ( !sink )
|
||||
return QVariantMap();
|
||||
|
||||
QgsFeature f;
|
||||
f.setAttributes( QgsAttributes() << 1 );
|
||||
f.setGeometry( geom );
|
||||
sink->addFeature( f, QgsFeatureSink::FastInsert );
|
||||
|
||||
feedback->setProgress( 100 );
|
||||
|
||||
QVariantMap outputs;
|
||||
outputs.insert( QStringLiteral( "OUTPUT" ), dest );
|
||||
return outputs;
|
||||
}
|
||||
|
||||
|
||||
///@endcond
|
||||
|
||||
|
||||
|
||||
|
@ -662,6 +662,56 @@ class QgsSimplifyAlgorithm : public QgsProcessingFeatureBasedAlgorithm
|
||||
std::unique_ptr< QgsMapToPixelSimplifier > mSimplifier;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Native extract/clip by extent algorithm.
|
||||
*/
|
||||
class QgsExtractByExtentAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
QgsExtractByExtentAlgorithm() = default;
|
||||
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
|
||||
QString name() const override { return QStringLiteral( "extractbyextent" ); }
|
||||
QString displayName() const override { return QObject::tr( "Extract/clip by extent" ); }
|
||||
virtual QStringList tags() const override { return QObject::tr( "clip,extract,intersect,intersection,mask,extent" ).split( ',' ); }
|
||||
QString group() const override { return QObject::tr( "Vector overlay" ); }
|
||||
QString shortHelpString() const override;
|
||||
QgsExtractByExtentAlgorithm *createInstance() const override SIP_FACTORY;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Native extent to layer algorithm.
|
||||
*/
|
||||
class QgsExtentToLayerAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
QgsExtentToLayerAlgorithm() = default;
|
||||
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
|
||||
QString name() const override { return QStringLiteral( "extenttolayer" ); }
|
||||
QString displayName() const override { return QObject::tr( "Create layer from extent" ); }
|
||||
virtual QStringList tags() const override { return QObject::tr( "extent,layer,polygon,create,new" ).split( ',' ); }
|
||||
QString group() const override { return QObject::tr( "Vector geometry" ); }
|
||||
QString shortHelpString() const override;
|
||||
QgsExtentToLayerAlgorithm *createInstance() const override SIP_FACTORY;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
|
||||
|
||||
};
|
||||
|
||||
///@endcond PRIVATE
|
||||
|
||||
#endif // QGSNATIVEALGORITHMS_H
|
||||
|
@ -550,9 +550,19 @@ QgsCoordinateReferenceSystem QgsProcessingAlgorithm::parameterAsCrs( const QVari
|
||||
return QgsProcessingParameters::parameterAsCrs( parameterDefinition( name ), parameters, context );
|
||||
}
|
||||
|
||||
QgsRectangle QgsProcessingAlgorithm::parameterAsExtent( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context ) const
|
||||
QgsCoordinateReferenceSystem QgsProcessingAlgorithm::parameterAsExtentCrs( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context )
|
||||
{
|
||||
return QgsProcessingParameters::parameterAsExtent( parameterDefinition( name ), parameters, context );
|
||||
return QgsProcessingParameters::parameterAsCrs( parameterDefinition( name ), parameters, context );
|
||||
}
|
||||
|
||||
QgsRectangle QgsProcessingAlgorithm::parameterAsExtent( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs ) const
|
||||
{
|
||||
return QgsProcessingParameters::parameterAsExtent( parameterDefinition( name ), parameters, context, crs );
|
||||
}
|
||||
|
||||
QgsGeometry QgsProcessingAlgorithm::parameterAsExtentGeometry( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs )
|
||||
{
|
||||
return QgsProcessingParameters::parameterAsExtentGeometry( parameterDefinition( name ), parameters, context, crs );
|
||||
}
|
||||
|
||||
QgsPointXY QgsProcessingAlgorithm::parameterAsPoint( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context ) const
|
||||
|
@ -648,8 +648,34 @@ class CORE_EXPORT QgsProcessingAlgorithm
|
||||
|
||||
/**
|
||||
* Evaluates the parameter with matching \a name to a rectangular extent.
|
||||
*
|
||||
* If \a crs is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
* reprojected so that it is in the specified \a crs. In this case the extent of the reproject rectangle will be returned.
|
||||
*
|
||||
* \see parameterAsExtentGeometry()
|
||||
*/
|
||||
QgsRectangle parameterAsExtent( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context ) const;
|
||||
QgsRectangle parameterAsExtent( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) const;
|
||||
|
||||
/**
|
||||
* Evaluates the parameter with matching \a name to a rectangular extent, and returns a geometry covering this extent.
|
||||
*
|
||||
* If \a crs is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
* reprojected so that it is in the specified \a crs. Unlike parameterAsExtent(), the reprojected rectangle returned by this function
|
||||
* will no longer be a rectangle itself (i.e. this method returns the geometry of the actual reprojected rectangle, while parameterAsExtent() returns
|
||||
* just the extent of the reprojected rectangle).
|
||||
*
|
||||
* \see parameterAsExtent()
|
||||
*/
|
||||
QgsGeometry parameterAsExtentGeometry( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
|
||||
/**
|
||||
* Returns the coordinate reference system associated with an extent parameter value.
|
||||
*
|
||||
* \see parameterAsExtent()
|
||||
*/
|
||||
QgsCoordinateReferenceSystem parameterAsExtentCrs( const QVariantMap ¶meters, const QString &name, QgsProcessingContext &context );
|
||||
|
||||
/**
|
||||
* Evaluates the parameter with matching \a name to a point.
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "qgsprocessingoutputs.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsreferencedgeometry.h"
|
||||
#include <functional>
|
||||
|
||||
bool QgsProcessingParameters::isDynamic( const QVariantMap ¶meters, const QString &name )
|
||||
@ -484,12 +485,29 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsP
|
||||
return crs;
|
||||
}
|
||||
|
||||
QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context )
|
||||
QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs )
|
||||
{
|
||||
if ( !definition )
|
||||
return QgsRectangle();
|
||||
|
||||
QVariant val = parameters.value( definition->name() );
|
||||
|
||||
if ( val.canConvert< QgsRectangle >() )
|
||||
{
|
||||
return val.value<QgsRectangle>();
|
||||
}
|
||||
if ( val.canConvert< QgsReferencedRectangle >() )
|
||||
{
|
||||
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
|
||||
if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
|
||||
{
|
||||
QgsCoordinateTransform ct( rr.crs(), crs );
|
||||
return ct.transformBoundingBox( rr );
|
||||
}
|
||||
return rr;
|
||||
}
|
||||
|
||||
QString rectText;
|
||||
if ( val.canConvert<QgsProperty>() )
|
||||
rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
|
||||
@ -521,6 +539,55 @@ QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingPara
|
||||
return QgsRectangle();
|
||||
}
|
||||
|
||||
QgsGeometry QgsProcessingParameters::parameterAsExtentGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs )
|
||||
{
|
||||
if ( !definition )
|
||||
return QgsGeometry();
|
||||
|
||||
QVariant val = parameters.value( definition->name() );
|
||||
|
||||
if ( val.canConvert< QgsReferencedRectangle >() )
|
||||
{
|
||||
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
|
||||
QgsGeometry g = QgsGeometry::fromRect( rr );
|
||||
if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
|
||||
{
|
||||
g = g.densifyByCount( 20 );
|
||||
QgsCoordinateTransform ct( rr.crs(), crs );
|
||||
try
|
||||
{
|
||||
g.transform( ct );
|
||||
}
|
||||
catch ( QgsCsException & )
|
||||
{
|
||||
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
|
||||
}
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
|
||||
}
|
||||
|
||||
QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context )
|
||||
{
|
||||
QVariant val = parameters.value( definition->name() );
|
||||
|
||||
if ( val.canConvert< QgsReferencedRectangle >() )
|
||||
{
|
||||
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
|
||||
if ( rr.crs().isValid() )
|
||||
{
|
||||
return rr.crs();
|
||||
}
|
||||
}
|
||||
|
||||
if ( context.project() )
|
||||
return context.project()->crs();
|
||||
else
|
||||
return QgsCoordinateReferenceSystem();
|
||||
}
|
||||
|
||||
QgsPointXY QgsProcessingParameters::parameterAsPoint( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context )
|
||||
{
|
||||
if ( !definition )
|
||||
@ -1133,6 +1200,17 @@ bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( input.canConvert< QgsRectangle >() )
|
||||
{
|
||||
QgsRectangle r = input.value<QgsRectangle>();
|
||||
return !r.isNull();
|
||||
}
|
||||
if ( input.canConvert< QgsReferencedRectangle >() )
|
||||
{
|
||||
QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
|
||||
return !r.isNull();
|
||||
}
|
||||
|
||||
if ( input.type() != QVariant::String || input.toString().isEmpty() )
|
||||
return mFlags & FlagOptional;
|
||||
|
||||
@ -1166,6 +1244,23 @@ QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value
|
||||
if ( value.canConvert<QgsProperty>() )
|
||||
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
|
||||
|
||||
if ( value.canConvert< QgsRectangle >() )
|
||||
{
|
||||
QgsRectangle r = value.value<QgsRectangle>();
|
||||
return QStringLiteral( "QgsRectangle( %1, %2, %3, %4 )" ).arg( qgsDoubleToString( r.xMinimum() ),
|
||||
qgsDoubleToString( r.yMinimum() ),
|
||||
qgsDoubleToString( r.xMaximum() ),
|
||||
qgsDoubleToString( r.yMaximum() ) );
|
||||
}
|
||||
if ( value.canConvert< QgsReferencedRectangle >() )
|
||||
{
|
||||
QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
|
||||
return QStringLiteral( "QgsReferencedRectangle( QgsRectangle( %1, %2, %3, %4 ), QgsCoordinateReferenceSystem( '%5' ) )" ).arg( qgsDoubleToString( r.xMinimum() ),
|
||||
qgsDoubleToString( r.yMinimum() ),
|
||||
qgsDoubleToString( r.xMaximum() ),
|
||||
qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
|
||||
}
|
||||
|
||||
QVariantMap p;
|
||||
p.insert( name(), value );
|
||||
QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
|
||||
|
@ -565,8 +565,36 @@ class CORE_EXPORT QgsProcessingParameters
|
||||
|
||||
/**
|
||||
* Evaluates the parameter with matching \a definition to a rectangular extent.
|
||||
*
|
||||
* If \a crs is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
* reprojected so that it is in the specified \a crs. In this case the extent of the reproject rectangle will be returned.
|
||||
*
|
||||
* \see parameterAsExtentGeometry()
|
||||
* \see parameterAsExtentCrs()
|
||||
*/
|
||||
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context );
|
||||
static QgsRectangle parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
|
||||
/**
|
||||
* Evaluates the parameter with matching \a definition to a rectangular extent, and returns a geometry covering this extent.
|
||||
*
|
||||
* If \a crs is set, and the original coordinate reference system of the parameter can be determined, then the extent will be automatically
|
||||
* reprojected so that it is in the specified \a crs. Unlike parameterAsExtent(), the reprojected rectangle returned by this function
|
||||
* will no longer be a rectangle itself (i.e. this method returns the geometry of the actual reprojected rectangle, while parameterAsExtent() returns
|
||||
* just the extent of the reprojected rectangle).
|
||||
*
|
||||
* \see parameterAsExtent()
|
||||
* \see parameterAsExtentCrs()
|
||||
*/
|
||||
static QgsGeometry parameterAsExtentGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context,
|
||||
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
|
||||
|
||||
/**
|
||||
* Returns the coordinate reference system associated with an extent parameter value.
|
||||
*
|
||||
* \see parameterAsExtent()
|
||||
*/
|
||||
static QgsCoordinateReferenceSystem parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context );
|
||||
|
||||
/**
|
||||
* Evaluates the parameter with matching \a definition to a point.
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgsuserprofile.h"
|
||||
#include "qgsuserprofilemanager.h"
|
||||
#include "qgsreferencedgeometry.h"
|
||||
|
||||
#include "gps/qgsgpsconnectionregistry.h"
|
||||
#include "processing/qgsprocessingregistry.h"
|
||||
@ -149,6 +150,8 @@ void QgsApplication::init( QString profileFolder )
|
||||
qRegisterMetaType<QgsUnitTypes::LayoutUnit>( "QgsUnitTypes::LayoutUnit" );
|
||||
qRegisterMetaType<QgsFeatureIds>( "QgsFeatureIds" );
|
||||
qRegisterMetaType<QgsMessageLog::MessageLevel>( "QgsMessageLog::MessageLevel" );
|
||||
qRegisterMetaType<QgsReferencedRectangle>( "QgsReferencedRectangle" );
|
||||
qRegisterMetaType<QgsReferencedRectangle>( "QgsReferencedPoint" );
|
||||
|
||||
QString prefixPath( getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : applicationDirPath() );
|
||||
// QgsDebugMsg( QString( "prefixPath(): %1" ).arg( prefixPath ) );
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsexpressioncontext.h"
|
||||
#include "qgsxmlutils.h"
|
||||
#include "qgsreferencedgeometry.h"
|
||||
|
||||
class DummyAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
@ -1844,6 +1845,10 @@ void TestQgsProcessing::parameterExtent()
|
||||
QVERIFY( def->checkValueIsAcceptable( "1,2,3,4" ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( "" ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( QgsRectangle( 1, 2, 3, 4 ) ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( QgsRectangle() ) );
|
||||
QVERIFY( def->checkValueIsAcceptable( QgsReferencedRectangle( QgsRectangle( 1, 2, 3, 4 ), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) ) );
|
||||
QVERIFY( !def->checkValueIsAcceptable( QgsReferencedRectangle( QgsRectangle(), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) ) );
|
||||
|
||||
// these checks require a context - otherwise we could potentially be referring to a layer source
|
||||
QVERIFY( def->checkValueIsAcceptable( "1,2,3" ) );
|
||||
@ -1881,15 +1886,70 @@ void TestQgsProcessing::parameterExtent()
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 3.3, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );
|
||||
|
||||
// with target CRS - should make no difference, because source CRS is unknown
|
||||
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 1.1, 0.001 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 2.2, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 3.3, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );
|
||||
|
||||
// nonsense string
|
||||
params.insert( "non_optional", QString( "i'm not a crs, and nothing you can do will make me one" ) );
|
||||
QVERIFY( QgsProcessingParameters::parameterAsExtent( def.get(), params, context ).isNull() );
|
||||
|
||||
// QgsRectangle
|
||||
params.insert( "non_optional", QgsRectangle( 11.1, 12.2, 13.3, 14.4 ) );
|
||||
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 11.1, 0.001 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 13.3, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 12.2, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 14.4, 0.001 );
|
||||
|
||||
// with target CRS - should make no difference, because source CRS is unknown
|
||||
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 11.1, 0.001 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 13.3, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 12.2, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 14.4, 0.001 );
|
||||
|
||||
QgsGeometry gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
|
||||
QCOMPARE( gExt.exportToWkt( 1 ), QStringLiteral( "Polygon ((11.1 12.2, 13.3 12.2, 13.3 14.4, 11.1 14.4, 11.1 12.2))" ) );
|
||||
|
||||
p.setCrs( QgsCoordinateReferenceSystem( "EPSG:3785" ) );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:3785" ) );
|
||||
|
||||
// QgsReferencedRectangle
|
||||
params.insert( "non_optional", QgsReferencedRectangle( QgsRectangle( 1.1, 2.2, 3.3, 4.4 ), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) );
|
||||
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 1.1, 0.001 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 3.3, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 2.2, 0.001 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 4.4, 0.001 );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:4326" ) );
|
||||
|
||||
// with target CRS
|
||||
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 122451, 100 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 367354, 100 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 244963, 100 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 490287, 100 );
|
||||
|
||||
// as reprojected geometry
|
||||
gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:3785" ) );
|
||||
QCOMPARE( gExt.geometry()->vertexCount(), 85 );
|
||||
ext = gExt.boundingBox();
|
||||
QGSCOMPARENEAR( ext.xMinimum(), 122451, 100 );
|
||||
QGSCOMPARENEAR( ext.xMaximum(), 367354, 100 );
|
||||
QGSCOMPARENEAR( ext.yMinimum(), 244963, 100 );
|
||||
QGSCOMPARENEAR( ext.yMaximum(), 490287, 100 );
|
||||
|
||||
QCOMPARE( def->valueAsPythonString( "1,2,3,4", context ), QStringLiteral( "'1,2,3,4'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( r1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( r1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( raster2, context ), QString( "'" ) + testDataDir + QStringLiteral( "landsat.tif'" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QgsRectangle( 11, 12, 13, 14 ), context ), QStringLiteral( "QgsRectangle( 11, 12, 13, 14 )" ) );
|
||||
QCOMPARE( def->valueAsPythonString( QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QStringLiteral( "QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( 'EPSG:4326' ) )" ) );
|
||||
|
||||
QString code = def->asScriptCode();
|
||||
QCOMPARE( code, QStringLiteral( "##non_optional=extent 1,2,3,4" ) );
|
||||
|
Loading…
x
Reference in New Issue
Block a user