[qgis] 01/01: Imported Upstream version 2.16.2+dfsg
Bas Couwenberg
sebastic at debian.org
Fri Aug 26 14:34:30 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch upstream
in repository qgis.
commit 81e727419a90712c45799d2d2b8d832158b75974
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Fri Aug 26 16:30:08 2016 +0200
Imported Upstream version 2.16.2+dfsg
---
.gitignore | 2 +
CMakeLists.txt | 2 +-
ChangeLog | 266 +++++++++++++++++++++
cmake_templates/qgsconfig.h.in | 4 +-
debian/changelog | 14 +-
debian/compat.in | 4 +-
debian/control.in | 50 ++--
.../libqgis-analysis{QGIS_ABI}.lintian-overrides | 1 +
debian/libqgis-core{QGIS_ABI}.lintian-overrides | 2 +
debian/libqgis-customwidgets.lintian-overrides | 1 -
debian/libqgis-customwidgets.lintian-overrides.in | 2 +
debian/python-qgis.install.in | 4 +-
debian/python-qgis.lintian-overrides.in | 1 +
debian/qgis-common.install | 5 +
debian/qgis-plugin-globe-common.install | 1 +
debian/qgis-plugin-globe.install | 1 +
debian/qgis-plugin-grass.lintian-overrides | 2 -
debian/qgis-provider.lintian-overrides | 1 +
debian/qgis-providers.install.in | 4 +-
debian/qgis-providers.lintian-overrides | 2 +
debian/qgis.install | 6 +-
debian/qgis.lintian-overrides | 6 +-
debian/rules | 15 +-
i18n/qgis_de.ts | 4 +-
python/core/qgsvectorlayer.sip | 26 +-
.../processing/algs/gdal/ogr2ogronesidebuffer.py | 26 +-
.../plugins/processing/algs/qgis/AddTableField.py | 5 +-
.../processing/algs/qgis/AutoincrementalField.py | 5 +-
python/plugins/processing/algs/qgis/Centroids.py | 2 +-
.../plugins/processing/algs/qgis/CheckValidity.py | 9 +-
python/plugins/processing/algs/qgis/ConcaveHull.py | 2 +-
python/plugins/processing/algs/qgis/ConvexHull.py | 2 +-
.../processing/algs/qgis/DensifyGeometries.py | 5 +-
python/plugins/processing/algs/qgis/Difference.py | 4 +-
python/plugins/processing/algs/qgis/Dissolve.py | 5 +-
python/plugins/processing/algs/qgis/Eliminate.py | 5 +-
.../processing/algs/qgis/EquivalentNumField.py | 5 +-
python/plugins/processing/algs/qgis/Explode.py | 3 +-
.../processing/algs/qgis/ExportGeometryInfo.py | 2 +-
.../processing/algs/qgis/ExtractByLocation.py | 2 +-
.../plugins/processing/algs/qgis/FieldPyculator.py | 7 +-
.../processing/algs/qgis/FieldsCalculator.py | 5 +-
.../plugins/processing/algs/qgis/FieldsMapper.py | 3 +-
.../plugins/processing/algs/qgis/Intersection.py | 5 +-
.../plugins/processing/algs/qgis/JoinAttributes.py | 3 +-
python/plugins/processing/algs/qgis/Merge.py | 10 +-
.../processing/algs/qgis/MultipartToSingleparts.py | 20 +-
.../algs/qgis/OrientedMinimumBoundingBox.py | 5 +-
.../processing/algs/qgis/PointsDisplacement.py | 5 +-
.../processing/algs/qgis/PointsInPolygon.py | 7 +-
.../processing/algs/qgis/PointsInPolygonUnique.py | 5 +-
.../algs/qgis/PointsInPolygonWeighted.py | 7 +-
.../processing/algs/qgis/PointsLayerFromTable.py | 3 +-
.../plugins/processing/algs/qgis/PointsToPaths.py | 2 +-
python/plugins/processing/algs/qgis/Polygonize.py | 3 +-
.../processing/algs/qgis/RandomPointsAlongLines.py | 2 +-
.../processing/algs/qgis/RandomPointsLayer.py | 2 +-
.../algs/qgis/RandomPointsPolygonsFixed.py | 2 +-
.../algs/qgis/RandomPointsPolygonsVariable.py | 2 +-
.../processing/algs/qgis/ReverseLineDirection.py | 3 +-
.../processing/algs/qgis/SaveSelectedFeatures.py | 5 +-
.../algs/qgis/SinglePartsToMultiparts.py | 2 +-
python/plugins/processing/algs/qgis/Smooth.py | 3 +-
python/plugins/processing/algs/qgis/SpatialJoin.py | 9 +-
python/plugins/processing/algs/qgis/SumLines.py | 6 +-
.../processing/algs/qgis/SymmetricalDifference.py | 13 +-
python/plugins/processing/algs/qgis/Union.py | 6 +-
python/plugins/processing/algs/qgis/VectorSplit.py | 2 +-
.../processing/algs/qgis/ZonalStatistics.py | 2 +-
python/plugins/processing/core/SilentProgress.py | 8 +-
.../plugins/processing/gui/AlgorithmDialogBase.py | 3 +
.../plugins/processing/gui/GetScriptsAndModels.py | 11 +-
.../processing/gui/ListMultiselectWidget.py | 10 +-
.../plugins/processing/gui/ScriptEditorDialog.py | 8 +-
.../processing/modeler/AddModelFromFileAction.py | 2 +-
python/plugins/processing/modeler/ModelerDialog.py | 4 +-
.../processing/script/AddScriptFromFileAction.py | 2 +-
python/testing/__init__.py | 5 +-
src/app/qgisapp.cpp | 6 +-
src/app/qgsbookmarks.cpp | 2 +
src/app/qgsdxfexportdialog.cpp | 8 +-
src/core/pal/feature.cpp | 80 ++++---
src/core/pal/feature.h | 6 +-
src/core/pal/geomfunction.cpp | 53 ++++
src/core/pal/geomfunction.h | 12 +
src/core/pal/layer.cpp | 2 +-
src/core/pal/layer.h | 16 --
src/core/pal/pointset.cpp | 45 +---
src/core/qgslabelfeature.cpp | 24 ++
src/core/qgslabelfeature.h | 34 +++
src/core/qgslabelingenginev2.cpp | 3 -
src/core/qgslabelingenginev2.h | 1 -
src/core/qgspallabeling.cpp | 15 ++
src/core/qgsvectorfilewriter.cpp | 9 +-
src/core/qgsvectorlayer.cpp | 77 +++++-
src/core/qgsvectorlayer.h | 26 +-
src/core/qgsvectorlayerlabelprovider.cpp | 1 -
src/core/raster/qgscolorrampshader.cpp | 3 +
src/gui/CMakeLists.txt | 19 ++
src/gui/attributetable/qgsattributetablemodel.cpp | 2 +-
src/gui/attributetable/qgsfeaturelistview.cpp | 3 +-
.../editorwidgets/core/qgseditorwidgetwrapper.cpp | 2 +-
.../editorwidgets/core/qgssearchwidgetwrapper.cpp | 2 +-
src/gui/qgsattributeform.cpp | 32 ++-
src/gui/qgsattributeform.h | 14 +-
.../qgssinglebandpseudocolorrendererwidget.cpp | 3 +
src/helpviewer/qgshelpviewer.cpp | 2 +-
.../dxf2shp_converter/dxflib/src/dl_dxf.cpp | 2 +-
src/providers/grass/qgis.g.info.c | 2 +-
src/providers/ogr/qgsogrfeatureiterator.cpp | 49 +++-
src/providers/ogr/qgsogrfeatureiterator.h | 9 +-
src/providers/ogr/qgsogrprovider.cpp | 23 +-
src/providers/wfs/qgswfscapabilities.cpp | 2 +-
src/providers/wfs/qgswfsconstants.cpp | 2 +
src/providers/wfs/qgswfsconstants.h | 4 +
src/providers/wfs/qgswfsdatasourceuri.cpp | 58 ++++-
src/providers/wfs/qgswfsdatasourceuri.h | 5 +-
src/providers/wfs/qgswfsprovider.cpp | 41 ++--
tests/src/gui/testqgsdualview.cpp | 27 +++
tests/src/python/CMakeLists.txt | 1 +
tests/src/python/providertestbase.py | 26 ++
tests/src/python/test_provider_tabfile.py | 18 +-
tests/src/python/test_provider_wfs.py | 88 +++++++
tests/src/python/test_qgsattributetablemodel.py | 31 ++-
tests/src/python/test_qgsfeatureiterator.py | 9 +-
tests/src/python/test_qgspallabeling_placement.py | 1 +
tests/src/python/test_qgsrastercolorrampshader.py | 37 +++
tests/src/python/test_qgsvectorfilewriter.py | 46 ++++
128 files changed, 1286 insertions(+), 407 deletions(-)
diff --git a/.gitignore b/.gitignore
index c06bd6e..a5dc157 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,4 +61,6 @@ tests/testdata/raster/band1_float32_noct_epsg4326.tif.aux.xml
tests/testdata/raster/band1_int16_noct_epsg4326.tif.aux.xml
tests/testdata/raster/band3_float32_noct_epsg4326.tif.aux.xml
tests/testdata/raster/band3_int16_noct_epsg4326.tif.aux.xml
+python/plugins/processing/tests/testdata/custom/grass7/float_raster.tif.aux.xml
+python/plugins/processing/tests/testdata/custom/grass7/raster_1class.tif.aux.xml
Thumb.db
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e57efa3..5f703bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
SET(CPACK_PACKAGE_VERSION_MINOR "16")
-SET(CPACK_PACKAGE_VERSION_PATCH "1")
+SET(CPACK_PACKAGE_VERSION_PATCH "2")
SET(COMPLETE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH})
SET(RELEASE_NAME "Nødebo")
IF (POLICY CMP0048) # in CMake 3.0.0+
diff --git a/ChangeLog b/ChangeLog
index 3def048..d73e733 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,269 @@
+Alexander Bruy <alexander.bruy at gmail.com> 2016-08-23
+
+ fix typo
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-23
+
+ fix switching of projects within unicode folders
+
+ (cherry picked from commit 3951f15b6481a85b551e2f33f26c2aeb6687a24a)
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-08-23
+
+ [processing] add missed error() method
+
+ (cherry picked from commit 6a7fa7dd5a199bfa0ced8e4768b910171c3b8e8e)
+
+Matthias Kuhn <matthias at opengis.ch> 2016-08-19
+
+ Improve wording
+
+ Fix #15456
+
+Matthias Kuhn <matthias at opengis.ch> 2016-08-19
+
+ Hide invalid constraints label when it's unused
+
+ Fix #15452
+
+Matthias Kuhn <matthias at opengis.ch> 2016-08-19
+
+ Widget constraints: use field alias where available
+
+ Fix #15455
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-18
+
+ dxf export: avoid symbology scale 0 (fixes #14138)
+
+ (cherry picked from commit 0a07fee15297e18a73b63f194f5aeecffd76800c)
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-18
+
+ debian packaging update
+
+ (cherry picked from commit 127fb683b226908c4f34a78a8fa1e43965a51dfa)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-17
+
+ fix repeated labels on curved lines when label width > repeat distance
+
+ (cherry-picked from fb346ecf4fda53ccac7ef939bc6ec84a361a9d58)
+ o
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-17
+
+ Make QgsVectorLayer uniqueValues/min/maxValue consider edits
+
+ Previously these methods would inconsistently handle the
+ edit buffer, eg uniqueValues would consider changed attributes
+ but not added features. Now uniqueValues, minimumValue and
+ maximumValue all consider both added features and changed
+ attribute values when performing their calculation.
+
+ The most noticable effect of this fix is that the unique
+ values widget now correctly shows values for features which
+ have been added but not yet committed to the provider.
+
+ (cherry-picked from 50c35929d86ab01b22c29cd129fd7019a1bf624a)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-17
+
+ Don't crash raster shader with nan or inf values (fix #15444)
+
+ (cherry-picked from 34ebe124ff62956095941b5bb76809c6ba4b1a0f)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-17
+
+ Fix some missing autoupdates for raster psuedo color widget
+
+ (cherry-picked from b349eb8a982d762d399ad4c21e3214195e6cd778)
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-15
+
+ exclude release name from version string (fixes #15258)
+
+ (cherry picked from commit 1391aad2f713a796b0ac3d0c22bec6c1c7ada3bb)
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-15
+
+ debian packaging update
+
+ (cherry picked from commit 977b5f2b8c9d5ee93e166a7c95f1f70fc2e800ec)
+
+Anita Graser <anitagraser at gmx.at> 2016-08-10
+
+ fixed failure to insert only one point
+
+ Previously, if pointsNumber was 1, it wouldn't insert a new point in the middle.
+ (cherry picked from commit 754ccefabc5c5fb9ba4472b182f1f05cd2a0ebb2)
+
+Larry Shaffer <lshaffer at boundlessgeo.com> 2016-08-10
+
+ [auth] Add missing auth system ui headers for external C++ apps
+
+ (cherry-picked from f3e90f1d5a87b2a7c6c693aa8ba3eaad64161b1d)
+
+Matthias Kuhn <matthias at opengis.ch> 2016-08-10
+
+ Fix crash when clicking in empty relation editor
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-10
+
+ Reset layers for each pal placement test, avoids all tests failing
+ because of one
+
+ (cherry-picked from 95ecdaf4383a0337710fd98fe34c93323be8e0ad)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-10
+
+ Fix "label only inside polygon" mode when used with perimeter placement
+
+ The option was not working with perimeter placements as perimeter placements alter
+ the label feature geometry to be a boundary linestring - hence no labels where
+ ever inside this boundary.
+
+ Accordingly this refactors how the force label inside polygon option functions.
+ Now QgsLabelFeatures can have a permissible zone geometry set, such that any
+ label candidates outside of this permissible zone are discarded.
+
+ This approach is more flexible as it could also be used for more labeling options
+ in future, eg discarding label candidates which are too far from a centroid or
+ something.
+
+ Sponsored by Andreas Neumann
+
+ (cherry-picked from c234d80e1e6c07813140df416b26ad5665b9ab99)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-09
+
+ Make test layer comparison handle different order of features
+
+ (cherry-picked from f449bf236198ced18bbd7078144f12a9aab77cd0)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-09
+
+ [processing] Fix broken multi field selection widget
+
+ (cherry-picked from fda93dfc574a152be2509d7f370af073abd3ba37)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-09
+
+ [processing] Fix multipart to singlepart handling of null geometry
+
+ (cherry-picked from 0455b6600d2ab443ea8d691e3c007ee481a30910)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-09
+
+ Add processing test .aux.xml to .gitignore
+
+ (cherry-picked from 0939dbf9df5d0cb6867a4d0b3ea6a543eea77366)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-09
+
+ [processing] Use layer crs/fields instead of provider crs/fields
+
+ Since the layer has more complete knowledge of the crs (ie, when
+ provider could not determine crs and user has selected it from
+ the list), and also better knowledge of layer fields (virtual
+ fields, joined fields) we should use these rather than the
+ provider methods.
+
+ (cherry-picked from 06c4b07222f9410e1669387a6497897c61748a16)
+
+Merge: 005d467 f49bd5c
+Alessandro Pasotti <elpaso at itopen.it> 2016-08-09
+
+ Merge pull request #3368 from elpaso/wfs_fixes
+
+ Try to fix #15360
+
+Alessandro Pasotti <apasotti at boundlessgeo.com> 2016-08-08
+
+ [WFS] Fixes #15360 and other issues
+
+ - fixes authcfg params not passed to requests
+ - fixes backward URI compatibility
+ - fixes version parameter ignored in old style URI
+ - check for "user" in addition to "username" in WFS URI
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-09
+
+ Implement provider side FilterFids iterators for OGR provider
+
+ Makes some operations with OGR sources magnitudes faster, ie
+ zoom to 20 selected features in a 4 million point dataset:
+
+ before: 14 seconds of blocked gui
+ after: instant
+
+ (cherry-picked from 1f02fd491d62b2a79ee1bd98000f48cb4db1b442)
+
+Even Rouault <even.rouault at spatialys.com> 2016-08-08
+
+ [QgsVectorFileWriter + OGR provider] Create Integer64 fields as Real fields when output driver doesn't support Integer64
+
+ Fix #15405
+
+Even Rouault <even.rouault at spatialys.com> 2016-08-08
+
+ [WFS provider] Succesfully analyze DescribeFeatureType response with <complexType> as inline element of <element> (#15395)
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-04
+
+ debian packaging update
+
+ (cherry picked from commit aef87037254729583590102e86a59ea51262cf78)
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-07-25
+
+ [processing] always use user-defined default folder for scripts/models
+
+ (cherry picked from commit 48cca3bc12e874d681669b47ce2ee24b96baa4de)
+
+ Conflicts:
+python/plugins/processing/modeler/AddModelFromFileAction.py
+python/plugins/processing/script/AddScriptFromFileAction.py
+
+Matthias Kuhn <matthias at opengis.ch> 2016-08-03
+
+ Don't show scrollbar in embedded drag and drop designer form
+
+Juergen E. Fischer <jef at norbit.de> 2016-07-31
+
+ debian packaging update
+
+ (cherry picked from commit 750e60fe19eb89489e5e0803717dbbfabfb75e0e)
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-03
+
+ fix crash when QSQLITE is unavailable (fixes #15358)
+
+ (cherry picked from commit 285bcd053c353bd99f7e8e71003f5b4bd39bde57)
+
+Matthias Kuhn <matthias at opengis.ch> 2016-08-01
+
+ Sort attribute table by value for numerical columns
+
+ Fix #15318
+ Fix #15295
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-08-01
+
+ [processing] don't apply additional parameter if offset curve operation is used (fix #15342)
+
+ (cherry picked from commit 1d2b0b4ca7658ed57c4663d9f064ca4bbc55381e)
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-08-01
+
+ [processing] add missed import (fix #15359)
+
+ (cherry picked from commit 98a55274063fcfe8174b3c3d0369d72d5e2f7c73)
+
+Juergen E. Fischer <jef at norbit.de> 2016-07-29
+
+ Release of 2.16.1
+
Nyall Dawson <nyall.dawson at gmail.com> 2016-07-29
Fix map not refreshed after using pan to selected (fix #15324)
diff --git a/cmake_templates/qgsconfig.h.in b/cmake_templates/qgsconfig.h.in
index 629c69a..c1b9e75 100644
--- a/cmake_templates/qgsconfig.h.in
+++ b/cmake_templates/qgsconfig.h.in
@@ -5,10 +5,10 @@
#define QGSCONFIG_H
// Version must be specified according to
-// <int>.<int>.<int>-<any text>.
+// <int>.<int>.<int>"
// or else upgrading old project file will not work
// reliably.
-#define VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${RELEASE_NAME}"
+#define VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
//used in vim src/core/qgis.cpp
//The way below should work but it resolves to a number like 0110 which the compiler treats as octal I think
diff --git a/debian/changelog b/debian/changelog
index 9da69c1..c5e60a7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,18 @@
-qgis (2.16.1) UNRELEASED; urgency=medium
+qgis (2.16.2) UNRELEASED; urgency=medium
+
+ * Release of 2.16.2
+
+ -- Jürgen E. Fischer <jef at norbit.de> Fri, 26 Aug 2016 13:58:37 +0200
+
+qgis (2.16.1) unstable; urgency=medium
* Release of 2.16.1
+ * drop support for debian wheezy and ubuntu wily
+ * add python-requests dependency for metasearch plugin
+ * lintian fixes
+ * add version constraint to libqgis-customwidgets dependency.
- -- Jürgen E. Fischer <jef at norbit.de> Fri, 29 Jul 2016 14:04:56 +0200
+ -- Jürgen E. Fischer <jef at norbit.de> Fri, 26 Aug 2016 13:58:36 +0200
qgis (2.16.0) unstable; urgency=medium
diff --git a/debian/compat.in b/debian/compat.in
index 286144b..d00268c 100644
--- a/debian/compat.in
+++ b/debian/compat.in
@@ -1,3 +1,3 @@
-#stretch sid jessie trusty wily xenial#9
-#wheezy jessie#8
+#stretch sid jessie trusty xenial#9
+#jessie#8
#precise#7
diff --git a/debian/control.in b/debian/control.in
index 3bc7f4e..789102d 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -6,21 +6,19 @@ Priority: optional
Build-Depends:
bison,
cmake (>= 2.8),
-#wily# cmake (<< 3.3.2),
-#sid stretch jessie wheezy trusty wily xenial# debhelper (>= 9),
-#sid stretch jessie trusty wily xenial# dh-python,
+#sid stretch jessie trusty xenial# debhelper (>= 9),
+#sid stretch jessie trusty xenial# dh-python,
#precise# debhelper (>= 7),
flex,
grass-dev,
libexpat1-dev,
libfcgi-dev,
-#sid stretch jessie trusty wily xenial# libgdal-dev (>= 1.10.1-0~),
+#sid stretch jessie trusty xenial# libgdal-dev (>= 1.10.1-0~),
#precise# libgdal-dev (>= 1.9.0) | libgdal1-dev (<< 1.9.0),
-#wheezy# libgdal1-dev,
gdal-bin,
python-gdal,
libgeos-dev (>= 3.0.0),
-#jessie wheezy precise trusty wily# libgsl0-dev,
+#jessie precise trusty# libgsl0-dev,
#sid stretch xenial# libgsl-dev,
libpq-dev,
libproj-dev,
@@ -28,10 +26,10 @@ Build-Depends:
libqt4-opengl-dev,
libqca2-dev,
libqca2-plugin-ossl,
-#wheezy jessie precise trusty utopic vivid wily# libqtwebkit-dev,
-#stretch jessie wheezy# libqwt-dev,
-#precise trusty wily xenial sid# libqwt5-qt4-dev,
-#sid stretch jessie wheezy trusty wily xenial# libqjson-dev,
+#jessie precise trusty xenial# libqtwebkit-dev,
+#stretch jessie# libqwt-dev,
+#precise trusty xenial sid# libqwt5-qt4-dev,
+#sid stretch jessie trusty xenial# libqjson-dev,
libspatialite-dev,
libsqlite3-dev,
libspatialindex-dev,
@@ -42,14 +40,13 @@ Build-Depends:
python-qt4-dev,
python-qt4-sql,
python-yaml, python-mock,
-#stretch sid wily xenial# python-future,
-#precise wheezy# python,
+#stretch sid xenial# python-future,
+#precise# python,
#precise# python-central (>= 0.5),
-#wheezy# python-dev,
-#sid stretch jessie trusty wily xenial# python-all (>= 2.6.6-3~), python-all-dev (>= 2.6.6-3~),
-#sid stretch jessie wily xenial# pyqt4.qsci-dev,
-#sid stretch jessie trusty wily xenial# python-pyspatialite,
-#sid wheezy jessie stretch trusty wily xenial# python-nose2,
+#sid stretch jessie trusty xenial# python-all (>= 2.6.6-3~), python-all-dev (>= 2.6.6-3~),
+#sid stretch jessie xenial# pyqt4.qsci-dev,
+#sid stretch jessie trusty xenial# python-pyspatialite,
+#sid jessie stretch trusty xenial# python-nose2,
python-sip (>= 4.5.0),
python-sip-dev (>= 4.5.0),
libosgearth-dev,
@@ -67,11 +64,10 @@ Build-Depends:
libqt4-sql-sqlite, python-psycopg2
Build-Conflicts: libqgis-dev, qgis-dev
#sid stretch xenial#Standards-Version: 3.9.7
-#jessie wily#Standards-Version: 3.9.6
-#wheezy#Standards-Version: 3.9.3
+#jessie#Standards-Version: 3.9.6
#precise trusty#Standards-Version: 3.8.4
#sid stretch jessie#X-Python-Version: >= 2.7, << 2.8
-#wheezy precise trusty wily xenial#XS-Python-Version: current
+#precise trusty xenial#XS-Python-Version: current
Vcs-Browser: https://github.com/qgis/QGIS/
Vcs-Git: https://github.com/qgis/QGIS.git
Homepage: http://qgis.org/
@@ -244,11 +240,10 @@ Section: libdevel
Depends:
grass-dev,
libexpat1-dev,
-#sid stretch jessie trusty wily xenial# libgdal-dev (>= 1.10.1-0~),
+#sid stretch jessie trusty xenial# libgdal-dev (>= 1.10.1-0~),
#precise# libgdal-dev (>= 1.9.0) | libgdal1-dev (<< 1.9.0),
-#wheezy# libgdal1-dev,
libgeos-dev (>= 3.0.0),
-#jessie wheezy precise trusty wily# libgsl0-dev,
+#jessie precise trusty# libgsl0-dev,
#sid stretch xenial# libgsl-dev,
libpq-dev,
libproj-dev,
@@ -383,11 +378,12 @@ Depends:
python-markupsafe,
python-pygments,
python-dateutil,
+ python-requests,
python-tz,
python-six,
python-yaml,
-#stretch sid wily xenial# python-future,
-#sid stretch jessie trusty wily xenial# python-pyspatialite,
+#stretch sid xenial# python-future,
+#sid stretch jessie trusty xenial# python-pyspatialite,
libqgispython{QGIS_ABI},
${shlibs:Depends},
${python:Depends},
@@ -395,7 +391,7 @@ Depends:
${sip:Depends}
Provides: ${python:Provides}
Recommends: liblwgeom-dev
-#wheezy precise#XB-Python-Version: ${python:Versions}
+#precise#XB-Python-Version: ${python:Versions}
Description: Python bindings to QGIS
QGIS is a Geographic Information System (GIS) which manages, analyzes and
display databases of geographic information.
@@ -411,7 +407,7 @@ Depends:
python-gdal,
python-matplotlib,
python-shapely,
- libqgis-customwidgets,
+ libqgis-customwidgets (>= ${source:Version}),
${misc:Depends}
XB-Python-Version: ${python:Versions}
Description: Python bindings to QGIS - architecture-independent files
diff --git a/debian/libqgis-analysis{QGIS_ABI}.lintian-overrides b/debian/libqgis-analysis{QGIS_ABI}.lintian-overrides
index ead8655..0df4bb6 100644
--- a/debian/libqgis-analysis{QGIS_ABI}.lintian-overrides
+++ b/debian/libqgis-analysis{QGIS_ABI}.lintian-overrides
@@ -1,2 +1,3 @@
libqgis-analysis{QGIS_ABI}: no-symbols-control-file
libqgis-analysis{QGIS_ABI}: shlib-calls-exit
+libqgis-analysis{QGIS_ABI}: spelling-error-in-binary usr/lib/libqgis_analysis.so.{QGIS_ABI} normalY normally
diff --git a/debian/libqgis-core{QGIS_ABI}.lintian-overrides b/debian/libqgis-core{QGIS_ABI}.lintian-overrides
index 5adeb61..60d9b9f 100644
--- a/debian/libqgis-core{QGIS_ABI}.lintian-overrides
+++ b/debian/libqgis-core{QGIS_ABI}.lintian-overrides
@@ -1,2 +1,4 @@
libqgis-core{QGIS_ABI}: shlib-calls-exit usr/lib/libqgis_core.so.{QGIS_ABI}
libqgis-core{QGIS_ABI}: no-symbols-control-file usr/lib/libqgis_core.so.{QGIS_ABI}
+libqgis-core{QGIS_ABI}: spelling-error-in-binary usr/lib/libqgis_core.so.{QGIS_ABI} naM name
+libqgis-core{QGIS_ABI}: spelling-error-in-binary usr/lib/libqgis_core.so.{QGIS_ABI} orderD ordered
diff --git a/debian/libqgis-customwidgets.lintian-overrides b/debian/libqgis-customwidgets.lintian-overrides
deleted file mode 100644
index 7e6ce08..0000000
--- a/debian/libqgis-customwidgets.lintian-overrides
+++ /dev/null
@@ -1 +0,0 @@
-libqgis-customwidgets: no-symbols-control-file
diff --git a/debian/libqgis-customwidgets.lintian-overrides.in b/debian/libqgis-customwidgets.lintian-overrides.in
new file mode 100644
index 0000000..863d93a
--- /dev/null
+++ b/debian/libqgis-customwidgets.lintian-overrides.in
@@ -0,0 +1,2 @@
+libqgis-customwidgets: no-symbols-control-file
+libqgis-customwidgets: spelling-error-in-binary {QT_PLUGIN_DIR}/designer/libqgis_customwidgets.so.{QGIS_ABI} YUr Your
diff --git a/debian/python-qgis.install.in b/debian/python-qgis.install.in
index 2a77bdd..f01f61c 100644
--- a/debian/python-qgis.install.in
+++ b/debian/python-qgis.install.in
@@ -7,5 +7,5 @@ usr/lib/python*/*-packages/qgis/networkanalysis/*
usr/lib/python*/*-packages/qgis/PyQt/*
usr/lib/python*/*-packages/qgis/server/*
usr/lib/python*/*-packages/qgis/testing/*
-#wheezy precise#usr/lib/python*/*-packages/pyspatialite/*.py
-#wheezy precise#usr/lib/python*/*-packages/pyspatialite/*.so
+#precise#usr/lib/python*/*-packages/pyspatialite/*.py
+#precise#usr/lib/python*/*-packages/pyspatialite/*.so
diff --git a/debian/python-qgis.lintian-overrides.in b/debian/python-qgis.lintian-overrides.in
index df98f72..694dcdd 100644
--- a/debian/python-qgis.lintian-overrides.in
+++ b/debian/python-qgis.lintian-overrides.in
@@ -1 +1,2 @@
python-qgis: hardening-no-fortify-functions
+python-qgis: spelling-error-in-binary usr/lib/python*/*-packages/qgis/*.so onself oneself
diff --git a/debian/qgis-common.install b/debian/qgis-common.install
index bd60a4a..25ff73b 100644
--- a/debian/qgis-common.install
+++ b/debian/qgis-common.install
@@ -12,8 +12,13 @@ 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/release-sponsors.html
usr/share/qgis/doc/style.css
usr/share/qgis/i18n/*
usr/share/qgis/images/*
usr/share/qgis/resources/spatialite.db
usr/share/qgis/resources/themes/*
+usr/share/pixmaps/
+usr/share/mime/packages/
+usr/share/mimelnk/
+usr/share/icons/hicolor/
diff --git a/debian/qgis-plugin-globe-common.install b/debian/qgis-plugin-globe-common.install
index 085c3bf..127ba65 100644
--- a/debian/qgis-plugin-globe-common.install
+++ b/debian/qgis-plugin-globe-common.install
@@ -1 +1,2 @@
usr/share/qgis/globe
+usr/include/osgEarthDrivers/feature_qgis
diff --git a/debian/qgis-plugin-globe.install b/debian/qgis-plugin-globe.install
index 4f5797a..a137f9c 100644
--- a/debian/qgis-plugin-globe.install
+++ b/debian/qgis-plugin-globe.install
@@ -1 +1,2 @@
usr/lib/qgis/plugins/libglobeplugin.so
+usr/lib/libosgdb_osgearth_feature_qgis.so
diff --git a/debian/qgis-plugin-grass.lintian-overrides b/debian/qgis-plugin-grass.lintian-overrides
deleted file mode 100644
index d830446..0000000
--- a/debian/qgis-plugin-grass.lintian-overrides
+++ /dev/null
@@ -1,2 +0,0 @@
-qgis-plugin-grass: package-name-doesnt-match-sonames
-qgis-plugin-grass: no-symbols-control-file
diff --git a/debian/qgis-provider.lintian-overrides b/debian/qgis-provider.lintian-overrides
new file mode 100644
index 0000000..89bd1bb
--- /dev/null
+++ b/debian/qgis-provider.lintian-overrides
@@ -0,0 +1 @@
+qgis: spelling-error-in-binary usr/lib/qgis/qgis_help YUr Your
diff --git a/debian/qgis-providers.install.in b/debian/qgis-providers.install.in
index 3d4d300..7e82c0f 100644
--- a/debian/qgis-providers.install.in
+++ b/debian/qgis-providers.install.in
@@ -17,6 +17,6 @@ usr/lib/qgis/plugins/libvirtuallayerprovider.so
usr/lib/qgis/plugins/libwcsprovider.so
usr/lib/qgis/plugins/libwfsprovider.so
usr/lib/qgis/plugins/libwmsprovider.so
-#sid stretch jessie wheezy trusty wily xenial#usr/lib/qgis/plugins/libarcgismapserverprovider.so
-#sid stretch jessie wheezy trusty wily xenial#usr/lib/qgis/plugins/libarcgisfeatureserverprovider.so
+#sid stretch jessie trusty xenial#usr/lib/qgis/plugins/libarcgismapserverprovider.so
+#sid stretch jessie trusty xenial#usr/lib/qgis/plugins/libarcgisfeatureserverprovider.so
{QT_PLUGIN_DIR}/sqldrivers/libqsqlspatialite.so
diff --git a/debian/qgis-providers.lintian-overrides b/debian/qgis-providers.lintian-overrides
new file mode 100644
index 0000000..5e600e1
--- /dev/null
+++ b/debian/qgis-providers.lintian-overrides
@@ -0,0 +1,2 @@
+qgis-providers: spelling-error-in-binary usr/lib/qgis/plugins/libdelimitedtextprovider.so AddD Add
+qgis-providers: spelling-error-in-binary usr/lib/qgis/plugins/libpostgresprovider.so theRes there's
diff --git a/debian/qgis.install b/debian/qgis.install
index b452705..9c2b7c4 100644
--- a/debian/qgis.install
+++ b/debian/qgis.install
@@ -15,8 +15,4 @@ usr/lib/qgis/plugins/libtopolplugin.so
usr/lib/qgis/plugins/libgeometrycheckerplugin.so
usr/lib/qgis/plugins/libgeometrysnapperplugin.so
usr/lib/qgis/qgis_help
-usr/share/pixmaps/
-usr/share/applications/
-usr/share/mime/packages/
-usr/share/mimelnk/
-usr/share/icons/hicolor/
+usr/share/applications
diff --git a/debian/qgis.lintian-overrides b/debian/qgis.lintian-overrides
index 72759f0..deda0be 100644
--- a/debian/qgis.lintian-overrides
+++ b/debian/qgis.lintian-overrides
@@ -1,4 +1,2 @@
-# 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
+qgis: spelling-error-in-binary usr/bin/qgis.bin YUr Your
+qgis: spelling-error-in-binary usr/lib/qgis/qgis_help YUr Your
diff --git a/debian/rules b/debian/rules
index 560325a..9a2d786 100755
--- a/debian/rules
+++ b/debian/rules
@@ -34,7 +34,7 @@ ifneq (,$(findstring -oracle,$(DISTRIBUTION)))
WITH_ORACLE=1
endif
-ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"wheezy jessie stretch precise trusty wily xenial"))
+ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"jessie stretch precise trusty xenial"))
DISTRIBUTION := sid
endif
@@ -68,6 +68,7 @@ CMAKE_OPTS := \
-DQGIS_CGIBIN_SUBDIR=/usr/lib/cgi-bin \
-DWITH_APIDOC=TRUE \
-DGENERATE_QHP=TRUE \
+ -DSUPPRESS_SIP_WARNINGS=TRUE \
-DWITH_CUSTOM_WIDGETS=TRUE \
-DWITH_INTERNAL_HTTPLIB2=FALSE \
-DWITH_INTERNAL_JINJA2=FALSE \
@@ -106,7 +107,7 @@ else
CMAKE_OPTS += -DWITH_INTERNAL_NOSE2=FALSE -DWITH_INTERNAL_SIX=FALSE
endif
-ifeq (,$(findstring $(DISTRIBUTION),"stretch sid wily xenial"))
+ifeq (,$(findstring $(DISTRIBUTION),"stretch sid xenial"))
CMAKE_OPTS += -DWITH_INTERNAL_FUTURE=TRUE
else
CMAKE_OPTS += -DWITH_INTERNAL_FUTURE=FALSE
@@ -116,7 +117,7 @@ ifneq (,$(WITH_GLOBE))
CMAKE_OPTS += -DWITH_GLOBE=TRUE
endif
-ifneq (,$(findstring $(DISTRIBUTION),"wheezy precise"))
+ifneq (,$(findstring $(DISTRIBUTION),"precise"))
CMAKE_OPTS += -DWITH_PYSPATIALITE=TRUE
endif
@@ -132,7 +133,7 @@ ifneq (,$(findstring $(DISTRIBUTION),"sid"))
CMAKE_OPTS += -DGEOS_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libgeos_c.so
endif
-ifneq (,$(findstring $(DISTRIBUTION),"jessie stretch trusty wily xenial sid"))
+ifneq (,$(findstring $(DISTRIBUTION),"jessie stretch trusty xenial sid"))
CMAKE_OPTS += -DPYTHON_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libpython2.7.so
endif
@@ -152,6 +153,10 @@ endif
-DORACLE_INCLUDEDIR=$(ORACLE_INCLUDEDIR)
endif
+ifneq (,$(findstring $(DISTRIBUTION),"sid stretch"))
+ CMAKE_OPTS += -DFCGI_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libfcgi.so
+endif
+
ifneq (,$(findstring $(DISTRIBUTION),"sid stretch jessie"))
CMAKE_OPTS += -DSPATIALINDEX_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libspatialindex.so
endif
@@ -170,7 +175,7 @@ else
CMAKE_OPTS += -DENABLE_TESTS=TRUE
endif
-ifneq (,$(findstring $(DISTRIBUTION),"wheezy jessie stretch trusty sid"))
+ifneq (,$(findstring $(DISTRIBUTION),"jessie stretch trusty sid"))
CPPFLAGS := $(shell dpkg-buildflags --get CPPFLAGS)
CFLAGS := $(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS)
CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) $(CPPFLAGS)
diff --git a/i18n/qgis_de.ts b/i18n/qgis_de.ts
index e790861..8ec2a1c 100644
--- a/i18n/qgis_de.ts
+++ b/i18n/qgis_de.ts
@@ -20740,8 +20740,8 @@ Nur %1 von %2 Objekten geschrieben.</translation>
</message>
<message>
<location filename="../src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp" line="73"/>
- <source>Is not missing (null)</source>
- <translation>Nicht belegt (NULL)</translation>
+ <source>Is not missing (not null)</source>
+ <translation>Nicht belegt (NOT NULL)</translation>
</message>
<message>
<location filename="../src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp" line="75"/>
diff --git a/python/core/qgsvectorlayer.sip b/python/core/qgsvectorlayer.sip
index a1784ca..3a5fbbc 100644
--- a/python/core/qgsvectorlayer.sip
+++ b/python/core/qgsvectorlayer.sip
@@ -1317,17 +1317,35 @@ class QgsVectorLayer : QgsMapLayer
/** Caches joined attributes if required (and not already done) */
void createJoinCaches();
- /** Returns unique values for column
+ /** Calculates a list of unique values contained within an attribute in the layer. Note that
+ * in some circumstances when unsaved changes are present for the layer then the returned list
+ * may contain outdated values (for instance when the attribute value in a saved feature has
+ * been changed inside the edit buffer then the previous saved value will be included in the
+ * returned list).
* @param index column index for attribute
* @param uniqueValues out: result list
- * @param limit maximum number of values to return (-1 if unlimited)
+ * @param limit maximum number of values to return (or -1 if unlimited)
+ * @see minimumValue()
+ * @see maximumValue()
*/
void uniqueValues( int index, QList<QVariant> &uniqueValues /Out/, int limit = -1 );
- /** Returns minimum value for an attribute column or invalid variant in case of error */
+ /** Returns the minimum value for an attribute column or an invalid variant in case of error.
+ * Note that in some circumstances when unsaved changes are present for the layer then the
+ * returned value may be outdated (for instance when the attribute value in a saved feature has
+ * been changed inside the edit buffer then the previous saved value may be returned as the minimum).
+ * @see maximumValue()
+ * @see uniqueValues()
+ */
QVariant minimumValue( int index );
- /** Returns maximum value for an attribute column or invalid variant in case of error */
+ /** Returns the maximum value for an attribute column or an invalid variant in case of error.
+ * Note that in some circumstances when unsaved changes are present for the layer then the
+ * returned value may be outdated (for instance when the attribute value in a saved feature has
+ * been changed inside the edit buffer then the previous saved value may be returned as the maximum).
+ * @see minimumValue()
+ * @see uniqueValues()
+ */
QVariant maximumValue( int index );
/** Calculates an aggregated value from the layer's features.
diff --git a/python/plugins/processing/algs/gdal/ogr2ogronesidebuffer.py b/python/plugins/processing/algs/gdal/ogr2ogronesidebuffer.py
index de4e459..a16cb51 100644
--- a/python/plugins/processing/algs/gdal/ogr2ogronesidebuffer.py
+++ b/python/plugins/processing/algs/gdal/ogr2ogronesidebuffer.py
@@ -85,7 +85,7 @@ class Ogr2OgrOneSideBuffer(GdalAlgorithm):
inLayer = self.getParameterValue(self.INPUT_LAYER)
ogrLayer = ogrConnectionString(inLayer)[1:-1]
layername = "'" + ogrLayerName(inLayer) + "'"
- operation = self.OPERATIONLIST[self.getParameterValue(self.OPERATION)]
+ operation = self.getParameterValue(self.OPERATION)
geometry = unicode(self.getParameterValue(self.GEOMETRY))
distance = unicode(self.getParameterValue(self.RADIUS))
leftright = self.LEFTRIGHTLIST[self.getParameterValue(self.LEFTRIGHT)]
@@ -104,12 +104,12 @@ class Ogr2OgrOneSideBuffer(GdalAlgorithm):
arguments.append(ogrLayer)
arguments.append(ogrLayerName(inLayer))
if dissolveall or field != 'None':
- if operation == 'Single Side Buffer':
+ if operation == 0:
arguments.append('-dialect sqlite -sql "SELECT ST_Union(ST_SingleSidedBuffer(')
else:
arguments.append('-dialect sqlite -sql "SELECT ST_Union(ST_OffsetCurve(')
else:
- if operation == 'Single Side Buffer':
+ if operation == 0:
arguments.append('-dialect sqlite -sql "SELECT ST_SingleSidedBuffer(')
else:
arguments.append('-dialect sqlite -sql "SELECT ST_OffsetCurve(')
@@ -118,14 +118,26 @@ class Ogr2OgrOneSideBuffer(GdalAlgorithm):
arguments.append(distance)
if dissolveall or field != 'None':
if leftright == 'Left':
- arguments.append(',0)),*')
+ if operation == 0:
+ arguments.append(',0)),*')
+ else:
+ arguments.append(')),*')
else:
- arguments.append(',1)),*')
+ if operation == 0:
+ arguments.append(',1)),*')
+ else:
+ arguments.append(')),*')
else:
if leftright == 'Left':
- arguments.append(',0),*')
+ if operation == 0:
+ arguments.append(',0),*')
+ else:
+ arguments.append('),*')
else:
- arguments.append(',1),*')
+ if operation == 0:
+ arguments.append(',1),*')
+ else:
+ arguments.append('),*')
arguments.append('FROM')
arguments.append(layername)
if field != 'None':
diff --git a/python/plugins/processing/algs/qgis/AddTableField.py b/python/plugins/processing/algs/qgis/AddTableField.py
index 93c7dad..d722eef 100644
--- a/python/plugins/processing/algs/qgis/AddTableField.py
+++ b/python/plugins/processing/algs/qgis/AddTableField.py
@@ -78,11 +78,10 @@ class AddTableField(GeoAlgorithm):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))
- provider = layer.dataProvider()
- fields = provider.fields()
+ fields = layer.fields()
fields.append(QgsField(fieldName, self.TYPES[fieldType], '',
fieldLength, fieldPrecision))
- writer = output.getVectorWriter(fields, provider.geometryType(),
+ writer = output.getVectorWriter(fields, layer.wkbType(),
layer.crs())
outFeat = QgsFeature()
features = vector.features(layer)
diff --git a/python/plugins/processing/algs/qgis/AutoincrementalField.py b/python/plugins/processing/algs/qgis/AutoincrementalField.py
index 4412d80..8ec34a1 100644
--- a/python/plugins/processing/algs/qgis/AutoincrementalField.py
+++ b/python/plugins/processing/algs/qgis/AutoincrementalField.py
@@ -49,10 +49,9 @@ class AutoincrementalField(GeoAlgorithm):
output = self.getOutputFromName(self.OUTPUT)
vlayer = \
dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
- vprovider = vlayer.dataProvider()
- fields = vprovider.fields()
+ fields = vlayer.fields()
fields.append(QgsField('AUTO', QVariant.Int))
- writer = output.getVectorWriter(fields, vprovider.geometryType(),
+ writer = output.getVectorWriter(fields, vlayer.wkbType(),
vlayer.crs())
outFeat = QgsFeature()
features = vector.features(vlayer)
diff --git a/python/plugins/processing/algs/qgis/Centroids.py b/python/plugins/processing/algs/qgis/Centroids.py
index 8d5ee99..505f39c 100644
--- a/python/plugins/processing/algs/qgis/Centroids.py
+++ b/python/plugins/processing/algs/qgis/Centroids.py
@@ -63,7 +63,7 @@ class Centroids(GeoAlgorithm):
writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(
- layer.pendingFields().toList(),
+ layer.fields(),
QGis.WKBPoint,
layer.crs())
diff --git a/python/plugins/processing/algs/qgis/CheckValidity.py b/python/plugins/processing/algs/qgis/CheckValidity.py
index db5b5e5..1ac8061 100644
--- a/python/plugins/processing/algs/qgis/CheckValidity.py
+++ b/python/plugins/processing/algs/qgis/CheckValidity.py
@@ -97,27 +97,26 @@ class CheckValidity(GeoAlgorithm):
def doCheck(self, progress):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))
- provider = layer.dataProvider()
settings = QSettings()
method = int(settings.value(settings_method_key, 1))
valid_ouput = self.getOutputFromName(self.VALID_OUTPUT)
- valid_fields = layer.pendingFields().toList()
+ valid_fields = layer.fields()
valid_writer = valid_ouput.getVectorWriter(
valid_fields,
- provider.geometryType(),
+ layer.wkbType(),
layer.crs())
valid_count = 0
invalid_ouput = self.getOutputFromName(self.INVALID_OUTPUT)
- invalid_fields = layer.pendingFields().toList() + [
+ invalid_fields = layer.fields().toList() + [
QgsField(name='_errors',
type=QVariant.String,
len=255)]
invalid_writer = invalid_ouput.getVectorWriter(
invalid_fields,
- provider.geometryType(),
+ layer.wkbType(),
layer.crs())
invalid_count = 0
diff --git a/python/plugins/processing/algs/qgis/ConcaveHull.py b/python/plugins/processing/algs/qgis/ConcaveHull.py
index 5279ac1..36df1eb 100644
--- a/python/plugins/processing/algs/qgis/ConcaveHull.py
+++ b/python/plugins/processing/algs/qgis/ConcaveHull.py
@@ -111,7 +111,7 @@ class ConcaveHull(GeoAlgorithm):
feat = QgsFeature()
dissolved_layer.getFeatures(QgsFeatureRequest().setFilterFid(0)).nextFeature(feat)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- layer.pendingFields().toList(), QGis.WKBPolygon, layer.crs())
+ layer.fields().toList(), QGis.WKBPolygon, layer.crs())
geom = feat.geometry()
if no_multigeom and geom.isMultipart():
# Only singlepart geometries are allowed
diff --git a/python/plugins/processing/algs/qgis/ConvexHull.py b/python/plugins/processing/algs/qgis/ConvexHull.py
index 0f1a1bc..9627f2d 100644
--- a/python/plugins/processing/algs/qgis/ConvexHull.py
+++ b/python/plugins/processing/algs/qgis/ConvexHull.py
@@ -97,7 +97,7 @@ class ConvexHull(GeoAlgorithm):
]
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, QGis.WKBPolygon, layer.dataProvider().crs())
+ fields, QGis.WKBPolygon, layer.crs())
outFeat = QgsFeature()
inGeom = QgsGeometry()
diff --git a/python/plugins/processing/algs/qgis/DensifyGeometries.py b/python/plugins/processing/algs/qgis/DensifyGeometries.py
index bbc9fb4..f19ade8 100644
--- a/python/plugins/processing/algs/qgis/DensifyGeometries.py
+++ b/python/plugins/processing/algs/qgis/DensifyGeometries.py
@@ -112,10 +112,7 @@ class DensifyGeometries(GeoAlgorithm):
def densify(self, polyline, pointsNumber):
output = []
- if pointsNumber != 1:
- multiplier = 1.0 / float(pointsNumber + 1)
- else:
- multiplier = 1
+ multiplier = 1.0 / float(pointsNumber + 1)
for i in xrange(len(polyline) - 1):
p1 = polyline[i]
p2 = polyline[i + 1]
diff --git a/python/plugins/processing/algs/qgis/Difference.py b/python/plugins/processing/algs/qgis/Difference.py
index 5ce7525..56f38a1 100644
--- a/python/plugins/processing/algs/qgis/Difference.py
+++ b/python/plugins/processing/algs/qgis/Difference.py
@@ -68,11 +68,11 @@ class Difference(GeoAlgorithm):
self.getParameterValue(Difference.OVERLAY))
ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID)
- geomType = layerA.dataProvider().geometryType()
+ geomType = layerA.wkbType()
writer = self.getOutputFromName(
Difference.OUTPUT).getVectorWriter(layerA.pendingFields(),
geomType,
- layerA.dataProvider().crs())
+ layerA.crs())
outFeat = QgsFeature()
index = vector.spatialindex(layerB)
diff --git a/python/plugins/processing/algs/qgis/Dissolve.py b/python/plugins/processing/algs/qgis/Dissolve.py
index 8154d08..c471553 100644
--- a/python/plugins/processing/algs/qgis/Dissolve.py
+++ b/python/plugins/processing/algs/qgis/Dissolve.py
@@ -70,12 +70,11 @@ class Dissolve(GeoAlgorithm):
fieldname = self.getParameterValue(Dissolve.FIELD)
vlayerA = dataobjects.getObjectFromUri(
self.getParameterValue(Dissolve.INPUT))
- vproviderA = vlayerA.dataProvider()
fields = vlayerA.fields()
writer = self.getOutputFromName(
Dissolve.OUTPUT).getVectorWriter(fields,
- vproviderA.geometryType(),
- vproviderA.crs())
+ vlayerA.wkbType(),
+ vlayerA.crs())
outFeat = QgsFeature()
features = vector.features(vlayerA)
total = 100.0 / len(features)
diff --git a/python/plugins/processing/algs/qgis/Eliminate.py b/python/plugins/processing/algs/qgis/Eliminate.py
index 5fa24e4..60e9601 100644
--- a/python/plugins/processing/algs/qgis/Eliminate.py
+++ b/python/plugins/processing/algs/qgis/Eliminate.py
@@ -315,10 +315,9 @@ class Eliminate(GeoAlgorithm):
# End while
# Create output
- provider = processLayer.dataProvider()
output = self.getOutputFromName(self.OUTPUT)
- writer = output.getVectorWriter(provider.fields(),
- provider.geometryType(), processLayer.crs())
+ writer = output.getVectorWriter(processLayer.fields(),
+ processLayer.wkbType(), processLayer.crs())
# Write all features that are left over to output layer
iterator = processLayer.getFeatures()
diff --git a/python/plugins/processing/algs/qgis/EquivalentNumField.py b/python/plugins/processing/algs/qgis/EquivalentNumField.py
index a60851e..0468b34 100644
--- a/python/plugins/processing/algs/qgis/EquivalentNumField.py
+++ b/python/plugins/processing/algs/qgis/EquivalentNumField.py
@@ -54,11 +54,10 @@ class EquivalentNumField(GeoAlgorithm):
output = self.getOutputFromName(self.OUTPUT)
vlayer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT))
- vprovider = vlayer.dataProvider()
fieldindex = vlayer.fieldNameIndex(fieldname)
- fields = vprovider.fields()
+ fields = vlayer.fields()
fields.append(QgsField('NUM_FIELD', QVariant.Int))
- writer = output.getVectorWriter(fields, vprovider.geometryType(),
+ writer = output.getVectorWriter(fields, vlayer.wkbType(),
vlayer.crs())
outFeat = QgsFeature()
classes = {}
diff --git a/python/plugins/processing/algs/qgis/Explode.py b/python/plugins/processing/algs/qgis/Explode.py
index a541971..daa35ba 100644
--- a/python/plugins/processing/algs/qgis/Explode.py
+++ b/python/plugins/processing/algs/qgis/Explode.py
@@ -48,8 +48,7 @@ class Explode(GeoAlgorithm):
vlayer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT))
output = self.getOutputFromName(self.OUTPUT)
- vprovider = vlayer.dataProvider()
- fields = vprovider.fields()
+ fields = vlayer.fields()
writer = output.getVectorWriter(fields, QGis.WKBLineString,
vlayer.crs())
outFeat = QgsFeature()
diff --git a/python/plugins/processing/algs/qgis/ExportGeometryInfo.py b/python/plugins/processing/algs/qgis/ExportGeometryInfo.py
index f5eb74d..ddd21c6 100644
--- a/python/plugins/processing/algs/qgis/ExportGeometryInfo.py
+++ b/python/plugins/processing/algs/qgis/ExportGeometryInfo.py
@@ -89,7 +89,7 @@ class ExportGeometryInfo(GeoAlgorithm):
fields.append(QgsField(yName, QVariant.Double))
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields.toList(), layer.dataProvider().geometryType(), layer.crs())
+ fields.toList(), layer.wkbType(), layer.crs())
ellips = None
crs = None
diff --git a/python/plugins/processing/algs/qgis/ExtractByLocation.py b/python/plugins/processing/algs/qgis/ExtractByLocation.py
index 3477ba4..5df9981 100644
--- a/python/plugins/processing/algs/qgis/ExtractByLocation.py
+++ b/python/plugins/processing/algs/qgis/ExtractByLocation.py
@@ -71,7 +71,7 @@ class ExtractByLocation(GeoAlgorithm):
output = self.getOutputFromName(self.OUTPUT)
writer = output.getVectorWriter(layer.pendingFields(),
- layer.dataProvider().geometryType(), layer.crs())
+ layer.wkbType(), layer.crs())
if 'disjoint' in predicates:
disjoinSet = []
diff --git a/python/plugins/processing/algs/qgis/FieldPyculator.py b/python/plugins/processing/algs/qgis/FieldPyculator.py
index a347759..0f517fc 100644
--- a/python/plugins/processing/algs/qgis/FieldPyculator.py
+++ b/python/plugins/processing/algs/qgis/FieldPyculator.py
@@ -88,11 +88,10 @@ class FieldsPyculator(GeoAlgorithm):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))
- provider = layer.dataProvider()
- fields = provider.fields()
+ fields = layer.fields()
fields.append(QgsField(fieldName, self.TYPES[fieldType], '',
fieldLength, fieldPrecision))
- writer = output.getVectorWriter(fields, provider.geometryType(),
+ writer = output.getVectorWriter(fields, layer.wkbType(),
layer.crs())
outFeat = QgsFeature()
new_ns = {}
@@ -107,7 +106,7 @@ class FieldsPyculator(GeoAlgorithm):
self.tr("FieldPyculator code execute error.Global code block can't be executed!\n%s\n%s") % (unicode(sys.exc_info()[0].__name__), unicode(sys.exc_info()[1])))
# Replace all fields tags
- fields = provider.fields()
+ fields = layer.fields()
num = 0
for field in fields:
field_name = unicode(field.name())
diff --git a/python/plugins/processing/algs/qgis/FieldsCalculator.py b/python/plugins/processing/algs/qgis/FieldsCalculator.py
index 0bddcab..f769566 100644
--- a/python/plugins/processing/algs/qgis/FieldsCalculator.py
+++ b/python/plugins/processing/algs/qgis/FieldsCalculator.py
@@ -94,12 +94,11 @@ class FieldsCalculator(GeoAlgorithm):
output.value = system.getTempFilenameInTempFolder(
output.name + '.' + ext)
- provider = layer.dataProvider()
- fields = layer.pendingFields()
+ fields = layer.fields()
if newField:
fields.append(QgsField(fieldName, fieldType, '', width, precision))
- writer = output.getVectorWriter(fields, provider.geometryType(),
+ writer = output.getVectorWriter(fields, layer.wkbType(),
layer.crs())
exp = QgsExpression(formula)
diff --git a/python/plugins/processing/algs/qgis/FieldsMapper.py b/python/plugins/processing/algs/qgis/FieldsMapper.py
index f7eb85e..d8c9679 100644
--- a/python/plugins/processing/algs/qgis/FieldsMapper.py
+++ b/python/plugins/processing/algs/qgis/FieldsMapper.py
@@ -68,7 +68,6 @@ class FieldsMapper(GeoAlgorithm):
output = self.getOutputFromName(self.OUTPUT_LAYER)
layer = dataobjects.getObjectFromUri(layer)
- provider = layer.dataProvider()
fields = []
expressions = []
@@ -109,7 +108,7 @@ class FieldsMapper(GeoAlgorithm):
expressions.append(expression)
writer = output.getVectorWriter(fields,
- provider.geometryType(),
+ layer.wkbType(),
layer.crs())
# Create output vector layer with new attributes
diff --git a/python/plugins/processing/algs/qgis/Intersection.py b/python/plugins/processing/algs/qgis/Intersection.py
index 76395c3..f774c30 100644
--- a/python/plugins/processing/algs/qgis/Intersection.py
+++ b/python/plugins/processing/algs/qgis/Intersection.py
@@ -73,12 +73,11 @@ class Intersection(GeoAlgorithm):
self.getParameterValue(self.INPUT))
vlayerB = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT2))
- vproviderA = vlayerA.dataProvider()
- geomType = vproviderA.geometryType()
+ geomType = vlayerA.wkbType()
fields = vector.combineVectorFields(vlayerA, vlayerB)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
- geomType, vproviderA.crs())
+ geomType, vlayerA.crs())
outFeat = QgsFeature()
index = vector.spatialindex(vlayerB)
selectionA = vector.features(vlayerA)
diff --git a/python/plugins/processing/algs/qgis/JoinAttributes.py b/python/plugins/processing/algs/qgis/JoinAttributes.py
index cb48f1a..e1422d7 100644
--- a/python/plugins/processing/algs/qgis/JoinAttributes.py
+++ b/python/plugins/processing/algs/qgis/JoinAttributes.py
@@ -69,14 +69,13 @@ class JoinAttributes(GeoAlgorithm):
field2 = self.getParameterValue(self.TABLE_FIELD_2)
layer = dataobjects.getObjectFromUri(input)
- provider = layer.dataProvider()
joinField1Index = layer.fieldNameIndex(field)
layer2 = dataobjects.getObjectFromUri(input2)
joinField2Index = layer2.fieldNameIndex(field2)
outFields = vector.combineVectorFields(layer, layer2)
- writer = output.getVectorWriter(outFields, provider.geometryType(),
+ writer = output.getVectorWriter(outFields, layer.wkbType(),
layer.crs())
# Cache attributes of Layer 2
diff --git a/python/plugins/processing/algs/qgis/Merge.py b/python/plugins/processing/algs/qgis/Merge.py
index b348a57..760b59a 100644
--- a/python/plugins/processing/algs/qgis/Merge.py
+++ b/python/plugins/processing/algs/qgis/Merge.py
@@ -66,14 +66,14 @@ class Merge(GeoAlgorithm):
layer = QgsVectorLayer(paths[x], unicode(x), 'ogr')
if (len(layers) > 0):
- if (layer.dataProvider().geometryType() != layers[0].dataProvider().geometryType()):
+ if (layer.wkbType() != layers[0].wkbType()):
raise GeoAlgorithmExecutionException(
self.tr('All layers must have same geometry type!'))
layers.append(layer)
totalFeatureCount += layer.featureCount()
- for sindex, sfield in enumerate(layer.dataProvider().fields()):
+ for sindex, sfield in enumerate(layer.fields()):
found = None
for dfield in fields:
if (dfield.name().upper() == sfield.name().upper()):
@@ -88,12 +88,12 @@ class Merge(GeoAlgorithm):
total = 100.0 / totalFeatureCount
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields.toList(), layers[0].dataProvider().geometryType(),
+ fields.toList(), layers[0].wkbType(),
layers[0].crs())
featureCount = 0
for layer in layers:
- for feature in layer.dataProvider().getFeatures():
+ for feature in layer.getFeatures():
sattributes = feature.attributes()
dattributes = []
for dindex, dfield in enumerate(fields):
@@ -104,7 +104,7 @@ class Merge(GeoAlgorithm):
else:
dattribute = ''
- for sindex, sfield in enumerate(layer.dataProvider().fields()):
+ for sindex, sfield in enumerate(layer.fields()):
if (sfield.name().upper() == dfield.name().upper()):
if (sfield.type() != dfield.type()):
raise GeoAlgorithmExecutionException(
diff --git a/python/plugins/processing/algs/qgis/MultipartToSingleparts.py b/python/plugins/processing/algs/qgis/MultipartToSingleparts.py
index 67f19ab..a95b577 100644
--- a/python/plugins/processing/algs/qgis/MultipartToSingleparts.py
+++ b/python/plugins/processing/algs/qgis/MultipartToSingleparts.py
@@ -58,25 +58,27 @@ class MultipartToSingleparts(GeoAlgorithm):
def processAlgorithm(self, progress):
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
- geomType = self.multiToSingleGeom(layer.dataProvider().geometryType())
+ geomType = self.multiToSingleGeom(layer.wkbType())
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
layer.pendingFields().toList(), geomType, layer.crs())
- outFeat = QgsFeature()
- inGeom = QgsGeometry()
-
features = vector.features(layer)
total = 100.0 / len(features)
for current, f in enumerate(features):
- inGeom = f.geometry()
+ outFeat = QgsFeature()
attrs = f.attributes()
-
- geometries = self.extractAsSingle(inGeom)
outFeat.setAttributes(attrs)
- for g in geometries:
- outFeat.setGeometry(g)
+ if f.constGeometry():
+ inGeom = QgsGeometry(f.constGeometry())
+ geometries = self.extractAsSingle(inGeom)
+
+ for g in geometries:
+ outFeat.setGeometry(g)
+ writer.addFeature(outFeat)
+ else:
+ #input feature with null geometry
writer.addFeature(outFeat)
progress.setPercentage(int(current * total))
diff --git a/python/plugins/processing/algs/qgis/OrientedMinimumBoundingBox.py b/python/plugins/processing/algs/qgis/OrientedMinimumBoundingBox.py
index 4f702e2d6..72e5900 100644
--- a/python/plugins/processing/algs/qgis/OrientedMinimumBoundingBox.py
+++ b/python/plugins/processing/algs/qgis/OrientedMinimumBoundingBox.py
@@ -82,11 +82,10 @@ class OrientedMinimumBoundingBox(GeoAlgorithm):
def layerOmmb(self, layer, writer, progress):
current = 0
- vprovider = layer.dataProvider()
- fit = vprovider.getFeatures()
+ fit = layer.getFeatures()
inFeat = QgsFeature()
- total = 100.0 / vprovider.featureCount()
+ total = 100.0 / layer.featureCount()
newgeometry = QgsGeometry()
first = True
while fit.nextFeature(inFeat):
diff --git a/python/plugins/processing/algs/qgis/PointsDisplacement.py b/python/plugins/processing/algs/qgis/PointsDisplacement.py
index bae5822..c61d480 100644
--- a/python/plugins/processing/algs/qgis/PointsDisplacement.py
+++ b/python/plugins/processing/algs/qgis/PointsDisplacement.py
@@ -62,9 +62,8 @@ class PointsDisplacement(GeoAlgorithm):
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER))
- provider = layer.dataProvider()
- writer = output.getVectorWriter(provider.fields(),
- provider.geometryType(), provider.crs())
+ writer = output.getVectorWriter(layer.fields(),
+ layer.wkbType(), layer.crs())
features = vector.features(layer)
diff --git a/python/plugins/processing/algs/qgis/PointsInPolygon.py b/python/plugins/processing/algs/qgis/PointsInPolygon.py
index e11f6e6..d457e9d 100644
--- a/python/plugins/processing/algs/qgis/PointsInPolygon.py
+++ b/python/plugins/processing/algs/qgis/PointsInPolygon.py
@@ -68,15 +68,14 @@ class PointsInPolygon(GeoAlgorithm):
pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS))
fieldName = self.getParameterValue(self.FIELD)
- polyProvider = polyLayer.dataProvider()
- fields = polyProvider.fields()
+ fields = polyLayer.fields()
fields.append(QgsField(fieldName, QVariant.Int))
(idxCount, fieldList) = vector.findOrCreateField(polyLayer,
- polyLayer.pendingFields(), fieldName)
+ polyLayer.fields(), fieldName)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields.toList(), polyProvider.geometryType(), polyProvider.crs())
+ fields.toList(), polyLayer.wkbType(), polyLayer.crs())
spatialIndex = vector.spatialindex(pointLayer)
diff --git a/python/plugins/processing/algs/qgis/PointsInPolygonUnique.py b/python/plugins/processing/algs/qgis/PointsInPolygonUnique.py
index 1da6ad0..d0dc350 100644
--- a/python/plugins/processing/algs/qgis/PointsInPolygonUnique.py
+++ b/python/plugins/processing/algs/qgis/PointsInPolygonUnique.py
@@ -62,8 +62,7 @@ class PointsInPolygonUnique(GeoAlgorithm):
fieldName = self.getParameterValue(self.FIELD)
classFieldName = self.getParameterValue(self.CLASSFIELD)
- polyProvider = polyLayer.dataProvider()
- fields = polyProvider.fields()
+ fields = polyLayer.fields()
fields.append(QgsField(fieldName, QVariant.Int))
classFieldIndex = pointLayer.fieldNameIndex(classFieldName)
@@ -71,7 +70,7 @@ class PointsInPolygonUnique(GeoAlgorithm):
polyLayer.pendingFields(), fieldName)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields.toList(), polyProvider.geometryType(), polyProvider.crs())
+ fields.toList(), polyLayer.wkbType(), polyLayer.crs())
spatialIndex = vector.spatialindex(pointLayer)
diff --git a/python/plugins/processing/algs/qgis/PointsInPolygonWeighted.py b/python/plugins/processing/algs/qgis/PointsInPolygonWeighted.py
index cb19a22..13ae723 100644
--- a/python/plugins/processing/algs/qgis/PointsInPolygonWeighted.py
+++ b/python/plugins/processing/algs/qgis/PointsInPolygonWeighted.py
@@ -69,15 +69,14 @@ class PointsInPolygonWeighted(GeoAlgorithm):
fieldName = self.getParameterValue(self.FIELD)
fieldIdx = pointLayer.fieldNameIndex(self.getParameterValue(self.WEIGHT))
- polyProvider = polyLayer.dataProvider()
- fields = polyProvider.fields()
+ fields = polyLayer.fields()
fields.append(QgsField(fieldName, QVariant.Int))
(idxCount, fieldList) = vector.findOrCreateField(polyLayer,
- polyLayer.pendingFields(), fieldName)
+ polyLayer.fields(), fieldName)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields.toList(), polyProvider.geometryType(), polyProvider.crs())
+ fields.toList(), polyLayer.wkbType(), polyLayer.crs())
spatialIndex = vector.spatialindex(pointLayer)
diff --git a/python/plugins/processing/algs/qgis/PointsLayerFromTable.py b/python/plugins/processing/algs/qgis/PointsLayerFromTable.py
index 07d45e1..4929870 100644
--- a/python/plugins/processing/algs/qgis/PointsLayerFromTable.py
+++ b/python/plugins/processing/algs/qgis/PointsLayerFromTable.py
@@ -63,8 +63,7 @@ class PointsLayerFromTable(GeoAlgorithm):
source = self.getParameterValue(self.INPUT)
vlayer = dataobjects.getObjectFromUri(source)
output = self.getOutputFromName(self.OUTPUT)
- vprovider = vlayer.dataProvider()
- fields = vprovider.fields()
+ fields = vlayer.fields()
writer = output.getVectorWriter(fields, QGis.WKBPoint, self.crs)
xfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.XFIELD))
yfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.YFIELD))
diff --git a/python/plugins/processing/algs/qgis/PointsToPaths.py b/python/plugins/processing/algs/qgis/PointsToPaths.py
index aaa33cb..8407916 100644
--- a/python/plugins/processing/algs/qgis/PointsToPaths.py
+++ b/python/plugins/processing/algs/qgis/PointsToPaths.py
@@ -81,7 +81,7 @@ class PointsToPaths(GeoAlgorithm):
fields.append(QgsField('begin', QVariant.String, '', 254, 0))
fields.append(QgsField('end', QVariant.String, '', 254, 0))
writer = self.getOutputFromName(self.OUTPUT_LINES).getVectorWriter(
- fields, QGis.WKBLineString, layer.dataProvider().crs())
+ fields, QGis.WKBLineString, layer.crs())
points = dict()
features = vector.features(layer)
diff --git a/python/plugins/processing/algs/qgis/Polygonize.py b/python/plugins/processing/algs/qgis/Polygonize.py
index 8334804..18a6900 100644
--- a/python/plugins/processing/algs/qgis/Polygonize.py
+++ b/python/plugins/processing/algs/qgis/Polygonize.py
@@ -60,9 +60,8 @@ class Polygonize(GeoAlgorithm):
def processAlgorithm(self, progress):
vlayer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
output = self.getOutputFromName(self.OUTPUT)
- vprovider = vlayer.dataProvider()
if self.getParameterValue(self.FIELDS):
- fields = vprovider.fields()
+ fields = vlayer.fields()
else:
fields = QgsFields()
if self.getParameterValue(self.GEOMETRY):
diff --git a/python/plugins/processing/algs/qgis/RandomPointsAlongLines.py b/python/plugins/processing/algs/qgis/RandomPointsAlongLines.py
index f7df447..6dcfb90 100644
--- a/python/plugins/processing/algs/qgis/RandomPointsAlongLines.py
+++ b/python/plugins/processing/algs/qgis/RandomPointsAlongLines.py
@@ -68,7 +68,7 @@ class RandomPointsAlongLines(GeoAlgorithm):
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, QGis.WKBPoint, layer.dataProvider().crs())
+ fields, QGis.WKBPoint, layer.crs())
nPoints = 0
nIterations = 0
diff --git a/python/plugins/processing/algs/qgis/RandomPointsLayer.py b/python/plugins/processing/algs/qgis/RandomPointsLayer.py
index 5042533..e661358 100644
--- a/python/plugins/processing/algs/qgis/RandomPointsLayer.py
+++ b/python/plugins/processing/algs/qgis/RandomPointsLayer.py
@@ -77,7 +77,7 @@ class RandomPointsLayer(GeoAlgorithm):
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, QGis.WKBPoint, layer.dataProvider().crs())
+ fields, QGis.WKBPoint, layer.crs())
nPoints = 0
nIterations = 0
diff --git a/python/plugins/processing/algs/qgis/RandomPointsPolygonsFixed.py b/python/plugins/processing/algs/qgis/RandomPointsPolygonsFixed.py
index 073f5c2..afe334c 100644
--- a/python/plugins/processing/algs/qgis/RandomPointsPolygonsFixed.py
+++ b/python/plugins/processing/algs/qgis/RandomPointsPolygonsFixed.py
@@ -83,7 +83,7 @@ class RandomPointsPolygonsFixed(GeoAlgorithm):
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, QGis.WKBPoint, layer.dataProvider().crs())
+ fields, QGis.WKBPoint, layer.crs())
da = QgsDistanceArea()
diff --git a/python/plugins/processing/algs/qgis/RandomPointsPolygonsVariable.py b/python/plugins/processing/algs/qgis/RandomPointsPolygonsVariable.py
index d14898a..fe88b9f 100644
--- a/python/plugins/processing/algs/qgis/RandomPointsPolygonsVariable.py
+++ b/python/plugins/processing/algs/qgis/RandomPointsPolygonsVariable.py
@@ -84,7 +84,7 @@ class RandomPointsPolygonsVariable(GeoAlgorithm):
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, QGis.WKBPoint, layer.dataProvider().crs())
+ fields, QGis.WKBPoint, layer.crs())
da = QgsDistanceArea()
diff --git a/python/plugins/processing/algs/qgis/ReverseLineDirection.py b/python/plugins/processing/algs/qgis/ReverseLineDirection.py
index 9b5eefa..c5bf196 100644
--- a/python/plugins/processing/algs/qgis/ReverseLineDirection.py
+++ b/python/plugins/processing/algs/qgis/ReverseLineDirection.py
@@ -49,12 +49,11 @@ class ReverseLineDirection(GeoAlgorithm):
def processAlgorithm(self, progress):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))
- provider = layer.dataProvider()
writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(
layer.fields().toList(),
- provider.geometryType(),
+ layer.wkbType(),
layer.crs())
outFeat = QgsFeature()
diff --git a/python/plugins/processing/algs/qgis/SaveSelectedFeatures.py b/python/plugins/processing/algs/qgis/SaveSelectedFeatures.py
index 756e870..77a8a58 100644
--- a/python/plugins/processing/algs/qgis/SaveSelectedFeatures.py
+++ b/python/plugins/processing/algs/qgis/SaveSelectedFeatures.py
@@ -52,9 +52,8 @@ class SaveSelectedFeatures(GeoAlgorithm):
vectorLayer = dataobjects.getObjectFromUri(inputFilename)
- provider = vectorLayer.dataProvider()
- writer = output.getVectorWriter(provider.fields(),
- provider.geometryType(), vectorLayer.crs())
+ writer = output.getVectorWriter(vectorLayer.fields(),
+ vectorLayer.wkbType(), vectorLayer.crs())
features = vector.features(vectorLayer)
total = 100.0 / len(features)
diff --git a/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py b/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py
index 37d841d..e563201 100644
--- a/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py
+++ b/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py
@@ -64,7 +64,7 @@ class SinglePartsToMultiparts(GeoAlgorithm):
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
fieldName = self.getParameterValue(self.FIELD)
- geomType = self.singleToMultiGeom(layer.dataProvider().geometryType())
+ geomType = self.singleToMultiGeom(layer.wkbType())
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
layer.pendingFields().toList(), geomType, layer.crs())
diff --git a/python/plugins/processing/algs/qgis/Smooth.py b/python/plugins/processing/algs/qgis/Smooth.py
index bd9c8f4..45bea2b 100644
--- a/python/plugins/processing/algs/qgis/Smooth.py
+++ b/python/plugins/processing/algs/qgis/Smooth.py
@@ -55,14 +55,13 @@ class Smooth(GeoAlgorithm):
def processAlgorithm(self, progress):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))
- provider = layer.dataProvider()
iterations = self.getParameterValue(self.ITERATIONS)
offset = self.getParameterValue(self.OFFSET)
writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(
layer.fields().toList(),
- provider.geometryType(),
+ layer.wkbType(),
layer.crs())
outFeat = QgsFeature()
diff --git a/python/plugins/processing/algs/qgis/SpatialJoin.py b/python/plugins/processing/algs/qgis/SpatialJoin.py
index edf5d98..056fce6 100644
--- a/python/plugins/processing/algs/qgis/SpatialJoin.py
+++ b/python/plugins/processing/algs/qgis/SpatialJoin.py
@@ -108,11 +108,8 @@ class SpatialJoin(GeoAlgorithm):
sumList = self.getParameterValue(self.STATS).lower().split(',')
- targetProvider = target.dataProvider()
- joinProvider = join.dataProvider()
-
- targetFields = targetProvider.fields()
- joinFields = joinProvider.fields()
+ targetFields = target.fields()
+ joinFields = join.fields()
fieldList = QgsFields()
@@ -141,7 +138,7 @@ class SpatialJoin(GeoAlgorithm):
fields.append(f)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, targetProvider.geometryType(), targetProvider.crs())
+ fields, target.wkbType(), target.crs())
outFeat = QgsFeature()
inFeatB = QgsFeature()
diff --git a/python/plugins/processing/algs/qgis/SumLines.py b/python/plugins/processing/algs/qgis/SumLines.py
index 7048fe6..e26cbb5 100644
--- a/python/plugins/processing/algs/qgis/SumLines.py
+++ b/python/plugins/processing/algs/qgis/SumLines.py
@@ -72,15 +72,13 @@ class SumLines(GeoAlgorithm):
lengthFieldName = self.getParameterValue(self.LEN_FIELD)
countFieldName = self.getParameterValue(self.COUNT_FIELD)
- polyProvider = polyLayer.dataProvider()
-
(idxLength, fieldList) = vector.findOrCreateField(polyLayer,
- polyLayer.pendingFields(), lengthFieldName)
+ polyLayer.fields(), lengthFieldName)
(idxCount, fieldList) = vector.findOrCreateField(polyLayer, fieldList,
countFieldName)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fieldList.toList(), polyProvider.geometryType(), polyProvider.crs())
+ fieldList.toList(), polyLayer.wkbType(), polyLayer.crs())
spatialIndex = vector.spatialindex(lineLayer)
diff --git a/python/plugins/processing/algs/qgis/SymmetricalDifference.py b/python/plugins/processing/algs/qgis/SymmetricalDifference.py
index 79f5500..251b8cc 100644
--- a/python/plugins/processing/algs/qgis/SymmetricalDifference.py
+++ b/python/plugins/processing/algs/qgis/SymmetricalDifference.py
@@ -65,13 +65,10 @@ class SymmetricalDifference(GeoAlgorithm):
layerB = dataobjects.getObjectFromUri(
self.getParameterValue(self.OVERLAY))
- providerA = layerA.dataProvider()
- providerB = layerB.dataProvider()
-
- geomType = providerA.geometryType()
+ geomType = layerA.wkbType()
fields = vector.combineVectorFields(layerA, layerB)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
- fields, geomType, providerA.crs())
+ fields, geomType, layerA.crs())
featB = QgsFeature()
outFeat = QgsFeature()
@@ -92,7 +89,7 @@ class SymmetricalDifference(GeoAlgorithm):
attrs = featA.attributes()
intersects = indexA.intersects(geom.boundingBox())
for i in intersects:
- providerB.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
+ layerB.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
tmpGeom = QgsGeometry(featB.geometry())
if diffGeom.intersects(tmpGeom):
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
@@ -117,7 +114,7 @@ class SymmetricalDifference(GeoAlgorithm):
count += 1
progress.setPercentage(int(count * total))
- length = len(providerA.fields())
+ length = len(layerA.fields())
for featA in featuresB:
add = True
@@ -127,7 +124,7 @@ class SymmetricalDifference(GeoAlgorithm):
attrs = [NULL] * length + attrs
intersects = indexB.intersects(geom.boundingBox())
for i in intersects:
- providerA.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
+ layerA.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
tmpGeom = QgsGeometry(featB.geometry())
if diffGeom.intersects(tmpGeom):
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
diff --git a/python/plugins/processing/algs/qgis/Union.py b/python/plugins/processing/algs/qgis/Union.py
index 84efb35..1fff140 100644
--- a/python/plugins/processing/algs/qgis/Union.py
+++ b/python/plugins/processing/algs/qgis/Union.py
@@ -72,9 +72,7 @@ class Union(GeoAlgorithm):
vlayerA = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT))
vlayerB = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT2))
- vproviderA = vlayerA.dataProvider()
-
- geomType = vproviderA.geometryType()
+ geomType = vlayerA.wkbType()
fields = vector.combineVectorFields(vlayerA, vlayerB)
writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter(fields,
geomType, vproviderA.crs())
@@ -175,7 +173,7 @@ class Union(GeoAlgorithm):
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
- length = len(vproviderA.fields())
+ length = len(vlayerA.fields())
atMapA = [None] * length
featuresA = vector.features(vlayerB)
diff --git a/python/plugins/processing/algs/qgis/VectorSplit.py b/python/plugins/processing/algs/qgis/VectorSplit.py
index 5c6cee7..7659808 100644
--- a/python/plugins/processing/algs/qgis/VectorSplit.py
+++ b/python/plugins/processing/algs/qgis/VectorSplit.py
@@ -71,7 +71,7 @@ class VectorSplit(GeoAlgorithm):
baseName = os.path.join(directory, '{0}_{1}'.format(layer.name(), fieldName))
fields = layer.pendingFields()
- crs = layer.dataProvider().crs()
+ crs = layer.crs()
geomType = layer.wkbType()
total = 100.0 / len(uniqueValues)
diff --git a/python/plugins/processing/algs/qgis/ZonalStatistics.py b/python/plugins/processing/algs/qgis/ZonalStatistics.py
index 4d09e4c..510bae2 100644
--- a/python/plugins/processing/algs/qgis/ZonalStatistics.py
+++ b/python/plugins/processing/algs/qgis/ZonalStatistics.py
@@ -158,7 +158,7 @@ class ZonalStatistics(GeoAlgorithm):
columnPrefix + 'mode', 21, 6)
writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
- fields.toList(), layer.dataProvider().geometryType(), layer.crs())
+ fields.toList(), layer.wkbType(), layer.crs())
outFeat = QgsFeature()
diff --git a/python/plugins/processing/core/SilentProgress.py b/python/plugins/processing/core/SilentProgress.py
index cff916f..06e5605 100644
--- a/python/plugins/processing/core/SilentProgress.py
+++ b/python/plugins/processing/core/SilentProgress.py
@@ -37,16 +37,16 @@ class SilentProgress(object):
def setPercentage(self, i):
pass
- def setInfo(self, _):
+ def setInfo(self, msg):
pass
- def setCommand(self, _):
+ def setCommand(self, msg):
pass
- def setDebugInfo(self, _):
+ def setDebugInfo(self, msg):
pass
- def setConsoleInfo(self, _):
+ def setConsoleInfo(self, msg):
pass
def close(self):
diff --git a/python/plugins/processing/gui/AlgorithmDialogBase.py b/python/plugins/processing/gui/AlgorithmDialogBase.py
index c4e02db..94775e8 100644
--- a/python/plugins/processing/gui/AlgorithmDialogBase.py
+++ b/python/plugins/processing/gui/AlgorithmDialogBase.py
@@ -171,6 +171,9 @@ class AlgorithmDialogBase(BASE, WIDGET):
self.setInfo(text, False)
QCoreApplication.processEvents()
+ def error(self, text):
+ self.setInfo(text, error=True)
+
def setParamValues(self):
pass
diff --git a/python/plugins/processing/gui/GetScriptsAndModels.py b/python/plugins/processing/gui/GetScriptsAndModels.py
index ab686e1..ccd4523 100644
--- a/python/plugins/processing/gui/GetScriptsAndModels.py
+++ b/python/plugins/processing/gui/GetScriptsAndModels.py
@@ -40,12 +40,13 @@ from qgis.utils import iface, show_message_log
from qgis.core import QgsNetworkAccessManager, QgsMessageLog
from qgis.gui import QgsMessageBar
+from processing.core.alglist import algList
from processing.gui.ToolboxAction import ToolboxAction
+from processing.gui import Help2Html
+from processing.gui.Help2Html import getDescription, ALG_DESC, ALG_VERSION, ALG_CREATOR
from processing.script.ScriptUtils import ScriptUtils
from processing.algs.r.RUtils import RUtils
from processing.modeler.ModelerUtils import ModelerUtils
-from processing.gui import Help2Html
-from processing.gui.Help2Html import getDescription, ALG_DESC, ALG_VERSION, ALG_CREATOR
pluginPath = os.path.split(os.path.dirname(__file__))[0]
WIDGET, BASE = uic.loadUiType(
@@ -128,15 +129,15 @@ class GetScriptsAndModelsDialog(BASE, WIDGET):
self.resourceType = resourceType
if self.resourceType == self.MODELS:
- self.folder = ModelerUtils.defaultModelsFolder()
+ self.folder = ModelerUtils.modelsFolders()[0]
self.urlBase = 'https://raw.githubusercontent.com/qgis/QGIS-Processing/master/models/'
self.icon = QIcon(os.path.join(pluginPath, 'images', 'model.png'))
elif self.resourceType == self.SCRIPTS:
- self.folder = ScriptUtils.defaultScriptsFolder()
+ self.folder = ScriptUtils.scriptsFolders()[0]
self.urlBase = 'https://raw.githubusercontent.com/qgis/QGIS-Processing/master/scripts/'
self.icon = QIcon(os.path.join(pluginPath, 'images', 'script.png'))
else:
- self.folder = RUtils.defaultRScriptsFolder()
+ self.folder = RUtils.RScriptsFolders()[0]
self.urlBase = 'https://raw.githubusercontent.com/qgis/QGIS-Processing/master/rscripts/'
self.icon = QIcon(os.path.join(pluginPath, 'images', 'r.svg'))
diff --git a/python/plugins/processing/gui/ListMultiselectWidget.py b/python/plugins/processing/gui/ListMultiselectWidget.py
index 3283ee4..f7ca14b 100644
--- a/python/plugins/processing/gui/ListMultiselectWidget.py
+++ b/python/plugins/processing/gui/ListMultiselectWidget.py
@@ -23,7 +23,7 @@ from qgis.PyQt.QtWidgets import (QGroupBox,
QListWidget,
QAbstractItemView)
from qgis.PyQt.QtGui import QFont
-from qgis.PyQt.QtCore import pyqtSignal
+from qgis.PyQt.QtCore import Qt, QSize, pyqtSignal
class ListMultiSelectWidget(QGroupBox):
@@ -163,7 +163,7 @@ class ListMultiSelectWidget(QGroupBox):
self._set_list_widget_defaults(self.unselected_widget)
unselected_label = QLabel()
unselected_label.setText('Unselected')
- unselected_label.setAlignment(Qt.Qt.AlignCenter)
+ unselected_label.setAlignment(Qt.AlignCenter)
unselected_label.setFont(italic_font)
unselected_v_layout = QVBoxLayout()
unselected_v_layout.addWidget(unselected_label)
@@ -174,7 +174,7 @@ class ListMultiSelectWidget(QGroupBox):
self._set_list_widget_defaults(self.selected_widget)
selected_label = QLabel()
selected_label.setText('Selected')
- selected_label.setAlignment(Qt.Qt.AlignCenter)
+ selected_label.setAlignment(Qt.AlignCenter)
selected_label.setFont(italic_font)
selected_v_layout = QVBoxLayout()
selected_v_layout.addWidget(selected_label)
@@ -215,7 +215,7 @@ class ListMultiSelectWidget(QGroupBox):
widget.setDragEnabled(True)
widget.setDragDropMode(QAbstractItemView.DragDrop)
widget.setDragDropOverwriteMode(False)
- widget.setDefaultDropAction(QtCore.Qt.MoveAction)
+ widget.setDefaultDropAction(Qt.MoveAction)
widget.setSelectionMode(QAbstractItemView.MultiSelection)
@@ -227,4 +227,4 @@ class SmallQPushButton(QPushButton):
buttons_size_policy = QSizePolicy(
QSizePolicy.Fixed, QSizePolicy.Fixed)
self.setSizePolicy(buttons_size_policy)
- self.setMaximumSize(QtCore.QSize(30, 30))
+ self.setMaximumSize(QSize(30, 30))
diff --git a/python/plugins/processing/gui/ScriptEditorDialog.py b/python/plugins/processing/gui/ScriptEditorDialog.py
index b178441..6f9fa24 100644
--- a/python/plugins/processing/gui/ScriptEditorDialog.py
+++ b/python/plugins/processing/gui/ScriptEditorDialog.py
@@ -193,10 +193,10 @@ class ScriptEditorDialog(BASE, WIDGET):
return
if self.algType == self.SCRIPT_PYTHON:
- scriptDir = ScriptUtils.defaultScriptsFolder()
+ scriptDir = ScriptUtils.scriptsFolders()[0]
filterName = self.tr('Python scripts (*.py)')
elif self.algType == self.SCRIPT_R:
- scriptDir = RUtils.defaultRScriptsFolder()
+ scriptDir = RUtils.RScriptsFolders()[0]
filterName = self.tr('Processing R script (*.rsx)')
self.filename = QFileDialog.getOpenFileName(
@@ -224,10 +224,10 @@ class ScriptEditorDialog(BASE, WIDGET):
def saveScript(self, saveAs):
if self.filename is None or saveAs:
if self.algType == self.SCRIPT_PYTHON:
- scriptDir = ScriptUtils.defaultScriptsFolder()
+ scriptDir = ScriptUtils.scriptsFolders()[0]
filterName = self.tr('Python scripts (*.py)')
elif self.algType == self.SCRIPT_R:
- scriptDir = RUtils.defaultRScriptsFolder()
+ scriptDir = RUtils.RScriptsFolders()[0]
filterName = self.tr('Processing R script (*.rsx)')
self.filename = unicode(QFileDialog.getSaveFileName(self,
diff --git a/python/plugins/processing/modeler/AddModelFromFileAction.py b/python/plugins/processing/modeler/AddModelFromFileAction.py
index 456fe6d..d95a716 100644
--- a/python/plugins/processing/modeler/AddModelFromFileAction.py
+++ b/python/plugins/processing/modeler/AddModelFromFileAction.py
@@ -71,6 +71,6 @@ class AddModelFromFileAction(ToolboxAction):
self.tr('Error reading model', 'AddModelFromFileAction'),
self.tr('Cannot read file', 'AddModelFromFileAction'))
return
- destFilename = os.path.join(ModelerUtils.modelsFolder(), os.path.basename(filename))
+ destFilename = os.path.join(ModelerUtils.modelsFolders()[0], os.path.basename(filename))
shutil.copyfile(filename, destFilename)
algList.reloadProvider('model')
diff --git a/python/plugins/processing/modeler/ModelerDialog.py b/python/plugins/processing/modeler/ModelerDialog.py
index ca95279..696d437 100644
--- a/python/plugins/processing/modeler/ModelerDialog.py
+++ b/python/plugins/processing/modeler/ModelerDialog.py
@@ -310,7 +310,7 @@ class ModelerDialog(BASE, WIDGET):
else:
filename = unicode(QFileDialog.getSaveFileName(self,
self.tr('Save Model'),
- ModelerUtils.defaultModelsFolder(),
+ ModelerUtils.modelsFolders()[0],
self.tr('Processing models (*.model)')))
if filename:
if not filename.endswith('.model'):
@@ -341,7 +341,7 @@ class ModelerDialog(BASE, WIDGET):
def openModel(self):
filename = unicode(QFileDialog.getOpenFileName(self,
- self.tr('Open Model'), ModelerUtils.defaultModelsFolder(),
+ self.tr('Open Model'), ModelerUtils.modelsFolders()[0],
self.tr('Processing models (*.model *.MODEL)')))
if filename:
try:
diff --git a/python/plugins/processing/script/AddScriptFromFileAction.py b/python/plugins/processing/script/AddScriptFromFileAction.py
index 75a9181..64a3123 100644
--- a/python/plugins/processing/script/AddScriptFromFileAction.py
+++ b/python/plugins/processing/script/AddScriptFromFileAction.py
@@ -65,7 +65,7 @@ class AddScriptFromFileAction(ToolboxAction):
self.tr('Error reading script', 'AddScriptFromFileAction'),
self.tr('The selected file does not contain a valid script', 'AddScriptFromFileAction'))
return
- destFilename = os.path.join(ScriptUtils.scriptsFolder(), os.path.basename(filename))
+ destFilename = os.path.join(ScriptUtils.scriptsFolders()[0], os.path.basename(filename))
with open(destFilename, 'w') as f:
f.write(script.script)
algList.reloadProvider('script')
diff --git a/python/testing/__init__.py b/python/testing/__init__.py
index 1285e75..3e1984a 100644
--- a/python/testing/__init__.py
+++ b/python/testing/__init__.py
@@ -73,7 +73,10 @@ class TestCase(_TestCase):
except KeyError:
precision = 14
- for feats in zip(layer_expected.getFeatures(request), layer_result.getFeatures(request)):
+ expected_features = sorted(layer_expected.getFeatures(request), key=lambda f: f.id())
+ result_features = sorted(layer_expected.getFeatures(request), key=lambda f: f.id())
+
+ for feats in zip(expected_features, result_features):
if feats[0].geometry() is not None:
geom0 = feats[0].geometry().geometry().asWkt(precision)
else:
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index 0a84300..94f4c2e 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -376,7 +376,7 @@ static void setTitleBarText_( QWidget & qgisApp )
{
QString caption = QgisApp::tr( "QGIS " );
- if ( QGis::QGIS_VERSION.endsWith( "Master" ) )
+ if ( QGis::QGIS_RELEASE_NAME == "Master" )
{
caption += QString( "%1" ).arg( QGis::QGIS_DEV_VERSION );
}
@@ -11258,13 +11258,13 @@ void QgisApp::projectChanged( const QDomDocument &doc )
if ( !prevProjectDir.isNull() )
{
QString prev = prevProjectDir;
- expr = QString( "sys.path.remove('%1'); " ).arg( prev.replace( '\'', "\\'" ) );
+ expr = QString( "sys.path.remove(u'%1'); " ).arg( prev.replace( '\'', "\\'" ) );
}
prevProjectDir = fi.canonicalPath();
QString prev = prevProjectDir;
- expr += QString( "sys.path.append('%1')" ).arg( prev.replace( '\'', "\\'" ) );
+ expr += QString( "sys.path.append(u'%1')" ).arg( prev.replace( '\'', "\\'" ) );
QgsPythonRunner::run( expr );
}
diff --git a/src/app/qgsbookmarks.cpp b/src/app/qgsbookmarks.cpp
index f288c8e..20a3eed 100644
--- a/src/app/qgsbookmarks.cpp
+++ b/src/app/qgsbookmarks.cpp
@@ -38,6 +38,8 @@
QgsBookmarks::QgsBookmarks( QWidget *parent )
: QgsDockWidget( parent )
+ , mQgisModel( nullptr )
+ , mProjectModel( nullptr )
{
setupUi( this );
restorePosition();
diff --git a/src/app/qgsdxfexportdialog.cpp b/src/app/qgsdxfexportdialog.cpp
index 028fbbb..b67a6ac 100644
--- a/src/app/qgsdxfexportdialog.cpp
+++ b/src/app/qgsdxfexportdialog.cpp
@@ -528,11 +528,13 @@ QList< QPair<QgsVectorLayer *, int> > QgsDxfExportDialog::layers() const
double QgsDxfExportDialog::symbologyScale() const
{
- double scale = 1 / mScaleWidget->scale();
+ if ( qgsDoubleNear( mScaleWidget->scale(), 0.0 ) )
+ return 1.0;
+
+ double scale = 1.0 / mScaleWidget->scale();
if ( qgsDoubleNear( scale, 0.0 ) )
- {
return 1.0;
- }
+
return scale;
}
diff --git a/src/core/pal/feature.cpp b/src/core/pal/feature.cpp
index 77bb9c2..8473231 100644
--- a/src/core/pal/feature.cpp
+++ b/src/core/pal/feature.cpp
@@ -227,7 +227,7 @@ LabelPosition::Quadrant FeaturePart::quadrantFromOffset() const
}
}
-int FeaturePart::createCandidatesOverPoint( double x, double y, QList< LabelPosition*>& lPos, double angle, PointSet *mapShape )
+int FeaturePart::createCandidatesOverPoint( double x, double y, QList< LabelPosition*>& lPos, double angle )
{
int nbp = 1;
@@ -294,9 +294,9 @@ int FeaturePart::createCandidatesOverPoint( double x, double y, QList< LabelPosi
double lx = x + xdiff;
double ly = y + ydiff;
- if ( mapShape && type == GEOS_POLYGON && mLF->layer()->fitInPolygonOnly() )
+ if ( mLF->permissibleZonePrepared() )
{
- if ( !mapShape->containsLabelCandidate( lx, ly, labelW, labelH, angle ) )
+ if ( !GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), lx, ly, labelW, labelH, angle ) )
{
return 0;
}
@@ -419,10 +419,12 @@ int FeaturePart::createCandidatesAtOrderedPositionsOverPoint( double x, double y
double labelX = referenceX + deltaX;
double labelY = referenceY + deltaY;
- lPos << new LabelPosition( i, labelX, labelY, labelWidth, labelHeight, angle, cost, this, false, quadrant );
-
- //TODO - tweak
- cost += 0.001;
+ if ( ! mLF->permissibleZonePrepared() || GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), labelX, labelY, labelWidth, labelHeight, angle ) )
+ {
+ lPos << new LabelPosition( i, labelX, labelY, labelWidth, labelHeight, angle, cost, this, false, quadrant );
+ //TODO - tweak
+ cost += 0.001;
+ }
++i;
}
@@ -430,7 +432,7 @@ int FeaturePart::createCandidatesAtOrderedPositionsOverPoint( double x, double y
return lPos.count();
}
-int FeaturePart::createCandidatesAroundPoint( double x, double y, QList< LabelPosition* >& lPos, double angle, PointSet *mapShape )
+int FeaturePart::createCandidatesAroundPoint( double x, double y, QList< LabelPosition* >& lPos, double angle )
{
double labelWidth = getLabelWidth();
double labelHeight = getLabelHeight();
@@ -547,9 +549,9 @@ int FeaturePart::createCandidatesAroundPoint( double x, double y, QList< LabelPo
cost = 0.0001 + 0.0020 * double( icost ) / double( numberCandidates - 1 );
- if ( mapShape && type == GEOS_POLYGON && mLF->layer()->fitInPolygonOnly() )
+ if ( mLF->permissibleZonePrepared() )
{
- if ( !mapShape->containsLabelCandidate( labelX, labelY, labelWidth, labelHeight, angle ) )
+ if ( !GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), labelX, labelY, labelWidth, labelHeight, angle ) )
{
continue;
}
@@ -698,17 +700,17 @@ int FeaturePart::createCandidatesAlongLine( QList< LabelPosition* >& lPos, Point
if ( aboveLine )
{
- if ( !mLF->layer()->fitInPolygonOnly() || mapShape->containsLabelCandidate( bx + cos( beta ) *distlabel, by + sin( beta ) *distlabel, xrm, yrm, alpha ) )
+ if ( !mLF->permissibleZonePrepared() || GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), bx + cos( beta ) *distlabel, by + sin( beta ) *distlabel, xrm, yrm, alpha ) )
positions.append( new LabelPosition( i, bx + cos( beta ) *distlabel, by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this, isRightToLeft ) ); // Line
}
if ( belowLine )
{
- if ( !mLF->layer()->fitInPolygonOnly() || mapShape->containsLabelCandidate( bx - cos( beta ) *( distlabel + yrm ), by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha ) )
+ if ( !mLF->permissibleZonePrepared() || GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), bx - cos( beta ) *( distlabel + yrm ), by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha ) )
positions.append( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ), by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this, isRightToLeft ) ); // Line
}
if ( flags & FLAG_ON_LINE )
{
- if ( !mLF->layer()->fitInPolygonOnly() || mapShape->containsLabelCandidate( bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha ) )
+ if ( !mLF->permissibleZonePrepared() || GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha ) )
positions.append( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this, isRightToLeft ) ); // Line
}
}
@@ -879,6 +881,7 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
delete slp;
return nullptr;
}
+
// Shift the character downwards since the draw position is specified at the baseline
// and we're calculating the mean line here
double dist = 0.9 * li->label_height / 2;
@@ -1047,14 +1050,36 @@ int FeaturePart::createCurvedCandidatesAlongLine( QList< LabelPosition* >& lPos,
// average angle is calculated with respect to periodicity of angles
double angle_avg = atan2( sin_avg / li->char_num, cos_avg / li->char_num );
- // displacement
- if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
- positions.append( _createCurvedCandidate( slp, angle_avg, mLF->distLabel() + li->label_height / 2 ) );
- if ( flags & FLAG_ON_LINE )
- positions.append( _createCurvedCandidate( slp, angle_avg, 0 ) );
- if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
- positions.append( _createCurvedCandidate( slp, angle_avg, -li->label_height / 2 - mLF->distLabel() ) );
+ // displacement - we loop through 3 times, generating above, online then below line placements successively
+ for ( int i = 0; i <= 2; ++i )
+ {
+ LabelPosition* p = nullptr;
+ if ( i == 0 && (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) ) )
+ p = _createCurvedCandidate( slp, angle_avg, mLF->distLabel() + li->label_height / 2 );
+ if ( i == 1 && flags & FLAG_ON_LINE )
+ p = _createCurvedCandidate( slp, angle_avg, 0 );
+ if ( i == 2 && (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
+ p = _createCurvedCandidate( slp, angle_avg, -li->label_height / 2 - mLF->distLabel() );
+
+ if ( p && mLF->permissibleZonePrepared() )
+ {
+ bool within = true;
+ LabelPosition* currentPos = p;
+ while ( within && currentPos )
+ {
+ within = GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), currentPos->getX(), currentPos->getY(), currentPos->getWidth(), currentPos->getHeight(), currentPos->getAlpha() );
+ currentPos = currentPos->getNextPart();
+ }
+ if ( !within )
+ {
+ delete p;
+ p = nullptr;
+ }
+ }
+ if ( p )
+ positions.append( p );
+ }
// delete original candidate
delete slp;
}
@@ -1144,7 +1169,7 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
//fit in polygon only mode slows down calculation a lot, so if it's enabled
//then use a smaller limit for number of iterations
- int maxTry = mLF->layer()->fitInPolygonOnly() ? 7 : 10;
+ int maxTry = mLF->permissibleZonePrepared() ? 7 : 10;
do
{
@@ -1158,10 +1183,11 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
continue;
}
- if ( mLF->layer()->arrangement() == QgsPalLayerSettings::Horizontal && mLF->layer()->fitInPolygonOnly() )
+ if ( mLF->layer()->arrangement() == QgsPalLayerSettings::Horizontal && mLF->permissibleZonePrepared() )
{
//check width/height of bbox is sufficient for label
- if ( box->length < labelWidth || box->width < labelHeight )
+ if ( mLF->permissibleZone().boundingBox().width() < labelWidth ||
+ mLF->permissibleZone().boundingBox().height() < labelHeight )
{
//no way label can fit in this box, skip it
continue;
@@ -1249,8 +1275,8 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
rx += box->x[0];
ry += box->y[0];
- bool candidateAcceptable = ( mLF->layer()->fitInPolygonOnly()
- ? mapShape->containsLabelCandidate( rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
+ bool candidateAcceptable = ( mLF->permissibleZonePrepared()
+ ? GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
: mapShape->containsPoint( rx, ry ) );
if ( candidateAcceptable )
{
@@ -1337,9 +1363,9 @@ int FeaturePart::createCandidates( QList< LabelPosition*>& lPos,
double cx, cy;
mapShape->getCentroid( cx, cy, mLF->layer()->centroidInside() );
if ( mLF->layer()->arrangement() == QgsPalLayerSettings::OverPoint )
- createCandidatesOverPoint( cx, cy, lPos, angle, mapShape );
+ createCandidatesOverPoint( cx, cy, lPos, angle );
else
- createCandidatesAroundPoint( cx, cy, lPos, angle, mapShape );
+ createCandidatesAroundPoint( cx, cy, lPos, angle );
break;
case QgsPalLayerSettings::Line:
createCandidatesAlongLine( lPos, mapShape );
diff --git a/src/core/pal/feature.h b/src/core/pal/feature.h
index eb2b3a6..05adb6f 100644
--- a/src/core/pal/feature.h
+++ b/src/core/pal/feature.h
@@ -132,20 +132,18 @@ namespace pal
* @param y y coordinate of the point
* @param lPos pointer to an array of candidates, will be filled by generated candidates
* @param angle orientation of the label
- * @param mapShape optional geometry of source polygon
* @returns the number of generated candidates
*/
- int createCandidatesAroundPoint( double x, double y, QList<LabelPosition *> &lPos, double angle, PointSet *mapShape = nullptr );
+ int createCandidatesAroundPoint( double x, double y, QList<LabelPosition *> &lPos, double angle );
/** Generate one candidate over or offset the specified point.
* @param x x coordinate of the point
* @param y y coordinate of the point
* @param lPos pointer to an array of candidates, will be filled by generated candidate
* @param angle orientation of the label
- * @param mapShape optional geometry of source polygon
* @returns the number of generated candidates (always 1)
*/
- int createCandidatesOverPoint( double x, double y, QList<LabelPosition *> &lPos, double angle, PointSet *mapShape = nullptr );
+ int createCandidatesOverPoint( double x, double y, QList<LabelPosition *> &lPos, double angle );
/** Generates candidates following a prioritised list of predefined positions around a point.
* @param x x coordinate of the point
diff --git a/src/core/pal/geomfunction.cpp b/src/core/pal/geomfunction.cpp
index bdf8c40..623e539 100644
--- a/src/core/pal/geomfunction.cpp
+++ b/src/core/pal/geomfunction.cpp
@@ -31,6 +31,8 @@
#include "feature.h"
#include "util.h"
#include "qgis.h"
+#include "pal.h"
+#include "qgsmessagelog.h"
using namespace pal;
@@ -315,6 +317,57 @@ int GeomFunction::reorderPolygon( int nbPoints, double *x, double *y )
return 0;
}
+bool GeomFunction::containsCandidate( const GEOSPreparedGeometry *geom, double x, double y, double width, double height, double alpha )
+{
+ if ( !geom )
+ return false;
+
+ GEOSContextHandle_t geosctxt = geosContext();
+ GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 5, 2 );
+
+ GEOSCoordSeq_setX_r( geosctxt, coord, 0, x );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 0, y );
+ if ( !qgsDoubleNear( alpha, 0.0 ) )
+ {
+ double beta = alpha + ( M_PI / 2 );
+ double dx1 = cos( alpha ) * width;
+ double dy1 = sin( alpha ) * width;
+ double dx2 = cos( beta ) * height;
+ double dy2 = sin( beta ) * height;
+ GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + dx1 );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 1, y + dy1 );
+ GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + dx1 + dx2 );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + dy1 + dy2 );
+ GEOSCoordSeq_setX_r( geosctxt, coord, 3, x + dx2 );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + dy2 );
+ }
+ else
+ {
+ GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + width );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 1, y );
+ GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + width );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + height );
+ GEOSCoordSeq_setX_r( geosctxt, coord, 3, x );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + height );
+ }
+ //close ring
+ GEOSCoordSeq_setX_r( geosctxt, coord, 4, x );
+ GEOSCoordSeq_setY_r( geosctxt, coord, 4, y );
+
+ try
+ {
+ GEOSGeometry* bboxGeos = GEOSGeom_createLinearRing_r( geosctxt, coord );
+ bool result = ( GEOSPreparedContainsProperly_r( geosctxt, geom, bboxGeos ) == 1 );
+ GEOSGeom_destroy_r( geosctxt, bboxGeos );
+ return result;
+ }
+ catch ( GEOSException &e )
+ {
+ QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
+ return false;
+ }
+}
+
void GeomFunction::findLineCircleIntersection( double cx, double cy, double radius,
double x1, double y1, double x2, double y2,
double& xRes, double& yRes )
diff --git a/src/core/pal/geomfunction.h b/src/core/pal/geomfunction.h
index 140ff75..2b745ca 100644
--- a/src/core/pal/geomfunction.h
+++ b/src/core/pal/geomfunction.h
@@ -31,6 +31,7 @@
#define PAL_GEOM_FUNCTION
#include "util.h"
+#include "qgsgeos.h"
namespace pal
{
@@ -99,6 +100,17 @@ namespace pal
//! Reorder points to have cross prod ((x,y)[i], (x,y)[i+1), point) > 0 when point is outside
static int reorderPolygon( int nbPoints, double *x, double *y );
+ /** Returns true if a GEOS prepared geometry totally contains a label candidate.
+ * @param geom GEOS prepared geometry
+ * @param x candidate x
+ * @param y candidate y
+ * @param width candidate width
+ * @param height candidate height
+ * @param alpha candidate angle
+ * @returns true if candidate is totally contained
+ */
+ static bool containsCandidate( const GEOSPreparedGeometry* geom, double x, double y, double width, double height, double alpha );
+
};
} //namespace
diff --git a/src/core/pal/layer.cpp b/src/core/pal/layer.cpp
index 604d2d1..e00b438 100644
--- a/src/core/pal/layer.cpp
+++ b/src/core/pal/layer.cpp
@@ -49,7 +49,6 @@ Layer::Layer( QgsAbstractLabelProvider* provider, const QString& name, QgsPalLay
, mLabelLayer( toLabel )
, mDisplayAll( displayAll )
, mCentroidInside( false )
- , mFitInPolygon( false )
, mArrangement( arrangement )
, mArrangementFlags( nullptr )
, mMode( LabelPerFeature )
@@ -427,6 +426,7 @@ void Layer::chopFeaturesAtRepeatDistance()
double chopInterval = fpart->repeatDistance();
if ( chopInterval != 0. && GEOSGeomTypeId_r( geosctxt, geom ) == GEOS_LINESTRING )
{
+ chopInterval *= ceil( fpart->getLabelWidth() / fpart->repeatDistance() );
double bmin[2], bmax[2];
fpart->getBoundingBox( bmin, bmax );
diff --git a/src/core/pal/layer.h b/src/core/pal/layer.h
index ba24fd4..e31c5d4 100644
--- a/src/core/pal/layer.h
+++ b/src/core/pal/layer.h
@@ -213,21 +213,6 @@ namespace pal
*/
bool centroidInside() const { return mCentroidInside; }
- /** Sets whether labels which do not fit completely within a polygon feature
- * are discarded.
- * @param fitInPolygon set to true to discard labels which do not fit within
- * polygon features. Set to false to allow labels which partially fall outside
- * the polygon.
- * @see fitInPolygonOnly
- */
- void setFitInPolygonOnly( bool fitInPolygon ) { mFitInPolygon = fitInPolygon; }
-
- /** Returns whether labels which do not fit completely within a polygon feature
- * are discarded.
- * @see setFitInPolygonOnly
- */
- bool fitInPolygonOnly() const { return mFitInPolygon; }
-
/** Register a feature in the layer.
*
* Does not take ownership of the label feature (it is owned by its provider).
@@ -269,7 +254,6 @@ namespace pal
bool mLabelLayer;
bool mDisplayAll;
bool mCentroidInside;
- bool mFitInPolygon;
/** Optional flags used for some placement methods */
QgsPalLayerSettings::Placement mArrangement;
diff --git a/src/core/pal/pointset.cpp b/src/core/pal/pointset.cpp
index 2626c3d..a996d77 100644
--- a/src/core/pal/pointset.cpp
+++ b/src/core/pal/pointset.cpp
@@ -289,50 +289,7 @@ bool PointSet::containsPoint( double x, double y ) const
bool PointSet::containsLabelCandidate( double x, double y, double width, double height, double alpha ) const
{
- GEOSContextHandle_t geosctxt = geosContext();
- GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 5, 2 );
-
- GEOSCoordSeq_setX_r( geosctxt, coord, 0, x );
- GEOSCoordSeq_setY_r( geosctxt, coord, 0, y );
- if ( !qgsDoubleNear( alpha, 0.0 ) )
- {
- double beta = alpha + ( M_PI / 2 );
- double dx1 = cos( alpha ) * width;
- double dy1 = sin( alpha ) * width;
- double dx2 = cos( beta ) * height;
- double dy2 = sin( beta ) * height;
- GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + dx1 );
- GEOSCoordSeq_setY_r( geosctxt, coord, 1, y + dy1 );
- GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + dx1 + dx2 );
- GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + dy1 + dy2 );
- GEOSCoordSeq_setX_r( geosctxt, coord, 3, x + dx2 );
- GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + dy2 );
- }
- else
- {
- GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + width );
- GEOSCoordSeq_setY_r( geosctxt, coord, 1, y );
- GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + width );
- GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + height );
- GEOSCoordSeq_setX_r( geosctxt, coord, 3, x );
- GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + height );
- }
- //close ring
- GEOSCoordSeq_setX_r( geosctxt, coord, 4, x );
- GEOSCoordSeq_setY_r( geosctxt, coord, 4, y );
-
- try
- {
- GEOSGeometry* bboxGeos = GEOSGeom_createLinearRing_r( geosctxt, coord );
- bool result = ( GEOSPreparedContainsProperly_r( geosctxt, preparedGeom(), bboxGeos ) == 1 );
- GEOSGeom_destroy_r( geosctxt, bboxGeos );
- return result;
- }
- catch ( GEOSException &e )
- {
- QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
- return false;
- }
+ return GeomFunction::containsCandidate( preparedGeom(), x, y, width, height, alpha );
}
void PointSet::splitPolygons( QLinkedList<PointSet*> &shapes_toProcess,
diff --git a/src/core/qgslabelfeature.cpp b/src/core/qgslabelfeature.cpp
index 4ed75b7..d371b31 100644
--- a/src/core/qgslabelfeature.cpp
+++ b/src/core/qgslabelfeature.cpp
@@ -35,6 +35,7 @@ QgsLabelFeature::QgsLabelFeature( QgsFeatureId id, GEOSGeometry* geometry, QSize
, mIsObstacle( false )
, mObstacleFactor( 1 )
, mInfo( nullptr )
+ , mPermissibleZoneGeosPrepared( nullptr )
{
}
@@ -46,6 +47,9 @@ QgsLabelFeature::~QgsLabelFeature()
if ( mObstacleGeometry )
GEOSGeom_destroy_r( QgsGeometry::getGEOSHandler(), mObstacleGeometry );
+ if ( mPermissibleZoneGeosPrepared )
+ GEOSPreparedGeom_destroy_r( QgsGeometry::getGEOSHandler(), mPermissibleZoneGeosPrepared );
+
delete mInfo;
}
@@ -56,3 +60,23 @@ void QgsLabelFeature::setObstacleGeometry( GEOSGeometry* obstacleGeom )
mObstacleGeometry = obstacleGeom;
}
+
+void QgsLabelFeature::setPermissibleZone( const QgsGeometry &geometry )
+{
+ mPermissibleZone = geometry;
+
+ if ( mPermissibleZoneGeosPrepared )
+ {
+ GEOSPreparedGeom_destroy_r( QgsGeometry::getGEOSHandler(), mPermissibleZoneGeosPrepared );
+ mPermissibleZoneGeosPrepared = nullptr;
+ }
+
+ if ( mPermissibleZone.isEmpty() )
+ return;
+
+ const GEOSGeometry* zoneGeos = mPermissibleZone.asGeos();
+ if ( !zoneGeos )
+ return;
+
+ mPermissibleZoneGeosPrepared = GEOSPrepare_r( QgsGeometry::getGEOSHandler(), zoneGeos );
+}
diff --git a/src/core/qgslabelfeature.h b/src/core/qgslabelfeature.h
index e2e0441..f99b67a 100644
--- a/src/core/qgslabelfeature.h
+++ b/src/core/qgslabelfeature.h
@@ -107,6 +107,32 @@ class CORE_EXPORT QgsLabelFeature
*/
GEOSGeometry* obstacleGeometry() const { return mObstacleGeometry; }
+ /** Sets the label's permissible zone geometry. If set, the feature's label MUST be fully contained
+ * within this zone, and the feature will not be labeled if no candidates can be generated which
+ * are not contained within the zone.
+ * @param geometry permissible zone geometry. If an invalid QgsGeometry is passed then no zone limit
+ * will be applied to the label candidates (this is the default behaviour).
+ * @note added in QGIS 3.0
+ * @see permissibleZone()
+ */
+ void setPermissibleZone( const QgsGeometry& geometry );
+
+ /** Returns the label's permissible zone geometry. If a valid geometry is returned, the feature's label
+ * MUST be fully contained within this zone, and the feature will not be labeled if no candidates can be
+ * generated which are not contained within the zone.
+ * @note added in QGIS 3.0
+ * @see setPermissibleZone()
+ * @see permissibleZonePrepared()
+ */
+ QgsGeometry permissibleZone() const { return mPermissibleZone; }
+
+ /** Returns a GEOS prepared geometry representing the label's permissibleZone().
+ * @see permissibleZone()
+ * @note added in QGIS 3.0
+ */
+ //TODO - remove when QgsGeometry caches GEOS preparedness
+ const GEOSPreparedGeometry* permissibleZonePrepared() const { return mPermissibleZoneGeosPrepared; }
+
//! Size of the label (in map units)
QSizeF size() const { return mSize; }
@@ -316,6 +342,8 @@ class CORE_EXPORT QgsLabelFeature
GEOSGeometry* mGeometry;
//! Optional geometry to use for label obstacles, if different to mGeometry
GEOSGeometry* mObstacleGeometry;
+ //! Optional geometry to use for label's permissible zone
+ QgsGeometry mPermissibleZone;
//! Width and height of the label
QSizeF mSize;
//! Visual margin of label contents
@@ -358,6 +386,12 @@ class CORE_EXPORT QgsLabelFeature
QString mLabelText;
//! extra information for curved labels (may be null)
pal::LabelInfo* mInfo;
+
+ private:
+
+ // TODO - not required when QgsGeometry caches geos preparedness
+ const GEOSPreparedGeometry* mPermissibleZoneGeosPrepared;
+
};
#endif // QGSLABELFEATURE_H
diff --git a/src/core/qgslabelingenginev2.cpp b/src/core/qgslabelingenginev2.cpp
index eaff8c1..5bc40b6 100644
--- a/src/core/qgslabelingenginev2.cpp
+++ b/src/core/qgslabelingenginev2.cpp
@@ -129,9 +129,6 @@ void QgsLabelingEngineV2::processProvider( QgsAbstractLabelProvider* provider, Q
// set whether location of centroid must be inside of polygons
l->setCentroidInside( flags.testFlag( QgsAbstractLabelProvider::CentroidMustBeInside ) );
- // set whether labels must fall completely within the polygon
- l->setFitInPolygonOnly( flags.testFlag( QgsAbstractLabelProvider::FitInPolygonOnly ) );
-
// set how to show upside-down labels
pal::Layer::UpsideDownLabels upsdnlabels;
switch ( provider->upsidedownLabels() )
diff --git a/src/core/qgslabelingenginev2.h b/src/core/qgslabelingenginev2.h
index aadeded..2b1a369 100644
--- a/src/core/qgslabelingenginev2.h
+++ b/src/core/qgslabelingenginev2.h
@@ -57,7 +57,6 @@ class CORE_EXPORT QgsAbstractLabelProvider
DrawAllLabels = 1 << 2, //!< whether all features will be labelled even though overlaps occur
MergeConnectedLines = 1 << 3, //!< whether adjacent lines (with the same label text) should be merged
CentroidMustBeInside = 1 << 4, //!< whether location of centroid must be inside of polygons
- FitInPolygonOnly = 1 << 5, //!< whether labels must fall completely within the polygon
LabelPerFeaturePart = 1 << 6, //!< whether to label each part of multi-part features separately
};
Q_DECLARE_FLAGS( Flags, Flag )
diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp
index f6dd0e6..6aeba76 100644
--- a/src/core/qgspallabeling.cpp
+++ b/src/core/qgspallabeling.cpp
@@ -2455,6 +2455,20 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
doClip = true;
}
+ // if using fitInPolygonOnly option, generate the permissible zone (must happen before geometry is modified - eg
+ // as a result of using perimeter based labeling and the geometry is converted to a boundary)
+ QgsGeometry permissibleZone;
+ if ( geom->type() == QGis::Polygon && fitInPolygonOnly )
+ {
+ permissibleZone = *geom;
+ if ( QgsPalLabeling::geometryRequiresPreparation( &permissibleZone, context, ct, doClip ? extentGeom : nullptr ) )
+ {
+ QgsGeometry* preparedZone = QgsPalLabeling::prepareGeometry( &permissibleZone, context, ct, doClip ? extentGeom : nullptr );
+ permissibleZone = *preparedZone;
+ delete preparedZone;
+ }
+ }
+
const GEOSGeometry* geos_geom = nullptr;
const QgsGeometry* preparedGeom = geom;
QScopedPointer<QgsGeometry> scopedPreparedGeom;
@@ -2853,6 +2867,7 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
( *labelFeature )->setAlwaysShow( alwaysShow );
( *labelFeature )->setRepeatDistance( repeatDist );
( *labelFeature )->setLabelText( labelText );
+ ( *labelFeature )->setPermissibleZone( permissibleZone );
if ( geosObstacleGeomClone )
{
( *labelFeature )->setObstacleGeometry( geosObstacleGeomClone );
diff --git a/src/core/qgsvectorfilewriter.cpp b/src/core/qgsvectorfilewriter.cpp
index 3f6542e..c44a14f 100644
--- a/src/core/qgsvectorfilewriter.cpp
+++ b/src/core/qgsvectorfilewriter.cpp
@@ -45,6 +45,7 @@
#include <ogr_srs_api.h>
#include <cpl_error.h>
#include <cpl_conv.h>
+#include <gdal.h>
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
#define TO8F(x) (x).toUtf8().constData()
@@ -435,10 +436,16 @@ void QgsVectorFileWriter::init( QString vectorFileName,
break;
#else
case QVariant::LongLong:
- ogrType = OFTInteger64;
+ {
+ const char* pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES, NULL );
+ if ( pszDataTypes && strstr( pszDataTypes, "Integer64" ) )
+ ogrType = OFTInteger64;
+ else
+ ogrType = OFTReal;
ogrWidth = ogrWidth > 0 && ogrWidth <= 20 ? ogrWidth : 20;
ogrPrecision = 0;
break;
+ }
#endif
case QVariant::String:
ogrType = OFTString;
diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp
index 6149e59..1071b65 100644
--- a/src/core/qgsvectorlayer.cpp
+++ b/src/core/qgsvectorlayer.cpp
@@ -3156,6 +3156,23 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
vals << v.toString();
}
+ QgsFeatureMap added = mEditBuffer->addedFeatures();
+ QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
+ while ( addedIt.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
+ {
+ addedIt.next();
+ QVariant v = addedIt.value().attribute( index );
+ if ( v.isValid() )
+ {
+ QString vs = v.toString();
+ if ( !vals.contains( vs ) )
+ {
+ vals << vs;
+ uniqueValues << v;
+ }
+ }
+ }
+
QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
{
@@ -3234,7 +3251,35 @@ QVariant QgsVectorLayer::minimumValue( int index )
return QVariant();
case QgsFields::OriginProvider: //a provider field
- return mDataProvider->minimumValue( index );
+ {
+ QVariant min = mDataProvider->minimumValue( index );
+ if ( mEditBuffer )
+ {
+ QgsFeatureMap added = mEditBuffer->addedFeatures();
+ QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
+ while ( addedIt.hasNext() )
+ {
+ addedIt.next();
+ QVariant v = addedIt.value().attribute( index );
+ if ( v.isValid() && qgsVariantLessThan( v, min ) )
+ {
+ min = v;
+ }
+ }
+
+ QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
+ while ( it.hasNext() )
+ {
+ it.next();
+ QVariant v = it.value().value( index );
+ if ( v.isValid() && qgsVariantLessThan( v, min ) )
+ {
+ min = v;
+ }
+ }
+ }
+ return min;
+ }
case QgsFields::OriginEdit:
{
@@ -3293,7 +3338,35 @@ QVariant QgsVectorLayer::maximumValue( int index )
return QVariant();
case QgsFields::OriginProvider: //a provider field
- return mDataProvider->maximumValue( index );
+ {
+ QVariant min = mDataProvider->maximumValue( index );
+ if ( mEditBuffer )
+ {
+ QgsFeatureMap added = mEditBuffer->addedFeatures();
+ QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
+ while ( addedIt.hasNext() )
+ {
+ addedIt.next();
+ QVariant v = addedIt.value().attribute( index );
+ if ( v.isValid() && qgsVariantGreaterThan( v, min ) )
+ {
+ min = v;
+ }
+ }
+
+ QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
+ while ( it.hasNext() )
+ {
+ it.next();
+ QVariant v = it.value().value( index );
+ if ( v.isValid() && qgsVariantGreaterThan( v, min ) )
+ {
+ min = v;
+ }
+ }
+ }
+ return min;
+ }
case QgsFields::OriginEdit:
// the layer is editable, but in certain cases it can still be avoided going through all features
diff --git a/src/core/qgsvectorlayer.h b/src/core/qgsvectorlayer.h
index 0d7c646..6bad318 100644
--- a/src/core/qgsvectorlayer.h
+++ b/src/core/qgsvectorlayer.h
@@ -1707,17 +1707,35 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Caches joined attributes if required (and not already done) */
void createJoinCaches();
- /** Returns unique values for column
+ /** Calculates a list of unique values contained within an attribute in the layer. Note that
+ * in some circumstances when unsaved changes are present for the layer then the returned list
+ * may contain outdated values (for instance when the attribute value in a saved feature has
+ * been changed inside the edit buffer then the previous saved value will be included in the
+ * returned list).
* @param index column index for attribute
* @param uniqueValues out: result list
- * @param limit maximum number of values to return (-1 if unlimited)
+ * @param limit maximum number of values to return (or -1 if unlimited)
+ * @see minimumValue()
+ * @see maximumValue()
*/
void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
- /** Returns minimum value for an attribute column or invalid variant in case of error */
+ /** Returns the minimum value for an attribute column or an invalid variant in case of error.
+ * Note that in some circumstances when unsaved changes are present for the layer then the
+ * returned value may be outdated (for instance when the attribute value in a saved feature has
+ * been changed inside the edit buffer then the previous saved value may be returned as the minimum).
+ * @see maximumValue()
+ * @see uniqueValues()
+ */
QVariant minimumValue( int index );
- /** Returns maximum value for an attribute column or invalid variant in case of error */
+ /** Returns the maximum value for an attribute column or an invalid variant in case of error.
+ * Note that in some circumstances when unsaved changes are present for the layer then the
+ * returned value may be outdated (for instance when the attribute value in a saved feature has
+ * been changed inside the edit buffer then the previous saved value may be returned as the maximum).
+ * @see minimumValue()
+ * @see uniqueValues()
+ */
QVariant maximumValue( int index );
/** Calculates an aggregated value from the layer's features.
diff --git a/src/core/qgsvectorlayerlabelprovider.cpp b/src/core/qgsvectorlayerlabelprovider.cpp
index 810361a..f5535ad 100644
--- a/src/core/qgsvectorlayerlabelprovider.cpp
+++ b/src/core/qgsvectorlayerlabelprovider.cpp
@@ -101,7 +101,6 @@ void QgsVectorLayerLabelProvider::init()
if ( mSettings.displayAll ) mFlags |= DrawAllLabels;
if ( mSettings.mergeLines ) mFlags |= MergeConnectedLines;
if ( mSettings.centroidInside ) mFlags |= CentroidMustBeInside;
- if ( mSettings.fitInPolygonOnly ) mFlags |= FitInPolygonOnly;
if ( mSettings.labelPerPart ) mFlags |= LabelPerFeaturePart;
mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
diff --git a/src/core/raster/qgscolorrampshader.cpp b/src/core/raster/qgscolorrampshader.cpp
index c8a19fa..bbf996e 100644
--- a/src/core/raster/qgscolorrampshader.cpp
+++ b/src/core/raster/qgscolorrampshader.cpp
@@ -88,6 +88,9 @@ bool QgsColorRampShader::shade( double theValue, int* theReturnRedValue, int* th
{
return false;
}
+ if ( qIsNaN( theValue ) || qIsInf( theValue ) )
+ return false;
+
int colorRampItemListCount = mColorRampItemList.count();
int idx;
if ( !mLUTInitialized )
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index fc352e4..470f1cb 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -708,6 +708,25 @@ IF (WITH_TOUCH)
ENDIF (WITH_TOUCH)
SET(QGIS_GUI_UI_HDRS
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthauthoritieseditor.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthcertificateinfo.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthcertificatemanager.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthconfigedit.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthconfigeditor.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthconfigidedit.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthconfigselect.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthconfiguriedit.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsautheditorwidgets.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthidentitieseditor.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthimportcertdialog.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthimportidentitydialog.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthmethodplugins.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthserverseditor.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthsslconfigwidget.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthsslerrorsdialog.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthsslimportdialog.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthsslimporterrors.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsauthtrustedcasdialog.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgscredentialdialog.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsdetaileditemwidgetbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionbuilderdialogbase.h
diff --git a/src/gui/attributetable/qgsattributetablemodel.cpp b/src/gui/attributetable/qgsattributetablemodel.cpp
index 78f8b15..454bf42 100644
--- a/src/gui/attributetable/qgsattributetablemodel.cpp
+++ b/src/gui/attributetable/qgsattributetablemodel.cpp
@@ -827,7 +827,7 @@ void QgsAttributeTableModel::prefetchSortData( const QString& expressionString )
}
else
{
- QVariant sortValue = widgetFactory->representValue( layer(), mSortFieldIndex, widgetConfig, widgetCache, f.attribute( mSortFieldIndex ) );
+ QVariant sortValue = widgetFactory->sortValue( layer(), mSortFieldIndex, widgetConfig, widgetCache, f.attribute( mSortFieldIndex ) );
mSortCache.insert( f.id(), sortValue );
}
}
diff --git a/src/gui/attributetable/qgsfeaturelistview.cpp b/src/gui/attributetable/qgsfeaturelistview.cpp
index 56f185e..17e4f53 100644
--- a/src/gui/attributetable/qgsfeaturelistview.cpp
+++ b/src/gui/attributetable/qgsfeaturelistview.cpp
@@ -258,7 +258,8 @@ void QgsFeatureListView::mouseReleaseEvent( QMouseEvent *event )
}
else
{
- mFeatureSelectionModel->enableSync( true );
+ if ( mFeatureSelectionModel )
+ mFeatureSelectionModel->enableSync( true );
}
}
diff --git a/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp b/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
index e7d0719..fdb7941 100644
--- a/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
+++ b/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
@@ -142,7 +142,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
{
if ( !expression.isEmpty() )
{
- QString fieldName = ft.fields()->field( mFieldIdx ).name();
+ QString fieldName = layer()->attributeDisplayName( mFieldIdx );
expression = "( " + expression + " ) AND ( " + fieldName + " IS NOT NULL)";
description = "( " + description + " ) AND NotNull";
}
diff --git a/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp b/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp
index 11b2bbb..58d57f7 100644
--- a/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp
+++ b/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp
@@ -70,7 +70,7 @@ QString QgsSearchWidgetWrapper::toString( QgsSearchWidgetWrapper::FilterFlag fla
case IsNull:
return QObject::tr( "Is missing (null)" );
case IsNotNull:
- return QObject::tr( "Is not missing (null)" );
+ return QObject::tr( "Is not missing (not null)" );
case IsNotBetween:
return QObject::tr( "Is not between (inclusive)" );
diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp
index aabbdfb..b123c37 100644
--- a/src/gui/qgsattributeform.cpp
+++ b/src/gui/qgsattributeform.cpp
@@ -780,12 +780,13 @@ bool QgsAttributeForm::currentFormFeature( QgsFeature &feature )
void QgsAttributeForm::clearInvalidConstraintsMessage()
{
+ mInvalidConstraintMessage->hide();
mInvalidConstraintMessage->clear();
mInvalidConstraintMessage->setStyleSheet( QString() );
}
-void QgsAttributeForm::displayInvalidConstraintMessage( const QStringList &f,
- const QStringList &d )
+void QgsAttributeForm::displayInvalidConstraintMessage( const QStringList& f,
+ const QStringList& d )
{
clearInvalidConstraintsMessage();
@@ -801,6 +802,7 @@ void QgsAttributeForm::displayInvalidConstraintMessage( const QStringList &f,
QString title = QString( "<img src=\"%1\"> <b>%2:" ).arg( icPath ).arg( tr( "Invalid fields" ) );
QString msg = QString( "%1</b><ul>%2</ul>" ).arg( title ).arg( descriptions ) ;
+ mInvalidConstraintMessage->show();
mInvalidConstraintMessage->setText( msg );
mInvalidConstraintMessage->setStyleSheet( "QLabel { background-color : #ffc800; }" );
}
@@ -888,7 +890,7 @@ void QgsAttributeForm::onUpdatedFields()
}
void QgsAttributeForm::onConstraintStatusChanged( const QString& constraint,
- const QString &description, const QString& err, bool ok )
+ const QString& description, const QString& err, bool ok )
{
QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( sender() );
Q_ASSERT( eww );
@@ -919,8 +921,8 @@ void QgsAttributeForm::onConstraintStatusChanged( const QString& constraint,
}
}
-void QgsAttributeForm::constraintDependencies( QgsEditorWidgetWrapper *w,
- QList<QgsEditorWidgetWrapper*> &wDeps )
+void QgsAttributeForm::constraintDependencies( QgsEditorWidgetWrapper* w,
+ QList<QgsEditorWidgetWrapper*>& wDeps )
{
QString name = w->field().name();
@@ -1048,6 +1050,7 @@ void QgsAttributeForm::init()
vl->addWidget( mMessageBar );
mInvalidConstraintMessage = new QLabel( this );
+ mInvalidConstraintMessage->hide();
vl->addWidget( mInvalidConstraintMessage );
setLayout( vl );
@@ -1548,15 +1551,22 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
}
else
{
- QScrollArea *scrollArea = new QScrollArea( parent );
+ myContainer = new QWidget();
- myContainer = new QWidget( scrollArea );
+ if ( context.formMode() != QgsAttributeEditorContext::Embed )
+ {
+ QScrollArea *scrollArea = new QScrollArea( parent );
- scrollArea->setWidget( myContainer );
- scrollArea->setWidgetResizable( true );
- scrollArea->setFrameShape( QFrame::NoFrame );
+ scrollArea->setWidget( myContainer );
+ scrollArea->setWidgetResizable( true );
+ scrollArea->setFrameShape( QFrame::NoFrame );
- newWidgetInfo.widget = scrollArea;
+ newWidgetInfo.widget = scrollArea;
+ }
+ else
+ {
+ newWidgetInfo.widget = myContainer;
+ }
}
QGridLayout* gbLayout = new QGridLayout();
diff --git a/src/gui/qgsattributeform.h b/src/gui/qgsattributeform.h
index 23b5a1c..76f96b9 100644
--- a/src/gui/qgsattributeform.h
+++ b/src/gui/qgsattributeform.h
@@ -256,7 +256,7 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
void onAttributeDeleted( int idx );
void onUpdatedFields();
void onConstraintStatusChanged( const QString& constraint,
- const QString &description, const QString& err, bool ok );
+ const QString& description, const QString& err, bool ok );
void preventFeatureRefresh();
void synchronizeEnabledState();
void layerSelectionChanged();
@@ -321,13 +321,13 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
//! constraints management
void updateAllConstaints();
- void updateConstraints( QgsEditorWidgetWrapper *w );
- bool currentFormFeature( QgsFeature &feature );
- bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions );
- void constraintDependencies( QgsEditorWidgetWrapper *w, QList<QgsEditorWidgetWrapper*> &wDeps );
+ void updateConstraints( QgsEditorWidgetWrapper* w );
+ bool currentFormFeature( QgsFeature& feature );
+ bool currentFormValidConstraints( QStringList& invalidFields, QStringList& descriptions );
+ void constraintDependencies( QgsEditorWidgetWrapper* w, QList<QgsEditorWidgetWrapper*>& wDeps );
void clearInvalidConstraintsMessage();
- void displayInvalidConstraintMessage( const QStringList &invalidFields,
- const QStringList &description );
+ void displayInvalidConstraintMessage( const QStringList& invalidFields,
+ const QStringList& description );
QgsVectorLayer* mLayer;
QgsFeature mFeature;
diff --git a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
index 3064a7c..7466309 100644
--- a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
+++ b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
@@ -147,6 +147,7 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
connect( mInvertCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( on_mClassifyButton_clicked() ) );
connect( mNumberOfEntriesSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( on_mClassifyButton_clicked() ) );
connect( mBandComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( on_mClassifyButton_clicked() ) );
+ connect( mClipCheckBox, SIGNAL( toggled( bool ) ), this, SIGNAL( widgetChanged() ) );
}
QgsSingleBandPseudoColorRendererWidget::~QgsSingleBandPseudoColorRendererWidget()
@@ -791,6 +792,7 @@ void QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited( QTr
{
mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
autoLabel();
+ emit widgetChanged();
}
else if ( column == LabelColumn )
{
@@ -873,6 +875,7 @@ void QgsSingleBandPseudoColorRendererWidget::on_mColorInterpolationComboBox_curr
header->setToolTip( ValueColumn, valueToolTip );
autoLabel();
+ emit widgetChanged();
}
void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
diff --git a/src/helpviewer/qgshelpviewer.cpp b/src/helpviewer/qgshelpviewer.cpp
index 176613f..e4d39c4 100644
--- a/src/helpviewer/qgshelpviewer.cpp
+++ b/src/helpviewer/qgshelpviewer.cpp
@@ -36,7 +36,7 @@ void QgsReaderThread::run()
QString help;
char buffer[1024];
- while ( fgets( buffer, sizeof buffer, stdin ) )
+ while ( fgets( buffer, sizeof buffer - 1, stdin ) )
{
if ( strcmp( buffer, "EOH\n" ) == 0 )
{
diff --git a/src/plugins/dxf2shp_converter/dxflib/src/dl_dxf.cpp b/src/plugins/dxf2shp_converter/dxflib/src/dl_dxf.cpp
index 549c1b1..43b71af 100644
--- a/src/plugins/dxf2shp_converter/dxflib/src/dl_dxf.cpp
+++ b/src/plugins/dxf2shp_converter/dxflib/src/dl_dxf.cpp
@@ -236,7 +236,7 @@ bool DL_Dxf::getStrippedLine(std::string& s, unsigned int size, FILE *fp) {
// Only the useful part of the line
char* line;
- line = fgets(wholeLine, size, fp);
+ line = fgets(wholeLine, size-1, fp);
if (line!=nullptr && line[0] != '\0') { // Evaluates to fgets() retval
// line == wholeLine at this point.
diff --git a/src/providers/grass/qgis.g.info.c b/src/providers/grass/qgis.g.info.c
index d5687d6..088ad48 100644
--- a/src/providers/grass/qgis.g.info.c
+++ b/src/providers/grass/qgis.g.info.c
@@ -217,7 +217,7 @@ int main( int argc, char **argv )
G_suppress_masking(); // must be after G_set_window()
fd = G_open_cell_old( rast_opt->answer, "" );
// wait for coords from stdin
- while ( fgets( buff, 100, stdin ) != 0 )
+ while ( fgets( buff, sizeof buff - 1, stdin ) != 0 )
{
if ( sscanf( buff, "%lf%lf", &x, &y ) != 2 )
{
diff --git a/src/providers/ogr/qgsogrfeatureiterator.cpp b/src/providers/ogr/qgsogrfeatureiterator.cpp
index 26e8ceb..04a0bc7 100644
--- a/src/providers/ogr/qgsogrfeatureiterator.cpp
+++ b/src/providers/ogr/qgsogrfeatureiterator.cpp
@@ -43,6 +43,8 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
, mSubsetStringSet( false )
, mFetchGeometry( false )
, mExpressionCompiled( false )
+ , mFilterFids( mRequest.filterFids() )
+ , mFilterFidsIt( mFilterFids.constBegin() )
{
mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mProvider->dataSourceUri() );
if ( !mConn->ds )
@@ -166,6 +168,22 @@ bool QgsOgrFeatureIterator::nextFeatureFilterExpression( QgsFeature& f )
return fetchFeature( f );
}
+bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature& feature ) const
+{
+ feature.setValid( false );
+ OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( id ) );
+ if ( !fet )
+ {
+ return false;
+ }
+
+ if ( readFeature( fet, feature ) )
+ OGR_F_Destroy( fet );
+
+ feature.setValid( true );
+ return true;
+}
+
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
{
feature.setValid( false );
@@ -175,19 +193,22 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
{
- OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) );
- if ( !fet )
+ bool result = fetchFeatureWithId( mRequest.filterFid(), feature );
+ close(); // the feature has been read or was not found: we have finished here
+ return result;
+ }
+ else if ( mRequest.filterType() == QgsFeatureRequest::FilterFids )
+ {
+ while ( mFilterFidsIt != mFilterFids.constEnd() )
{
- close();
- return false;
- }
-
- if ( readFeature( fet, feature ) )
- OGR_F_Destroy( fet );
+ QgsFeatureId nextId = *mFilterFidsIt;
+ mFilterFidsIt++;
- feature.setValid( true );
- close(); // the feature has been read: we have finished here
- return true;
+ if ( fetchFeatureWithId( nextId, feature ) )
+ return true;
+ }
+ close();
+ return false;
}
OGRFeatureH fet;
@@ -220,6 +241,8 @@ bool QgsOgrFeatureIterator::rewind()
OGR_L_ResetReading( ogrLayer );
+ mFilterFidsIt = mFilterFids.constBegin();
+
return true;
}
@@ -246,7 +269,7 @@ bool QgsOgrFeatureIterator::close()
}
-void QgsOgrFeatureIterator::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex )
+void QgsOgrFeatureIterator::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex ) const
{
if ( mSource->mFirstFieldIsFid && attindex == 0 )
{
@@ -264,7 +287,7 @@ void QgsOgrFeatureIterator::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature
}
-bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
+bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) const
{
feature.setFeatureId( OGR_F_GetFID( fet ) );
feature.initAttributes( mSource->mFields.count() );
diff --git a/src/providers/ogr/qgsogrfeatureiterator.h b/src/providers/ogr/qgsogrfeatureiterator.h
index 263a0f9..15bb5a7 100644
--- a/src/providers/ogr/qgsogrfeatureiterator.h
+++ b/src/providers/ogr/qgsogrfeatureiterator.h
@@ -68,10 +68,10 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsOgr
//! fetch next feature filter expression
bool nextFeatureFilterExpression( QgsFeature& f ) override;
- bool readFeature( OGRFeatureH fet, QgsFeature& feature );
+ bool readFeature( OGRFeatureH fet, QgsFeature& feature ) const;
//! Get an attribute associated with a feature
- void getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex );
+ void getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex ) const;
bool mFeatureFetched;
@@ -85,6 +85,11 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsOgr
private:
bool mExpressionCompiled;
+ QgsFeatureIds mFilterFids;
+ QgsFeatureIds::const_iterator mFilterFidsIt;
+
+ bool fetchFeatureWithId( QgsFeatureId id, QgsFeature& feature ) const;
+
};
#endif // QGSOGRFEATUREITERATOR_H
diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp
index c826240..122a52d 100644
--- a/src/providers/ogr/qgsogrprovider.cpp
+++ b/src/providers/ogr/qgsogrprovider.cpp
@@ -1276,6 +1276,8 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
bool returnvalue = true;
+ QMap< QString, QVariant::Type > mapFieldTypesToPatch;
+
for ( QList<QgsField>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter )
{
OGRFieldType type;
@@ -1287,8 +1289,17 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
break;
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
case QVariant::LongLong:
- type = OFTInteger64;
+ {
+ const char* pszDataTypes = GDALGetMetadataItem( ogrDriver, GDAL_DMD_CREATIONFIELDDATATYPES, NULL );
+ if ( pszDataTypes && strstr( pszDataTypes, "Integer64" ) )
+ type = OFTInteger64;
+ else
+ {
+ mapFieldTypesToPatch[ iter->name()] = iter->type();
+ type = OFTReal;
+ }
break;
+ }
#endif
case QVariant::Double:
type = OFTReal;
@@ -1326,6 +1337,16 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
OGR_Fld_Destroy( fielddefn );
}
loadFields();
+
+ // Patch field type in case of Integer64->Real mapping so that QVariant::LongLong
+ // is still returned to the caller
+ for ( QMap< QString, QVariant::Type >::const_iterator it = mapFieldTypesToPatch.begin(); it != mapFieldTypesToPatch.end(); ++it )
+ {
+ int idx = mAttributeFields.fieldNameIndex( it.key() );
+ if ( idx >= 0 )
+ mAttributeFields[ idx ].setType( *it );
+ }
+
return returnvalue;
}
diff --git a/src/providers/wfs/qgswfscapabilities.cpp b/src/providers/wfs/qgswfscapabilities.cpp
index e3349d4..ec83cd2 100644
--- a/src/providers/wfs/qgswfscapabilities.cpp
+++ b/src/providers/wfs/qgswfscapabilities.cpp
@@ -26,7 +26,7 @@
#include <QSettings>
#include <QStringList>
-QgsWFSCapabilities::QgsWFSCapabilities( const QString& theUri )
+QgsWFSCapabilities::QgsWFSCapabilities( const QString &theUri )
: QgsWFSRequest( theUri )
{
connect( this, SIGNAL( downloadFinished() ), this, SLOT( capabilitiesReplyFinished() ) );
diff --git a/src/providers/wfs/qgswfsconstants.cpp b/src/providers/wfs/qgswfsconstants.cpp
index 380e5f0..2aecf3e 100644
--- a/src/providers/wfs/qgswfsconstants.cpp
+++ b/src/providers/wfs/qgswfsconstants.cpp
@@ -23,11 +23,13 @@ const QString QgsWFSConstants::XMLSCHEMA_NAMESPACE( "http://www.w3.org/2001/XMLS
const QString QgsWFSConstants::URI_PARAM_URL( "url" );
const QString QgsWFSConstants::URI_PARAM_USERNAME( "username" );
+const QString QgsWFSConstants::URI_PARAM_USER( "user" );
const QString QgsWFSConstants::URI_PARAM_PASSWORD( "password" );
const QString QgsWFSConstants::URI_PARAM_AUTHCFG( "authcfg" );
const QString QgsWFSConstants::URI_PARAM_VERSION( "version" );
const QString QgsWFSConstants::URI_PARAM_TYPENAME( "typename" );
const QString QgsWFSConstants::URI_PARAM_SRSNAME( "srsname" );
+const QString QgsWFSConstants::URI_PARAM_BBOX( "bbox" );
const QString QgsWFSConstants::URI_PARAM_FILTER( "filter" );
const QString QgsWFSConstants::URI_PARAM_RESTRICT_TO_REQUEST_BBOX( "retrictToRequestBBOX" );
const QString QgsWFSConstants::URI_PARAM_MAXNUMFEATURES( "maxNumFeatures" );
diff --git a/src/providers/wfs/qgswfsconstants.h b/src/providers/wfs/qgswfsconstants.h
index 3011a34..23345ac 100644
--- a/src/providers/wfs/qgswfsconstants.h
+++ b/src/providers/wfs/qgswfsconstants.h
@@ -29,12 +29,16 @@ struct QgsWFSConstants
// URI parameters
static const QString URI_PARAM_URL;
static const QString URI_PARAM_USERNAME;
+ // QgsDataSourceURI recognizes "user" instead of "username"
+ // we are going to check both
+ static const QString URI_PARAM_USER;
static const QString URI_PARAM_PASSWORD;
static const QString URI_PARAM_AUTHCFG;
static const QString URI_PARAM_VERSION;
static const QString URI_PARAM_TYPENAME;
static const QString URI_PARAM_SRSNAME;
static const QString URI_PARAM_FILTER;
+ static const QString URI_PARAM_BBOX;
static const QString URI_PARAM_RESTRICT_TO_REQUEST_BBOX;
static const QString URI_PARAM_MAXNUMFEATURES;
static const QString URI_PARAM_IGNOREAXISORIENTATION;
diff --git a/src/providers/wfs/qgswfsdatasourceuri.cpp b/src/providers/wfs/qgswfsdatasourceuri.cpp
index 735051c..337563b 100644
--- a/src/providers/wfs/qgswfsdatasourceuri.cpp
+++ b/src/providers/wfs/qgswfsdatasourceuri.cpp
@@ -13,6 +13,8 @@
* *
***************************************************************************/
+#include "QtGlobal"
+
#include "qgswfsconstants.h"
#include "qgswfsdatasourceuri.h"
#include "qgsmessagelog.h"
@@ -25,11 +27,26 @@ QgsWFSDataSourceURI::QgsWFSDataSourceURI( const QString& uri )
if ( !mURI.hasParam( QgsWFSConstants::URI_PARAM_URL ) )
{
QUrl url( uri );
- QString srsname = url.queryItemValue( "SRSNAME" );
- QString bbox = url.queryItemValue( "BBOX" );
- QString typeName = url.queryItemValue( "TYPENAME" );
- QString filter = url.queryItemValue( "FILTER" );
+ // Transform all param keys to lowercase
+ typedef QPair<QString, QString> queryItem;
+ QList<queryItem> items( url.queryItems() );
+ foreach ( queryItem item, items )
+ {
+ url.removeQueryItem( item.first );
+ url.addQueryItem( item.first.toLower(), item.second );
+ }
+
+ QString srsname = url.queryItemValue( QgsWFSConstants::URI_PARAM_SRSNAME );
+ QString bbox = url.queryItemValue( QgsWFSConstants::URI_PARAM_BBOX );
+ QString typeName = url.queryItemValue( QgsWFSConstants::URI_PARAM_TYPENAME );
+ QString version = url.queryItemValue( QgsWFSConstants::URI_PARAM_VERSION );
+ QString filter = url.queryItemValue( QgsWFSConstants::URI_PARAM_FILTER );
mAuth.mUserName = url.queryItemValue( QgsWFSConstants::URI_PARAM_USERNAME );
+ // In QgsDataSourceURI, the "username" param is named "user", check it
+ if ( mAuth.mUserName.isEmpty() )
+ {
+ mAuth.mUserName = url.queryItemValue( QgsWFSConstants::URI_PARAM_USER );
+ }
mAuth.mPassword = url.queryItemValue( QgsWFSConstants::URI_PARAM_PASSWORD );
mAuth.mAuthCfg = url.queryItemValue( QgsWFSConstants::URI_PARAM_AUTHCFG );
@@ -49,6 +66,7 @@ QgsWFSDataSourceURI::QgsWFSDataSourceURI( const QString& uri )
mURI.setParam( QgsWFSConstants::URI_PARAM_URL, url.toEncoded() );
setTypeName( typeName );
setSRSName( srsname );
+ setVersion( version );
//if the xml comes from the dialog, it needs to be a string to pass the validity test
if ( filter.startsWith( '\'' ) && filter.endsWith( '\'' ) && filter.size() > 1 )
@@ -63,17 +81,32 @@ QgsWFSDataSourceURI::QgsWFSDataSourceURI( const QString& uri )
}
else
{
- mAuth.mUserName = mURI.param( QgsWFSConstants::URI_PARAM_USERNAME );
- mAuth.mPassword = mURI.param( QgsWFSConstants::URI_PARAM_PASSWORD );
- mAuth.mAuthCfg = mURI.param( QgsWFSConstants::URI_PARAM_AUTHCFG );
+ mAuth.mUserName = mURI.username();
+ mAuth.mPassword = mURI.password();
+ mAuth.mAuthCfg = mURI.authConfigId();
}
}
-QString QgsWFSDataSourceURI::uri()
+const QString QgsWFSDataSourceURI::uri( bool expandAuthConfig ) const
{
- return mURI.uri();
+ QgsDataSourceURI theURI( mURI );
+ // Add auth params back into the uri
+ if ( ! mAuth.mAuthCfg.isEmpty() )
+ {
+ theURI.setAuthConfigId( mAuth.mAuthCfg );
+ }
+ if ( ! mAuth.mUserName.isEmpty() )
+ {
+ theURI.setUsername( mAuth.mUserName );
+ }
+ if ( ! mAuth.mPassword.isEmpty() )
+ {
+ theURI.setPassword( mAuth.mPassword );
+ }
+ return theURI.uri( expandAuthConfig );
}
+
QUrl QgsWFSDataSourceURI::baseURL( bool bIncludeServiceWFS ) const
{
QUrl url( mURI.param( QgsWFSConstants::URI_PARAM_URL ) );
@@ -122,6 +155,13 @@ void QgsWFSDataSourceURI::setSRSName( const QString& crsString )
mURI.setParam( QgsWFSConstants::URI_PARAM_SRSNAME, crsString );
}
+void QgsWFSDataSourceURI::setVersion( const QString& versionString )
+{
+ mURI.removeParam( QgsWFSConstants::URI_PARAM_VERSION );
+ if ( !versionString.isEmpty() )
+ mURI.setParam( QgsWFSConstants::URI_PARAM_VERSION, versionString );
+}
+
QString QgsWFSDataSourceURI::SRSName() const
{
return mURI.param( QgsWFSConstants::URI_PARAM_SRSNAME );
diff --git a/src/providers/wfs/qgswfsdatasourceuri.h b/src/providers/wfs/qgswfsdatasourceuri.h
index d995b1c..7375068 100644
--- a/src/providers/wfs/qgswfsdatasourceuri.h
+++ b/src/providers/wfs/qgswfsdatasourceuri.h
@@ -66,7 +66,7 @@ class QgsWFSDataSourceURI
explicit QgsWFSDataSourceURI( const QString& uri );
/** Return the URI */
- QString uri();
+ const QString uri( bool expandAuthConfig = true ) const;
/** Return base URL (with SERVICE=WFS parameter if bIncludeServiceWFS=true) */
QUrl baseURL( bool bIncludeServiceWFS = true ) const;
@@ -92,6 +92,9 @@ class QgsWFSDataSourceURI
/** Set SRS name (in the normalized form EPSG:xxxx) */
void setSRSName( const QString& crsString );
+ /** Set version */
+ void setVersion( const QString& versionString );
+
/** Get OGC filter xml or a QGIS expression */
QString filter() const;
diff --git a/src/providers/wfs/qgswfsprovider.cpp b/src/providers/wfs/qgswfsprovider.cpp
index 41759c9..17617ac 100644
--- a/src/providers/wfs/qgswfsprovider.cpp
+++ b/src/providers/wfs/qgswfsprovider.cpp
@@ -1101,7 +1101,7 @@ bool QgsWFSProvider::describeFeatureType( QString& geometryAttribute, QgsFields&
{
fields.clear();
- QgsWFSDescribeFeatureType describeFeatureType( mShared->mURI.uri() );
+ QgsWFSDescribeFeatureType describeFeatureType( mShared->mURI.uri( false ) );
if ( !describeFeatureType.requestFeatureType( mShared->mWFSVersion,
mShared->mURI.typeName() ) )
{
@@ -1162,17 +1162,23 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
// collect the correspond type.
QDomElement elementElement = schemaElement.firstChildElement( "element" );
QString elementTypeString;
+ QDomElement complexTypeElement;
while ( !elementElement.isNull() )
{
QString name = elementElement.attribute( "name" );
if ( name == unprefixedTypename )
{
elementTypeString = elementElement.attribute( "type" );
+ if ( elementTypeString.isEmpty() )
+ {
+ // e.g http://afnemers.ruimtelijkeplannen.nl/afnemers2012/services?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=app:Bouwvlak
+ complexTypeElement = elementElement.firstChildElement( "complexType" );
+ }
break;
}
elementElement = elementElement.nextSiblingElement( "element" );
}
- if ( elementTypeString.isEmpty() )
+ if ( elementTypeString.isEmpty() && complexTypeElement.isNull() )
{
// "http://demo.deegree.org/inspire-workspace/services/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=ad:Address"
QDomElement iter = schemaElement.firstChildElement();
@@ -1207,21 +1213,24 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
elementTypeString = elementTypeString.section( ':', 1 );
}
- //the <complexType> element corresponding to the feature type
- QDomElement complexTypeElement = schemaElement.firstChildElement( "complexType" );
- while ( !complexTypeElement.isNull() )
+ if ( complexTypeElement.isNull() )
{
- QString name = complexTypeElement.attribute( "name" );
- if ( name == elementTypeString )
+ //the <complexType> element corresponding to the feature type
+ complexTypeElement = schemaElement.firstChildElement( "complexType" );
+ while ( !complexTypeElement.isNull() )
{
- break;
+ QString name = complexTypeElement.attribute( "name" );
+ if ( name == elementTypeString )
+ {
+ break;
+ }
+ complexTypeElement = complexTypeElement.nextSiblingElement( "complexType" );
+ }
+ if ( complexTypeElement.isNull() )
+ {
+ errorMsg = tr( "Cannot find ComplexType element '%1'" ).arg( elementTypeString );
+ return false;
}
- complexTypeElement = complexTypeElement.nextSiblingElement( "complexType" );
- }
- if ( complexTypeElement.isNull() )
- {
- errorMsg = tr( "Cannot find ComplexType element '%1'" ).arg( elementTypeString );
- return false;
}
//we have the relevant <complexType> element. Now find out the geometry and the thematic attributes
@@ -1321,7 +1330,7 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument& doc, QDomDocum
return false;
}
- QgsWFSTransactionRequest request( mShared->mURI.uri() );
+ QgsWFSTransactionRequest request( mShared->mURI.uri( false ) );
return request.send( doc, serverResponse );
}
@@ -1424,7 +1433,7 @@ bool QgsWFSProvider::getCapabilities()
if ( mShared->mCaps.version.isEmpty() )
{
- QgsWFSCapabilities getCapabilities( mShared->mURI.uri() );
+ QgsWFSCapabilities getCapabilities( mShared->mURI.uri( false ) );
if ( !getCapabilities.requestCapabilities( true ) )
{
QgsMessageLog::logMessage( tr( "GetCapabilities failed for url %1: %2" ).
diff --git a/tests/src/gui/testqgsdualview.cpp b/tests/src/gui/testqgsdualview.cpp
index 4e2b017..0882a32 100644
--- a/tests/src/gui/testqgsdualview.cpp
+++ b/tests/src/gui/testqgsdualview.cpp
@@ -171,6 +171,33 @@ void TestQgsDualView::testSort()
QModelIndex index = mDualView->tableView()->model()->index( i, 0 );
QCOMPARE( mDualView->tableView()->model()->data( index ).toString(), classes.at( i ) );
}
+
+ QStringList headings;
+ headings << "0"
+ << "0"
+ << "12"
+ << "34"
+ << "80"
+ << "85"
+ << "90"
+ << "90"
+ << "95"
+ << "100"
+ << "140"
+ << "160"
+ << "180"
+ << "240"
+ << "270"
+ << "300"
+ << "340";
+
+ mDualView->setSortExpression( "Heading" );
+
+ for ( int i = 0; i < headings.length(); ++i )
+ {
+ QModelIndex index = mDualView->tableView()->model()->index( i, 1 );
+ QCOMPARE( mDualView->tableView()->model()->data( index ).toString(), headings.at( i ) );
+ }
}
void TestQgsDualView::testAttributeFormSharedValueScanning()
diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt
index 1fddd91..eb6d877 100644
--- a/tests/src/python/CMakeLists.txt
+++ b/tests/src/python/CMakeLists.txt
@@ -69,6 +69,7 @@ ADD_PYTHON_TEST(PyQgsPoint test_qgspoint.py)
ADD_PYTHON_TEST(PyQgsRangeWidgets test_qgsrangewidgets.py)
ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py)
ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
+ADD_PYTHON_TEST(PyQgsRasterColorRampShader test_qgsrastercolorrampshader.py)
ADD_PYTHON_TEST(PyQgsRectangle test_qgsrectangle.py)
ADD_PYTHON_TEST(PyQgsRelation test_qgsrelation.py)
ADD_PYTHON_TEST(PyQgsRelationManager test_qgsrelationmanager.py)
diff --git a/tests/src/python/providertestbase.py b/tests/src/python/providertestbase.py
index 5d19ffd..698e4d3 100644
--- a/tests/src/python/providertestbase.py
+++ b/tests/src/python/providertestbase.py
@@ -383,10 +383,36 @@ class ProviderTestCase(object):
expected = set([fids[1], fids[3], fids[4]])
assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)
+ #providers should ignore non-existant fids
+ result = set([f.id() for f in self.provider.getFeatures(QgsFeatureRequest().setFilterFids([-101, fids[1], -102, fids[3], -103, fids[4], -104]))])
+ expected = set([fids[1], fids[3], fids[4]])
+ assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)
+
result = set([f.id() for f in self.provider.getFeatures(QgsFeatureRequest().setFilterFids([]))])
expected = set([])
assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)
+ # Rewind mid-way
+ request = QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]])
+ feature_it = self.provider.getFeatures(request)
+ feature = QgsFeature()
+ feature.setValid(True)
+ self.assertTrue(feature_it.nextFeature(feature))
+ self.assertIn(feature.id(), [fids[1], fids[3], fids[4]])
+ first_feature = feature
+ self.assertTrue(feature.isValid())
+ # rewind
+ self.assertTrue(feature_it.rewind())
+ self.assertTrue(feature_it.nextFeature(feature))
+ self.assertEqual(feature.id(), first_feature.id())
+ self.assertTrue(feature.isValid())
+ # grab all features
+ self.assertTrue(feature_it.nextFeature(feature))
+ self.assertTrue(feature_it.nextFeature(feature))
+ # none left
+ self.assertFalse(feature_it.nextFeature(feature))
+ self.assertFalse(feature.isValid())
+
def testGetFeaturesFilterRectTests(self):
extent = QgsRectangle(-70, 67, -60, 80)
request = QgsFeatureRequest().setFilterRect(extent)
diff --git a/tests/src/python/test_provider_tabfile.py b/tests/src/python/test_provider_tabfile.py
index ca86d22..3acaff6 100644
--- a/tests/src/python/test_provider_tabfile.py
+++ b/tests/src/python/test_provider_tabfile.py
@@ -14,8 +14,8 @@ __revision__ = '$Format:%H$'
import os
import tempfile
-from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsVectorDataProvider
-from qgis.PyQt.QtCore import QDate, QTime, QDateTime, QVariant
+from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsVectorDataProvider, QgsField
+from qgis.PyQt.QtCore import QDate, QTime, QDateTime, QVariant, QDir
from qgis.testing import (
start_app,
unittest
@@ -90,6 +90,20 @@ class TestPyQgsTabfileProvider(unittest.TestCase):
self.assertEquals(vl.dataProvider().property("_debug_open_mode"), "read-only")
self.assertTrue(vl.dataProvider().isValid())
+ @unittest.expectedFailure(int(osgeo.gdal.VersionInfo()[:1]) < 2)
+ def testInteger64WriteTabfile(self):
+ """Check writing Integer64 fields to an MapInfo tabfile (which does not support that type)."""
+
+ base_dest_file_name = os.path.join(str(QDir.tempPath()), 'integer64')
+ dest_file_name = base_dest_file_name + '.tab'
+ shutil.copy(os.path.join(TEST_DATA_DIR, 'tab_file.tab'), base_dest_file_name + '.tab')
+ shutil.copy(os.path.join(TEST_DATA_DIR, 'tab_file.dat'), base_dest_file_name + '.dat')
+ shutil.copy(os.path.join(TEST_DATA_DIR, 'tab_file.map'), base_dest_file_name + '.map')
+ shutil.copy(os.path.join(TEST_DATA_DIR, 'tab_file.id'), base_dest_file_name + '.id')
+ vl = QgsVectorLayer(u'{}|layerid=0'.format(dest_file_name), u'test', u'ogr')
+ self.assertTrue(vl.isValid())
+ self.assertTrue(vl.dataProvider().addAttributes([QgsField("int8", QVariant.LongLong, "integer64")]))
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/src/python/test_provider_wfs.py b/tests/src/python/test_provider_wfs.py
index dcdb1cc..07da9ad 100644
--- a/tests/src/python/test_provider_wfs.py
+++ b/tests/src/python/test_provider_wfs.py
@@ -2111,6 +2111,94 @@ class TestPyQgsWFSProvider(unittest.TestCase, ProviderTestCase):
got = got_f[0].geometry().geometry()
self.assertEqual((got.x(), got.y()), (2.0, 49.0))
+ def testDescribeFeatureTypeWithInlineType(self):
+ """Test a DescribeFeatureType response with a inline ComplexType (#15395)."""
+
+ endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_testDescribeFeatureTypeWithInlineType'
+
+ with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.1.0'), 'wb') as f:
+ f.write("""
+<wfs:WFS_Capabilities version="1.1.0" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://schemas.opengis.net/gml">
+ <FeatureTypeList>
+ <FeatureType>
+ <Name>my:typename</Name>
+ <Title>Title</Title>
+ <Abstract>Abstract</Abstract>
+ <DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>2 49</ows:LowerCorner>
+ <ows:UpperCorner>2 49</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ </FeatureType>
+ </FeatureTypeList>
+</wfs:WFS_Capabilities>""".encode('UTF-8'))
+
+ with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=my:typename'), 'wb') as f:
+ f.write("""
+<schema
+ targetNamespace="http://my"
+ xmlns:my="http://my"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:gml="http://www.opengis.net/gml"
+ elementFormDefault="qualified" version="0.1" >
+ <import namespace="http://www.opengis.net/gml"
+ schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />
+ <element name="typename"
+ substitutionGroup="gml:_Feature">
+ <complexType>
+ <complexContent>
+ <extension base="gml:AbstractFeatureType">
+ <sequence>
+ <element name="geometryProperty" type="gml:GeometryPropertyType" minOccurs="0" maxOccurs="1"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+ </element>
+</schema>
+""".encode('UTF-8'))
+
+ with open(sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&SRSNAME=urn:ogc:def:crs:EPSG::4326"""), 'wb') as f:
+ f.write("""
+<wfs:FeatureCollection
+ xmlns:my="http://my"
+ xmlns:gml="http://www.opengis.net/gml"
+ xmlns:wfs="http://www.opengis.net/wfs"
+ xmlns:ogc="http://www.opengis.net/ogc">
+ <gml:boundedBy>
+ <gml:Envelope srsName="EPSG:4326">
+ <gml:lowerCorner>49.000000 2.000000</gml:lowerCorner>
+ <gml:upperCorner>49.000000 2.000000</gml:upperCorner>
+ </gml:Envelope>
+ </gml:boundedBy>
+ <gml:featureMember>
+ <my:typename gml:id="typename.1">
+ <gml:boundedBy>
+ <gml:Envelope srsName="EPSG:4326">
+ <gml:lowerCorner>49.000000 2.000000</gml:lowerCorner>
+ <gml:upperCorner>49.000000 2.000000</gml:upperCorner>
+ </gml:Envelope>
+ </gml:boundedBy>
+ <my:geometryProperty>
+ <gml:Point srsName="EPSG:4326">
+ <gml:pos>49.000000 2.000000</gml:pos>
+ </gml:Point>
+ </my:geometryProperty>
+ </my:typename>
+ </gml:featureMember>
+</wfs:FeatureCollection>
+
+""".encode('UTF-8'))
+
+ vl = QgsVectorLayer(u"url='http://" + endpoint + u"' typename='my:typename' version='1.1.0'", u'test', u'WFS')
+ assert vl.isValid()
+
+ got_f = [f for f in vl.getFeatures()]
+ got = got_f[0].geometry().geometry()
+ self.assertEqual((got.x(), got.y()), (2.0, 49.0))
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/src/python/test_qgsattributetablemodel.py b/tests/src/python/test_qgsattributetablemodel.py
index 5a01928..9fabaec 100644
--- a/tests/src/python/test_qgsattributetablemodel.py
+++ b/tests/src/python/test_qgsattributetablemodel.py
@@ -12,8 +12,17 @@ __copyright__ = 'Copyright 2015, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
-from qgis.gui import QgsAttributeTableModel, QgsEditorWidgetRegistry
-from qgis.core import QgsFeature, QgsGeometry, QgsPoint, QgsVectorLayer, QgsVectorLayerCache
+from qgis.gui import (
+ QgsAttributeTableModel,
+ QgsEditorWidgetRegistry
+)
+from qgis.core import (
+ QgsFeature,
+ QgsGeometry,
+ QgsPoint,
+ QgsVectorLayer,
+ QgsVectorLayerCache
+)
from qgis.testing import (start_app,
unittest
@@ -51,20 +60,20 @@ class TestQgsAttributeTableModel(unittest.TestCase):
f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100 * i, 2 ^ i)))
features.append(f)
- assert pr.addFeatures(features)
+ self.assertTrue(pr.addFeatures(features))
return layer
def testLoad(self):
- assert self.am.rowCount() == 10, self.am.rowCount()
- assert self.am.columnCount() == 2, self.am.columnCount()
+ self.assertEquals(self.am.rowCount(), 10)
+ self.assertEquals(self.am.columnCount(), 2)
def testRemove(self):
self.layer.startEditing()
self.layer.deleteFeature(5)
- assert self.am.rowCount() == 9, self.am.rowCount()
+ self.assertEquals(self.am.rowCount(), 9)
self.layer.setSelectedFeatures([1, 3, 6, 7])
self.layer.deleteSelectedFeatures()
- assert self.am.rowCount() == 5, self.am.rowCount()
+ self.assertEquals(self.am.rowCount(), 5)
def testAdd(self):
self.layer.startEditing()
@@ -74,14 +83,14 @@ class TestQgsAttributeTableModel(unittest.TestCase):
f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
self.layer.addFeature(f)
- assert self.am.rowCount() == 11, self.am.rowCount()
+ self.assertEquals(self.am.rowCount(), 11)
def testRemoveColumns(self):
- assert self.layer.startEditing()
+ self.assertTrue(self.layer.startEditing())
- assert self.layer.deleteAttribute(1)
+ self.assertTrue(self.layer.deleteAttribute(1))
- assert self.am.columnCount() == 1, self.am.columnCount()
+ self.assertEquals(self.am.columnCount(), 1)
if __name__ == '__main__':
unittest.main()
diff --git a/tests/src/python/test_qgsfeatureiterator.py b/tests/src/python/test_qgsfeatureiterator.py
index 9b29a61..d6ca9b9 100644
--- a/tests/src/python/test_qgsfeatureiterator.py
+++ b/tests/src/python/test_qgsfeatureiterator.py
@@ -79,23 +79,20 @@ class TestQgsFeatureIterator(unittest.TestCase):
ids = [feat.id() for feat in pointLayer.getFeatures(QgsFeatureRequest().setFilterFids([7, 8, 12, 30]))]
expectedIds = [7, 8, 12]
- myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
- assert ids == expectedIds, myMessage
+ self.assertEquals(set(ids), set(expectedIds))
pointLayer.startEditing()
self.addFeatures(pointLayer)
ids = [feat.id() for feat in pointLayer.getFeatures(QgsFeatureRequest().setFilterFids([-4, 7, 8, 12, 30]))]
expectedIds = [-4, 7, 8, 12]
- myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
- assert ids == expectedIds, myMessage
+ self.assertEquals(set(ids), set(expectedIds))
pointLayer.rollBack()
ids = [feat.id() for feat in pointLayer.getFeatures(QgsFeatureRequest().setFilterFids([-2, 7, 8, 12, 30]))]
expectedIds = [7, 8, 12]
- myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
- assert ids == expectedIds, myMessage
+ self.assertEquals(set(ids), set(expectedIds))
def addFeatures(self, vl):
feat = QgsFeature()
diff --git a/tests/src/python/test_qgspallabeling_placement.py b/tests/src/python/test_qgspallabeling_placement.py
index e7c5c37..5b32792 100644
--- a/tests/src/python/test_qgspallabeling_placement.py
+++ b/tests/src/python/test_qgspallabeling_placement.py
@@ -48,6 +48,7 @@ class TestPlacementBase(TestQgsPalLabeling):
def setUp(self):
"""Run before each test."""
super(TestPlacementBase, self).setUp()
+ self.removeAllLayers()
self.configTest('pal_placement', 'sp')
self._TestImage = ''
# ensure per test map settings stay encapsulated
diff --git a/tests/src/python/test_qgsrastercolorrampshader.py b/tests/src/python/test_qgsrastercolorrampshader.py
new file mode 100644
index 0000000..e32d734
--- /dev/null
+++ b/tests/src/python/test_qgsrastercolorrampshader.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+"""QGIS Unit tests for QgsColorRampShader.
+
+.. note:: This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+"""
+
+__author__ = 'Nyall Dawson'
+__date__ = '17/08/2016'
+__copyright__ = 'Copyright 2016, The QGIS Project'
+# This will get replaced with a git SHA1 when you do a git archive
+__revision__ = '$Format:%H$'
+
+import qgis # NOQA
+
+
+from qgis.PyQt.QtGui import QColor
+
+from qgis.core import (QgsColorRampShader)
+from qgis.testing import unittest
+
+
+class TestQgsRasterColorRampShader(unittest.TestCase):
+
+ def testNan(self):
+ shader = QgsColorRampShader()
+
+ item1 = QgsColorRampShader.ColorRampItem(1, QColor(0, 0, 0))
+ item2 = QgsColorRampShader.ColorRampItem(2, QColor(255, 255, 255))
+ shader.setColorRampItemList([item1, item2])
+ self.assertFalse(shader.shade(float('NaN'))[0])
+ self.assertFalse(shader.shade(float("inf"))[0])
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/src/python/test_qgsvectorfilewriter.py b/tests/src/python/test_qgsvectorfilewriter.py
index 3b98e2e..f2d94f8 100644
--- a/tests/src/python/test_qgsvectorfilewriter.py
+++ b/tests/src/python/test_qgsvectorfilewriter.py
@@ -36,6 +36,10 @@ from utilities import writeShape, compareWkt
start_app()
+def GDAL_COMPUTE_VERSION(maj, min, rev):
+ return ((maj) * 1000000 + (min) * 10000 + (rev) * 100)
+
+
class TestFieldValueConverter(QgsVectorFileWriter.FieldValueConverter):
def __init__(self, layer):
@@ -416,5 +420,47 @@ class TestQgsVectorLayer(unittest.TestCase):
self.assertEqual(f['nonconv'], 1)
self.assertEqual(f['conv_attr'], 'converted_val')
+ @unittest.expectedFailure(int(osgeo.gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0))
+ def testInteger64WriteTabfile(self):
+ """Check writing Integer64 fields to an MapInfo tabfile (which does not support that type)."""
+ ml = QgsVectorLayer(
+ ('Point?crs=epsg:4326&field=int8:int8'),
+ 'test',
+ 'memory')
+
+ self.assertIsNotNone(ml, 'Provider not initialized')
+ self.assertTrue(ml.isValid(), 'Source layer not valid')
+ provider = ml.dataProvider()
+ self.assertIsNotNone(provider)
+
+ ft = QgsFeature()
+ ft.setAttributes([2123456789])
+ res, features = provider.addFeatures([ft])
+ self.assertTrue(res)
+ self.assertTrue(features)
+
+ dest_file_name = os.path.join(str(QDir.tempPath()), 'integer64.tab')
+ crs = QgsCoordinateReferenceSystem()
+ crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
+ write_result = QgsVectorFileWriter.writeAsVectorFormat(
+ ml,
+ dest_file_name,
+ 'utf-8',
+ crs,
+ 'MapInfo File')
+ self.assertEqual(write_result, QgsVectorFileWriter.NoError)
+
+ # Open result and check
+ created_layer = QgsVectorLayer(u'{}|layerid=0'.format(dest_file_name), u'test', u'ogr')
+
+ fields = created_layer.dataProvider().fields()
+ self.assertEqual(fields.at(fields.indexFromName('int8')).type(), QVariant.Double)
+
+ f = next(created_layer.getFeatures(QgsFeatureRequest()))
+
+ int8_idx = created_layer.fieldNameIndex('int8')
+ self.assertEqual(f.attributes()[int8_idx], 2123456789)
+
+
if __name__ == '__main__':
unittest.main()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/qgis.git
More information about the Pkg-grass-devel
mailing list