Skip to content

Instantly share code, notes, and snippets.

@dakcarto
Last active November 2, 2016 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dakcarto/8a6a45737523efce13c7f1521ff85c8b to your computer and use it in GitHub Desktop.
Save dakcarto/8a6a45737523efce13c7f1521ff85c8b to your computer and use it in GitHub Desktop.
From d527c8571c4a7e9ed2a671126faa0284ff436019 Mon Sep 17 00:00:00 2001
From: Matteo Ghetta <matteo.ghetta@gmail.com>
Date: Mon, 10 Oct 2016 10:48:27 +0200
Subject: [PATCH] Missing import fixed for R algorithm
---
python/plugins/processing/algs/r/RUtils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/plugins/processing/algs/r/RUtils.py b/python/plugins/processing/algs/r/RUtils.py
index ddfe701..8c5612c 100644
--- a/python/plugins/processing/algs/r/RUtils.py
+++ b/python/plugins/processing/algs/r/RUtils.py
@@ -33,7 +33,7 @@ import subprocess
from PyQt4.QtCore import QSettings, QCoreApplication
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.ProcessingLog import ProcessingLog
-from processing.tools.system import userFolder, isWindows, mkdir
+from processing.tools.system import userFolder, isWindows, mkdir, getTempFilenameInTempFolder
class RUtils:
--
2.8.1
From 6bf74b437646c480595ead6765102a3f70825b4f Mon Sep 17 00:00:00 2001
From: "Juergen E. Fischer" <jef@norbit.de>
Date: Sat, 22 Oct 2016 21:54:28 +0200
Subject: [PATCH] fix #15744 (followup dbf6169)
---
python/plugins/processing/algs/qgis/Eliminate.py | 3 ---
1 file changed, 3 deletions(-)
diff --git a/python/plugins/processing/algs/qgis/Eliminate.py b/python/plugins/processing/algs/qgis/Eliminate.py
index 6bc6352..a975ee6 100644
--- a/python/plugins/processing/algs/qgis/Eliminate.py
+++ b/python/plugins/processing/algs/qgis/Eliminate.py
@@ -54,9 +54,6 @@ class Eliminate(GeoAlgorithm):
MODE_SMALLEST_AREA = 1
MODE_BOUNDARY = 2
- def getIcon(self):
- return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'eliminate.png'))
-
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Eliminate sliver polygons')
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools')
--
2.8.1
From 36db42ebb4e2e338ae56a3ade68083e06d70cb7a Mon Sep 17 00:00:00 2001
From: rldhont <rldhont@gmail.com>
Date: Tue, 25 Oct 2016 13:40:10 +0200
Subject: [PATCH] [BUGFIX][QGIS Server] Do not cache invalid layer
After readLayerXml, the server stored layers in cache and in registry without verifying validity.
---
src/server/qgshostedrdsbuilder.cpp | 2 +-
src/server/qgsserverprojectparser.cpp | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/server/qgshostedrdsbuilder.cpp b/src/server/qgshostedrdsbuilder.cpp
index acba4e6..72b236d 100644
--- a/src/server/qgshostedrdsbuilder.cpp
+++ b/src/server/qgshostedrdsbuilder.cpp
@@ -61,7 +61,7 @@ QgsMapLayer* QgsHostedRDSBuilder::createMapLayer( const QDomElement& elem,
{
rl = qobject_cast<QgsRasterLayer*>( QgsMSLayerCache::instance()->searchLayer( uri, layerName ) );
}
- if ( !rl )
+ if ( !rl || !rl->isValid() )
{
QgsDebugMsg( "hostedrds layer not in cache, so create and insert it" );
rl = new QgsRasterLayer( uri, layerNameFromUri( uri ) );
diff --git a/src/server/qgsserverprojectparser.cpp b/src/server/qgsserverprojectparser.cpp
index f3807a0..89361db 100644
--- a/src/server/qgsserverprojectparser.cpp
+++ b/src/server/qgsserverprojectparser.cpp
@@ -278,6 +278,10 @@ QgsMapLayer* QgsServerProjectParser::createLayerFromElement( const QDomElement&
layer->readLayerXML( const_cast<QDomElement&>( elem ) ); //should be changed to const in QgsMapLayer
//layer->setLayerName( layerName( elem ) );
+ if ( !layer->isValid() )
+ {
+ return nullptr;
+ }
// Insert layer in registry and cache before addValueRelationLayersForLayer
if ( !QgsMapLayerRegistry::instance()->mapLayer( id ) )
QgsMapLayerRegistry::instance()->addMapLayer( layer, false, false );
--
2.8.1
From 2a13dbff39ca63f9a8c9c5c653ac08ab245dcd5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Germ=C3=A1n?= <geotux_tuxman@linuxmail.org>
Date: Tue, 25 Oct 2016 20:57:22 -0500
Subject: [PATCH] Import vector because it is used in line 95.
It seems that line 95 was added by a cherry pick commit.
---
python/plugins/processing/algs/qgis/Eliminate.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/plugins/processing/algs/qgis/Eliminate.py b/python/plugins/processing/algs/qgis/Eliminate.py
index a975ee6..63dd595 100644
--- a/python/plugins/processing/algs/qgis/Eliminate.py
+++ b/python/plugins/processing/algs/qgis/Eliminate.py
@@ -37,7 +37,7 @@ from processing.core.parameters import ParameterTableField
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterSelection
from processing.core.outputs import OutputVector
-from processing.tools import dataobjects
+from processing.tools import dataobjects, vector
class Eliminate(GeoAlgorithm):
--
2.8.1
From fa7491f28168d12887a93bb116026e591d4729c2 Mon Sep 17 00:00:00 2001
From: Marco Hugentobler <marco.hugentobler@sourcepole.ch>
Date: Thu, 27 Oct 2016 09:18:11 +0200
Subject: [PATCH] Fix python bindings of QgsGeometryRubberBand
---
python/gui/qgsgeometryrubberband.sip | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/gui/qgsgeometryrubberband.sip b/python/gui/qgsgeometryrubberband.sip
index 4d8cc7a..3cb22a7 100644
--- a/python/gui/qgsgeometryrubberband.sip
+++ b/python/gui/qgsgeometryrubberband.sip
@@ -54,7 +54,7 @@ class QgsGeometryRubberBand: QgsMapCanvasItem
~QgsGeometryRubberBand();
/** Sets geometry (takes ownership). Geometry is expected to be in map coordinates */
- void setGeometry( QgsAbstractGeometryV2* geom );
+ void setGeometry( QgsAbstractGeometryV2* geom /Transfer/ );
/** Returns a pointer to the geometry*/
const QgsAbstractGeometryV2* geometry();
/** Moves vertex to new position (in map coordinates)*/
--
2.8.1
From 68cbf0701206a156b71500b75e10aff8cee93f86 Mon Sep 17 00:00:00 2001
From: Nyall Dawson <nyall.dawson@gmail.com>
Date: Fri, 28 Oct 2016 07:58:58 +1000
Subject: [PATCH] Speed up point layer rendering - don't calculate unused label
obstacles
Cuts render time by ~60%. Fix #15752.
(cherry-picked from 5798a82c8011ea7f44a1ed1d55ef0719786e8056)
---
src/core/qgsvectorlayerrenderer.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp
index 6c7e477..126869b 100644
--- a/src/core/qgsvectorlayerrenderer.cpp
+++ b/src/core/qgsvectorlayerrenderer.cpp
@@ -333,7 +333,7 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )
}
}
// new labeling engine
- if ( mContext.labelingEngineV2() )
+ if ( mContext.labelingEngineV2() && ( mLabelProvider || mDiagramProvider ) )
{
QScopedPointer<QgsGeometry> obstacleGeometry;
QgsSymbolV2List symbols = mRendererV2->originalSymbolsForFeature( fet, mContext );
--
2.8.1
From 5f01a87278eaca8bda625f6e1d52bf3cdf582669 Mon Sep 17 00:00:00 2001
From: Nyall Dawson <nyall.dawson@gmail.com>
Date: Fri, 28 Oct 2016 08:25:40 +1000
Subject: [PATCH] Optimise QgsAbstractGeometry
Make nCoordinates virtual, and provide shortcuts for some
geometry types. The base method which calls coordinateSequence()
is quite slow in certain circumstances.
Speeds up rendering point layers by ~25%, also likely to
speed up lots of geometry heavy operations throughout QGIS
Refs #15752
(cherry-picked from 49432a84683e99bdc2592e7ae808e81fa3bc40cd)
---
python/core/geometry/qgsabstractgeometryv2.sip | 2 +-
python/core/geometry/qgscurvepolygonv2.sip | 1 +
python/core/geometry/qgsgeometrycollectionv2.sip | 1 +
python/core/geometry/qgslinestringv2.sip | 1 +
python/core/geometry/qgsmultipointv2.sip | 1 +
python/core/geometry/qgspointv2.sip | 1 +
src/core/geometry/qgsabstractgeometryv2.h | 2 +-
src/core/geometry/qgscurvepolygonv2.cpp | 21 +++++++++++++++++++++
src/core/geometry/qgscurvepolygonv2.h | 1 +
src/core/geometry/qgsgeometrycollectionv2.cpp | 16 ++++++++++++++++
src/core/geometry/qgsgeometrycollectionv2.h | 2 ++
src/core/geometry/qgslinestringv2.h | 1 +
src/core/geometry/qgsmultipointv2.h | 1 +
src/core/geometry/qgspointv2.h | 1 +
14 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/python/core/geometry/qgsabstractgeometryv2.sip b/python/core/geometry/qgsabstractgeometryv2.sip
index 2264423..1840fd9 100644
--- a/python/core/geometry/qgsabstractgeometryv2.sip
+++ b/python/core/geometry/qgsabstractgeometryv2.sip
@@ -227,7 +227,7 @@ class QgsAbstractGeometryV2
/** Returns the number of nodes contained in the geometry
*/
- int nCoordinates() const;
+ virtual int nCoordinates() const;
/** Returns the point corresponding to a specified vertex id
*/
diff --git a/python/core/geometry/qgscurvepolygonv2.sip b/python/core/geometry/qgscurvepolygonv2.sip
index 4843e16..268b114 100644
--- a/python/core/geometry/qgscurvepolygonv2.sip
+++ b/python/core/geometry/qgscurvepolygonv2.sip
@@ -65,6 +65,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
virtual bool deleteVertex( QgsVertexId position );
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
+ virtual int nCoordinates() const;
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const;
diff --git a/python/core/geometry/qgsgeometrycollectionv2.sip b/python/core/geometry/qgsgeometrycollectionv2.sip
index 87c2f0e..6930477 100644
--- a/python/core/geometry/qgsgeometrycollectionv2.sip
+++ b/python/core/geometry/qgsgeometrycollectionv2.sip
@@ -69,6 +69,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
virtual QgsRectangle boundingBox() const;
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
+ virtual int nCoordinates() const;
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const;
diff --git a/python/core/geometry/qgslinestringv2.sip b/python/core/geometry/qgslinestringv2.sip
index 319a811..5257225 100644
--- a/python/core/geometry/qgslinestringv2.sip
+++ b/python/core/geometry/qgslinestringv2.sip
@@ -134,6 +134,7 @@ class QgsLineStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine() const /Factory/;
int numPoints() const;
+ virtual int nCoordinates() const;
void points( QList<QgsPointV2>& pt ) const;
void draw( QPainter& p ) const;
diff --git a/python/core/geometry/qgsmultipointv2.sip b/python/core/geometry/qgsmultipointv2.sip
index 2838451..beec306 100644
--- a/python/core/geometry/qgsmultipointv2.sip
+++ b/python/core/geometry/qgsmultipointv2.sip
@@ -16,6 +16,7 @@ class QgsMultiPointV2: public QgsGeometryCollectionV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
QString asJSON( int precision = 17 ) const;
+ virtual int nCoordinates() const;
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
diff --git a/python/core/geometry/qgspointv2.sip b/python/core/geometry/qgspointv2.sip
index 13d3f48..a92278f 100644
--- a/python/core/geometry/qgspointv2.sip
+++ b/python/core/geometry/qgspointv2.sip
@@ -156,6 +156,7 @@ class QgsPointV2: public QgsAbstractGeometryV2
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t );
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
+ virtual int nCoordinates() const;
//low-level editing
virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex );
diff --git a/src/core/geometry/qgsabstractgeometryv2.h b/src/core/geometry/qgsabstractgeometryv2.h
index f5493f9..e6d4984 100644
--- a/src/core/geometry/qgsabstractgeometryv2.h
+++ b/src/core/geometry/qgsabstractgeometryv2.h
@@ -213,7 +213,7 @@ class CORE_EXPORT QgsAbstractGeometryV2
/** Returns the number of nodes contained in the geometry
*/
- int nCoordinates() const;
+ virtual int nCoordinates() const;
/** Returns the point corresponding to a specified vertex id
*/
diff --git a/src/core/geometry/qgscurvepolygonv2.cpp b/src/core/geometry/qgscurvepolygonv2.cpp
index 0393dbc..b4abde2 100644
--- a/src/core/geometry/qgscurvepolygonv2.cpp
+++ b/src/core/geometry/qgscurvepolygonv2.cpp
@@ -607,6 +607,27 @@ QgsCoordinateSequenceV2 QgsCurvePolygonV2::coordinateSequence() const
return mCoordinateSequence;
}
+int QgsCurvePolygonV2::nCoordinates() const
+{
+ if ( !mCoordinateSequence.isEmpty() )
+ return QgsAbstractGeometryV2::nCoordinates();
+
+ int count = 0;
+
+ if ( mExteriorRing )
+ {
+ count += mExteriorRing->nCoordinates();
+ }
+
+ QList<QgsCurveV2*>::const_iterator it = mInteriorRings.constBegin();
+ for ( ; it != mInteriorRings.constEnd(); ++it )
+ {
+ count += ( *it )->nCoordinates();
+ }
+
+ return count;
+}
+
double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
if ( !mExteriorRing )
diff --git a/src/core/geometry/qgscurvepolygonv2.h b/src/core/geometry/qgscurvepolygonv2.h
index c644d37..e8c4e94 100644
--- a/src/core/geometry/qgscurvepolygonv2.h
+++ b/src/core/geometry/qgscurvepolygonv2.h
@@ -91,6 +91,7 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
virtual bool deleteVertex( QgsVertexId position ) override;
virtual QgsCoordinateSequenceV2 coordinateSequence() const override;
+ virtual int nCoordinates() const override;
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override;
diff --git a/src/core/geometry/qgsgeometrycollectionv2.cpp b/src/core/geometry/qgsgeometrycollectionv2.cpp
index 2cec10c..f545d18 100644
--- a/src/core/geometry/qgsgeometrycollectionv2.cpp
+++ b/src/core/geometry/qgsgeometrycollectionv2.cpp
@@ -361,6 +361,22 @@ QgsCoordinateSequenceV2 QgsGeometryCollectionV2::coordinateSequence() const
return mCoordinateSequence;
}
+int QgsGeometryCollectionV2::nCoordinates() const
+{
+ if ( !mCoordinateSequence.isEmpty() )
+ return QgsAbstractGeometryV2::nCoordinates();
+
+ int count = 0;
+
+ QVector< QgsAbstractGeometryV2* >::const_iterator geomIt = mGeometries.constBegin();
+ for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
+ {
+ count += ( *geomIt )->nCoordinates();
+ }
+
+ return count;
+}
+
double QgsGeometryCollectionV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::PART, pt, segmentPt, vertexAfter, leftOf, epsilon );
diff --git a/src/core/geometry/qgsgeometrycollectionv2.h b/src/core/geometry/qgsgeometrycollectionv2.h
index 12c0c48..77e7e86 100644
--- a/src/core/geometry/qgsgeometrycollectionv2.h
+++ b/src/core/geometry/qgsgeometrycollectionv2.h
@@ -93,6 +93,8 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
virtual QgsRectangle boundingBox() const override;
virtual QgsCoordinateSequenceV2 coordinateSequence() const override;
+ virtual int nCoordinates() const override;
+
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override;
diff --git a/src/core/geometry/qgslinestringv2.h b/src/core/geometry/qgslinestringv2.h
index 16677d5..f43a915 100644
--- a/src/core/geometry/qgslinestringv2.h
+++ b/src/core/geometry/qgslinestringv2.h
@@ -159,6 +159,7 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine() const override;
int numPoints() const override;
+ virtual int nCoordinates() const override { return mX.size(); }
void points( QgsPointSequenceV2 &pt ) const override;
void draw( QPainter& p ) const override;
diff --git a/src/core/geometry/qgsmultipointv2.h b/src/core/geometry/qgsmultipointv2.h
index 977a2e7..67e5566 100644
--- a/src/core/geometry/qgsmultipointv2.h
+++ b/src/core/geometry/qgsmultipointv2.h
@@ -39,6 +39,7 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollectionV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
QString asJSON( int precision = 17 ) const override;
+ virtual int nCoordinates() const override { return mGeometries.size(); }
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
diff --git a/src/core/geometry/qgspointv2.h b/src/core/geometry/qgspointv2.h
index 2ed1e64..ac2900c 100644
--- a/src/core/geometry/qgspointv2.h
+++ b/src/core/geometry/qgspointv2.h
@@ -168,6 +168,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QTransform& t ) override;
virtual QgsCoordinateSequenceV2 coordinateSequence() const override;
+ virtual int nCoordinates() const override { return 1; }
//low-level editing
virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ) override { Q_UNUSED( position ); Q_UNUSED( vertex ); return false; }
--
2.8.1
From c93d56a94c5c5696e5b5f4285cb03f591020bebd Mon Sep 17 00:00:00 2001
From: Nyall Dawson <nyall.dawson@gmail.com>
Date: Fri, 28 Oct 2016 08:36:54 +1000
Subject: [PATCH] Use QgsExpressionContextScope::addVariable instead of
setVariable
...where appropriate (ie, read-only, non user set variables).
It's much faster as it doesn't need to check whether the
variable already exists.
Results in ~10% improvement in rendering speed. Refs #15752.
(cherry-picked from 85897885445c7383938ac89318d12a7d37024bb4)
---
src/app/composer/qgsattributeselectiondialog.cpp | 2 +-
src/app/qgsattributetabledialog.cpp | 4 ++--
src/app/qgsfieldcalculator.cpp | 4 ++--
src/core/composer/qgscomposerattributetablev2.cpp | 2 +-
src/core/composer/qgscomposermapgrid.cpp | 8 ++++----
src/core/qgsconditionalstyle.cpp | 2 +-
src/core/qgsexpression.cpp | 4 ++--
src/core/qgsexpressioncontext.cpp | 4 ++--
src/core/symbology-ng/qgssymbolv2.cpp | 10 +++++-----
src/gui/attributetable/qgsfieldconditionalformatwidget.cpp | 2 +-
src/gui/symbology-ng/qgssymbollayerv2widget.cpp | 2 +-
11 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/app/composer/qgsattributeselectiondialog.cpp b/src/app/composer/qgsattributeselectiondialog.cpp
index 0e4fdc5..7c360de 100644
--- a/src/app/composer/qgsattributeselectiondialog.cpp
+++ b/src/app/composer/qgsattributeselectiondialog.cpp
@@ -107,7 +107,7 @@ static QgsExpressionContext _getExpressionContext( const void* context )
}
QScopedPointer< QgsExpressionContext > expContext( object->createExpressionContext() );
- expContext->lastScope()->setVariable( "row_number", 1 );
+ expContext->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), 1, true ) );
expContext->setHighlightedVariables( QStringList() << "row_number" );
return QgsExpressionContext( *expContext );
}
diff --git a/src/app/qgsattributetabledialog.cpp b/src/app/qgsattributetabledialog.cpp
index 8a1684b..1670cd3 100644
--- a/src/app/qgsattributetabledialog.cpp
+++ b/src/app/qgsattributetabledialog.cpp
@@ -55,7 +55,7 @@ static QgsExpressionContext _getExpressionContext( const void* context )
if ( layer )
expContext << QgsExpressionContextUtils::layerScope( layer );
- expContext.lastScope()->setVariable( "row_number", 1 );
+ expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), 1, true ) );
expContext.setHighlightedVariables( QStringList() << "row_number" );
@@ -393,7 +393,7 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, const
}
context.setFeature( feature );
- context.lastScope()->setVariable( QString( "row_number" ), rownum );
+ context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), rownum, true ) );
QVariant value = exp.evaluate( &context );
fld.convertCompatible( value );
diff --git a/src/app/qgsfieldcalculator.cpp b/src/app/qgsfieldcalculator.cpp
index f8dc400..b26ab2a 100644
--- a/src/app/qgsfieldcalculator.cpp
+++ b/src/app/qgsfieldcalculator.cpp
@@ -43,7 +43,7 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl, QWidget* parent )
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( mVectorLayer );
- expContext.lastScope()->setVariable( "row_number", 1 );
+ expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), 1, true ) );
expContext.setHighlightedVariables( QStringList() << "row_number" );
builder->setLayer( vl );
@@ -281,7 +281,7 @@ void QgsFieldCalculator::accept()
while ( fit.nextFeature( feature ) )
{
expContext.setFeature( feature );
- expContext.lastScope()->setVariable( QString( "row_number" ), rownum );
+ expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), rownum, true ) );
QVariant value = exp.evaluate( &expContext );
if ( exp.hasEvalError() )
diff --git a/src/core/composer/qgscomposerattributetablev2.cpp b/src/core/composer/qgscomposerattributetablev2.cpp
index 2b58610..e88677b 100644
--- a/src/core/composer/qgscomposerattributetablev2.cpp
+++ b/src/core/composer/qgscomposerattributetablev2.cpp
@@ -503,7 +503,7 @@ bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &co
{
// Lets assume it's an expression
QgsExpression* expression = new QgsExpression(( *columnIt )->attribute() );
- context->lastScope()->setVariable( QString( "row_number" ), counter + 1 );
+ context->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), counter + 1, true ) );
expression->prepare( context.data() );
QVariant value = expression->evaluate( context.data() );
currentRow << value;
diff --git a/src/core/composer/qgscomposermapgrid.cpp b/src/core/composer/qgscomposermapgrid.cpp
index 9f89f73..c1911a8 100644
--- a/src/core/composer/qgscomposermapgrid.cpp
+++ b/src/core/composer/qgscomposermapgrid.cpp
@@ -1502,8 +1502,8 @@ QString QgsComposerMapGrid::gridAnnotationString( double value, QgsComposerMapGr
}
else if ( mGridAnnotationFormat == CustomFormat )
{
- expressionContext.lastScope()->setVariable( "grid_number", value );
- expressionContext.lastScope()->setVariable( "grid_axis", coord == QgsComposerMapGrid::Longitude ? "x" : "y" );
+ expressionContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_number" ), value, true ) );
+ expressionContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_axis" ), coord == QgsComposerMapGrid::Longitude ? "x" : "y", true ) );
if ( !mGridAnnotationExpression.data() )
{
mGridAnnotationExpression.reset( new QgsExpression( mGridAnnotationExpressionString ) );
@@ -2238,8 +2238,8 @@ QgsExpressionContext* QgsComposerMapGrid::createExpressionContext() const
{
QgsExpressionContext* context = QgsComposerObject::createExpressionContext();
context->appendScope( new QgsExpressionContextScope( tr( "Grid" ) ) );
- context->lastScope()->setVariable( "grid_number", 0 );
- context->lastScope()->setVariable( "grid_axis", "x" );
+ context->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_number" ), 0, true ) );
+ context->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_axis" ), "x", true ) );
context->setHighlightedVariables( QStringList() << "grid_number" << "grid_axis" );
return context;
}
diff --git a/src/core/qgsconditionalstyle.cpp b/src/core/qgsconditionalstyle.cpp
index 3cfa6b5..169af65 100644
--- a/src/core/qgsconditionalstyle.cpp
+++ b/src/core/qgsconditionalstyle.cpp
@@ -195,7 +195,7 @@ void QgsConditionalStyle::setSymbol( QgsSymbolV2* value )
bool QgsConditionalStyle::matches( const QVariant& value, QgsExpressionContext& context ) const
{
QgsExpression exp( mRule );
- context.lastScope()->setVariable( "value", value );
+ context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "value" ), value, true ) );
return exp.evaluate( &context ).toBool();
}
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index 2b2c98a..95f9ddf 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -1027,7 +1027,7 @@ static QVariant fcnFeature( const QVariantList&, const QgsExpressionContext* con
if ( !context )
return QVariant();
- return context->variable( QgsExpressionContext::EXPR_FEATURE );
+ return context->feature();
}
static QVariant fcnAttribute( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
@@ -4313,7 +4313,7 @@ QVariant QgsExpression::NodeColumnRef::eval( QgsExpression *parent, const QgsExp
if ( context && context->hasVariable( QgsExpressionContext::EXPR_FEATURE ) )
{
- QgsFeature feature = qvariant_cast<QgsFeature>( context->variable( QgsExpressionContext::EXPR_FEATURE ) );
+ QgsFeature feature = context->feature();
if ( index >= 0 )
return feature.attribute( index );
else
diff --git a/src/core/qgsexpressioncontext.cpp b/src/core/qgsexpressioncontext.cpp
index c5512cc..501fc12 100644
--- a/src/core/qgsexpressioncontext.cpp
+++ b/src/core/qgsexpressioncontext.cpp
@@ -191,12 +191,12 @@ void QgsExpressionContextScope::addFunction( const QString& name, QgsScopedExpre
void QgsExpressionContextScope::setFeature( const QgsFeature &feature )
{
- setVariable( QgsExpressionContext::EXPR_FEATURE, QVariant::fromValue( feature ) );
+ addVariable( StaticVariable( QgsExpressionContext::EXPR_FEATURE, QVariant::fromValue( feature ), true ) );
}
void QgsExpressionContextScope::setFields( const QgsFields &fields )
{
- setVariable( QgsExpressionContext::EXPR_FIELDS, QVariant::fromValue( fields ) );
+ addVariable( StaticVariable( QgsExpressionContext::EXPR_FIELDS, QVariant::fromValue( fields ), true ) );
}
diff --git a/src/core/symbology-ng/qgssymbolv2.cpp b/src/core/symbology-ng/qgssymbolv2.cpp
index aa3a84b..70cd0a1 100644
--- a/src/core/symbology-ng/qgssymbolv2.cpp
+++ b/src/core/symbology-ng/qgssymbolv2.cpp
@@ -738,8 +738,8 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
{
context.expressionContext().appendScope( mSymbolRenderContext->expressionContextScope() );
QgsExpressionContextUtils::updateSymbolScope( this, mSymbolRenderContext->expressionContextScope() );
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometry()->partCount() );
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1 );
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometryPartCount(), true ) );
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1, true ) );
}
switch ( QgsWKBTypes::flatType( segmentizedGeometry->geometry()->wkbType() ) )
@@ -806,7 +806,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
for ( int i = 0; i < mp->numGeometries(); ++i )
{
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 );
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
const QgsPointV2* point = static_cast< const QgsPointV2* >( mp->geometryN( i ) );
_getPoint( pt, context, point );
@@ -836,7 +836,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
for ( unsigned int i = 0; i < num && wkbPtr; ++i )
{
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 );
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
if ( geomCollection )
{
@@ -870,7 +870,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
for ( unsigned int i = 0; i < num && wkbPtr; ++i )
{
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 );
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
if ( geomCollection )
{
diff --git a/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp b/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
index ffc158e..ded4665 100644
--- a/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
+++ b/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
@@ -63,7 +63,7 @@ void QgsFieldConditionalFormatWidget::setExpression()
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( mLayer );
- context.lastScope()->setVariable( "value", 0 );
+ context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "value" ), 0, true ) );
context.setHighlightedVariables( QStringList() << "value" );
QgsExpressionBuilderDialog dlg( mLayer, mRuleEdit->text(), this, "generic", context );
diff --git a/src/gui/symbology-ng/qgssymbollayerv2widget.cpp b/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
index ed76136..dab2ceb 100644
--- a/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
+++ b/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
@@ -80,7 +80,7 @@ static QgsExpressionContext _getExpressionContext( const void* context )
{
//cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
//color, but that's not accessible here). 99% of the time these will be the same anyway
- symbolScope->setVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbolLayer->color() );
+ symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbolLayer->color(), true ) );
}
expContext << symbolScope;
expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, 1, true ) );
--
2.8.1
From 9a6cefcd4b50ec0112c82434031555519063b46f Mon Sep 17 00:00:00 2001
From: Martin Dobias <wonder.sk@gmail.com>
Date: Mon, 3 Oct 2016 12:04:03 +0800
Subject: [PATCH] Fix listing of WMTS layers in browser (fixes #15350)
(cherry picked from commit 29d2bef7954d4e2b2cf21611c1398d0a7666e4c6)
---
src/providers/wms/qgswmsdataitems.cpp | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/src/providers/wms/qgswmsdataitems.cpp b/src/providers/wms/qgswmsdataitems.cpp
index d7508a0..16b3f9d 100644
--- a/src/providers/wms/qgswmsdataitems.cpp
+++ b/src/providers/wms/qgswmsdataitems.cpp
@@ -115,46 +115,61 @@ QVector<QgsDataItem*> QgsWMSConnectionItem::createChildren()
QgsDataItem *layerItem = l.styles.size() == 1 ? this : new QgsDataCollectionItem( this, title, mPath + '/' + l.identifier );
if ( layerItem != this )
{
+ layerItem->setCapabilities( layerItem->capabilities2() & ~QgsDataItem::Fertile );
+ layerItem->setState( QgsDataItem::Populated );
layerItem->setToolTip( title );
- addChildItem( layerItem );
+ children << layerItem;
}
Q_FOREACH ( const QgsWmtsStyle &style, l.styles )
{
QString styleName = style.title.isEmpty() ? style.identifier : style.title;
if ( layerItem == this )
- styleName.prepend( title + " - " );
+ styleName = title; // just one style so no need to display it
QgsDataItem *styleItem = l.setLinks.size() == 1 ? layerItem : new QgsDataCollectionItem( layerItem, styleName, layerItem->path() + '/' + style.identifier );
if ( styleItem != layerItem )
{
+ styleItem->setCapabilities( styleItem->capabilities2() & ~QgsDataItem::Fertile );
+ styleItem->setState( QgsDataItem::Populated );
styleItem->setToolTip( styleName );
- layerItem->addChildItem( styleItem );
+ if ( layerItem == this )
+ children << styleItem;
+ else
+ layerItem->addChildItem( styleItem );
}
Q_FOREACH ( const QgsWmtsTileMatrixSetLink &setLink, l.setLinks )
{
QString linkName = setLink.tileMatrixSet;
if ( styleItem == layerItem )
- linkName.prepend( styleName + " - " );
+ linkName = styleName; // just one link so no need to display it
QgsDataItem *linkItem = l.formats.size() == 1 ? styleItem : new QgsDataCollectionItem( styleItem, linkName, styleItem->path() + '/' + setLink.tileMatrixSet );
if ( linkItem != styleItem )
{
+ linkItem->setCapabilities( linkItem->capabilities2() & ~QgsDataItem::Fertile );
+ linkItem->setState( QgsDataItem::Populated );
linkItem->setToolTip( linkName );
- styleItem->addChildItem( linkItem );
+ if ( styleItem == this )
+ children << linkItem;
+ else
+ styleItem->addChildItem( linkItem );
}
Q_FOREACH ( const QString& format, l.formats )
{
QString name = format;
if ( linkItem == styleItem )
- name.prepend( linkName + " - " );
+ name = linkName; // just one format so no need to display it
- QgsDataItem *layerItem = new QgsWMTSLayerItem( linkItem, name, linkItem->path() + '/' + name, uri,
+ QgsDataItem *tileLayerItem = new QgsWMTSLayerItem( linkItem, name, linkItem->path() + '/' + name, uri,
l.identifier, format, style.identifier, setLink.tileMatrixSet, tileMatrixSets[ setLink.tileMatrixSet ].crs, title );
- layerItem->setToolTip( name );
- linkItem->addChildItem( layerItem );
+ tileLayerItem->setToolTip( name );
+ if ( linkItem == this )
+ children << tileLayerItem;
+ else
+ linkItem->addChildItem( tileLayerItem );
}
}
}
--
2.8.1
From 80e820f41f15a7020c7c0c843149443bf92660b2 Mon Sep 17 00:00:00 2001
From: Nyall Dawson <nyall.dawson@gmail.com>
Date: Fri, 28 Oct 2016 16:56:46 +1000
Subject: [PATCH] Fix build
---
src/core/qgsexpression.cpp | 2 +-
src/core/symbology-ng/qgssymbolv2.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index 95f9ddf..8a09c1a 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -1027,7 +1027,7 @@ static QVariant fcnFeature( const QVariantList&, const QgsExpressionContext* con
if ( !context )
return QVariant();
- return context->feature();
+ return context->variable( QgsExpressionContext::EXPR_FEATURE );
}
static QVariant fcnAttribute( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
diff --git a/src/core/symbology-ng/qgssymbolv2.cpp b/src/core/symbology-ng/qgssymbolv2.cpp
index 70cd0a1..45a1f83 100644
--- a/src/core/symbology-ng/qgssymbolv2.cpp
+++ b/src/core/symbology-ng/qgssymbolv2.cpp
@@ -738,7 +738,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
{
context.expressionContext().appendScope( mSymbolRenderContext->expressionContextScope() );
QgsExpressionContextUtils::updateSymbolScope( this, mSymbolRenderContext->expressionContextScope() );
- mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometryPartCount(), true ) );
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometry()->partCount(), true ) );
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1, true ) );
}
--
2.8.1
From f3652069cf3b57608299e24d0e2097c28e2391e6 Mon Sep 17 00:00:00 2001
From: Martin Dobias <wonder.sk@gmail.com>
Date: Mon, 3 Oct 2016 15:29:10 +0800
Subject: [PATCH] Fix WMS identify when using "Feature" format and the layer
has named CRS
(cherry picked from commit 9ef91ea6294cdab762ffb2543d02473bcccbed80)
---
src/providers/wms/qgswmsprovider.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/providers/wms/qgswmsprovider.cpp b/src/providers/wms/qgswmsprovider.cpp
index 9a72362..48718bc 100644
--- a/src/providers/wms/qgswmsprovider.cpp
+++ b/src/providers/wms/qgswmsprovider.cpp
@@ -2677,7 +2677,7 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
QString crsType = result.property( "crs" ).property( "type" ).toString();
QString crsText;
if ( crsType == "name" )
- crsText = result.property( "crs" ).property( "name" ).toString();
+ crsText = result.property( "crs" ).property( "properties" ).property( "name" ).toString();
else if ( crsType == "EPSG" )
crsText = QString( "%1:%2" ).arg( crsType, result.property( "crs" ).property( "properties" ).property( "code" ).toString() );
else
@@ -2773,6 +2773,7 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
catch ( const QString &err )
{
QgsDebugMsg( QString( "JSON error: %1\nResult: %2" ).arg( err, QString::fromUtf8( mIdentifyResultBodies.value( jsonPart ) ) ) );
+ results.insert( results.size(), err ); // string returned for format type "feature" means error
}
delete coordinateTransform;
--
2.8.1
From 66a213bc5aa9fa22affc512c31b80594ce6d3ffa Mon Sep 17 00:00:00 2001
From: Martin Dobias <wonder.sk@gmail.com>
Date: Wed, 5 Oct 2016 09:08:21 +0800
Subject: [PATCH] Fix crash when loading WCS layers (fixes #15595)
The problem is that some providers would still issue network
requests in prepareJobs() - this should be ideally avoided,
because it is run in main thread - all the work should be deferred
to be done in worker thread.
(cherry picked from commit 08f4a0f40cce21d5730653a75bdd44f175f3b0b8)
---
src/gui/qgsmapcanvas.cpp | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp
index 856d16b..7308b05 100644
--- a/src/gui/qgsmapcanvas.cpp
+++ b/src/gui/qgsmapcanvas.cpp
@@ -663,9 +663,6 @@ void QgsMapCanvas::refreshMap()
stopRendering(); // if any...
- // from now on we can accept refresh requests again
- mRefreshScheduled = false;
-
//build the expression context
QgsExpressionContext expressionContext;
expressionContext << QgsExpressionContextUtils::globalScope()
@@ -698,6 +695,14 @@ void QgsMapCanvas::refreshMap()
mJob->start();
+ // from now on we can accept refresh requests again
+ // this must be reset only after the job has been started, because
+ // some providers (yes, it's you WCS and AMS!) during preparation
+ // do network requests and start an internal event loop, which may
+ // end up calling refresh() and would schedule another refresh,
+ // deleting the one we have just started.
+ mRefreshScheduled = false;
+
mMapUpdateTimer.start();
emit renderStarting();
--
2.8.1
From 9f228d4b7c260bf7fd9aec8f6489b51fc1b58b8a Mon Sep 17 00:00:00 2001
From: Hugo Mercier <hugo.mercier@oslandia.com>
Date: Fri, 28 Oct 2016 11:17:46 +0200
Subject: [PATCH] Don't delete QgsAttributeDialog too early. Fixes #15737
(cherry picked from commit 9ecdf6101433)
---
src/app/qgsfeatureaction.cpp | 32 ++++++++++++++++++++------------
src/gui/qgsattributedialog.cpp | 5 +----
src/gui/qgsattributedialog.h | 5 ++---
3 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/src/app/qgsfeatureaction.cpp b/src/app/qgsfeatureaction.cpp
index 106cfcf..a78df31 100644
--- a/src/app/qgsfeatureaction.cpp
+++ b/src/app/qgsfeatureaction.cpp
@@ -98,7 +98,9 @@ bool QgsFeatureAction::viewFeatureForm( QgsHighlight *h )
QgsAttributeDialog *dialog = newDialog( true );
dialog->setHighlight( h );
- dialog->show(); // will also delete the dialog on close (show() is overridden)
+ // delete the dialog when it is closed
+ dialog->setAttribute( Qt::WA_DeleteOnClose );
+ dialog->show();
return true;
}
@@ -108,24 +110,29 @@ bool QgsFeatureAction::editFeature( bool showModal )
if ( !mLayer )
return false;
- QgsAttributeDialog *dialog = newDialog( false );
-
- if ( !mFeature->isValid() )
- dialog->setIsAddDialog( true );
-
if ( showModal )
{
- dialog->setAttribute( Qt::WA_DeleteOnClose );
- int rv = dialog->exec();
+ QScopedPointer<QgsAttributeDialog> dialog( newDialog( false ) );
+
+ if ( !mFeature->isValid() )
+ dialog->setIsAddDialog( true );
+ int rv = dialog->exec();
mFeature->setAttributes( dialog->feature()->attributes() );
return rv;
}
else
{
- dialog->show(); // will also delete the dialog on close (show() is overridden)
- }
+ QgsAttributeDialog* dialog = newDialog( false );
+
+ if ( !mFeature->isValid() )
+ dialog->setIsAddDialog( true );
+ // delete the dialog when it is closed
+ dialog->setAttribute( Qt::WA_DeleteOnClose );
+ dialog->show();
+ }
+
return true;
}
@@ -193,6 +200,8 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes, boo
else
{
QgsAttributeDialog *dialog = newDialog( false );
+ // delete the dialog when it is closed
+ dialog->setAttribute( Qt::WA_DeleteOnClose );
dialog->setIsAddDialog( true );
dialog->setEditCommandMessage( text() );
@@ -201,12 +210,11 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes, boo
if ( !showModal )
{
setParent( dialog ); // keep dialog until the dialog is closed and destructed
- dialog->show(); // will also delete the dialog on close (show() is overridden)
+ dialog->show();
mFeature = nullptr;
return true;
}
- dialog->setAttribute( Qt::WA_DeleteOnClose );
dialog->exec();
}
diff --git a/src/gui/qgsattributedialog.cpp b/src/gui/qgsattributedialog.cpp
index ee1b9cf..ee71f2e 100644
--- a/src/gui/qgsattributedialog.cpp
+++ b/src/gui/qgsattributedialog.cpp
@@ -87,11 +87,8 @@ void QgsAttributeDialog::accept()
QDialog::accept();
}
-void QgsAttributeDialog::show( bool autoDelete )
+void QgsAttributeDialog::show()
{
- if ( autoDelete )
- setAttribute( Qt::WA_DeleteOnClose );
-
QDialog::show();
raise();
activateWindow();
diff --git a/src/gui/qgsattributedialog.h b/src/gui/qgsattributedialog.h
index e7dd32b..4263f32 100644
--- a/src/gui/qgsattributedialog.h
+++ b/src/gui/qgsattributedialog.h
@@ -130,9 +130,8 @@ class GUI_EXPORT QgsAttributeDialog : public QDialog
public slots:
void accept() override;
- //! Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form and is deleted when
- //! closed.
- void show( bool autoDelete = true );
+ //! Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form
+ void show();
private:
void init( QgsVectorLayer* layer, QgsFeature* feature, const QgsAttributeEditorContext& context );
--
2.8.1
From afd04eb0b860cd1266368741f7eea97f92433f22 Mon Sep 17 00:00:00 2001
From: Martin Dobias <wonder.sk@gmail.com>
Date: Fri, 7 Oct 2016 17:34:54 +0800
Subject: [PATCH] Fix crash in node tool after deleting the whole geometry
(fixes #15659)
Made sure that both closestVertex() and closestSegment() return negative
distance on error (e.g. with null or emtpy geometry).
Also fixes snapping when dealing with layers with null/invalid geometries
(cherry picked from commit c093d5188fad685c4a596ff23c27aad7d151dac2)
---
src/app/nodetool/qgsmaptoolnodetool.cpp | 7 +++--
src/core/geometry/qgscircularstringv2.cpp | 3 +++
src/core/geometry/qgscurvepolygonv2.cpp | 2 +-
src/core/geometry/qgsgeometry.cpp | 9 +++++--
src/core/geometry/qgsgeometryutils.cpp | 1 +
src/core/geometry/qgsgeometryutils.h | 8 ++++--
src/core/geometry/qgslinestringv2.cpp | 10 ++-----
src/core/qgspointlocator.cpp | 2 ++
tests/src/core/testqgsgeometry.cpp | 5 ++--
tests/src/core/testqgspointlocator.cpp | 43 +++++++++++++++++++++++++++++++
10 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/src/app/nodetool/qgsmaptoolnodetool.cpp b/src/app/nodetool/qgsmaptoolnodetool.cpp
index ccb0786..0ca5092 100644
--- a/src/app/nodetool/qgsmaptoolnodetool.cpp
+++ b/src/app/nodetool/qgsmaptoolnodetool.cpp
@@ -272,12 +272,11 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e )
// get geometry and find if snapping is near it
int atVertex, beforeVertex, afterVertex;
- double dist;
- QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( layerCoordPoint, atVertex, beforeVertex, afterVertex, dist );
- dist = sqrt( dist );
+ double sqrDist; // will be negative on error
+ QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( layerCoordPoint, atVertex, beforeVertex, afterVertex, sqrDist );
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertex, tol );
- if ( dist <= tol )
+ if ( sqrDist >= 0 && sqrt( sqrDist ) <= tol )
{
// some vertex selected
mMoving = true;
diff --git a/src/core/geometry/qgscircularstringv2.cpp b/src/core/geometry/qgscircularstringv2.cpp
index 7245894..c88c4f7 100644
--- a/src/core/geometry/qgscircularstringv2.cpp
+++ b/src/core/geometry/qgscircularstringv2.cpp
@@ -825,6 +825,9 @@ double QgsCircularStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& se
}
}
+ if ( minDist == std::numeric_limits<double>::max() )
+ return -1; // error: no segments
+
segmentPt = minDistSegmentPoint;
vertexAfter = minDistVertexAfter;
vertexAfter.part = 0;
diff --git a/src/core/geometry/qgscurvepolygonv2.cpp b/src/core/geometry/qgscurvepolygonv2.cpp
index b4abde2..33c037f 100644
--- a/src/core/geometry/qgscurvepolygonv2.cpp
+++ b/src/core/geometry/qgscurvepolygonv2.cpp
@@ -632,7 +632,7 @@ double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segm
{
if ( !mExteriorRing )
{
- return 0.0;
+ return -1;
}
QList<QgsCurveV2*> segmentList;
segmentList.append( mExteriorRing );
diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp
index 8cf207b..682b066 100644
--- a/src/core/geometry/qgsgeometry.cpp
+++ b/src/core/geometry/qgsgeometry.cpp
@@ -347,6 +347,7 @@ QgsPoint QgsGeometry::closestVertex( const QgsPoint& point, int& atVertex, int&
{
if ( !d->geometry )
{
+ sqrDist = -1;
return QgsPoint( 0, 0 );
}
@@ -531,12 +532,14 @@ double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVert
{
if ( !d->geometry )
{
- return 0.0;
+ return -1;
}
QgsVertexId vId;
QgsPointV2 pt( point.x(), point.y() );
QgsPointV2 closestPoint = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, vId );
+ if ( !vId.isValid() )
+ return -1;
atVertex = vertexNrFromVertexId( vId );
return QgsGeometryUtils::sqrDistance2D( closestPoint, pt );
}
@@ -550,7 +553,7 @@ double QgsGeometry::closestSegmentWithContext(
{
if ( !d->geometry )
{
- return 0;
+ return -1;
}
QgsPointV2 segmentPt;
@@ -558,6 +561,8 @@ double QgsGeometry::closestSegmentWithContext(
bool leftOfBool;
double sqrDist = d->geometry->closestSegment( QgsPointV2( point.x(), point.y() ), segmentPt, vertexAfter, &leftOfBool, epsilon );
+ if ( sqrDist < 0 )
+ return -1;
minDistPoint.setX( segmentPt.x() );
minDistPoint.setY( segmentPt.y() );
diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp
index 19e60d1..f913c0a 100644
--- a/src/core/geometry/qgsgeometryutils.cpp
+++ b/src/core/geometry/qgsgeometryutils.cpp
@@ -65,6 +65,7 @@ QgsPointV2 QgsGeometryUtils::closestVertex( const QgsAbstractGeometryV2& geom, c
double minDist = std::numeric_limits<double>::max();
double currentDist = 0;
QgsPointV2 minDistPoint;
+ id = QgsVertexId(); // set as invalid
QgsVertexId vertexId;
QgsPointV2 vertex;
diff --git a/src/core/geometry/qgsgeometryutils.h b/src/core/geometry/qgsgeometryutils.h
index 667fae1..7d7bd8d 100644
--- a/src/core/geometry/qgsgeometryutils.h
+++ b/src/core/geometry/qgsgeometryutils.h
@@ -37,7 +37,8 @@ class CORE_EXPORT QgsGeometryUtils
*/
static QList<QgsLineStringV2*> extractLineStrings( const QgsAbstractGeometryV2* geom );
- /** Returns the closest vertex to a geometry for a specified point
+ /** Returns the closest vertex to a geometry for a specified point.
+ * On error null point will be returned and "id" argument will be invalid.
*/
static QgsPointV2 closestVertex( const QgsAbstractGeometryV2& geom, const QgsPointV2& pt, QgsVertexId& id );
@@ -227,7 +228,7 @@ class CORE_EXPORT QgsGeometryUtils
for ( int i = 0; i < container.size(); ++i )
{
sqrDist = container.at( i )->closestSegment( pt, segmentPt, vertexAfter, leftOf, epsilon );
- if ( sqrDist < minDist )
+ if ( sqrDist >= 0 && sqrDist < minDist )
{
minDist = sqrDist;
minDistSegmentX = segmentPt.x();
@@ -257,6 +258,9 @@ class CORE_EXPORT QgsGeometryUtils
}
}
+ if ( minDist == std::numeric_limits<double>::max() )
+ return -1; // error: no segments
+
segmentPt.setX( minDistSegmentX );
segmentPt.setY( minDistSegmentY );
vertexAfter = minDistVertexAfter;
diff --git a/src/core/geometry/qgslinestringv2.cpp b/src/core/geometry/qgslinestringv2.cpp
index 13534a8..d39b61f 100644
--- a/src/core/geometry/qgslinestringv2.cpp
+++ b/src/core/geometry/qgslinestringv2.cpp
@@ -744,16 +744,10 @@ double QgsLineStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmen
double segmentPtX, segmentPtY;
int size = mX.size();
- if ( size == 0 )
+ if ( size == 0 || size == 1 )
{
vertexAfter = QgsVertexId( 0, 0, 0 );
- return sqrDist;
- }
- else if ( size == 1 )
- {
- segmentPt = pointN( 0 );
- vertexAfter = QgsVertexId( 0, 0, 1 );
- return QgsGeometryUtils::sqrDistance2D( pt, segmentPt );
+ return -1;
}
for ( int i = 1; i < size; ++i )
{
diff --git a/src/core/qgspointlocator.cpp b/src/core/qgspointlocator.cpp
index 66b2647..ecad55e 100644
--- a/src/core/qgspointlocator.cpp
+++ b/src/core/qgspointlocator.cpp
@@ -100,6 +100,8 @@ class QgsPointLocator_VisitorNearestVertex : public IVisitor
int vertexIndex, beforeVertex, afterVertex;
double sqrDist;
QgsPoint pt = geom->closestVertex( mSrcPoint, vertexIndex, beforeVertex, afterVertex, sqrDist );
+ if ( sqrDist < 0 )
+ return; // probably empty geometry
QgsPointLocator::Match m( QgsPointLocator::Vertex, mLocator->mLayer, id, sqrt( sqrDist ), pt, vertexIndex );
// in range queries the filter may reject some matches
diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp
index 785c4ab..905c0a2 100644
--- a/tests/src/core/testqgsgeometry.cpp
+++ b/tests/src/core/testqgsgeometry.cpp
@@ -2010,11 +2010,10 @@ void TestQgsGeometry::lineStringV2()
//closest segment
QgsLineStringV2 l35;
bool leftOf = false;
+ p = QgsPointV2(); // reset all coords to zero
( void )l35.closestSegment( QgsPointV2( 1, 2 ), p, v, 0, 0 ); //empty line, just want no crash
l35.setPoints( QgsPointSequenceV2() << QgsPointV2( 5, 10 ) );
- QVERIFY( qgsDoubleNear( l35.closestSegment( QgsPointV2( 5, 10 ), p, v, 0, 0 ), 0 ) );
- QCOMPARE( p, QgsPointV2( 5, 10 ) );
- QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
+ QVERIFY( l35.closestSegment( QgsPointV2( 5, 10 ), p, v, 0, 0 ) < 0 );
l35.setPoints( QgsPointSequenceV2() << QgsPointV2( 5, 10 ) << QgsPointV2( 10, 10 ) );
QVERIFY( qgsDoubleNear( l35.closestSegment( QgsPointV2( 4, 11 ), p, v, &leftOf, 0 ), 2.0 ) );
QCOMPARE( p, QgsPointV2( 5, 10 ) );
diff --git a/tests/src/core/testqgspointlocator.cpp b/tests/src/core/testqgspointlocator.cpp
index cb7e805..090c705 100644
--- a/tests/src/core/testqgspointlocator.cpp
+++ b/tests/src/core/testqgspointlocator.cpp
@@ -23,6 +23,7 @@
#include "qgsgeometry.h"
#include "qgsmaplayerregistry.h"
#include "qgspointlocator.h"
+#include "qgspolygonv2.h"
struct FilterExcludePoint : public QgsPointLocator::MatchFilter
@@ -256,6 +257,48 @@ class TestQgsPointLocator : public QObject
QVERIFY( m2.isValid() );
QCOMPARE( m2.point(), QgsPoint( 1, 1 ) );
}
+
+ void testNullGeometries()
+ {
+ QgsVectorLayer* vlNullGeom = new QgsVectorLayer( "Polygon", "x", "memory" );
+ QgsFeature ff( 0 );
+ ff.setGeometry( QgsGeometry() );
+ QgsFeatureList flist;
+ flist << ff;
+ vlNullGeom->dataProvider()->addFeatures( flist );
+
+ QgsPointLocator loc( vlNullGeom, 0, nullptr );
+
+ QgsPointLocator::Match m1 = loc.nearestVertex( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() );
+ QVERIFY( !m1.isValid() );
+
+ QgsPointLocator::Match m2 = loc.nearestEdge( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() );
+ QVERIFY( !m2.isValid() );
+
+ delete vlNullGeom;
+ }
+
+ void testEmptyGeometries()
+ {
+ QgsVectorLayer* vlEmptyGeom = new QgsVectorLayer( "Polygon", "x", "memory" );
+ QgsFeature ff( 0 );
+ QgsGeometry g;
+ g.setGeometry( new QgsPolygonV2() );
+ ff.setGeometry( g );
+ QgsFeatureList flist;
+ flist << ff;
+ vlEmptyGeom->dataProvider()->addFeatures( flist );
+
+ QgsPointLocator loc( vlEmptyGeom, 0, nullptr );
+
+ QgsPointLocator::Match m1 = loc.nearestVertex( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() );
+ QVERIFY( !m1.isValid() );
+
+ QgsPointLocator::Match m2 = loc.nearestEdge( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() );
+ QVERIFY( !m2.isValid() );
+
+ delete vlEmptyGeom;
+ }
};
QTEST_MAIN( TestQgsPointLocator )
--
2.8.1
From d6860f30ad90bb0a8008a01db3de48b081df94cd Mon Sep 17 00:00:00 2001
From: Martin Dobias <wonder.sk@gmail.com>
Date: Fri, 14 Oct 2016 11:17:36 +0800
Subject: [PATCH] Fix layer tree expanded state when used expand/collapse all
(fixes #15691)
(cherry picked from commit de85fdd6e8fa3d4f38196376aabccce317cbf341)
---
python/gui/layertree/qgslayertreeview.sip | 8 ++++++
src/app/qgisapp.cpp | 4 +--
src/gui/layertree/qgslayertreeview.cpp | 46 +++++++++++++++++++++++++++++++
src/gui/layertree/qgslayertreeview.h | 8 ++++++
4 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/python/gui/layertree/qgslayertreeview.sip b/python/gui/layertree/qgslayertreeview.sip
index af1f539..636a276 100644
--- a/python/gui/layertree/qgslayertreeview.sip
+++ b/python/gui/layertree/qgslayertreeview.sip
@@ -72,6 +72,14 @@ class QgsLayerTreeView : QTreeView
//! Force refresh of layer symbology. Normally not needed as the changes of layer's renderer are monitored by the model
void refreshLayerSymbology( const QString& layerId );
+ //! Enhancement of QTreeView::expandAll() that also records expanded state in layer tree nodes
+ //! @note added in QGIS 2.18
+ void expandAllNodes();
+
+ //! Enhancement of QTreeView::collapseAll() that also records expanded state in layer tree nodes
+ //! @note added in QGIS 2.18
+ void collapseAllNodes();
+
signals:
//! Emitted when a current layer is changed
void currentLayerChanged( QgsMapLayer* layer );
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index 581b4d1..e4e6496 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -2757,11 +2757,11 @@ void QgisApp::initLayerTreeView()
QAction* actionExpandAll = new QAction( tr( "Expand All" ), this );
actionExpandAll->setIcon( QgsApplication::getThemeIcon( "/mActionExpandTree.svg" ) );
actionExpandAll->setToolTip( tr( "Expand All" ) );
- connect( actionExpandAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( expandAll() ) );
+ connect( actionExpandAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( expandAllNodes() ) );
QAction* actionCollapseAll = new QAction( tr( "Collapse All" ), this );
actionCollapseAll->setIcon( QgsApplication::getThemeIcon( "/mActionCollapseTree.svg" ) );
actionCollapseAll->setToolTip( tr( "Collapse All" ) );
- connect( actionCollapseAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( collapseAll() ) );
+ connect( actionCollapseAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( collapseAllNodes() ) );
QToolBar* toolbar = new QToolBar();
toolbar->setIconSize( QSize( 16, 16 ) );
diff --git a/src/gui/layertree/qgslayertreeview.cpp b/src/gui/layertree/qgslayertreeview.cpp
index 7530c26..74b298b 100644
--- a/src/gui/layertree/qgslayertreeview.cpp
+++ b/src/gui/layertree/qgslayertreeview.cpp
@@ -313,3 +313,49 @@ void QgsLayerTreeView::refreshLayerSymbology( const QString& layerId )
if ( nodeLayer )
layerTreeModel()->refreshLayerLegend( nodeLayer );
}
+
+
+static void _expandAllLegendNodes( QgsLayerTreeLayer* nodeLayer, bool expanded, QgsLayerTreeModel* model )
+{
+ // for layers we also need to find out with legend nodes contain some children and make them expanded/collapsed
+ // if we are collapsing, we just write out an empty list
+ QStringList lst;
+ if ( expanded )
+ {
+ Q_FOREACH ( QgsLayerTreeModelLegendNode* legendNode, model->layerLegendNodes( nodeLayer ) )
+ {
+ QString parentKey = legendNode->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString();
+ if ( !parentKey.isEmpty() && !lst.contains( parentKey ) )
+ lst << parentKey;
+ }
+ }
+ nodeLayer->setCustomProperty( "expandedLegendNodes", lst );
+}
+
+
+static void _expandAllNodes( QgsLayerTreeGroup* parent, bool expanded, QgsLayerTreeModel* model )
+{
+ Q_FOREACH ( QgsLayerTreeNode* node, parent->children() )
+ {
+ node->setExpanded( expanded );
+ if ( QgsLayerTree::isGroup( node ) )
+ _expandAllNodes( QgsLayerTree::toGroup( node ), expanded, model );
+ else if ( QgsLayerTree::isLayer( node ) )
+ _expandAllLegendNodes( QgsLayerTree::toLayer( node ), expanded, model );
+ }
+}
+
+
+void QgsLayerTreeView::expandAllNodes()
+{
+ // unfortunately expandAll() does not emit expanded() signals
+ _expandAllNodes( layerTreeModel()->rootGroup(), true, layerTreeModel() );
+ expandAll();
+}
+
+void QgsLayerTreeView::collapseAllNodes()
+{
+ // unfortunately collapseAll() does not emit collapsed() signals
+ _expandAllNodes( layerTreeModel()->rootGroup(), false, layerTreeModel() );
+ collapseAll();
+}
diff --git a/src/gui/layertree/qgslayertreeview.h b/src/gui/layertree/qgslayertreeview.h
index bf3fe5f..2a3878c 100644
--- a/src/gui/layertree/qgslayertreeview.h
+++ b/src/gui/layertree/qgslayertreeview.h
@@ -91,6 +91,14 @@ class GUI_EXPORT QgsLayerTreeView : public QTreeView
//! Force refresh of layer symbology. Normally not needed as the changes of layer's renderer are monitored by the model
void refreshLayerSymbology( const QString& layerId );
+ //! Enhancement of QTreeView::expandAll() that also records expanded state in layer tree nodes
+ //! @note added in QGIS 2.18
+ void expandAllNodes();
+
+ //! Enhancement of QTreeView::collapseAll() that also records expanded state in layer tree nodes
+ //! @note added in QGIS 2.18
+ void collapseAllNodes();
+
signals:
//! Emitted when a current layer is changed
void currentLayerChanged( QgsMapLayer* layer );
--
2.8.1
From 8cf03ced0c94835fb96302b6ca49d5a98117bc44 Mon Sep 17 00:00:00 2001
From: Even Rouault <even.rouault@spatialys.com>
Date: Mon, 31 Oct 2016 17:10:58 +0100
Subject: [PATCH] [OGR provider] Make addAttributes() return the requested
field type, precision and width so as to make
QgsVectorLayerEditBuffer::commitChanges() API
Fixes #15614
---
src/providers/ogr/qgsogrprovider.cpp | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp
index 850a5ab..4335927 100644
--- a/src/providers/ogr/qgsogrprovider.cpp
+++ b/src/providers/ogr/qgsogrprovider.cpp
@@ -1153,8 +1153,12 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
bool returnvalue = true;
+ QMap< QString, QgsField > mapFieldNameToOriginalField;
+
for ( QList<QgsField>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter )
{
+ mapFieldNameToOriginalField[ iter->name()] = *iter;
+
OGRFieldType type;
switch ( iter->type() )
@@ -1164,8 +1168,16 @@ 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
+ {
+ type = OFTReal;
+ }
break;
+ }
#endif
case QVariant::Double:
type = OFTReal;
@@ -1203,6 +1215,26 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
OGR_Fld_Destroy( fielddefn );
}
loadFields();
+
+ // The check in QgsVectorLayerEditBuffer::commitChanges() is questionable with
+ // real-world drivers that might only be able to satisfy request only partially.
+ // So to avoid erroring out, patch field type, width and precision to match
+ // what was requested.
+ // For example in case of Integer64->Real mapping so that QVariant::LongLong is
+ // still returned to the caller
+ // Or if a field width was specified but not strictly enforced by the driver (#15614)
+ for ( QMap< QString, QgsField >::const_iterator it = mapFieldNameToOriginalField.begin();
+ it != mapFieldNameToOriginalField.end(); ++it )
+ {
+ int idx = mAttributeFields.fieldNameIndex( it.key() );
+ if ( idx >= 0 )
+ {
+ mAttributeFields[ idx ].setType( it->type() );
+ mAttributeFields[ idx ].setLength( it->length() );
+ mAttributeFields[ idx ].setPrecision( it->precision() );
+ }
+ }
+
return returnvalue;
}
--
2.8.1
From 819f571b478f971236f6d04c349108cc6f0a2c3c Mon Sep 17 00:00:00 2001
From: Even Rouault <even.rouault@spatialys.com>
Date: Mon, 31 Oct 2016 18:16:29 +0100
Subject: [PATCH] Fix test_provider_ogr_gpkg.py
---
tests/src/python/test_provider_ogr_gpkg.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py
index d2e0f0c..7af9188 100644
--- a/tests/src/python/test_provider_ogr_gpkg.py
+++ b/tests/src/python/test_provider_ogr_gpkg.py
@@ -160,9 +160,10 @@ class TestPyQgsOGRProviderGpkg(unittest.TestCase):
return
self.internalTestBug15351('commit_closeIter_closeProvider')
- @unittest.expectedFailure(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 1, 2))
def testGeopackageExtentUpdate(self):
''' test http://hub.qgis.org/issues/15273 '''
+ if int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 1, 2):
+ return
tmpfile = os.path.join(self.basetestpath, 'testGeopackageExtentUpdate.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint)
--
2.8.1
From 053c531177c924dc2b9e71ef792985932818abdc Mon Sep 17 00:00:00 2001
From: "Juergen E. Fischer" <jef@norbit.de>
Date: Tue, 1 Nov 2016 13:46:29 +0100
Subject: [PATCH] fix typos
(cherry picked from commit 7a326b1b8d7026bc2782afc0fdc5abbaa1065370)
---
python/gui/qgsextentgroupbox.sip | 2 +-
python/plugins/processing/algs/help/qgis.yaml | 4 ++--
src/gui/qgsextentgroupbox.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/python/gui/qgsextentgroupbox.sip b/python/gui/qgsextentgroupbox.sip
index 1a5c658..c2b72d0 100644
--- a/python/gui/qgsextentgroupbox.sip
+++ b/python/gui/qgsextentgroupbox.sip
@@ -58,7 +58,7 @@ class QgsExtentGroupBox : QgsCollapsibleGroupBox
//! set output extent to be the same as current extent (may be transformed to output CRS)
void setOutputExtentFromCurrent();
- //! set output extent to custom extent (may be transformed to outut CRS)
+ //! set output extent to custom extent (may be transformed to output CRS)
void setOutputExtentFromUser( const QgsRectangle& extent, const QgsCoordinateReferenceSystem& crs );
signals:
diff --git a/python/plugins/processing/algs/help/qgis.yaml b/python/plugins/processing/algs/help/qgis.yaml
index bcf266f..3061611 100644
--- a/python/plugins/processing/algs/help/qgis.yaml
+++ b/python/plugins/processing/algs/help/qgis.yaml
@@ -394,9 +394,9 @@ qgis:splitlineswithlines: >
This algorithm split the lines in a line layer using the lines in another line layer to define the breaking points. Intersection between geometries in both layers are considered as split points.
qgis:splitvectorlayer: >
- This algorithm takes a vector layer and an attribute and generates a set of vector layers in an outut folder. Each of the layers created in that folder contains all features from the input layer with the same value for the specified attribute.
+ This algorithm takes a vector layer and an attribute and generates a set of vector layers in an output folder. Each of the layers created in that folder contains all features from the input layer with the same value for the specified attribute.
- The number of files generated is equal to the nuber of different values found for the specified attribute.
+ The number of files generated is equal to the nubmer of different values found for the specified attribute.
qgis:statisticsbycategories:
diff --git a/src/gui/qgsextentgroupbox.h b/src/gui/qgsextentgroupbox.h
index b8ca133..19c545e 100644
--- a/src/gui/qgsextentgroupbox.h
+++ b/src/gui/qgsextentgroupbox.h
@@ -70,7 +70,7 @@ class GUI_EXPORT QgsExtentGroupBox : public QgsCollapsibleGroupBox, private Ui::
//! set output extent to be the same as current extent (may be transformed to output CRS)
void setOutputExtentFromCurrent();
- //! set output extent to custom extent (may be transformed to outut CRS)
+ //! set output extent to custom extent (may be transformed to output CRS)
void setOutputExtentFromUser( const QgsRectangle& extent, const QgsCoordinateReferenceSystem& crs );
signals:
--
2.8.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment