diff --git a/.ci/travis/scripts/ctest2travis.py b/.ci/travis/scripts/ctest2travis.py
index ebd15a3c229e..5db960f8f16b 100755
--- a/.ci/travis/scripts/ctest2travis.py
+++ b/.ci/travis/scripts/ctest2travis.py
@@ -45,8 +45,17 @@ def start_fold(tag):
def end_fold():
- tag = fold_stack.pop()
- sys.stdout.write('travis_fold:end:{}\n'.format(tag))
+ try:
+ tag = fold_stack.pop()
+ sys.stdout.write('travis_fold:end:{}\n'.format(tag))
+ except IndexError:
+ updated_line = colored("======================", 'magenta')
+ updated_line += colored("ctest2travis error when processing the following line:", 'magenta')
+ updated_line += colored("----------------------", 'magenta')
+ updated_line += colored(updated_line, 'magenta')
+ updated_line += colored("----------------------", 'magenta')
+ updated_line += colored("Tried to end fold, but fold was never started.", 'magenta')
+ updated_line += colored("======================", 'magenta')
test_count = 0
diff --git a/python/plugins/processing/tests/testdata/expected/dissolve_field.gml b/python/plugins/processing/tests/testdata/expected/dissolve_field.gml
index 9dcfe77c61e6..b4196927d2cd 100644
--- a/python/plugins/processing/tests/testdata/expected/dissolve_field.gml
+++ b/python/plugins/processing/tests/testdata/expected/dissolve_field.gml
@@ -13,7 +13,7 @@
- 6.241458733205375,-0.054510556621882 7.241458733205375,-1.054510556621882 5.241458733205375,-1.054510556621882 6.241458733205375,-0.054510556621882
+ 6.241458733205375,-0.054510556621882 7.241458733205375,-1.054510556621882 5.241458733205375,-1.054510556621882 6.241458733205375,-0.054510556621882
dd
0
@@ -26,7 +26,7 @@
- 3,2 6,1 6,-3 2,-1 -1,-1 -1,3 3,3 3,2
+ 3,2 6,1 6,-3 2,-1 -1,-1 -1,3 3,3 3,2
aa
1
44.123456
@@ -42,7 +42,7 @@
- 8.162955854126682,2.738771593090211 8.162955854126682,3.738771593090211 9.162955854126682,3.738771593090211 9.162955854126682,2.738771593090211 8.162955854126682,2.738771593090211
+ 8.162955854126682,2.738771593090211 8.162955854126682,3.738771593090211 9.162955854126682,3.738771593090211 9.162955854126682,2.738771593090211 8.162955854126682,2.738771593090211
cc
0.123
diff --git a/python/plugins/processing/tests/testdata/expected/dissolve_two_fields.gml b/python/plugins/processing/tests/testdata/expected/dissolve_two_fields.gml
index 542aaaa1d0b1..5f2c0ef22ad6 100644
--- a/python/plugins/processing/tests/testdata/expected/dissolve_two_fields.gml
+++ b/python/plugins/processing/tests/testdata/expected/dissolve_two_fields.gml
@@ -13,7 +13,7 @@
- 2.620729366602688,5.088675623800385 2.620729366602688,6.088675623800385 3.620729366602688,6.088675623800385 3.620729366602688,5.088675623800385 2.620729366602688,5.088675623800385
+ 2.620729366602688,5.088675623800385 2.620729366602688,6.088675623800385 3.620729366602688,6.088675623800385 3.620729366602688,5.088675623800385 2.620729366602688,5.088675623800385
bb
2
0.123
@@ -21,7 +21,7 @@
- 6.241458733205375,-0.054510556621882 7.241458733205375,-1.054510556621882 5.241458733205375,-1.054510556621882 6.241458733205375,-0.054510556621882
+ 6.241458733205375,-0.054510556621882 7.241458733205375,-1.054510556621882 5.241458733205375,-1.054510556621882 6.241458733205375,-0.054510556621882
dd
0
@@ -42,7 +42,7 @@
- 3,2 6,1 6,-3 2,-1 -1,-1 -1,3 3,3 3,2
+ 3,2 6,1 6,-3 2,-1 -1,-1 -1,3 3,3 3,2
aa
1
44.123456
@@ -50,7 +50,7 @@
- 8.162955854126682,2.738771593090211 8.162955854126682,3.738771593090211 9.162955854126682,3.738771593090211 9.162955854126682,2.738771593090211 8.162955854126682,2.738771593090211
+ 8.162955854126682,2.738771593090211 8.162955854126682,3.738771593090211 9.162955854126682,3.738771593090211 9.162955854126682,2.738771593090211 8.162955854126682,2.738771593090211
cc
0.123
diff --git a/python/plugins/processing/tests/testdata/expected/nullGeometryDissolve_output.gml b/python/plugins/processing/tests/testdata/expected/nullGeometryDissolve_output.gml
index a41bd0da4f2e..123c01707b7e 100644
--- a/python/plugins/processing/tests/testdata/expected/nullGeometryDissolve_output.gml
+++ b/python/plugins/processing/tests/testdata/expected/nullGeometryDissolve_output.gml
@@ -13,7 +13,7 @@
- 1756812.050985608249903,5080657.52322755753994 1758058.328737602569163,5080656.446172921918333 1758032.602247689384967,5078868.455123908817768 1756869.935587913962081,5078877.136755040846765 1755007.051325645996258,5078864.273510087281466 1754831.111262238584459,5080811.882167040370405 1756812.050985608249903,5080657.52322755753994
+ 1756812.050985608249903,5080657.52322755753994 1758058.328737602569163,5080656.446172921918333 1758032.602247689384967,5078868.455123908817768 1756869.935587913962081,5078877.136755040846765 1755007.051325645996258,5078864.273510087281466 1754831.111262238584459,5080811.882167040370405 1756812.050985608249903,5080657.52322755753994
diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
index 00d526ececb3..8b808ff7b0bd 100644
--- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
+++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
@@ -252,32 +252,30 @@ tests:
name: expected/autoincrement_field.gml
type: vector
-# - algorithm: qgis:dissolve
-# name: Dissolve using field
-# params:
-# DISSOLVE_ALL: false
-# FIELD: name
-# INPUT:
-# name: dissolve_polys.gml
-# type: vector
-# results:
-# OUTPUT:
-# name: expected/dissolve_field.gml
-# type: vector
-#
-# - algorithm: qgis:dissolve
-# name: Dissolve using two fields
-# params:
-# DISSOLVE_ALL: false
-# FIELD: intval;name
-# INPUT:
-# name: dissolve_polys.gml
-# type: vector
-# results:
-# OUTPUT:
-# name: expected/dissolve_two_fields.gml
-# type: vector
-#
+ - algorithm: native:dissolve
+ name: Dissolve using field
+ params:
+ FIELD: name
+ INPUT:
+ name: dissolve_polys.gml
+ type: vector
+ results:
+ OUTPUT:
+ name: expected/dissolve_field.gml
+ type: vector
+
+ - algorithm: native:dissolve
+ name: Dissolve using two fields
+ params:
+ FIELD: intval;name
+ INPUT:
+ name: dissolve_polys.gml
+ type: vector
+ results:
+ OUTPUT:
+ name: expected/dissolve_two_fields.gml
+ type: vector
+
# - name: Dissolve with geometries reported as valid but as invalid with isGeosValid
# algorithm: qgis:dissolve
# params:
diff --git a/src/core/processing/qgsnativealgorithms.cpp b/src/core/processing/qgsnativealgorithms.cpp
index 953d2ee2f23e..d6f5f9be3768 100644
--- a/src/core/processing/qgsnativealgorithms.cpp
+++ b/src/core/processing/qgsnativealgorithms.cpp
@@ -269,7 +269,7 @@ QString QgsDissolveAlgorithm::shortHelpString() const
return QObject::tr( "This algorithm takes a polygon or line vector layer and combines their geometries into new geometries. One or more attributes can "
"be specified to dissolve only geometries belonging to the same class (having the same value for the specified attributes), alternatively "
"all geometries can be dissolved.\n\n"
- "If the geometries to be dissolved are spatially separated from each other the output will be multi geometries. "
+ "All output geometries will be converted to multi geometries. "
"In case the input is a polygon layer, common boundaries of adjacent polygons being dissolved will get erased." );
}
@@ -362,26 +362,27 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meter
break;
}
- if ( f.hasGeometry() && f.geometry() )
+ QVariantList indexAttributes;
+ Q_FOREACH ( int index, fieldIndexes )
{
- QVariantList indexAttributes;
- Q_FOREACH ( int index, fieldIndexes )
- {
- indexAttributes << f.attribute( index );
- }
+ indexAttributes << f.attribute( index );
+ }
- if ( !attributeHash.contains( indexAttributes ) )
- {
- // keep attributes of first feature
- attributeHash.insert( indexAttributes, f.attributes() );
- }
+ if ( !attributeHash.contains( indexAttributes ) )
+ {
+ // keep attributes of first feature
+ attributeHash.insert( indexAttributes, f.attributes() );
+ }
+
+ if ( f.hasGeometry() && f.geometry() )
+ {
geometryHash[ indexAttributes ].append( f.geometry() );
}
}
int numberFeatures = attributeHash.count();
- QHash< QVariant, QList< QgsGeometry > >::const_iterator geomIt = geometryHash.constBegin();
- for ( ; geomIt != geometryHash.constEnd(); ++geomIt )
+ QHash< QVariant, QgsAttributes >::const_iterator attrIt = attributeHash.constBegin();
+ for ( ; attrIt != attributeHash.constEnd(); ++attrIt )
{
if ( feedback->isCanceled() )
{
@@ -389,8 +390,16 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap ¶meter
}
QgsFeature outputFeature;
- outputFeature.setGeometry( QgsGeometry::unaryUnion( geomIt.value() ) );
- outputFeature.setAttributes( attributeHash.value( geomIt.key() ) );
+ if ( geometryHash.contains( attrIt.key() ) )
+ {
+ QgsGeometry geom = QgsGeometry::unaryUnion( geometryHash.value( attrIt.key() ) );
+ if ( !geom.isMultipart() )
+ {
+ geom.convertToMultiType();
+ }
+ outputFeature.setGeometry( geom );
+ }
+ outputFeature.setAttributes( attrIt.value() );
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );
feedback->setProgress( current * 100.0 / numberFeatures );
diff --git a/src/core/qgis.cpp b/src/core/qgis.cpp
index 8e3cda05f653..976746423497 100644
--- a/src/core/qgis.cpp
+++ b/src/core/qgis.cpp
@@ -247,9 +247,30 @@ uint qHash( const QVariant &variant )
case QVariant::Char:
return qHash( variant.toChar() );
case QVariant::List:
+
+#if QT_VERSION >= 0x050600
return qHash( variant.toList() );
+#else
+ {
+ QVariantList list = variant.toList();
+ if ( list.isEmpty() )
+ return -1;
+ else
+ return qHash( list.at( 0 ) );
+ }
+#endif
case QVariant::StringList:
+#if QT_VERSION >= 0x050600
return qHash( variant.toStringList() );
+#else
+ {
+ QStringList list = variant.toStringList();
+ if ( list.isEmpty() )
+ return -1;
+ else
+ return qHash( list.at( 0 ) );
+ }
+#endif
case QVariant::ByteArray:
return qHash( variant.toByteArray() );
case QVariant::Date: