mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-01 00:05:25 -04:00
Merge branch 'master' of https://github.com/QGIS/QGIS into regularShape_gui
This commit is contained in:
commit
d1e40d9086
@ -1,4 +1,7 @@
|
||||
|
||||
# CACHE_TAG is provided by Docker cloud
|
||||
# see https://docs.docker.com/docker-cloud/builds/advanced/
|
||||
# using ARG in FROM requires min v17.05.0-ce
|
||||
ARG CACHE_TAG=latest
|
||||
|
||||
FROM qgis/qgis3-build-deps:${CACHE_TAG}
|
||||
|
@ -1,6 +1,7 @@
|
||||
# About QGIS
|
||||
|
||||
[](https://travis-ci.org/qgis/QGIS)
|
||||
[](https://cloud.docker.com/app/qgis/repository/docker/qgis/qgis/general)
|
||||
|
||||
QGIS is an Open Source Geographic Information System. The project was born in
|
||||
May of 2002 and was established as a project on SourceForge in June of the same
|
||||
@ -63,7 +64,7 @@ an email address where we can request additional information.
|
||||
## Support
|
||||
You can get support in the following ways:
|
||||
|
||||
- Using the QGIS community site at http://qgis.org
|
||||
- Using the QGIS community site at http://qgis.org
|
||||
- Joining the [qgis-users mailing list](https://lists.osgeo.org/mailman/listinfo/qgis-user)
|
||||
- Using IRC by joining the [#qgis](http://webchat.freenode.net/?channels=#qgis) channel on irc.freenode.net. Please wait around for a response to your question as many folks on the channel are doing other things and it may take a while for them to notice your question.
|
||||
- Join the [Gitter](https://gitter.im/qgis/QGIS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) chat.
|
||||
|
3
debian/libqgis-dev.install.in
vendored
3
debian/libqgis-dev.install.in
vendored
@ -3,7 +3,8 @@ usr/lib/libqgis_app.so
|
||||
usr/lib/libqgis_core.so
|
||||
usr/lib/libqgis_gui.so
|
||||
usr/lib/libqgis_analysis.so
|
||||
#server#usr/lib/libqgis_server.so
|
||||
usr/lib/libqgis_native.so
|
||||
usr/lib/libqgis_server.so
|
||||
usr/lib/libqgisgrass{GRASSVER}.so
|
||||
usr/lib/libqgispython.so
|
||||
usr/share/qgis/FindQGIS.cmake
|
||||
|
1
debian/qgis-common.install
vendored
1
debian/qgis-common.install
vendored
@ -12,6 +12,7 @@ usr/share/qgis/doc/images
|
||||
usr/share/qgis/doc/index.html
|
||||
usr/share/qgis/doc/news
|
||||
usr/share/qgis/doc/news.html
|
||||
usr/share/qgis/doc/nohelp.html
|
||||
usr/share/qgis/doc/style.css
|
||||
usr/share/qgis/i18n/*
|
||||
usr/share/qgis/images/*
|
||||
|
1
debian/qgis.install
vendored
1
debian/qgis.install
vendored
@ -6,7 +6,6 @@ usr/lib/qgis/plugins/libspatialqueryplugin.so
|
||||
usr/lib/qgis/plugins/libofflineeditingplugin.so
|
||||
usr/lib/qgis/plugins/libtopolplugin.so
|
||||
usr/lib/qgis/plugins/libgeometrycheckerplugin.so
|
||||
usr/lib/qgis/qgis_help
|
||||
usr/share/pixmaps/
|
||||
usr/share/applications/
|
||||
usr/share/mime/packages/
|
||||
|
4
debian/qgis.lintian-overrides
vendored
4
debian/qgis.lintian-overrides
vendored
@ -1,4 +0,0 @@
|
||||
# Build uses -D_FORTIFY_SOURCE=2, but hardening-check reports:
|
||||
# Fortify Source functions: no, only unprotected functions found!
|
||||
# unprotected: fgets
|
||||
qgis: hardening-no-fortify-functions usr/lib/qgis/qgis_help
|
@ -269,6 +269,7 @@ should now call QgsCoordinateReferenceSystem::invalidateCache() and QgsCoordinat
|
||||
- QgsFileNameWidgetWrapper was removed. Use QgsExternalResourceWidgetWrapper instead.
|
||||
- QgsFileDropEdit was removed. Use QgsFileWidget instead.
|
||||
- QgsFormAnnotationItem. Use QgsFormAnnotation instead.
|
||||
- QgsGeometryAnalyzer. Use the equivalent Processing algorithms instead.
|
||||
- QgsHtmlAnnotationItem. Use QgsHtmlAnnotation instead.
|
||||
- QgsHttpTransaction. This class was outdated and code should be ported to native Qt or Python implementations.
|
||||
- QgsGenericProjectionSelector. Use QgsProjectionSelectionTreeWidget instead.
|
||||
@ -287,6 +288,7 @@ should now call QgsCoordinateReferenceSystem::invalidateCache() and QgsCoordinat
|
||||
- QgsMapRenderer. It has been replaced by QgsMapRendererJob with subclasses and QgsMapSettings.
|
||||
- QgsMapToolTouch. The touch navigation functionality is now built into the standard QgsMapToolPan tool.
|
||||
- QgsPhotoWidgetWrapper was removed. Use QgsExternalResourceWidgetWrapper instead.
|
||||
- QgsPointSample. Use the Processing "Random Points in Polygon" algorithm instead.
|
||||
- QgsPseudoColorShader. This shader has been broken for some time and was replaced by QgsSingleBandPseudoColorRenderer.
|
||||
- QgsProjectBadLayerGuiHandler was removed. It was unused in QGIS code and barely useful. Implement your own QgsProjectBadLayerHandler subclass if needed.
|
||||
- QgsRendererV2DataDefinedMenus was removed. Use QgsPropertyOverrideButton instead.
|
||||
|
@ -384,7 +384,6 @@ tar -C %OSGEO4W_ROOT% -cjf %ARCH%/release/qgis/%PACKAGENAME%/%PACKAGENAME%-%VERS
|
||||
"apps/%PACKAGENAME%/plugins/spatialqueryplugin.dll" ^
|
||||
"apps/%PACKAGENAME%/plugins/topolplugin.dll" ^
|
||||
"apps/%PACKAGENAME%/plugins/geometrycheckerplugin.dll" ^
|
||||
"apps/%PACKAGENAME%/qgis_help.exe" ^
|
||||
"apps/%PACKAGENAME%/qtplugins/sqldrivers/qsqlspatialite.dll" ^
|
||||
"apps/%PACKAGENAME%/qtplugins/designer/" ^
|
||||
"apps/%PACKAGENAME%/python/" ^
|
||||
|
@ -12,9 +12,6 @@
|
||||
%Include raster/qgsrastermatrix.sip
|
||||
%Include raster/qgsrastercalcnode.sip
|
||||
%Include raster/qgstotalcurvaturefilter.sip
|
||||
%Include vector/qgsgeometryanalyzer.sip
|
||||
%Include vector/qgsoverlayanalyzer.sip
|
||||
%Include vector/qgspointsample.sip
|
||||
%Include vector/qgstransectsample.sip
|
||||
%Include vector/qgszonalstatistics.sip
|
||||
%Include interpolation/qgsinterpolator.sip
|
||||
|
@ -1,143 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/analysis/vector/qgsgeometryanalyzer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGeometryAnalyzer
|
||||
{
|
||||
%Docstring
|
||||
The QGis class provides vector geometry analysis functions
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgeometryanalyzer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
bool simplify( QgsVectorLayer *layer, const QString &shapefileName, double tolerance,
|
||||
bool onlySelectedFeatures = false, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Simplify vector layer using (a modified) Douglas-Peucker algorithm
|
||||
and write it to a new shape file
|
||||
\param layer input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param tolerance (level of simplification)
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool centroids( QgsVectorLayer *layer, const QString &shapefileName,
|
||||
bool onlySelectedFeatures = false, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Calculate the true centroids, or 'center of mass' for a vector layer and
|
||||
write it to a new shape file
|
||||
\param layer input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool extent( QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures = false, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Create a polygon based on the extent of all (selected) features and write it to a new shape file
|
||||
\param layer input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool buffer( QgsVectorLayer *layer, const QString &shapefileName, double bufferDistance,
|
||||
bool onlySelectedFeatures = false, bool dissolve = false, int bufferDistanceField = -1, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Create buffers for a vector layer and write it to a new shape file
|
||||
\param layer input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param bufferDistance distance for buffering (if no buffer field is specified)
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param dissolve if true, merge all the buffers to a big multipolygon
|
||||
\param bufferDistanceField index of the attribute field that contains the buffer distance (or -1 if all features have the same buffer distance)
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool convexHull( QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures = false,
|
||||
int uniqueIdField = -1, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Create convex hull(s) of a vector layer and write it to a new shape file
|
||||
\param layer input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param uniqueIdField index of the attribute field that contains the unique convex hull id (or -1 if
|
||||
all features have the same buffer distance)
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool dissolve( QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures = false,
|
||||
int uniqueIdField = -1, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Dissolve a vector layer and write it to a new shape file
|
||||
\param layer input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param uniqueIdField index of the attribute field that contains the unique id to dissolve on (or -1 if
|
||||
all features should be dissolved together)
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool eventLayer( QgsVectorLayer *lineLayer, QgsVectorLayer *eventLayer, int lineField, int eventField, QgsFeatureIds &unlocatedFeatureIds /Out/, const QString &outputLayer,
|
||||
const QString &outputFormat, int locationField1, int locationField2 = -1, int offsetField = -1, double offsetScale = 1.0,
|
||||
bool forceSingleGeometry = false, QgsVectorDataProvider *memoryProvider = 0, QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Creates an event layer (multipoint or multiline) by locating features from a (non-spatial) event table along the features of a line layer.
|
||||
Note that currently (until QgsGeometry supports m-values) the z-coordinate of the line layer is used for linear referencing
|
||||
\param lineLayer layer with the line geometry
|
||||
\param eventLayer layer with features and location field
|
||||
\param lineField join index in line layer
|
||||
\param eventField join index in event layer
|
||||
\param outputLayer name of output file (can be empty if a memory layer is used)
|
||||
\param outputFormat name of output format (can be empty if a memory provider is used to store the results)
|
||||
\param unlocatedFeatureIds out: ids of event features where linear referencing was not successful
|
||||
\param locationField1 attribute index of location field in event layer
|
||||
\param locationField2 attribute index of location end field (or -1 for point layer)
|
||||
\param offsetField attribute index for offset field. Negative offset value = offset to left side, positive value = offset to right side
|
||||
\param offsetScale factor to scale offset
|
||||
\param forceSingleGeometry force layer to single point/line type. Feature attributes are copied in case of multiple matches
|
||||
\param memoryProvider memory provider to write output to (can be 0 if output is written to a file)
|
||||
\param p progress dialog or 0 if no progress dialog should be shown
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsGeometry locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry &lineGeom );
|
||||
%Docstring
|
||||
Returns linear reference geometry as a multiline (or 0 if no match). Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)
|
||||
:rtype: QgsGeometry
|
||||
%End
|
||||
|
||||
QgsGeometry locateAlongMeasure( double measure, const QgsGeometry &lineGeom );
|
||||
%Docstring
|
||||
Returns linear reference geometry. Unlike the PostGIS function, this method always returns multipoint or 0 if no match (not geometry collection).
|
||||
Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)
|
||||
:rtype: QgsGeometry
|
||||
%End
|
||||
|
||||
};
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/analysis/vector/qgsgeometryanalyzer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -1,46 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/analysis/vector/qgsoverlayanalyzer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsOverlayAnalyzer
|
||||
{
|
||||
%Docstring
|
||||
The QGis class provides vector overlay analysis functions
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsoverlayanalyzer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
bool intersection( QgsVectorLayer *layerA, QgsVectorLayer *layerB,
|
||||
const QString &shapefileName, bool onlySelectedFeatures = false,
|
||||
QProgressDialog *p = 0 );
|
||||
%Docstring
|
||||
Perform an intersection on two input vector layers and write output to a new shape file
|
||||
\param layerA input vector layer
|
||||
\param layerB input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/analysis/vector/qgsoverlayanalyzer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -1,38 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/analysis/vector/qgspointsample.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
class QgsPointSample
|
||||
{
|
||||
%Docstring
|
||||
Creates random points in polygons / multipolygons*
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgspointsample.h"
|
||||
%End
|
||||
public:
|
||||
QgsPointSample( QgsVectorLayer *inputLayer, const QString &outputLayer, const QString &nPointsAttribute, const QString &minDistAttribute = QString() );
|
||||
|
||||
int createRandomPoints( QProgressDialog *pd );
|
||||
%Docstring
|
||||
Starts calculation of random points
|
||||
:return: 0 in case of success*
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/analysis/vector/qgspointsample.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -223,12 +223,6 @@ Returns the path to the licence file.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString helpAppPath();
|
||||
%Docstring
|
||||
Returns the path to the help application.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString i18nPath();
|
||||
%Docstring
|
||||
Returns the path to the translation directory.
|
||||
|
@ -35,6 +35,7 @@ from .GdalUtils import GdalUtils
|
||||
|
||||
from .AssignProjection import AssignProjection
|
||||
from .aspect import aspect
|
||||
from .buildvrt import buildvrt
|
||||
from .ColorRelief import ColorRelief
|
||||
from .tri import tri
|
||||
from .warp import warp
|
||||
@ -44,7 +45,6 @@ from .nearblack import nearblack
|
||||
# from .translate import translate
|
||||
# from .pct2rgb import pct2rgb
|
||||
# from .merge import merge
|
||||
# from .buildvrt import buildvrt
|
||||
# from .polygonize import polygonize
|
||||
# from .gdaladdo import gdaladdo
|
||||
# from .ClipByExtent import ClipByExtent
|
||||
@ -144,6 +144,7 @@ class GdalAlgorithmProvider(QgsProcessingProvider):
|
||||
# information(),
|
||||
AssignProjection(),
|
||||
aspect(),
|
||||
buildvrt(),
|
||||
ColorRelief(),
|
||||
tri(),
|
||||
warp(),
|
||||
@ -151,7 +152,6 @@ class GdalAlgorithmProvider(QgsProcessingProvider):
|
||||
# rgb2pct(),
|
||||
# pct2rgb(),
|
||||
# merge(),
|
||||
# buildvrt(),
|
||||
# polygonize(),
|
||||
# gdaladdo(),
|
||||
# ClipByExtent(),
|
||||
|
@ -29,14 +29,16 @@ import os
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
|
||||
from qgis.core import QgsProcessingUtils
|
||||
from qgis.core import (QgsProcessing,
|
||||
QgsProperty,
|
||||
QgsProcessingParameterMultipleLayers,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterBoolean,
|
||||
QgsProcessingParameterRasterDestination,
|
||||
QgsProcessingOutputLayerDefinition,
|
||||
QgsProcessingUtils)
|
||||
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
|
||||
from processing.core.outputs import OutputRaster
|
||||
from processing.core.parameters import ParameterBoolean
|
||||
from processing.core.parameters import ParameterMultipleInput
|
||||
from processing.core.parameters import ParameterSelection
|
||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||
from processing.tools import dataobjects
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
@ -55,15 +57,27 @@ class buildvrt(GdalAlgorithm):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.addParameter(ParameterMultipleInput(self.INPUT,
|
||||
self.tr('Input layers'), dataobjects.TYPE_RASTER))
|
||||
self.addParameter(ParameterSelection(self.RESOLUTION,
|
||||
self.tr('Resolution'), self.RESOLUTION_OPTIONS, 0))
|
||||
self.addParameter(ParameterBoolean(self.SEPARATE,
|
||||
self.tr('Layer stack'), True))
|
||||
self.addParameter(ParameterBoolean(self.PROJ_DIFFERENCE,
|
||||
self.tr('Allow projection difference'), False))
|
||||
self.addOutput(OutputRaster(buildvrt.OUTPUT, self.tr('Virtual')))
|
||||
|
||||
class ParameterVrtDestination(QgsProcessingParameterRasterDestination):
|
||||
|
||||
def __init__(self, name, description):
|
||||
super().__init__(name, description)
|
||||
|
||||
def type(self):
|
||||
return 'vrt_destination'
|
||||
|
||||
def defaultFileExtension(self):
|
||||
return 'vrt'
|
||||
|
||||
self.addParameter(QgsProcessingParameterMultipleLayers(self.INPUT,
|
||||
self.tr('Input layers'), QgsProcessing.TypeRaster))
|
||||
self.addParameter(QgsProcessingParameterEnum(self.RESOLUTION,
|
||||
self.tr('Resolution'), options=self.RESOLUTION_OPTIONS, defaultValue=0))
|
||||
self.addParameter(QgsProcessingParameterBoolean(self.SEPARATE,
|
||||
self.tr('Layer stack'), defaultValue=True))
|
||||
self.addParameter(QgsProcessingParameterBoolean(self.PROJ_DIFFERENCE,
|
||||
self.tr('Allow projection difference'), defaultValue=False))
|
||||
self.addParameter(ParameterVrtDestination(self.OUTPUT, self.tr('Virtual')))
|
||||
|
||||
def name(self):
|
||||
return 'buildvirtualraster'
|
||||
@ -80,25 +94,34 @@ class buildvrt(GdalAlgorithm):
|
||||
def getConsoleCommands(self, parameters, context, feedback):
|
||||
arguments = []
|
||||
arguments.append('-resolution')
|
||||
arguments.append(self.RESOLUTION_OPTIONS[self.getParameterValue(self.RESOLUTION)])
|
||||
if self.getParameterValue(buildvrt.SEPARATE):
|
||||
arguments.append(self.RESOLUTION_OPTIONS[self.parameterAsEnum(parameters, self.RESOLUTION, context)])
|
||||
if self.parameterAsBool(parameters, buildvrt.SEPARATE, context):
|
||||
arguments.append('-separate')
|
||||
if self.getParameterValue(buildvrt.PROJ_DIFFERENCE):
|
||||
if self.parameterAsBool(parameters, buildvrt.PROJ_DIFFERENCE, context):
|
||||
arguments.append('-allow_projection_difference')
|
||||
# Always write input files to a text file in case there are many of them and the
|
||||
# length of the command will be longer then allowed in command prompt
|
||||
listFile = os.path.join(QgsProcessingUtils.tempFolder(), 'buildvrtInputFiles.txt')
|
||||
with open(listFile, 'w') as f:
|
||||
f.write(self.getParameterValue(buildvrt.INPUT).replace(';', '\n'))
|
||||
layers = []
|
||||
for l in self.parameterAsLayerList(parameters, self.INPUT, context):
|
||||
layers.append(l.source())
|
||||
f.write('\n'.join(layers))
|
||||
arguments.append('-input_file_list')
|
||||
arguments.append(listFile)
|
||||
out = self.getOutputValue(buildvrt.OUTPUT)
|
||||
|
||||
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
||||
# Ideally the file extensions should be limited to just .vrt but I'm not sure how
|
||||
# to do it simply so instead a check is performed.
|
||||
_, ext = os.path.splitext(out)
|
||||
if not ext.lower() == '.vrt':
|
||||
out = out.replace(ext, '.vrt')
|
||||
self.setOutputValue(self.OUTPUT, out)
|
||||
out = out[:-len(ext)] + '.vrt'
|
||||
if isinstance(parameters[self.OUTPUT], QgsProcessingOutputLayerDefinition):
|
||||
output_def = QgsProcessingOutputLayerDefinition(parameters[self.OUTPUT])
|
||||
output_def.sink = QgsProperty.fromValue(out)
|
||||
self.setOutputValue(self.OUTPUT, output_def)
|
||||
else:
|
||||
self.setOutputValue(self.OUTPUT, out)
|
||||
arguments.append(out)
|
||||
|
||||
return ['gdalbuildvrt', GdalUtils.escapeAndJoin(arguments)]
|
||||
|
@ -29,12 +29,17 @@ __revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
|
||||
from qgis.core import QgsSettings
|
||||
from qgis.core import (QgsSettings,
|
||||
QgsProcessing,
|
||||
QgsVectorFileWriter,
|
||||
QgsProviderRegistry,
|
||||
QgsProcessingModelChildParameterSource)
|
||||
from qgis.PyQt import uic
|
||||
from qgis.PyQt.QtCore import Qt
|
||||
from qgis.PyQt.QtCore import QByteArray
|
||||
from qgis.PyQt.QtWidgets import QDialog, QAbstractItemView, QPushButton, QDialogButtonBox
|
||||
from qgis.PyQt.QtWidgets import QDialog, QAbstractItemView, QPushButton, QDialogButtonBox, QFileDialog
|
||||
from qgis.PyQt.QtGui import QStandardItemModel, QStandardItem
|
||||
from processing.tools import dataobjects
|
||||
|
||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||
WIDGET, BASE = uic.loadUiType(
|
||||
@ -43,9 +48,11 @@ WIDGET, BASE = uic.loadUiType(
|
||||
|
||||
class MultipleInputDialog(BASE, WIDGET):
|
||||
|
||||
def __init__(self, options, selectedoptions=None):
|
||||
def __init__(self, options, selectedoptions=None, datatype=None):
|
||||
super(MultipleInputDialog, self).__init__(None)
|
||||
self.setupUi(self)
|
||||
self.datatype = datatype
|
||||
self.model = None
|
||||
|
||||
self.lstLayers.setSelectionMode(QAbstractItemView.NoSelection)
|
||||
|
||||
@ -68,6 +75,11 @@ class MultipleInputDialog(BASE, WIDGET):
|
||||
self.btnToggleSelection = QPushButton(self.tr('Toggle selection'))
|
||||
self.buttonBox.addButton(self.btnToggleSelection,
|
||||
QDialogButtonBox.ActionRole)
|
||||
if self.datatype is not None:
|
||||
btnAddFile = QPushButton(self.tr('Add file(s)…'))
|
||||
btnAddFile.clicked.connect(self.addFiles)
|
||||
self.buttonBox.addButton(btnAddFile,
|
||||
QDialogButtonBox.ActionRole)
|
||||
|
||||
self.btnSelectAll.clicked.connect(lambda: self.selectAll(True))
|
||||
self.btnClearSelection.clicked.connect(lambda: self.selectAll(False))
|
||||
@ -76,6 +88,7 @@ class MultipleInputDialog(BASE, WIDGET):
|
||||
self.settings = QgsSettings()
|
||||
self.restoreGeometry(self.settings.value("/Processing/multipleInputDialogGeometry", QByteArray()))
|
||||
|
||||
self.lstLayers.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
self.populateList()
|
||||
self.finished.connect(self.saveWindowGeometry)
|
||||
|
||||
@ -83,15 +96,26 @@ class MultipleInputDialog(BASE, WIDGET):
|
||||
self.settings.setValue("/Processing/multipleInputDialogGeometry", self.saveGeometry())
|
||||
|
||||
def populateList(self):
|
||||
model = QStandardItemModel()
|
||||
self.model = QStandardItemModel()
|
||||
for value, text in self.options:
|
||||
item = QStandardItem(text)
|
||||
item.setData(value, Qt.UserRole)
|
||||
item.setCheckState(Qt.Checked if value in self.selectedoptions else Qt.Unchecked)
|
||||
item.setCheckable(True)
|
||||
model.appendRow(item)
|
||||
self.model.appendRow(item)
|
||||
|
||||
self.lstLayers.setModel(model)
|
||||
# add extra options (e.g. manually added layers)
|
||||
for t in [o for o in self.selectedoptions if not isinstance(o, int)]:
|
||||
if isinstance(t, QgsProcessingModelChildParameterSource):
|
||||
item = QStandardItem(t.staticValue())
|
||||
else:
|
||||
item = QStandardItem(t)
|
||||
item.setData(item.text(), Qt.UserRole)
|
||||
item.setCheckState(Qt.Checked)
|
||||
item.setCheckable(True)
|
||||
self.model.appendRow(item)
|
||||
|
||||
self.lstLayers.setModel(self.model)
|
||||
|
||||
def accept(self):
|
||||
self.selectedoptions = []
|
||||
@ -106,15 +130,56 @@ class MultipleInputDialog(BASE, WIDGET):
|
||||
self.selectedoptions = None
|
||||
QDialog.reject(self)
|
||||
|
||||
def getItemsToModify(self):
|
||||
items = []
|
||||
if len(self.lstLayers.selectedIndexes()) > 1:
|
||||
for i in self.lstLayers.selectedIndexes():
|
||||
items.append(self.model.itemFromIndex(i))
|
||||
else:
|
||||
for i in range(self.model.rowCount()):
|
||||
items.append(self.model.item(i))
|
||||
return items
|
||||
|
||||
def selectAll(self, value):
|
||||
model = self.lstLayers.model()
|
||||
for i in range(model.rowCount()):
|
||||
item = model.item(i)
|
||||
for item in self.getItemsToModify():
|
||||
item.setCheckState(Qt.Checked if value else Qt.Unchecked)
|
||||
|
||||
def toggleSelection(self):
|
||||
model = self.lstLayers.model()
|
||||
for i in range(model.rowCount()):
|
||||
item = model.item(i)
|
||||
for item in self.getItemsToModify():
|
||||
checked = item.checkState() == Qt.Checked
|
||||
item.setCheckState(Qt.Unchecked if checked else Qt.Checked)
|
||||
|
||||
def getFileFilter(self, datatype):
|
||||
"""
|
||||
Returns a suitable file filter pattern for the specified parameter definition
|
||||
:param param:
|
||||
:return:
|
||||
"""
|
||||
if datatype == QgsProcessing.TypeRaster:
|
||||
return QgsProviderRegistry.instance().fileRasterFilters()
|
||||
elif datatype == QgsProcessing.TypeFile:
|
||||
return self.tr('All files (*.*)')
|
||||
else:
|
||||
exts = QgsVectorFileWriter.supportedFormatExtensions()
|
||||
for i in range(len(exts)):
|
||||
exts[i] = self.tr('{0} files (*.{1})').format(exts[i].upper(), exts[i].lower())
|
||||
return self.tr('All files (*.*)') + ';;' + ';;'.join(exts)
|
||||
|
||||
def addFiles(self):
|
||||
filter = self.getFileFilter(self.datatype)
|
||||
|
||||
settings = QgsSettings()
|
||||
path = str(settings.value('/Processing/LastInputPath'))
|
||||
|
||||
ret, selected_filter = QFileDialog.getOpenFileNames(self, self.tr('Select file(s)'),
|
||||
path, filter)
|
||||
if ret:
|
||||
files = list(ret)
|
||||
settings.setValue('/Processing/LastInputPath',
|
||||
os.path.dirname(str(files[0])))
|
||||
for filename in files:
|
||||
item = QStandardItem(filename)
|
||||
item.setData(filename, Qt.UserRole)
|
||||
item.setCheckState(Qt.Checked)
|
||||
item.setCheckable(True)
|
||||
self.model.appendRow(item)
|
||||
|
@ -28,9 +28,10 @@ __revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
|
||||
from qgis.core import QgsProcessing
|
||||
from qgis.PyQt import uic
|
||||
from qgis.PyQt.QtCore import pyqtSignal
|
||||
|
||||
''
|
||||
from processing.gui.MultipleInputDialog import MultipleInputDialog
|
||||
from processing.gui.MultipleFileInputDialog import MultipleFileInputDialog
|
||||
|
||||
@ -63,10 +64,10 @@ class MultipleInputPanel(BASE, WIDGET):
|
||||
self.tr('{0} elements selected').format(len(self.selectedoptions)))
|
||||
|
||||
def showSelectionDialog(self):
|
||||
if self.datatype is None:
|
||||
dlg = MultipleInputDialog(self.options, self.selectedoptions)
|
||||
else:
|
||||
if self.datatype == QgsProcessing.TypeFile:
|
||||
dlg = MultipleFileInputDialog(self.selectedoptions)
|
||||
else:
|
||||
dlg = MultipleInputDialog(self.options, self.selectedoptions, datatype=self.datatype)
|
||||
dlg.exec_()
|
||||
if dlg.selectedoptions is not None:
|
||||
self.selectedoptions = dlg.selectedoptions
|
||||
@ -76,12 +77,15 @@ class MultipleInputPanel(BASE, WIDGET):
|
||||
|
||||
def updateForOptions(self, options):
|
||||
selectedoptions = []
|
||||
selected = [self.options[i] for i in self.selectedoptions]
|
||||
selected = [self.options[i] if isinstance(i, int) else i for i in self.selectedoptions]
|
||||
for sel in selected:
|
||||
try:
|
||||
idx = options.index(sel)
|
||||
selectedoptions.append(idx)
|
||||
except ValueError:
|
||||
pass
|
||||
if isinstance(sel, int):
|
||||
try:
|
||||
idx = options.index(sel)
|
||||
selectedoptions.append(idx)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
selectedoptions.append(sel)
|
||||
self.options = options
|
||||
self.setSelectedItems(selectedoptions)
|
||||
|
@ -69,6 +69,7 @@ from qgis.core import (
|
||||
QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputString,
|
||||
QgsProcessingOutputNumber,
|
||||
QgsProcessingModelChildParameterSource,
|
||||
QgsProcessingModelAlgorithm)
|
||||
|
||||
from qgis.PyQt.QtWidgets import (
|
||||
@ -524,20 +525,20 @@ class MultipleInputWidgetWrapper(WidgetWrapper):
|
||||
|
||||
def _getOptions(self):
|
||||
if self.param.layerType() == QgsProcessing.TypeVectorAny:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFeatureSource, QgsProcessingOutputVectorLayer)
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers), QgsProcessingOutputVectorLayer)
|
||||
elif self.param.layerType() == QgsProcessing.TypeVectorPoint:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFeatureSource, QgsProcessingOutputVectorLayer,
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers), QgsProcessingOutputVectorLayer,
|
||||
[QgsProcessing.TypeVectorPoint, QgsProcessing.TypeVectorAny])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVectorLine:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFeatureSource, QgsProcessingOutputVectorLayer,
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers), QgsProcessingOutputVectorLayer,
|
||||
[QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorAny])
|
||||
elif self.param.layerType() == QgsProcessing.TypeVectorPolygon:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFeatureSource, QgsProcessingOutputVectorLayer,
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers), QgsProcessingOutputVectorLayer,
|
||||
[QgsProcessing.TypeVectorPolygon, QgsProcessing.TypeVectorAny])
|
||||
elif self.param.layerType() == QgsProcessing.TypeRaster:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterRasterLayer, QgsProcessingOutputRasterLayer)
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterRasterLayer, QgsProcessingParameterMultipleLayers), QgsProcessingOutputRasterLayer)
|
||||
elif self.param.layerType() == QgsProcessing.TypeTable:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterVectorLayer, OutputTable)
|
||||
options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers), OutputTable)
|
||||
else:
|
||||
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFile, OutputFile)
|
||||
options = sorted(options, key=lambda opt: self.dialog.resolveValueDescription(opt))
|
||||
@ -546,7 +547,7 @@ class MultipleInputWidgetWrapper(WidgetWrapper):
|
||||
def createWidget(self):
|
||||
if self.dialogType == DIALOG_STANDARD:
|
||||
if self.param.layerType() == QgsProcessing.TypeFile:
|
||||
return MultipleInputPanel(datatype=dataobjects.TYPE_FILE)
|
||||
return MultipleInputPanel(datatype=QgsProcessing.TypeFile)
|
||||
else:
|
||||
if self.param.layerType() == QgsProcessing.TypeRaster:
|
||||
options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
|
||||
@ -555,14 +556,14 @@ class MultipleInputWidgetWrapper(WidgetWrapper):
|
||||
else:
|
||||
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.param.layerType()], False)
|
||||
opts = [getExtendedLayerName(opt) for opt in options]
|
||||
return MultipleInputPanel(opts)
|
||||
return MultipleInputPanel(opts, datatype=self.param.layerType())
|
||||
elif self.dialogType == DIALOG_BATCH:
|
||||
widget = BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
|
||||
widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
|
||||
return widget
|
||||
else:
|
||||
options = [self.dialog.resolveValueDescription(opt) for opt in self._getOptions()]
|
||||
return MultipleInputPanel(options)
|
||||
return MultipleInputPanel(options, datatype=self.param.layerType())
|
||||
|
||||
def refresh(self):
|
||||
if self.param.layerType() != QgsProcessing.TypeFile:
|
||||
@ -582,11 +583,20 @@ class MultipleInputWidgetWrapper(WidgetWrapper):
|
||||
return self.widget.setText(value)
|
||||
else:
|
||||
options = self._getOptions()
|
||||
selected = []
|
||||
for i, opt in enumerate(options):
|
||||
if opt in value:
|
||||
selected.append(i)
|
||||
self.widget.setSelectedItems(selected)
|
||||
|
||||
if not isinstance(value, (tuple, list)):
|
||||
value = [value]
|
||||
|
||||
selected_options = []
|
||||
for sel in value:
|
||||
if sel in options:
|
||||
selected_options.append(options.index(sel))
|
||||
elif isinstance(sel, QgsProcessingModelChildParameterSource):
|
||||
selected_options.append(sel.staticValue())
|
||||
else:
|
||||
selected_options.append(sel)
|
||||
|
||||
self.widget.setSelectedItems(selected_options)
|
||||
|
||||
def value(self):
|
||||
if self.dialogType == DIALOG_STANDARD:
|
||||
@ -599,12 +609,12 @@ class MultipleInputWidgetWrapper(WidgetWrapper):
|
||||
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
|
||||
else:
|
||||
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.param.layerType()], False)
|
||||
return [options[i] for i in self.widget.selectedoptions]
|
||||
return [options[i] if isinstance(i, int) else i for i in self.widget.selectedoptions]
|
||||
elif self.dialogType == DIALOG_BATCH:
|
||||
return self.widget.getText()
|
||||
else:
|
||||
options = self._getOptions()
|
||||
values = [options[i] for i in self.widget.selectedoptions]
|
||||
values = [options[i] if isinstance(i, int) else QgsProcessingModelChildParameterSource.fromStaticValue(i) for i in self.widget.selectedoptions]
|
||||
if len(values) == 0 and not self.param.flags() & QgsProcessing.FlagOptional:
|
||||
raise InvalidParameterValue()
|
||||
return values
|
||||
|
@ -44,6 +44,7 @@ from qgis.core import (QgsProcessingParameterDefinition,
|
||||
QgsProcessingModelChildAlgorithm,
|
||||
QgsProcessingModelChildParameterSource,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingParameterMultipleLayers,
|
||||
QgsProcessingParameterRasterDestination,
|
||||
QgsProcessingParameterFileDestination,
|
||||
QgsProcessingParameterFolderDestination,
|
||||
@ -236,11 +237,11 @@ class ModelerParametersDialog(QDialog):
|
||||
# upgrade paramType to list
|
||||
if paramType is None:
|
||||
paramType = []
|
||||
elif not isinstance(paramType, list):
|
||||
elif not isinstance(paramType, (tuple, list)):
|
||||
paramType = [paramType]
|
||||
if outTypes is None:
|
||||
outTypes = []
|
||||
elif not isinstance(outTypes, list):
|
||||
elif not isinstance(outTypes, (tuple, list)):
|
||||
outTypes = [outTypes]
|
||||
|
||||
return self.model.availableSourcesForChild(self.childId, [p.typeName() for p in paramType if issubclass(p, QgsProcessingParameterDefinition)],
|
||||
|
@ -35,12 +35,9 @@ SET(QGIS_ANALYSIS_SRCS
|
||||
raster/qgsrastercalculator.cpp
|
||||
raster/qgsrastermatrix.cpp
|
||||
vector/mersenne-twister.cpp
|
||||
vector/qgsgeometryanalyzer.cpp
|
||||
vector/qgsgeometrysnapper.cpp
|
||||
vector/qgspointsample.cpp
|
||||
vector/qgstransectsample.cpp
|
||||
vector/qgszonalstatistics.cpp
|
||||
vector/qgsoverlayanalyzer.cpp
|
||||
|
||||
openstreetmap/qgsosmbase.cpp
|
||||
openstreetmap/qgsosmdatabase.cpp
|
||||
@ -116,9 +113,6 @@ SET(QGIS_ANALYSIS_HDRS
|
||||
raster/qgsrastercalcnode.h
|
||||
raster/qgstotalcurvaturefilter.h
|
||||
|
||||
vector/qgsgeometryanalyzer.h
|
||||
vector/qgsoverlayanalyzer.h
|
||||
vector/qgspointsample.h
|
||||
vector/qgstransectsample.h
|
||||
vector/qgszonalstatistics.h
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,161 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsgeometryanalyzer.h - QGIS Tools for vector geometry analysis
|
||||
-------------------
|
||||
begin : 19 March 2009
|
||||
copyright : (C) Carson Farmer
|
||||
email : carson.farmer@gmail.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGEOMETRYANALYZERH
|
||||
#define QGSGEOMETRYANALYZERH
|
||||
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgis_analysis.h"
|
||||
|
||||
class QgsVectorFileWriter;
|
||||
class QProgressDialog;
|
||||
class QgsVectorDataProvider;
|
||||
class QgsDistanceArea;
|
||||
|
||||
/** \ingroup analysis
|
||||
* The QGis class provides vector geometry analysis functions
|
||||
*/
|
||||
|
||||
class ANALYSIS_EXPORT QgsGeometryAnalyzer
|
||||
{
|
||||
public:
|
||||
|
||||
/** Simplify vector layer using (a modified) Douglas-Peucker algorithm
|
||||
* and write it to a new shape file
|
||||
* \param layer input vector layer
|
||||
* \param shapefileName path to the output shp
|
||||
* \param tolerance (level of simplification)
|
||||
* \param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
* \param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool simplify( QgsVectorLayer *layer, const QString &shapefileName, double tolerance,
|
||||
bool onlySelectedFeatures = false, QProgressDialog *p = nullptr );
|
||||
|
||||
/** Calculate the true centroids, or 'center of mass' for a vector layer and
|
||||
* write it to a new shape file
|
||||
* \param layer input vector layer
|
||||
* \param shapefileName path to the output shp
|
||||
* \param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
* \param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool centroids( QgsVectorLayer *layer, const QString &shapefileName,
|
||||
bool onlySelectedFeatures = false, QProgressDialog *p = nullptr );
|
||||
|
||||
/** Create a polygon based on the extent of all (selected) features and write it to a new shape file
|
||||
* \param layer input vector layer
|
||||
* \param shapefileName path to the output shp
|
||||
* \param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
* \param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool extent( QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures = false, QProgressDialog *p = 0 );
|
||||
|
||||
/** Create buffers for a vector layer and write it to a new shape file
|
||||
* \param layer input vector layer
|
||||
* \param shapefileName path to the output shp
|
||||
* \param bufferDistance distance for buffering (if no buffer field is specified)
|
||||
* \param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
* \param dissolve if true, merge all the buffers to a big multipolygon
|
||||
* \param bufferDistanceField index of the attribute field that contains the buffer distance (or -1 if all features have the same buffer distance)
|
||||
* \param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool buffer( QgsVectorLayer *layer, const QString &shapefileName, double bufferDistance,
|
||||
bool onlySelectedFeatures = false, bool dissolve = false, int bufferDistanceField = -1, QProgressDialog *p = nullptr );
|
||||
|
||||
/** Create convex hull(s) of a vector layer and write it to a new shape file
|
||||
* \param layer input vector layer
|
||||
* \param shapefileName path to the output shp
|
||||
* \param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
* \param uniqueIdField index of the attribute field that contains the unique convex hull id (or -1 if
|
||||
* all features have the same buffer distance)
|
||||
* \param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool convexHull( QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures = false,
|
||||
int uniqueIdField = -1, QProgressDialog *p = nullptr );
|
||||
|
||||
/** Dissolve a vector layer and write it to a new shape file
|
||||
* \param layer input vector layer
|
||||
* \param shapefileName path to the output shp
|
||||
* \param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
* \param uniqueIdField index of the attribute field that contains the unique id to dissolve on (or -1 if
|
||||
* all features should be dissolved together)
|
||||
* \param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool dissolve( QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures = false,
|
||||
int uniqueIdField = -1, QProgressDialog *p = nullptr );
|
||||
|
||||
/** Creates an event layer (multipoint or multiline) by locating features from a (non-spatial) event table along the features of a line layer.
|
||||
* Note that currently (until QgsGeometry supports m-values) the z-coordinate of the line layer is used for linear referencing
|
||||
* \param lineLayer layer with the line geometry
|
||||
* \param eventLayer layer with features and location field
|
||||
* \param lineField join index in line layer
|
||||
* \param eventField join index in event layer
|
||||
* \param outputLayer name of output file (can be empty if a memory layer is used)
|
||||
* \param outputFormat name of output format (can be empty if a memory provider is used to store the results)
|
||||
* \param unlocatedFeatureIds out: ids of event features where linear referencing was not successful
|
||||
* \param locationField1 attribute index of location field in event layer
|
||||
* \param locationField2 attribute index of location end field (or -1 for point layer)
|
||||
* \param offsetField attribute index for offset field. Negative offset value = offset to left side, positive value = offset to right side
|
||||
* \param offsetScale factor to scale offset
|
||||
* \param forceSingleGeometry force layer to single point/line type. Feature attributes are copied in case of multiple matches
|
||||
* \param memoryProvider memory provider to write output to (can be 0 if output is written to a file)
|
||||
* \param p progress dialog or 0 if no progress dialog should be shown
|
||||
*/
|
||||
bool eventLayer( QgsVectorLayer *lineLayer, QgsVectorLayer *eventLayer, int lineField, int eventField, QgsFeatureIds &unlocatedFeatureIds SIP_OUT, const QString &outputLayer,
|
||||
const QString &outputFormat, int locationField1, int locationField2 = -1, int offsetField = -1, double offsetScale = 1.0,
|
||||
bool forceSingleGeometry = false, QgsVectorDataProvider *memoryProvider = nullptr, QProgressDialog *p = nullptr );
|
||||
|
||||
//! Returns linear reference geometry as a multiline (or 0 if no match). Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)
|
||||
QgsGeometry locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry &lineGeom );
|
||||
|
||||
/** Returns linear reference geometry. Unlike the PostGIS function, this method always returns multipoint or 0 if no match (not geometry collection).
|
||||
* Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)
|
||||
*/
|
||||
QgsGeometry locateAlongMeasure( double measure, const QgsGeometry &lineGeom );
|
||||
|
||||
private:
|
||||
|
||||
QList<double> simpleMeasure( QgsGeometry &geometry );
|
||||
double perimeterMeasure( const QgsGeometry &geometry, QgsDistanceArea &measure );
|
||||
//! Helper function to simplify an individual feature
|
||||
void simplifyFeature( QgsFeature &f, QgsVectorFileWriter *vfw, double tolerance );
|
||||
//! Helper function to get the cetroid of an individual feature
|
||||
void centroidFeature( QgsFeature &f, QgsVectorFileWriter *vfw );
|
||||
//! Helper function to buffer an individual feature
|
||||
void bufferFeature( QgsFeature &f, int nProcessedFeatures, QgsVectorFileWriter *vfw, bool dissolve, QgsGeometry &dissolveGeometry,
|
||||
double bufferDistance, int bufferDistanceField );
|
||||
//! Helper function to get the convex hull of feature(s)
|
||||
void convexFeature( QgsFeature &f, int nProcessedFeatures, QgsGeometry &dissolveGeometry );
|
||||
//! Helper function to dissolve feature(s)
|
||||
QgsGeometry dissolveFeature( const QgsFeature &f, const QgsGeometry &dissolveInto );
|
||||
|
||||
//helper functions for event layer
|
||||
void addEventLayerFeature( QgsFeature &feature, const QgsGeometry &geom, const QgsGeometry &lineGeom, QgsVectorFileWriter *fileWriter, QgsFeatureList &memoryFeatures, int offsetField = -1, double offsetScale = 1.0,
|
||||
bool forceSingleType = false );
|
||||
|
||||
/** Create geometry offset relative to line geometry.
|
||||
\param geom the geometry to modify
|
||||
\param lineGeom the line geometry to which the feature is referenced
|
||||
\param offset the offset value in layer unit. Negative values mean offset towards left, positive values offset to the right side*/
|
||||
QgsGeometry createOffsetGeometry( const QgsGeometry &geom, const QgsGeometry &lineGeom, double offset );
|
||||
QgsPointXY createPointOffset( double x, double y, double dist, const QgsGeometry &lineGeom ) const;
|
||||
QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline &result, double fromMeasure, double toMeasure );
|
||||
QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint &result, double measure );
|
||||
static bool clipSegmentByRange( double x1, double y1, double m1, double x2, double y2, double m2, double range1, double range2, QgsPointXY &pt1, QgsPointXY &pt2, bool &secondPointClipped );
|
||||
static void locateAlongSegment( double x1, double y1, double m1, double x2, double y2, double m2, double measure, bool &pt1Ok, QgsPointXY &pt1, bool &pt2Ok, QgsPointXY &pt2 );
|
||||
};
|
||||
#endif //QGSVECTORANALYZER
|
@ -1,195 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsoverlayanalyzer.cpp - QGIS Tools for vector geometry analysis
|
||||
-------------------
|
||||
begin : 8 Nov 2009
|
||||
copyright : (C) Carson J. Q. Farmer
|
||||
email : carson.farmer@gmail.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsoverlayanalyzer.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include "qgsfields.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgsspatialindex.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsdistancearea.h"
|
||||
#include <QProgressDialog>
|
||||
|
||||
bool QgsOverlayAnalyzer::intersection( QgsVectorLayer *layerA, QgsVectorLayer *layerB,
|
||||
const QString &shapefileName, bool onlySelectedFeatures,
|
||||
QProgressDialog *p )
|
||||
{
|
||||
if ( !layerA || !layerB )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsVectorDataProvider *dpA = layerA->dataProvider();
|
||||
QgsVectorDataProvider *dpB = layerB->dataProvider();
|
||||
if ( !dpA || !dpB )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsWkbTypes::Type outputType = dpA->wkbType();
|
||||
QgsCoordinateReferenceSystem crs = layerA->crs();
|
||||
QgsFields fieldsA = layerA->fields();
|
||||
QgsFields fieldsB = layerB->fields();
|
||||
combineFieldLists( fieldsA, fieldsB );
|
||||
|
||||
QgsVectorFileWriter vWriter( shapefileName, dpA->encoding(), fieldsA, outputType, crs );
|
||||
QgsFeature currentFeature;
|
||||
|
||||
//take only selection
|
||||
if ( onlySelectedFeatures )
|
||||
{
|
||||
QgsFeatureIds selectionB = layerB->selectedFeatureIds();
|
||||
QgsFeatureRequest req = QgsFeatureRequest().setFilterFids( selectionB ).setSubsetOfAttributes( QgsAttributeList() );
|
||||
QgsSpatialIndex index = QgsSpatialIndex( layerB->getFeatures( req ) );
|
||||
|
||||
//use QgsVectorLayer::featureAtId
|
||||
const QgsFeatureIds selectionA = layerA->selectedFeatureIds();
|
||||
if ( p )
|
||||
{
|
||||
p->setMaximum( selectionA.size() );
|
||||
}
|
||||
req = QgsFeatureRequest().setFilterFids( selectionA );
|
||||
QgsFeatureIterator selectionAIt = layerA->getFeatures( req );
|
||||
QgsFeature currentFeature;
|
||||
int processedFeatures = 0;
|
||||
while ( selectionAIt.nextFeature( currentFeature ) )
|
||||
{
|
||||
if ( p )
|
||||
{
|
||||
p->setValue( processedFeatures );
|
||||
}
|
||||
|
||||
if ( p && p->wasCanceled() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
intersectFeature( currentFeature, &vWriter, layerB, &index );
|
||||
++processedFeatures;
|
||||
}
|
||||
|
||||
if ( p )
|
||||
{
|
||||
p->setValue( selectionA.size() );
|
||||
}
|
||||
}
|
||||
//take all features
|
||||
else
|
||||
{
|
||||
QgsFeatureRequest req = QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() );
|
||||
QgsSpatialIndex index = QgsSpatialIndex( layerB->getFeatures( req ) );
|
||||
|
||||
int featureCount = layerA->featureCount();
|
||||
if ( p )
|
||||
{
|
||||
p->setMaximum( featureCount );
|
||||
}
|
||||
int processedFeatures = 0;
|
||||
|
||||
QgsFeatureIterator fit = layerA->getFeatures();
|
||||
|
||||
QgsFeature currentFeature;
|
||||
while ( fit.nextFeature( currentFeature ) )
|
||||
{
|
||||
if ( p )
|
||||
{
|
||||
p->setValue( processedFeatures );
|
||||
}
|
||||
if ( p && p->wasCanceled() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
intersectFeature( currentFeature, &vWriter, layerB, &index );
|
||||
++processedFeatures;
|
||||
}
|
||||
if ( p )
|
||||
{
|
||||
p->setValue( featureCount );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsOverlayAnalyzer::intersectFeature( QgsFeature &f, QgsVectorFileWriter *vfw,
|
||||
QgsVectorLayer *vl, QgsSpatialIndex *index )
|
||||
{
|
||||
if ( !f.hasGeometry() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsGeometry featureGeometry = f.geometry();
|
||||
QgsGeometry intersectGeometry;
|
||||
QgsFeature overlayFeature;
|
||||
|
||||
QList<QgsFeatureId> intersects = index->intersects( featureGeometry.boundingBox() );
|
||||
QgsFeatureRequest req = QgsFeatureRequest().setFilterFids( intersects.toSet() );
|
||||
QgsFeatureIterator intersectIt = vl->getFeatures( req );
|
||||
QgsFeature outFeature;
|
||||
while ( intersectIt.nextFeature( overlayFeature ) )
|
||||
{
|
||||
if ( featureGeometry.intersects( overlayFeature.geometry() ) )
|
||||
{
|
||||
intersectGeometry = featureGeometry.intersection( overlayFeature.geometry() );
|
||||
|
||||
outFeature.setGeometry( intersectGeometry );
|
||||
QgsAttributes attributesA = f.attributes();
|
||||
QgsAttributes attributesB = overlayFeature.attributes();
|
||||
combineAttributeMaps( attributesA, attributesB );
|
||||
outFeature.setAttributes( attributesA );
|
||||
|
||||
//add it to vector file writer
|
||||
if ( vfw )
|
||||
{
|
||||
vfw->addFeature( outFeature );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsOverlayAnalyzer::combineFieldLists( QgsFields &fieldListA, const QgsFields &fieldListB )
|
||||
{
|
||||
QList<QString> names;
|
||||
Q_FOREACH ( const QgsField &field, fieldListA )
|
||||
names.append( field.name() );
|
||||
|
||||
for ( int idx = 0; idx < fieldListB.count(); ++idx )
|
||||
{
|
||||
QgsField field = fieldListB.at( idx );
|
||||
int count = 0;
|
||||
while ( names.contains( field.name() ) )
|
||||
{
|
||||
QString name = QStringLiteral( "%1_%2" ).arg( field.name() ).arg( count );
|
||||
field = QgsField( name, field.type() );
|
||||
++count;
|
||||
}
|
||||
fieldListA.append( field );
|
||||
names.append( field.name() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsOverlayAnalyzer::combineAttributeMaps( QgsAttributes &attributesA, const QgsAttributes &attributesB )
|
||||
{
|
||||
attributesA += attributesB;
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsoverlayanalyzer.h - QGIS Tools for vector geometry analysis
|
||||
-------------------
|
||||
begin : 19 March 2009
|
||||
copyright : (C) Carson Farmer
|
||||
email : carson.farmer@gmail.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSOVERLAYANALYZERH
|
||||
#define QGSOVERLAYANALYZERH
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgis_analysis.h"
|
||||
|
||||
class QgsVectorFileWriter;
|
||||
class QProgressDialog;
|
||||
class QgsSpatialIndex;
|
||||
|
||||
/** \ingroup analysis
|
||||
* The QGis class provides vector overlay analysis functions
|
||||
*/
|
||||
|
||||
class ANALYSIS_EXPORT QgsOverlayAnalyzer
|
||||
{
|
||||
public:
|
||||
|
||||
/** Perform an intersection on two input vector layers and write output to a new shape file
|
||||
\param layerA input vector layer
|
||||
\param layerB input vector layer
|
||||
\param shapefileName path to the output shp
|
||||
\param onlySelectedFeatures if true, only selected features are considered, else all the features
|
||||
\param p progress dialog (or 0 if no progress dialog is to be shown)
|
||||
*/
|
||||
bool intersection( QgsVectorLayer *layerA, QgsVectorLayer *layerB,
|
||||
const QString &shapefileName, bool onlySelectedFeatures = false,
|
||||
QProgressDialog *p = nullptr );
|
||||
|
||||
private:
|
||||
|
||||
void combineFieldLists( QgsFields &fieldListA, const QgsFields &fieldListB );
|
||||
void intersectFeature( QgsFeature &f, QgsVectorFileWriter *vfw, QgsVectorLayer *dp, QgsSpatialIndex *index );
|
||||
void combineAttributeMaps( QgsAttributes &attributesA, const QgsAttributes &attributesB );
|
||||
};
|
||||
|
||||
#endif //QGSVECTORANALYZER
|
@ -1,170 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgspointsample.cpp
|
||||
---------------------
|
||||
begin : July 2013
|
||||
copyright : (C) 2013 by Marco Hugentobler
|
||||
email : marco dot hugentobler at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgspointsample.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsspatialindex.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include <QFile>
|
||||
#include "mersenne-twister.h"
|
||||
|
||||
|
||||
QgsPointSample::QgsPointSample( QgsVectorLayer *inputLayer, const QString &outputLayer, const QString &nPointsAttribute, const QString &minDistAttribute ): mInputLayer( inputLayer ),
|
||||
mOutputLayer( outputLayer ), mNumberOfPointsAttribute( nPointsAttribute ), mMinDistanceAttribute( minDistAttribute ), mNCreatedPoints( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
QgsPointSample::QgsPointSample()
|
||||
: mInputLayer( nullptr )
|
||||
, mNCreatedPoints( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
int QgsPointSample::createRandomPoints( QProgressDialog *pd )
|
||||
{
|
||||
Q_UNUSED( pd );
|
||||
|
||||
//create input layer from id (test if polygon, valid)
|
||||
if ( !mInputLayer )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( mInputLayer->geometryType() != QgsWkbTypes::PolygonGeometry )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
//delete output file if it already exists
|
||||
if ( QFile::exists( mOutputLayer ) )
|
||||
{
|
||||
QgsVectorFileWriter::deleteShapeFile( mOutputLayer );
|
||||
}
|
||||
|
||||
//create vector file writer
|
||||
QgsFields outputFields;
|
||||
outputFields.append( QgsField( QStringLiteral( "id" ), QVariant::Int ) );
|
||||
outputFields.append( QgsField( QStringLiteral( "station_id" ), QVariant::Int ) );
|
||||
outputFields.append( QgsField( QStringLiteral( "stratum_id" ), QVariant::Int ) );
|
||||
QgsVectorFileWriter writer( mOutputLayer, QStringLiteral( "UTF-8" ),
|
||||
outputFields,
|
||||
QgsWkbTypes::Point,
|
||||
mInputLayer->crs() );
|
||||
|
||||
//check if creation of output layer successful
|
||||
if ( writer.hasError() != QgsVectorFileWriter::NoError )
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
//init random number generator
|
||||
mt_srand( QTime::currentTime().msec() );
|
||||
QgsFeature fet;
|
||||
int nPoints = 0;
|
||||
double minDistance = 0;
|
||||
mNCreatedPoints = 0;
|
||||
|
||||
QgsFeatureIterator fIt = mInputLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes(
|
||||
QStringList() << mNumberOfPointsAttribute << mMinDistanceAttribute, mInputLayer->fields() ) );
|
||||
while ( fIt.nextFeature( fet ) )
|
||||
{
|
||||
nPoints = fet.attribute( mNumberOfPointsAttribute ).toInt();
|
||||
if ( !mMinDistanceAttribute.isEmpty() )
|
||||
{
|
||||
minDistance = fet.attribute( mMinDistanceAttribute ).toDouble();
|
||||
}
|
||||
addSamplePoints( fet, writer, nPoints, minDistance );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QgsPointSample::addSamplePoints( QgsFeature &inputFeature, QgsVectorFileWriter &writer, int nPoints, double minDistance )
|
||||
{
|
||||
if ( !inputFeature.hasGeometry() )
|
||||
return;
|
||||
|
||||
QgsGeometry geom = inputFeature.geometry();
|
||||
QgsRectangle geomRect = geom.boundingBox();
|
||||
if ( geomRect.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsSpatialIndex sIndex; //to check minimum distance
|
||||
QMap< QgsFeatureId, QgsPointXY > pointMapForFeature;
|
||||
|
||||
int nIterations = 0;
|
||||
int maxIterations = nPoints * 200;
|
||||
int points = 0;
|
||||
|
||||
double randX = 0;
|
||||
double randY = 0;
|
||||
|
||||
while ( nIterations < maxIterations && points < nPoints )
|
||||
{
|
||||
randX = ( ( double )mt_rand() / MD_RAND_MAX ) * geomRect.width() + geomRect.xMinimum();
|
||||
randY = ( ( double )mt_rand() / MD_RAND_MAX ) * geomRect.height() + geomRect.yMinimum();
|
||||
QgsPointXY randPoint( randX, randY );
|
||||
QgsGeometry ptGeom = QgsGeometry::fromPoint( randPoint );
|
||||
if ( ptGeom.within( geom ) && checkMinDistance( randPoint, sIndex, minDistance, pointMapForFeature ) )
|
||||
{
|
||||
//add feature to writer
|
||||
QgsFeature f( mNCreatedPoints );
|
||||
f.setAttribute( QStringLiteral( "id" ), mNCreatedPoints + 1 );
|
||||
f.setAttribute( QStringLiteral( "station_id" ), points + 1 );
|
||||
f.setAttribute( QStringLiteral( "stratum_id" ), inputFeature.id() );
|
||||
f.setGeometry( ptGeom );
|
||||
writer.addFeature( f );
|
||||
sIndex.insertFeature( f );
|
||||
pointMapForFeature.insert( mNCreatedPoints, randPoint );
|
||||
++points;
|
||||
++mNCreatedPoints;
|
||||
}
|
||||
++nIterations;
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsPointSample::checkMinDistance( QgsPointXY &pt, QgsSpatialIndex &index, double minDistance, QMap< QgsFeatureId, QgsPointXY > &pointMap )
|
||||
{
|
||||
if ( minDistance <= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<QgsFeatureId> neighborList = index.nearestNeighbor( pt, 1 );
|
||||
if ( neighborList.isEmpty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QMap< QgsFeatureId, QgsPointXY >::const_iterator it = pointMap.find( neighborList[0] );
|
||||
if ( it == pointMap.constEnd() ) //should not happen
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsPointXY neighborPt = it.value();
|
||||
if ( neighborPt.sqrDist( pt ) < ( minDistance * minDistance ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgspointsample.h
|
||||
---------------------
|
||||
begin : July 2013
|
||||
copyright : (C) 2013 by Marco Hugentobler
|
||||
email : marco dot hugentobler at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSPOINTSAMPLE_H
|
||||
#define QGSPOINTSAMPLE_H
|
||||
|
||||
#include "qgsfeature.h"
|
||||
#include <QString>
|
||||
#include "qgis_analysis.h"
|
||||
|
||||
class QgsFeature;
|
||||
class QgsPointXY;
|
||||
class QgsSpatialIndex;
|
||||
class QgsVectorFileWriter;
|
||||
class QgsVectorLayer;
|
||||
class QProgressDialog;
|
||||
|
||||
/** \ingroup analysis
|
||||
* Creates random points in polygons / multipolygons*/
|
||||
class ANALYSIS_EXPORT QgsPointSample
|
||||
{
|
||||
public:
|
||||
QgsPointSample( QgsVectorLayer *inputLayer, const QString &outputLayer, const QString &nPointsAttribute, const QString &minDistAttribute = QString() );
|
||||
|
||||
/** Starts calculation of random points
|
||||
\returns 0 in case of success*/
|
||||
int createRandomPoints( QProgressDialog *pd );
|
||||
|
||||
private:
|
||||
|
||||
QgsPointSample(); //default constructor is forbidden
|
||||
void addSamplePoints( QgsFeature &inputFeature, QgsVectorFileWriter &writer, int nPoints, double minDistance );
|
||||
bool checkMinDistance( QgsPointXY &pt, QgsSpatialIndex &index, double minDistance, QMap< QgsFeatureId, QgsPointXY > &pointMap );
|
||||
|
||||
//! Layer id of input polygon/multipolygon layer
|
||||
QgsVectorLayer *mInputLayer = nullptr;
|
||||
//! Output path of result layer
|
||||
QString mOutputLayer;
|
||||
//! Attribute containing number of points per feature
|
||||
QString mNumberOfPointsAttribute;
|
||||
//! Attribute containing minimum distance between sample points (or -1 if no min. distance constraint)
|
||||
QString mMinDistanceAttribute;
|
||||
QgsFeatureId mNCreatedPoints; //helper to find free ids
|
||||
};
|
||||
|
||||
#endif // QGSPOINTSAMPLE_H
|
@ -124,8 +124,6 @@ SET(QGIS_APP_SRCS
|
||||
qgstextannotationdialog.cpp
|
||||
qgssvgannotationdialog.cpp
|
||||
qgsundowidget.cpp
|
||||
qgstipgui.cpp
|
||||
qgstipfactory.cpp
|
||||
qgsvectorlayerproperties.cpp
|
||||
qgsmapthemes.cpp
|
||||
qgshandlebadlayers.cpp
|
||||
@ -342,8 +340,6 @@ SET (QGIS_APP_MOC_HDRS
|
||||
qgsstatisticalsummarydockwidget.h
|
||||
qgssvgannotationdialog.h
|
||||
qgstextannotationdialog.h
|
||||
qgstipgui.h
|
||||
qgstipfactory.h
|
||||
qgsundowidget.h
|
||||
qgsvectorlayerproperties.h
|
||||
qgsmapthemes.h
|
||||
|
@ -261,7 +261,6 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
|
||||
#include "qgstaskmanagerwidget.h"
|
||||
#include "qgssymbolselectordialog.h"
|
||||
#include "qgstextannotation.h"
|
||||
#include "qgstipgui.h"
|
||||
#include "qgsundowidget.h"
|
||||
#include "qgsuserinputdockwidget.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
@ -1181,18 +1180,6 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
toggleSnapping->setProperty( "Icon", QgsApplication::getThemeIcon( "/mIconSnapping.svg" ) );
|
||||
connect( toggleSnapping, &QShortcut::activated, mSnappingUtils, &QgsSnappingUtils::toggleEnabled );
|
||||
|
||||
// Show a nice tip of the day
|
||||
if ( settings.value( QStringLiteral( "qgis/showTips%1" ).arg( Qgis::QGIS_VERSION_INT / 100 ), true ).toBool() )
|
||||
{
|
||||
mSplash->hide();
|
||||
QgsTipGui myTip( this );
|
||||
myTip.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "Tips are disabled" );
|
||||
}
|
||||
|
||||
if ( ! QTouchDevice::devices().isEmpty() )
|
||||
{
|
||||
//add reacting to long click in touch
|
||||
|
@ -628,7 +628,6 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
|
||||
mLegendLayersBoldChkBx->setChecked( mSettings->value( QStringLiteral( "/qgis/legendLayersBold" ), true ).toBool() );
|
||||
mLegendGroupsBoldChkBx->setChecked( mSettings->value( QStringLiteral( "/qgis/legendGroupsBold" ), false ).toBool() );
|
||||
cbxHideSplash->setChecked( mSettings->value( QStringLiteral( "/qgis/hideSplash" ), false ).toBool() );
|
||||
cbxShowTips->setChecked( mSettings->value( QStringLiteral( "/qgis/showTips%1" ).arg( Qgis::QGIS_VERSION_INT / 100 ), true ).toBool() );
|
||||
mDataSourceManagerNonModal->setChecked( mSettings->value( "/qgis/dataSourceManagerNonModal", false ).toBool() );
|
||||
cbxCheckVersion->setChecked( mSettings->value( QStringLiteral( "/qgis/checkVersion" ), true ).toBool() );
|
||||
cbxAttributeTableDocked->setChecked( mSettings->value( QStringLiteral( "/qgis/dockAttributeTable" ), false ).toBool() );
|
||||
@ -1209,7 +1208,6 @@ void QgsOptions::saveOptions()
|
||||
bool legendGroupsBold = mSettings->value( QStringLiteral( "/qgis/legendGroupsBold" ), false ).toBool();
|
||||
mSettings->setValue( QStringLiteral( "/qgis/legendGroupsBold" ), mLegendGroupsBoldChkBx->isChecked() );
|
||||
mSettings->setValue( QStringLiteral( "/qgis/hideSplash" ), cbxHideSplash->isChecked() );
|
||||
mSettings->setValue( QStringLiteral( "/qgis/showTips%1" ).arg( Qgis::QGIS_VERSION_INT / 100 ), cbxShowTips->isChecked() );
|
||||
mSettings->setValue( QStringLiteral( "/qgis/dataSourceManagerNonModal" ), mDataSourceManagerNonModal->isChecked() );
|
||||
mSettings->setValue( QStringLiteral( "/qgis/checkVersion" ), cbxCheckVersion->isChecked() );
|
||||
mSettings->setValue( QStringLiteral( "/qgis/dockAttributeTable" ), cbxAttributeTableDocked->isChecked() );
|
||||
|
@ -1,59 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgstip.h
|
||||
---------------------
|
||||
begin : February 2011
|
||||
copyright : (C) 2011 by Tim Sutton
|
||||
email : tim at linfiniti 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSTIP
|
||||
#define QGSTIP
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include "qgis_app.h"
|
||||
|
||||
/** \ingroup app
|
||||
* \brief An QgsTip represents a tip generated by the
|
||||
* QgsTipFactory factory class to serve up tips to the user.
|
||||
* Tips can be generic, in which case they make no mention of
|
||||
* gui dialogs etc, or gui-specific in which case they may allude
|
||||
* to features of the graphical user interface.
|
||||
* \see also QgsTipOfTheDay, QgsTipFactory
|
||||
*/
|
||||
|
||||
class APP_EXPORT QgsTip
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
QgsTip() {}
|
||||
//! Destructor
|
||||
~QgsTip() {}
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
//! Get the tip title
|
||||
QString title() {return mTitle;}
|
||||
//! Get the tip content
|
||||
QString content() {return mContent;}
|
||||
|
||||
//
|
||||
// Mutators
|
||||
//
|
||||
//! Set the tip title
|
||||
void setTitle( const QString &title ) {mTitle = title;}
|
||||
//! Set the tip content
|
||||
void setContent( const QString &content ) {mContent = content;}
|
||||
private:
|
||||
QString mTitle;
|
||||
QString mContent;
|
||||
};
|
||||
|
||||
#endif //QGSTIP
|
||||
|
@ -1,362 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgstipfactory.cpp
|
||||
---------------------
|
||||
begin : February 2011
|
||||
copyright : (C) 2007 by Tim Sutton
|
||||
email : tim at linfiniti 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgstipfactory.h"
|
||||
#include <QTime>
|
||||
//for rand & srand
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
QgsTipFactory::QgsTipFactory() : QObject()
|
||||
{
|
||||
// I'm just doing this in a simple way so
|
||||
// its easy for translators...later
|
||||
// it its worth the time I'll move this data
|
||||
// into a sqlite database...
|
||||
QgsTip myTip;
|
||||
myTip.setTitle( tr( "QGIS is open source" ) );
|
||||
myTip.setContent( tr( "QGIS is open source software."
|
||||
" This means that the software source code can be freely viewed"
|
||||
" and modified. The GPL places a restriction that any modifications"
|
||||
" you make must be made available in source form to whoever you give"
|
||||
" modified versions to, and that you can not create a new version of"
|
||||
" QGIS under a 'closed source' license. Visit"
|
||||
" <a href=\"https://qgis.org\"> the QGIS home page</a>"
|
||||
" for more information."
|
||||
) );
|
||||
addGenericTip( myTip );
|
||||
//
|
||||
myTip.setTitle( tr( "QGIS Publications" ) );
|
||||
myTip.setContent( tr( "If you write a scientific paper or any other article"
|
||||
" that refers to QGIS we would love to include your work"
|
||||
" in the <a href=\"https://qgis.org/en/site/about/case_studies/index.html\">case studies section</a> of"
|
||||
" the QGIS home page."
|
||||
) );
|
||||
addGenericTip( myTip );
|
||||
myTip.setTitle( tr( "Become a QGIS translator" ) );
|
||||
myTip.setContent( tr( "Would you like to see QGIS"
|
||||
" in your native language? We are looking for more translators"
|
||||
" and would appreciate your help! The translation process is"
|
||||
" fairly straight forward - instructions are available in the"
|
||||
" QGIS wiki"
|
||||
" <a href=\"https://qgis.org/en/site/getinvolved/translate.html#howto-translate-gui\">translator's page.</a>"
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
myTip.setTitle( tr( "Getting Help With QGIS" ) );
|
||||
myTip.setContent( tr( "If you need help using QGIS"
|
||||
" there is a 'users' mailing list where users help each other with issues"
|
||||
" related to using QGIS. We also have a 'developers' mailing list"
|
||||
" for those wanting help and discuss things relating to the QGIS code base."
|
||||
" Details on different means to get help are described in the"
|
||||
" <a href=\"https://qgis.org/en/site/forusers/support.html#mailing-lists\">community section</a> of the QGIS home page."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
myTip.setTitle( tr( "Is it 'QGIS' or 'Quantum GIS'?" ) );
|
||||
myTip.setContent( tr( "Both used to be correct, but we recently decided to just use 'QGIS'. For articles we suggest you write 'QGIS is ....'"
|
||||
) );
|
||||
addGenericTip( myTip );
|
||||
myTip.setTitle( tr( "How do I refer to QGIS?" ) );
|
||||
myTip.setContent( tr( "QGIS is spelled in all caps."
|
||||
" We have various subprojects of the QGIS project"
|
||||
" and it will help to avoid confusion if you refer to each by"
|
||||
" its name:"
|
||||
"<ul>"
|
||||
"<li><strong>QGIS Library</strong> - this is the C++ library that contains"
|
||||
" the core logic that is used to build the QGIS user interface and other applications.</li>"
|
||||
"<li><strong>QGIS Desktop</strong> - this is the desktop application that you know and love so much :-).</li>"
|
||||
"<li><strong>QGIS Server</strong> - this is a server-side application based on the QGIS Library"
|
||||
" that will serve up your .qgs projects using OGC standard protocols.</li>"
|
||||
"</ul>"
|
||||
) );
|
||||
addGenericTip( myTip );
|
||||
// This tip contributed by Andreas Neumann
|
||||
myTip.setTitle( tr( "Add the current date to a map layout" ) );
|
||||
myTip.setContent( tr( "You can add a current date variable to your map"
|
||||
" layout. Create a regular text label and add the string"
|
||||
" $CURRENT_DATE(yyyy-MM-dd) to the text box. See the"
|
||||
" <a href=\"https://doc.qt.io/qt-5.3/qdate.html#toString\">"
|
||||
"QDate::toString format documentation</a> for the possible date formats."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
myTip.setTitle( tr( "Moving Elements and Maps in the Print Composer" ) );
|
||||
myTip.setContent( tr( "In the print composer toolbar you can find two buttons for moving"
|
||||
" elements. The first one ( <img src=\":/images/themes/default/mActionSelect.svg\"/> )"
|
||||
" selects and moves elements in the layout. After selecting the element"
|
||||
" with this tool you can also move them around with the arrow keys."
|
||||
" For accurate positioning use the <strong>%1</strong> section,"
|
||||
" which can be found in the tab <strong>%2</strong>."
|
||||
" The other move tool ( <img src=\":/images/themes/default/mActionMoveItemContent.svg\"/> )"
|
||||
" allows you to move the map content within a map frame." )
|
||||
.arg( tr( "Position and Size" ) )
|
||||
.arg( tr( "Item Properties" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
addGuiTip( myTip );
|
||||
// This tip contributed by Andreas Neumann
|
||||
myTip.setTitle( tr( "Lock an item in the layout view" ) );
|
||||
myTip.setContent( tr( "Locking an element in the layout view prevents you to select or accidentally"
|
||||
" move it with the mouse. Locking an item is done by checking its"
|
||||
" <img src=\":/images/themes/default/locked.svg\"/> state in the"
|
||||
" <strong>%1</strong> tab. While in a locked state, you can still get it"
|
||||
" selected from the <strong>%1</strong> tab, and configure any of its"
|
||||
" properties in the <strong>%2</strong> tab, including precisely setting"
|
||||
" its position and size." )
|
||||
.arg( tr( "Items" ) )
|
||||
.arg( tr( "Item Properties" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
// This tip contributed by Andreas Neumann
|
||||
myTip.setTitle( tr( "Rotating a map and linking a north arrow" ) );
|
||||
myTip.setContent( tr( "In the Print Composer you can rotate a map by setting its rotation value"
|
||||
" in the tab <strong>Item Properties -> Map -> Main properties</strong> section."
|
||||
" To place a north arrow in your layout you can use the"
|
||||
" <strong>%1</strong> tool. After the selection and"
|
||||
" placement of the north arrow in the layout you can link it"
|
||||
" with a specific map frame by activating the <strong>%2</strong>"
|
||||
" checkbox and selecting a map frame. Whenever you change the rotation"
|
||||
" value of a linked map, the north arrow will now automatically adjust"
|
||||
" its rotation." )
|
||||
.arg( tr( "Add Image" ) )
|
||||
.arg( tr( "Sync with map" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
addGuiTip( myTip );
|
||||
// This tip contributed by Andreas Neumann
|
||||
myTip.setTitle( tr( "Numeric scale value in map layout linked to map frame" ) );
|
||||
myTip.setContent( tr( "If you want to place a text label as a placeholder for the"
|
||||
" current scale, linked to a map frame, you need to place a scalebar and"
|
||||
" set the style to 'Numeric'. You also need to select the map frame, if there"
|
||||
" is more than one."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by Tim
|
||||
myTip.setTitle( tr( "Using the mouse scroll wheel" ) );
|
||||
myTip.setContent( tr( "You can use the scroll wheel on your mouse to zoom in,"
|
||||
" out and pan the map. Scroll forwards to zoom in, scroll backwards to"
|
||||
" zoom out and press and hold the scroll wheel down to pan the map. You"
|
||||
" can configure the zoom scale factor in the <strong> %1 -> %2 </strong> panel." )
|
||||
.arg( tr( "Options" ) )
|
||||
.arg( tr( "Map tools" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
addGuiTip( myTip );
|
||||
// by Tim
|
||||
myTip.setTitle( tr( "Disabling rendering" ) );
|
||||
myTip.setContent( tr( "Sometimes you have a very large dataset which takes ages"
|
||||
" to draw. If you are going to be performing several"
|
||||
" actions (e.g. modifying symbology options) and wish to temporarily"
|
||||
" disable map rendering while you do so, you can uncheck the 'Render'"
|
||||
" checkbox in the bottom right of the status bar. Don't forget to check"
|
||||
" it on again when you are ready to have the map draw itself again!"
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// Tip contributed by Alister Hood
|
||||
myTip.setTitle( tr( "Join intersected polylines when rendering" ) );
|
||||
myTip.setContent( tr( "When applying layered styles to a polyline layer, you can join"
|
||||
" intersecting lines together simply by enabling symbol levels."
|
||||
" The image below shows a before (left) and after (right) view of"
|
||||
" an intersection when symbol levels are enabled." ) +
|
||||
QStringLiteral( "<p><center><img src=\":/images/tips/symbol_levels.png\"/></center></p>" )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
// by Tim
|
||||
myTip.setTitle( tr( "Auto-enable on the fly projection" ) );
|
||||
myTip.setContent( tr( "In the options dialog, under the CRS tab, you can set QGIS so that"
|
||||
" whenever you create a new project, 'on the fly projection' is enabled"
|
||||
" automatically and a pre-selected Coordinate Reference System of your"
|
||||
" choice is used."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by Tim
|
||||
myTip.setTitle( tr( "Sponsor QGIS" ) );
|
||||
myTip.setContent( tr( "If QGIS is saving you money or you like our work and"
|
||||
" have the financial ability to help, please consider sponsoring the"
|
||||
" development of QGIS. We use money from sponsors to pay for"
|
||||
" travel and costs related to our regular hackfest meetings, and to generally"
|
||||
" support the goals of our project. Please see the <a"
|
||||
" href=\"https://qgis.org/en/site/getinvolved/governance/sponsorship/sponsorship.html\">QGIS Sponsorship Web"
|
||||
" Page</a> for more details."
|
||||
) );
|
||||
addGenericTip( myTip );
|
||||
// by gsherman
|
||||
myTip.setTitle( tr( "QGIS has Plugins!" ) );
|
||||
myTip.setContent( tr( "QGIS has plugins that extend its functionality."
|
||||
" QGIS ships with some core plugins you can explore from the"
|
||||
" <strong> %1 -> %2</strong> menu. In addition there"
|
||||
" are a lot of <a href=\"https://plugins.qgis.org/\">Python plugins </a>"
|
||||
" contributed by the user community that can be"
|
||||
" installed via this same menu. Don't miss out on all QGIS has to offer!"
|
||||
" Check out the plugins and see what they can do for you." )
|
||||
.arg( tr( "Plugins" ) )
|
||||
.arg( tr( "Manage and Install Plugins..." ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
addGenericTip( myTip );
|
||||
// by yjacolin
|
||||
myTip.setTitle( tr( "Add an action to layer" ) );
|
||||
myTip.setContent( tr( "Action in a layer allows user to trigger action when clicking on a geometry"
|
||||
" with 'Run Feature Action' tools."
|
||||
"For example, you can open a HTML page using the field value of the geometry "
|
||||
"as a parameter. Look at the <a href=\"https://docs.qgis.org/latest/en/docs/user_manual/working_with_vector/vector_properties.html?#actions-menu\">documentation</a>."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by yjacolin
|
||||
myTip.setTitle( tr( "Copy, paste and cut in QGIS" ) );
|
||||
myTip.setContent( tr( "Copy, paste, and cut work as in another applications in QGIS. Select a "
|
||||
"feature (a geometry or an attribute row in the attribute table) and use "
|
||||
"one of these shortcuts: Ctrl+C to copy, Ctrl+X to cut, and Ctrl+V to paste."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by yjacolin
|
||||
myTip.setTitle( tr( "Right click with identify tools" ) );
|
||||
myTip.setContent( tr( "Right click with the identify tool to show a context menu from which you can "
|
||||
"choose the layer in which to identify a feature. A sub-menu will list features "
|
||||
"identified and a third sub-menu will show the action link setup for the layer. "
|
||||
"If one of this sub-menu doesn't contain any information, the next sub-menu "
|
||||
"will appear instead. For example, if you have just one layer, and click "
|
||||
"somewhere with several features, the first menu will list the features "
|
||||
"instead of layer list."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by Alister Hood
|
||||
myTip.setTitle( tr( "Use VRT files" ) );
|
||||
myTip.setContent( tr( "If you have a number of aerial photos spread across a wide area, instead of "
|
||||
"loading each file as a separate layer you can treat them all as a single layer "
|
||||
"by using a .vrt file. "
|
||||
"To create a .vrt, go to <strong> %1 -> %2 -> %3</strong>." )
|
||||
.arg( tr( "Raster" ) )
|
||||
.arg( tr( "Miscellaneous" ) )
|
||||
.arg( tr( "Build Virtual Raster (Catalog)" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
// by Harrissou Sant-anna
|
||||
myTip.setTitle( tr( "Switch quickly between different styles of the layer" ) );
|
||||
myTip.setContent( tr( "From the Layer properties dialog, use the <strong>Styles -> Add</strong> combobox"
|
||||
" to create as many combinations of layer properties settings (symbology, labeling,"
|
||||
" diagram, fields form, actions...) as you want. Then, simply switch between styles"
|
||||
" from the context menu of the layer in <strong>%1</strong> to automatically"
|
||||
" get different custom representations of your data." )
|
||||
.arg( tr( "Layers Panel" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
// by Harrissou Sant-anna
|
||||
myTip.setTitle( tr( "Live update rendering" ) );
|
||||
myTip.setContent( tr( "Press F7 to activate the <strong>%1</strong> panel from which you can"
|
||||
" easily and quickly configure the layer rendering. Check the <strong>%2</strong>"
|
||||
" option to automatically apply to the map canvas each of your modifications." )
|
||||
.arg( tr( "Layer Styling" ) )
|
||||
.arg( tr( "Live update" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
// by Harrissou Sant-anna
|
||||
myTip.setTitle( tr( "Print or export a specific feature from an atlas composition" ) );
|
||||
myTip.setContent( tr( "If you want to print or export the composition of only one feature of the atlas,"
|
||||
" start the atlas preview, select the desired feature in the drop-down list"
|
||||
" and click on <strong>Composer -> Print</strong> menu (or use <strong>Composer ->"
|
||||
" Export...</strong> to any supported file format)."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by Harrissou Sant-anna
|
||||
myTip.setTitle( tr( "Start QGIS from command line" ) );
|
||||
myTip.setContent( tr( "QGIS can be launched from command line and supports a number of options. This can be"
|
||||
" handy if you need to use QGIS with particular configurations such as custom"
|
||||
" user profile or, without plugins... To get the list of the options,"
|
||||
" enter qgis --help on the command line."
|
||||
) );
|
||||
addGuiTip( myTip );
|
||||
// by Harrissou Sant-anna
|
||||
myTip.setTitle( tr( "Set your own shortcuts for your actions" ) );
|
||||
myTip.setContent( tr( "QGIS provides you with a list of predefined shortcuts you can use to speed"
|
||||
" your workflow. These are available under <strong> %1 -> %2 </strong>"
|
||||
" menu and can be extended and customized for any dialog or tool." )
|
||||
.arg( tr( "Settings" ) )
|
||||
.arg( tr( "Keyboard Shortcuts" ) )
|
||||
);
|
||||
addGuiTip( myTip );
|
||||
|
||||
/* Template for adding more tips
|
||||
myTip.setTitle(tr(""));
|
||||
myTip.setContent(tr(""
|
||||
));
|
||||
addGuiTip(myTip);
|
||||
*/
|
||||
}
|
||||
|
||||
QgsTipFactory::~QgsTipFactory()
|
||||
{
|
||||
|
||||
}
|
||||
//private helper method
|
||||
void QgsTipFactory::addGuiTip( const QgsTip &tip )
|
||||
{
|
||||
mGuiTips << tip;
|
||||
mAllTips << tip;
|
||||
}
|
||||
//private helper method
|
||||
void QgsTipFactory::addGenericTip( const QgsTip &tip )
|
||||
{
|
||||
mGenericTips << tip;
|
||||
mAllTips << tip;
|
||||
}
|
||||
QgsTip QgsTipFactory::getTip()
|
||||
{
|
||||
int myRand = qrand();
|
||||
int myValue = static_cast<int>( myRand % mAllTips.count() ); //range [0,(count-1)]
|
||||
QgsTip myTip = mAllTips.at( myValue );
|
||||
return myTip;
|
||||
}
|
||||
QgsTip QgsTipFactory::getTip( int position )
|
||||
{
|
||||
QgsTip myTip = mAllTips.at( position );
|
||||
return myTip;
|
||||
}
|
||||
QgsTip QgsTipFactory::getGenericTip()
|
||||
{
|
||||
int myRand = qrand();
|
||||
int myValue = static_cast<int>( myRand % mGenericTips.count() ); //range [0,(count-1)]
|
||||
QgsTip myTip = mGenericTips.at( myValue );
|
||||
return myTip;
|
||||
}
|
||||
QgsTip QgsTipFactory::getGuiTip()
|
||||
{
|
||||
int myRand = qrand();
|
||||
int myValue = static_cast<int>( myRand % mGuiTips.count() ); //range [0,(count-1)]
|
||||
QgsTip myTip = mGuiTips.at( myValue );
|
||||
return myTip;
|
||||
}
|
||||
|
||||
int QgsTipFactory::randomNumber( int max )
|
||||
{
|
||||
Q_UNUSED( max );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsTipFactory::position( QgsTip tip )
|
||||
{
|
||||
for ( int i = 0; i < mAllTips.count(); ++i )
|
||||
{
|
||||
QgsTip myTip = mAllTips.at( i );
|
||||
if ( myTip.title() == tip.title() )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int QgsTipFactory::count()
|
||||
{
|
||||
return mAllTips.count();
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgstipfactory.h
|
||||
---------------------
|
||||
begin : February 2011
|
||||
copyright : (C) 2011 by Tim Sutton
|
||||
email : tim at linfiniti 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSTIPFACTORY
|
||||
#define QGSTIPFACTORY
|
||||
|
||||
#include "qgstip.h"
|
||||
#include <QList>
|
||||
#include "qgis_app.h"
|
||||
|
||||
/** \ingroup app
|
||||
* \brief A factory class to serve up tips to the user.
|
||||
* Tips can be generic, in which case they make no mention of
|
||||
* gui dialogs etc, or gui-specific in which case they may allude
|
||||
* to features of the graphical user interface.
|
||||
* \see also QgsTipOfTheDay, QgsTip
|
||||
*/
|
||||
|
||||
class APP_EXPORT QgsTipFactory : public QObject
|
||||
{
|
||||
Q_OBJECT //used for tr() so we don't need to do QObject::tr()
|
||||
public:
|
||||
//! Constructor
|
||||
QgsTipFactory();
|
||||
|
||||
~QgsTipFactory();
|
||||
|
||||
/** Get a random tip (generic or gui-centric)
|
||||
* \returns An QgsTip containing the tip
|
||||
*/
|
||||
QgsTip getTip();
|
||||
|
||||
/** Get a specific tip (generic or gui-centric).
|
||||
* \param position The tip returned will be based on the
|
||||
* number passed in as position. If the
|
||||
* position is invalid, an empty string will be
|
||||
* returned.
|
||||
* \returns An QgsTip containing the tip
|
||||
*/
|
||||
QgsTip getTip( int position );
|
||||
|
||||
/** Get a random generic tip
|
||||
* \returns An QgsTip containing the tip
|
||||
*/
|
||||
QgsTip getGenericTip();
|
||||
|
||||
/** Get a random gui-centric tip
|
||||
* \returns An QgsTip containing the tip
|
||||
*/
|
||||
QgsTip getGuiTip();
|
||||
|
||||
int position( QgsTip );
|
||||
int count();
|
||||
|
||||
private:
|
||||
void addGenericTip( const QgsTip & );
|
||||
void addGuiTip( const QgsTip & );
|
||||
int randomNumber( int max );
|
||||
//@TODO move tipts into a sqlite db
|
||||
QList <QgsTip> mGenericTips;
|
||||
QList <QgsTip> mGuiTips;
|
||||
QList <QgsTip> mAllTips;
|
||||
};
|
||||
#endif //QGSTIPFACTORY
|
||||
|
@ -1,108 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgstipgui.cpp - description
|
||||
-------------------
|
||||
begin : Sat Aug 10 2002
|
||||
copyright : (C) 2002 by Gary E.Sherman
|
||||
email : sherman at mrcc.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
#include "qgstipgui.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgstip.h"
|
||||
#include "qgstipfactory.h"
|
||||
|
||||
#ifdef Q_OS_MACX
|
||||
QgsTipGui::QgsTipGui( QWidget *parent )
|
||||
: QDialog( parent, Qt::WindowSystemMenuHint ) // Dialog with close button only
|
||||
#else
|
||||
QgsTipGui::QgsTipGui( QWidget * parent )
|
||||
: QDialog( parent ) // Normal dialog in non Mac-OS
|
||||
#endif
|
||||
{
|
||||
setupUi( this );
|
||||
init();
|
||||
}
|
||||
|
||||
QgsTipGui::~QgsTipGui()
|
||||
{
|
||||
}
|
||||
|
||||
void QgsTipGui::init()
|
||||
{
|
||||
|
||||
QgsTipFactory myFactory;
|
||||
QgsTip myTip = myFactory.getTip();
|
||||
mTipPosition = myFactory.position( myTip );
|
||||
|
||||
showTip( myTip );
|
||||
|
||||
QPushButton *pb = nullptr;
|
||||
pb = new QPushButton( tr( "&Previous" ) );
|
||||
connect( pb, &QAbstractButton::clicked, this, &QgsTipGui::prevClicked );
|
||||
buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
|
||||
|
||||
pb = new QPushButton( tr( "&Next" ) );
|
||||
connect( pb, &QAbstractButton::clicked, this, &QgsTipGui::nextClicked );
|
||||
buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
|
||||
}
|
||||
|
||||
void QgsTipGui::showTip( QgsTip myTip )
|
||||
{
|
||||
// TODO - This html construction can be simplified using QStringBuilder
|
||||
// once Qt 4.6 is the minimum required version for building QGIS.
|
||||
//
|
||||
QString content = "<img src='"
|
||||
+ QgsApplication::appIconPath()
|
||||
+ "' style='float:left;'>"
|
||||
+ "<h2>"
|
||||
+ myTip.title()
|
||||
+ "</h2><br clear='all'/>"
|
||||
+ myTip.content();
|
||||
|
||||
txtTip->setHtml( content );
|
||||
}
|
||||
|
||||
void QgsTipGui::on_cbxDisableTips_toggled( bool flag )
|
||||
{
|
||||
QgsSettings settings;
|
||||
//note the ! below as when the cbx is checked (true) we want to
|
||||
//change the setting to false
|
||||
settings.setValue( QStringLiteral( "/qgis/showTips%1" ).arg( Qgis::QGIS_VERSION_INT / 100 ), !flag );
|
||||
hide();
|
||||
}
|
||||
|
||||
void QgsTipGui::nextClicked()
|
||||
{
|
||||
mTipPosition += 1;
|
||||
QgsTipFactory myFactory;
|
||||
if ( mTipPosition >= myFactory.count() )
|
||||
{
|
||||
mTipPosition = 0;
|
||||
}
|
||||
QgsTip myTip = myFactory.getTip( mTipPosition );
|
||||
showTip( myTip );
|
||||
}
|
||||
|
||||
void QgsTipGui::prevClicked()
|
||||
{
|
||||
mTipPosition -= 1;
|
||||
QgsTipFactory myFactory;
|
||||
if ( mTipPosition < 0 )
|
||||
{
|
||||
mTipPosition = myFactory.count() - 1;
|
||||
}
|
||||
QgsTip myTip = myFactory.getTip( mTipPosition );
|
||||
showTip( myTip );
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgstipgui.h - description
|
||||
-------------------
|
||||
begin : Fri 18 Feb 2011
|
||||
copyright : (C) 2011 by Tim Sutton
|
||||
email : tim@linfiniti.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSTIPGUI_H
|
||||
#define QGSTIPGUI_H
|
||||
|
||||
#include "ui_qgstipguibase.h"
|
||||
#include "qgis_app.h"
|
||||
class QgsTip;
|
||||
|
||||
class APP_EXPORT QgsTipGui : public QDialog, private Ui::QgsTipGuiBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsTipGui( QWidget *parent = nullptr );
|
||||
~QgsTipGui();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void showTip( QgsTip );
|
||||
|
||||
int mTipPosition;
|
||||
|
||||
private slots:
|
||||
void on_cbxDisableTips_toggled( bool flag );
|
||||
void prevClicked();
|
||||
void nextClicked();
|
||||
};
|
||||
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
#include "qgsprocessingoutputs.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include <functional>
|
||||
|
||||
bool QgsProcessingParameters::isDynamic( const QVariantMap ¶meters, const QString &name )
|
||||
{
|
||||
@ -596,33 +597,38 @@ QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsPro
|
||||
|
||||
QStringList resultStringList;
|
||||
|
||||
if ( val.canConvert<QgsProperty>() )
|
||||
resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
|
||||
else if ( val.type() == QVariant::List )
|
||||
std::function< void( const QVariant &var ) > processVariant;
|
||||
processVariant = [ &resultStringList, &layers, &context, &definition, &processVariant ]( const QVariant & var )
|
||||
{
|
||||
Q_FOREACH ( const QVariant &var, val.toList() )
|
||||
if ( var.type() == QVariant::List )
|
||||
{
|
||||
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
|
||||
Q_FOREACH ( const QVariant &listVar, var.toList() )
|
||||
{
|
||||
layers << layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultStringList << var.toString();
|
||||
processVariant( listVar );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( val.type() == QVariant::StringList )
|
||||
{
|
||||
Q_FOREACH ( const QString &s, val.toStringList() )
|
||||
else if ( var.type() == QVariant::StringList )
|
||||
{
|
||||
resultStringList << s;
|
||||
Q_FOREACH ( const QString &s, var.toStringList() )
|
||||
{
|
||||
resultStringList << s;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
resultStringList << val.toString();
|
||||
else if ( var.canConvert<QgsProperty>() )
|
||||
resultStringList << var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
|
||||
else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
|
||||
{
|
||||
layers << layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultStringList << var.toString();
|
||||
}
|
||||
};
|
||||
|
||||
if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
|
||||
processVariant( val );
|
||||
|
||||
if ( layers.isEmpty() && ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
|
||||
{
|
||||
resultStringList.clear();
|
||||
// check default
|
||||
|
@ -614,21 +614,6 @@ QString QgsApplication::licenceFilePath()
|
||||
return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/LICENSE" );
|
||||
}
|
||||
|
||||
QString QgsApplication::helpAppPath()
|
||||
{
|
||||
QString helpAppPath;
|
||||
#ifdef Q_OS_MACX
|
||||
helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
|
||||
#else
|
||||
helpAppPath = libexecPath();
|
||||
#endif
|
||||
helpAppPath += QLatin1String( "/qgis_help" );
|
||||
#ifdef Q_OS_WIN
|
||||
helpAppPath += ".exe";
|
||||
#endif
|
||||
return helpAppPath;
|
||||
}
|
||||
|
||||
QString QgsApplication::i18nPath()
|
||||
{
|
||||
if ( ABISYM( mRunningFromBuildDir ) )
|
||||
|
@ -234,9 +234,6 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
*/
|
||||
static QString licenceFilePath();
|
||||
|
||||
//! Returns the path to the help application.
|
||||
static QString helpAppPath();
|
||||
|
||||
//! Returns the path to the translation directory.
|
||||
static QString i18nPath();
|
||||
|
||||
|
@ -20,13 +20,18 @@
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsogrprovider.h"
|
||||
#include "qgsnewgeopackagelayerdialog.h"
|
||||
#include "qgsmessageoutput.h"
|
||||
#include "qgsvectorlayerexporter.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
|
||||
QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );
|
||||
|
||||
QgsDataItem *QgsGeoPackageDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
|
||||
{
|
||||
QgsDebugMsg( "path = " + path );
|
||||
@ -268,6 +273,115 @@ QList<QAction *> QgsGeoPackageConnectionItem::actions()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAction )
|
||||
{
|
||||
|
||||
if ( !QgsMimeDataUtils::isUriList( data ) )
|
||||
return false;
|
||||
|
||||
// TODO: probably should show a GUI with settings etc
|
||||
QString uri;
|
||||
|
||||
QStringList importResults;
|
||||
bool hasError = false;
|
||||
|
||||
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
|
||||
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
|
||||
{
|
||||
if ( u.layerType == QStringLiteral( "vector" ) )
|
||||
{
|
||||
// open the source layer
|
||||
bool owner;
|
||||
QString error;
|
||||
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error );
|
||||
if ( !srcLayer )
|
||||
{
|
||||
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( srcLayer->isValid() )
|
||||
{
|
||||
uri = mPath;
|
||||
QgsDebugMsgLevel( "URI " + uri, 3 );
|
||||
|
||||
// check if the destination layer already exists
|
||||
bool exists = false;
|
||||
// Q_FOREACH won't detach ...
|
||||
for ( const auto child : children() )
|
||||
{
|
||||
if ( child->name() == u.name )
|
||||
{
|
||||
exists = true;
|
||||
}
|
||||
}
|
||||
if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ),
|
||||
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
|
||||
{
|
||||
|
||||
std::unique_ptr< QMap<QString, QVariant> > options( new QMap<QString, QVariant> );
|
||||
options->insert( QStringLiteral( "driverName" ), QStringLiteral( "GPKG" ) );
|
||||
options->insert( QStringLiteral( "update" ), true );
|
||||
options->insert( QStringLiteral( "overwrite" ), true );
|
||||
options->insert( QStringLiteral( "layerName" ), u.name );
|
||||
|
||||
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri, QStringLiteral( "ogr" ), srcLayer->crs(), options.get(), owner ) );
|
||||
|
||||
// when export is successful:
|
||||
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
|
||||
{
|
||||
// this is gross - TODO - find a way to get access to messageBar from data items
|
||||
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
|
||||
refreshConnections();
|
||||
} );
|
||||
|
||||
// when an error occurs:
|
||||
connect( exportTask.get(), &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
|
||||
{
|
||||
if ( error != QgsVectorLayerExporter::ErrUserCanceled )
|
||||
{
|
||||
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
|
||||
output->setTitle( tr( "Import to GeoPackage database" ) );
|
||||
output->setMessage( tr( "Failed to import some layers!\n\n" ) + errorMessage, QgsMessageOutput::MessageText );
|
||||
output->showMessage();
|
||||
}
|
||||
} );
|
||||
|
||||
QgsApplication::taskManager()->addTask( exportTask.release() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) );
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: implemnent raster import
|
||||
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
|
||||
output->setTitle( tr( "Import to GeoPackage database faile" ) );
|
||||
output->setMessage( tr( "Failed to import some layers!\n\n" ) + QStringLiteral( "Raster import is not yet implemented!\n" ), QgsMessageOutput::MessageText );
|
||||
output->showMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( hasError )
|
||||
{
|
||||
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
|
||||
output->setTitle( tr( "Import to GeoPackage database" ) );
|
||||
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
|
||||
output->showMessage();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QgsLayerItem::LayerType QgsGeoPackageConnectionItem::layerTypeFromDb( const QString &geometryType )
|
||||
{
|
||||
if ( geometryType.contains( QStringLiteral( "Point" ), Qt::CaseInsensitive ) )
|
||||
@ -327,7 +441,6 @@ void QgsGeoPackageConnectionItem::addTable()
|
||||
QList<QAction *> QgsGeoPackageAbstractLayerItem::actions()
|
||||
{
|
||||
QList<QAction *> lst;
|
||||
|
||||
// TODO: delete layer when the provider supports it (not currently implemented)
|
||||
return lst;
|
||||
}
|
||||
@ -352,3 +465,55 @@ QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent,
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
QList<QAction *> QgsGeoPackageVectorLayerItem::actions()
|
||||
{
|
||||
QList<QAction *> lst = QgsGeoPackageAbstractLayerItem::actions();
|
||||
QAction *actionDeleteLayer = new QAction( tr( "Delete layer '%1'..." ).arg( mName ), this );
|
||||
connect( actionDeleteLayer, &QAction::triggered, this, &QgsGeoPackageVectorLayerItem::deleteLayer );
|
||||
lst.append( actionDeleteLayer );
|
||||
return lst;
|
||||
}
|
||||
|
||||
|
||||
void QgsGeoPackageVectorLayerItem::deleteLayer()
|
||||
{
|
||||
// Check if the layer is in the registry
|
||||
const QgsMapLayer *projectLayer = nullptr;
|
||||
Q_FOREACH ( const QgsMapLayer *layer, QgsProject::instance()->mapLayers() )
|
||||
{
|
||||
if ( layer->publicSource() == mUri )
|
||||
{
|
||||
projectLayer = layer;
|
||||
}
|
||||
}
|
||||
if ( ! projectLayer )
|
||||
{
|
||||
if ( QMessageBox::question( nullptr, QObject::tr( "Delete Layer" ),
|
||||
QObject::tr( "Are you sure you want to delete layer '%1' from GeoPackage?" ).arg( mName ),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
|
||||
return;
|
||||
|
||||
QString errCause;
|
||||
bool res = ::deleteLayer( mUri, errCause );
|
||||
if ( !res )
|
||||
{
|
||||
QMessageBox::warning( nullptr, tr( "Delete Layer" ), errCause );
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information( nullptr, tr( "Delete Layer" ), tr( "Layer deleted successfully." ) );
|
||||
if ( mParent )
|
||||
mParent->refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning( nullptr, QObject::tr( "Delete Layer" ), QObject::tr( "The layer '%1' cannot be deleted because it is in the current project as '%2',"
|
||||
" remove it from the project and retry." ).arg( mName, projectLayer->name() ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -49,7 +49,11 @@ class QgsGeoPackageVectorLayerItem : public QgsGeoPackageAbstractLayerItem
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGeoPackageVectorLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType );
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
QList<QAction *> actions() override;
|
||||
public slots:
|
||||
void deleteLayer();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -67,7 +71,7 @@ class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
|
||||
#endif
|
||||
|
||||
virtual bool acceptDrop() override { return true; }
|
||||
//virtual bool handleDrop( const QMimeData *data, Qt::DropAction action ) override;
|
||||
virtual bool handleDrop( const QMimeData *data, Qt::DropAction action ) override;
|
||||
|
||||
//! Return the layer type from \a geometryType
|
||||
static QgsLayerItem::LayerType layerTypeFromDb( const QString &geometryType );
|
||||
|
@ -18,10 +18,12 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsproject.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
#include <QAction>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <ogr_srs_api.h>
|
||||
#include <cpl_error.h>
|
||||
@ -31,11 +33,14 @@
|
||||
QGISEXTERN QStringList fileExtensions();
|
||||
QGISEXTERN QStringList wildcards();
|
||||
|
||||
QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );
|
||||
|
||||
|
||||
QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem *parent,
|
||||
QString name, QString path, QString uri, LayerType layerType )
|
||||
QString name, QString path, QString uri, LayerType layerType, bool isSubLayer )
|
||||
: QgsLayerItem( parent, name, path, uri, layerType, QStringLiteral( "ogr" ) )
|
||||
{
|
||||
mIsSubLayer = isSubLayer;
|
||||
mToolTip = uri;
|
||||
setState( Populated ); // children are not expected
|
||||
|
||||
@ -56,6 +61,7 @@ QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem *parent,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool QgsOgrLayerItem::setCrs( const QgsCoordinateReferenceSystem &crs )
|
||||
{
|
||||
if ( !( mCapabilities & SetCrs ) )
|
||||
@ -110,9 +116,71 @@ QString QgsOgrLayerItem::layerName() const
|
||||
return info.completeBaseName();
|
||||
}
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
QList<QAction *> QgsOgrLayerItem::actions()
|
||||
{
|
||||
QList<QAction *> lst;
|
||||
// Messages are different for files and tables
|
||||
QString message = mIsSubLayer ? QObject::tr( "Delete layer '%1'..." ).arg( mName ) : QObject::tr( "Delete file '%1'..." ).arg( mUri );
|
||||
QAction *actionDeleteLayer = new QAction( message, this );
|
||||
connect( actionDeleteLayer, &QAction::triggered, this, &QgsOgrLayerItem::deleteLayer );
|
||||
lst.append( actionDeleteLayer );
|
||||
return lst;
|
||||
}
|
||||
|
||||
void QgsOgrLayerItem::deleteLayer()
|
||||
{
|
||||
// Messages are different for files and tables
|
||||
QString title = mIsSubLayer ? QObject::tr( "Delete Layer" ) : QObject::tr( "Delete File" );
|
||||
// Check if the layer is in the registry
|
||||
const QgsMapLayer *projectLayer = nullptr;
|
||||
Q_FOREACH ( const QgsMapLayer *layer, QgsProject::instance()->mapLayers() )
|
||||
{
|
||||
if ( layer->publicSource() == mUri )
|
||||
{
|
||||
projectLayer = layer;
|
||||
}
|
||||
}
|
||||
if ( ! projectLayer )
|
||||
{
|
||||
QString confirmMessage;
|
||||
if ( mIsSubLayer )
|
||||
{
|
||||
confirmMessage = QObject::tr( "Are you sure you want to delete layer '%1' from datasource?" ).arg( mName );
|
||||
}
|
||||
else
|
||||
{
|
||||
confirmMessage = QObject::tr( "Are you sure you want to delete file '%1'?" ).arg( mUri );
|
||||
}
|
||||
if ( QMessageBox::question( nullptr, title,
|
||||
confirmMessage,
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
|
||||
return;
|
||||
|
||||
QString errCause;
|
||||
bool res = ::deleteLayer( mUri, errCause );
|
||||
if ( !res )
|
||||
{
|
||||
QMessageBox::warning( nullptr, title, errCause );
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information( nullptr, title, mIsSubLayer ? tr( "Layer deleted successfully." ) : tr( "File deleted successfully." ) );
|
||||
if ( mParent )
|
||||
mParent->refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning( nullptr, title, QObject::tr( "The layer '%1' cannot be deleted because it is in the current project as '%2',"
|
||||
" remove it from the project and retry." ).arg( mName, projectLayer->name() ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// -------
|
||||
|
||||
static QgsOgrLayerItem *dataItemForLayer( QgsDataItem *parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId )
|
||||
static QgsOgrLayerItem *dataItemForLayer( QgsDataItem *parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId, bool isSubLayer = false )
|
||||
{
|
||||
OGRLayerH hLayer = OGR_DS_GetLayer( hDataSource, layerId );
|
||||
OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );
|
||||
@ -166,7 +234,7 @@ static QgsOgrLayerItem *dataItemForLayer( QgsDataItem *parentItem, QString name,
|
||||
|
||||
QgsDebugMsgLevel( "OGR layer uri : " + layerUri, 2 );
|
||||
|
||||
return new QgsOgrLayerItem( parentItem, name, path, layerUri, layerType );
|
||||
return new QgsOgrLayerItem( parentItem, name, path, layerUri, layerType, isSubLayer );
|
||||
}
|
||||
|
||||
// ----
|
||||
@ -189,7 +257,7 @@ QVector<QgsDataItem *> QgsOgrDataCollectionItem::createChildren()
|
||||
children.reserve( numLayers );
|
||||
for ( int i = 0; i < numLayers; ++i )
|
||||
{
|
||||
QgsOgrLayerItem *item = dataItemForLayer( this, QString(), mPath, hDataSource, i );
|
||||
QgsOgrLayerItem *item = dataItemForLayer( this, QString(), mPath, hDataSource, i, true );
|
||||
children.append( item );
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,19 @@ class QgsOgrLayerItem : public QgsLayerItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsOgrLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType );
|
||||
QgsOgrLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType, bool isSubLayer = false );
|
||||
|
||||
bool setCrs( const QgsCoordinateReferenceSystem &crs ) override;
|
||||
|
||||
QString layerName() const override;
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
QList<QAction *> actions() override;
|
||||
public slots:
|
||||
void deleteLayer();
|
||||
#endif
|
||||
private:
|
||||
bool mIsSubLayer;
|
||||
};
|
||||
|
||||
|
||||
|
@ -4297,3 +4297,76 @@ QGISEXTERN void cleanupProvider()
|
||||
// NOTE: QgsApplication takes care of
|
||||
// calling OGRCleanupAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QGISEXTERN bool deleteLayer( const QString &uri, QString &errCause )
|
||||
{
|
||||
bool isSubLayer;
|
||||
int layerIndex;
|
||||
QString layerName;
|
||||
QString subsetString;
|
||||
OGRwkbGeometryType ogrGeometryType;
|
||||
QString filePath = AnalyzeURI( uri,
|
||||
isSubLayer,
|
||||
layerIndex,
|
||||
layerName,
|
||||
subsetString,
|
||||
ogrGeometryType );
|
||||
|
||||
OGRDataSourceH hDS = GDALOpenEx( filePath.toLocal8Bit().data(), GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_UPDATE, NULL, NULL, NULL );
|
||||
if ( hDS && ( ! layerName.isEmpty() || layerIndex != -1 ) )
|
||||
{
|
||||
if ( layerIndex == -1 )
|
||||
{
|
||||
for ( int i = 0; i < GDALDatasetGetLayerCount( hDS ); i++ )
|
||||
{
|
||||
OGRLayerH hL = GDALDatasetGetLayer( hDS, i );
|
||||
if ( layerName == QString( OGR_L_GetName( hL ) ) )
|
||||
{
|
||||
layerIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
OGRErr error = GDALDatasetDeleteLayer( hDS, layerIndex );
|
||||
switch ( error )
|
||||
{
|
||||
case OGRERR_NOT_ENOUGH_DATA:
|
||||
errCause = QObject::tr( "Not enough data to deserialize" );
|
||||
break;
|
||||
case OGRERR_NOT_ENOUGH_MEMORY:
|
||||
errCause = QObject::tr( "Not enough memory" );
|
||||
break;
|
||||
case OGRERR_UNSUPPORTED_GEOMETRY_TYPE:
|
||||
errCause = QObject::tr( "Unsupported geometry type" );
|
||||
break;
|
||||
case OGRERR_UNSUPPORTED_OPERATION:
|
||||
errCause = QObject::tr( "Unsupported operation" );
|
||||
break;
|
||||
case OGRERR_CORRUPT_DATA:
|
||||
errCause = QObject::tr( "Corrupt data" );
|
||||
break;
|
||||
case OGRERR_FAILURE:
|
||||
errCause = QObject::tr( "Failure" );
|
||||
break;
|
||||
case OGRERR_UNSUPPORTED_SRS:
|
||||
errCause = QObject::tr( "Unsupported SRS" );
|
||||
break;
|
||||
case OGRERR_INVALID_HANDLE:
|
||||
errCause = QObject::tr( "Invalid handle" );
|
||||
break;
|
||||
case OGRERR_NON_EXISTING_FEATURE:
|
||||
errCause = QObject::tr( "Non existing feature" );
|
||||
break;
|
||||
default:
|
||||
case OGRERR_NONE:
|
||||
errCause = QObject::tr( "Success" );
|
||||
break;
|
||||
}
|
||||
errCause = QObject::tr( "GDAL result code: %s" ).arg( errCause );
|
||||
return error == OGRERR_NONE;
|
||||
}
|
||||
// This should never happen:
|
||||
errCause = QObject::tr( "Layer not found: %s" ).arg( uri );
|
||||
return false;
|
||||
}
|
||||
|
@ -602,8 +602,32 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_29">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_16">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="mDataSourceManagerNonModal">
|
||||
<property name="text">
|
||||
<string>Modeless data source manager dialog</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="mCustomGroupBoxChkBx">
|
||||
<property name="text">
|
||||
<string>QGIS-styled group boxes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="cbxCheckVersion">
|
||||
<property name="text">
|
||||
<string>Check QGIS version at startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="cbxHideSplash">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
@ -616,82 +640,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxShowTips">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show tips at start up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxCheckVersion">
|
||||
<property name="text">
|
||||
<string>Check QGIS version at startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_30">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mDataSourceManagerNonModal">
|
||||
<property name="text">
|
||||
<string>Modeless data source manager dialog</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mCustomGroupBoxChkBx">
|
||||
<property name="text">
|
||||
<string>QGIS-styled group boxes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_31">
|
||||
<item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="mNativeColorDialogsChkBx">
|
||||
<property name="text">
|
||||
<string>Use native color chooser dialogs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="mLiveColorDialogsChkBx">
|
||||
<property name="text">
|
||||
<string>Use live-updating color chooser dialogs</string>
|
||||
@ -5543,12 +5499,6 @@ The bigger the number, the faster zooming with the mouse wheel will be.</string>
|
||||
<tabstop>mFontFamilyComboBox</tabstop>
|
||||
<tabstop>spinFontSize</tabstop>
|
||||
<tabstop>mMessageTimeoutSpnBx</tabstop>
|
||||
<tabstop>cbxHideSplash</tabstop>
|
||||
<tabstop>cbxShowTips</tabstop>
|
||||
<tabstop>cbxCheckVersion</tabstop>
|
||||
<tabstop>mCustomGroupBoxChkBx</tabstop>
|
||||
<tabstop>mNativeColorDialogsChkBx</tabstop>
|
||||
<tabstop>mLiveColorDialogsChkBx</tabstop>
|
||||
<tabstop>groupBox_11</tabstop>
|
||||
<tabstop>mProjectOnLaunchCmbBx</tabstop>
|
||||
<tabstop>mProjectOnLaunchLineEdit</tabstop>
|
||||
|
@ -63,7 +63,6 @@ ENDMACRO (ADD_QGIS_TEST)
|
||||
#############################################################
|
||||
# Tests:
|
||||
SET(TESTS
|
||||
testqgsvectoranalyzer.cpp
|
||||
testqgsgeometrysnapper.cpp
|
||||
testopenstreetmap.cpp
|
||||
testqgszonalstatistics.cpp
|
||||
|
@ -1,145 +0,0 @@
|
||||
/***************************************************************************
|
||||
testqgsvectoranalyzer.cpp
|
||||
--------------------------------------
|
||||
Date : Sun Sep 16 12:22:49 AKDT 2007
|
||||
Copyright : (C) 2007 by Gary E. Sherman
|
||||
Email : sherman at mrcc 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgstest.h"
|
||||
|
||||
//header for class being tested
|
||||
#include <qgsgeometryanalyzer.h>
|
||||
#include <qgsapplication.h>
|
||||
#include <qgsproviderregistry.h>
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
class TestQgsVectorAnalyzer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TestQgsVectorAnalyzer()
|
||||
: mpLineLayer( 0 )
|
||||
, mpPolyLayer( 0 )
|
||||
, mpPointLayer( 0 )
|
||||
{}
|
||||
|
||||
private slots:
|
||||
void initTestCase();// will be called before the first testfunction is executed.
|
||||
void cleanupTestCase();// will be called after the last testfunction was executed.
|
||||
void init() ;// will be called before each testfunction is executed.
|
||||
void cleanup() ;// will be called after every testfunction.
|
||||
//! Our tests proper begin here
|
||||
void singleToMulti();
|
||||
void multiToSingle();
|
||||
void extractNodes();
|
||||
void polygonsToLines();
|
||||
void exportGeometryInfo();
|
||||
void simplifyGeometry();
|
||||
void polygonCentroids();
|
||||
void layerExtent();
|
||||
private:
|
||||
QgsGeometryAnalyzer mAnalyzer;
|
||||
QgsVectorLayer *mpLineLayer = nullptr;
|
||||
QgsVectorLayer *mpPolyLayer = nullptr;
|
||||
QgsVectorLayer *mpPointLayer = nullptr;
|
||||
|
||||
};
|
||||
|
||||
void TestQgsVectorAnalyzer::initTestCase()
|
||||
{
|
||||
//
|
||||
// Runs once before any tests are run
|
||||
//
|
||||
// init QGIS's paths - true means that all path will be inited from prefix
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
QgsApplication::showSettings();
|
||||
|
||||
//create some objects that will be used in all tests...
|
||||
//create a map layer that will be used in all tests...
|
||||
QString myBaseFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
|
||||
QString myEndName = QStringLiteral( "lines.shp" );
|
||||
QString myFileName = myBaseFileName + '/' + myEndName;
|
||||
qDebug() << myFileName;
|
||||
QFileInfo myLineInfo( myFileName );
|
||||
mpLineLayer = new QgsVectorLayer( myLineInfo.filePath(),
|
||||
myLineInfo.completeBaseName(), QStringLiteral( "ogr" ) );
|
||||
|
||||
myEndName = QStringLiteral( "polys.shp" );
|
||||
myFileName = myBaseFileName + '/' + myEndName;
|
||||
QFileInfo myPolyInfo( myFileName );
|
||||
mpPolyLayer = new QgsVectorLayer( myPolyInfo.filePath(),
|
||||
myPolyInfo.completeBaseName(), QStringLiteral( "ogr" ) );
|
||||
|
||||
myEndName = QStringLiteral( "points.shp" );
|
||||
myFileName = myBaseFileName + '/' + myEndName;
|
||||
QFileInfo myPointInfo( myFileName );
|
||||
mpPointLayer = new QgsVectorLayer( myPointInfo.filePath(),
|
||||
myPointInfo.completeBaseName(), QStringLiteral( "ogr" ) );
|
||||
}
|
||||
void TestQgsVectorAnalyzer::cleanupTestCase()
|
||||
{
|
||||
delete mpLineLayer;
|
||||
delete mpPolyLayer;
|
||||
delete mpPointLayer;
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
void TestQgsVectorAnalyzer::init()
|
||||
{
|
||||
|
||||
}
|
||||
void TestQgsVectorAnalyzer::cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
void TestQgsVectorAnalyzer::singleToMulti()
|
||||
{
|
||||
|
||||
}
|
||||
void TestQgsVectorAnalyzer::multiToSingle()
|
||||
{
|
||||
|
||||
}
|
||||
void TestQgsVectorAnalyzer::extractNodes()
|
||||
{
|
||||
|
||||
}
|
||||
void TestQgsVectorAnalyzer::polygonsToLines()
|
||||
{
|
||||
|
||||
}
|
||||
void TestQgsVectorAnalyzer::exportGeometryInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsVectorAnalyzer::simplifyGeometry()
|
||||
{
|
||||
QString myTmpDir = QDir::tempPath() + '/';
|
||||
QString myFileName = myTmpDir + "simplify_layer.shp";
|
||||
QVERIFY( mAnalyzer.simplify( mpLineLayer, myFileName, 1.0 ) );
|
||||
}
|
||||
|
||||
void TestQgsVectorAnalyzer::polygonCentroids()
|
||||
{
|
||||
QString myTmpDir = QDir::tempPath() + '/';
|
||||
QString myFileName = myTmpDir + "centroid_layer.shp";
|
||||
QVERIFY( mAnalyzer.centroids( mpPolyLayer, myFileName ) );
|
||||
}
|
||||
|
||||
void TestQgsVectorAnalyzer::layerExtent()
|
||||
{
|
||||
QString myTmpDir = QDir::tempPath() + '/';
|
||||
QString myFileName = myTmpDir + "extent_layer.shp";
|
||||
QVERIFY( mAnalyzer.extent( mpPointLayer, myFileName ) );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsVectorAnalyzer )
|
||||
#include "testqgsvectoranalyzer.moc"
|
@ -2183,7 +2183,8 @@ void TestQgsProcessing::parameterLayerList()
|
||||
QFileInfo fi1( raster1 );
|
||||
QgsRasterLayer *r1 = new QgsRasterLayer( fi1.filePath(), "R1" );
|
||||
QgsVectorLayer *v1 = new QgsVectorLayer( "Polygon?crs=EPSG:3111", "V4", "memory" );
|
||||
p.addMapLayers( QList<QgsMapLayer *>() << v1 << r1 );
|
||||
QgsVectorLayer *v2 = new QgsVectorLayer( "Polygon?crs=EPSG:3111", "V5", "memory" );
|
||||
p.addMapLayers( QList<QgsMapLayer *>() << v1 << v2 << r1 );
|
||||
QgsProcessingContext context;
|
||||
context.setProject( &p );
|
||||
|
||||
@ -2225,6 +2226,14 @@ void TestQgsProcessing::parameterLayerList()
|
||||
params.insert( "non_optional", QVariantList() << QVariant::fromValue( v1 ) << QVariant::fromValue( r1 ) );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 << r1 );
|
||||
|
||||
// mix of list and single layers (happens from models)
|
||||
params.insert( "non_optional", QVariantList() << QVariant( QVariantList() << QVariant::fromValue( v1 ) << QVariant::fromValue( v2 ) ) << QVariant::fromValue( r1 ) );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 << v2 << r1 );
|
||||
|
||||
// mix of two lists (happens from models)
|
||||
params.insert( "non_optional", QVariantList() << QVariant( QVariantList() << QVariant::fromValue( v1 ) << QVariant::fromValue( v2 ) ) << QVariant( QVariantList() << QVariant::fromValue( r1 ) ) );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 << v2 << r1 );
|
||||
|
||||
// mix of existing layers and non project layer string
|
||||
params.insert( "non_optional", QVariantList() << v1->id() << raster2 );
|
||||
QList< QgsMapLayer *> layers = QgsProcessingParameters::parameterAsLayerList( def.get(), params, context );
|
||||
@ -2310,6 +2319,9 @@ void TestQgsProcessing::parameterLayerList()
|
||||
params.insert( "optional", QVariant() );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 );
|
||||
|
||||
params.insert( "optional", QVariantList() << QVariant::fromValue( r1 ) );
|
||||
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << r1 );
|
||||
|
||||
code = def->asScriptCode();
|
||||
QCOMPARE( code, QStringLiteral( "##optional=optional multiple vector " ) + v1->id() );
|
||||
fromCode.reset( dynamic_cast< QgsProcessingParameterMultipleLayers * >( QgsProcessingParameters::parameterFromScriptCode( code ) ) );
|
||||
|
Loading…
x
Reference in New Issue
Block a user