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: