Skip to content

Commit

Permalink
QgsVectorLayerUtils::guessFriendlyIdentifierField(): improve heuristi…
Browse files Browse the repository at this point in the history
…cs to work better with WFS layers analyzed with the GMLAS driver
  • Loading branch information
rouault committed Feb 19, 2024
1 parent 114a842 commit 6307107
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
30 changes: 29 additions & 1 deletion src/core/vector/qgsvectorlayerutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1239,9 +1239,37 @@ QString QgsVectorLayerUtils::guessFriendlyIdentifierField( const QgsFields &fiel
break;
}

const QString candidateName = bestCandidateName.isEmpty() ? bestCandidateNameWithAntiCandidate : bestCandidateName;
QString candidateName = bestCandidateName.isEmpty() ? bestCandidateNameWithAntiCandidate : bestCandidateName;
if ( !candidateName.isEmpty() )
{
// Special case for layers got from WFS using the OGR GMLAS field parsing logic.
// Such layers contain a "id" field (the gml:id attribute of the object),
// as well as a gml_name (a <gml:name>) element. However this gml:name is often
// absent, partly because it is a property of the base class in GML schemas, and
// that a lot of readers are not able to deduce its potential presence.
// So try to look at another field whose name would end with _name
// And fallback to using the "id" field that should always be filled.
if ( candidateName == QLatin1String( "gml_name" ) &&
fields.indexOf( QStringLiteral( "id" ) ) >= 0 )
{
candidateName.clear();
// Try to find a field ending with "_name", which is not "gml_name"
for ( const QgsField &field : std::as_const( fields ) )
{
const QString fldName = field.name();
if ( fldName != QLatin1String( "gml_name" ) && fldName.endsWith( QLatin1String( "_name" ) ) )
{
candidateName = fldName;
break;
}
}
if ( candidateName.isEmpty() )
{
// Fallback to "id"
candidateName = QStringLiteral( "id" );
}
}

if ( foundFriendly )
*foundFriendly = true;
return candidateName;
Expand Down
13 changes: 13 additions & 0 deletions tests/src/python/test_qgsvectorlayerutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,19 @@ def testGuessFriendlyIdentifierField(self):
fields.append(QgsField('org', QVariant.String))
self.assertEqual(QgsVectorLayerUtils.guessFriendlyIdentifierField(fields), 'station')

# Particular case for WFS layers analyzed with the GMLAS driver.
# We prioritize a field ending with _name, but which is not gml_name
fields = QgsFields()
fields.append(QgsField('id', QVariant.String))
fields.append(QgsField('gml_name', QVariant.String))
fields.append(QgsField('other_name', QVariant.String))
self.assertEqual(QgsVectorLayerUtils.guessFriendlyIdentifierField(fields), 'other_name')

fields = QgsFields()
fields.append(QgsField('id', QVariant.String))
fields.append(QgsField('gml_name', QVariant.String))
self.assertEqual(QgsVectorLayerUtils.guessFriendlyIdentifierField(fields), 'id')


if __name__ == '__main__':
unittest.main()

0 comments on commit 6307107

Please sign in to comment.