Skip to content

Commit

Permalink
Fetch embedded symbols via OGR feature styles when requested
Browse files Browse the repository at this point in the history
Allows symbology embedded in TAB files to be read
  • Loading branch information
nyalldawson committed Mar 6, 2021
1 parent 9b20e5d commit 6a4ba2d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/core/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -48,6 +48,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource *source, bool
, mFirstFieldIsFid( source->mFirstFieldIsFid )
, mFieldsWithoutFid( source->mFieldsWithoutFid )
, mAuthCfg( source->mAuthCfg )
, mSymbolType( QgsSymbol::symbolTypeForGeometryType( QgsWkbTypes::geometryType( source->mWkbType ) ) )
{

/* When inside a transaction for GPKG/SQLite and fetching fid(s) we might be nested inside an outer fetching loop,
Expand Down Expand Up @@ -567,6 +568,12 @@ bool QgsOgrFeatureIterator::readFeature( gdal::ogr_feature_unique_ptr fet, QgsFe
}
}

if ( mRequest.flags() & QgsFeatureRequest::EmbeddedSymbols )
{
const QString styleString( OGR_F_GetStyleString( fet.get() ) );
feature.setEmbeddedSymbol( QgsOgrUtils::symbolFromStyleString( styleString, mSymbolType ).release() );
}

return true;
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/providers/ogr/qgsogrfeatureiterator.h
Expand Up @@ -109,6 +109,8 @@ class QgsOgrFeatureIterator final: public QgsAbstractFeatureIteratorFromSource<Q

QgsFeedback *mInterruptionChecker = nullptr;

QgsSymbol::SymbolType mSymbolType = QgsSymbol::Hybrid;

/* This flag tells the iterator when to skip all calls that might reset the reading (rewind),
* to be used when the request is for a single fid or for a list of fids and we are inside
* a transaction for SQLITE-based layers */
Expand Down
21 changes: 18 additions & 3 deletions tests/src/python/test_provider_tabfile.py
Expand Up @@ -11,19 +11,20 @@
__copyright__ = 'Copyright 2016, The QGIS Project'

import os
import shutil
import tempfile

from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsVectorDataProvider, QgsField
import osgeo.gdal # NOQA
from qgis.PyQt.QtCore import QDate, QTime, QDateTime, QVariant, QDir
from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsVectorDataProvider, QgsField
from qgis.testing import start_app, unittest

import osgeo.gdal # NOQA
from utilities import unitTestDataPath
import shutil

start_app()
TEST_DATA_DIR = unitTestDataPath()


# Note - doesn't implement ProviderTestCase as OGR provider is tested by the shapefile provider test


Expand Down Expand Up @@ -96,6 +97,20 @@ def testInteger64WriteTabfile(self):
self.assertTrue(vl.isValid())
self.assertTrue(vl.dataProvider().addAttributes([QgsField("int8", QVariant.LongLong, "integer64")]))

def testEmbeddedSymbols(self):
"""
Test retrieving embedded symbols from a TAB file
"""
layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'embedded_symbols', 'lines.TAB'), 'Lines')
self.assertTrue(layer.isValid())

# symbols should not be fetched by default
self.assertFalse(any(f.embeddedSymbol() for f in layer.getFeatures()))

symbols = [f.embeddedSymbol().clone() for f in layer.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.EmbeddedSymbols))]
self.assertTrue(all(symbols))
self.assertCountEqual([s.color().name() for s in symbols], ['#0040c0', '#ffb060', '#e03800'])


if __name__ == '__main__':
unittest.main()
Binary file added tests/testdata/embedded_symbols/lines.DAT
Binary file not shown.
Binary file added tests/testdata/embedded_symbols/lines.ID
Binary file not shown.
Binary file added tests/testdata/embedded_symbols/lines.MAP
Binary file not shown.
9 changes: 9 additions & 0 deletions tests/testdata/embedded_symbols/lines.TAB
@@ -0,0 +1,9 @@
!table
!version 450
!charset WindowsLatin1

Definition Table
Type NATIVE Charset "WindowsLatin1"
Fields 2
Field1 Char (10) ;
Field2 Integer ;

0 comments on commit 6a4ba2d

Please sign in to comment.