Skip to content

Commit 557cc6f

Browse files
committed
GPX: added support for featureSource()
1 parent 8d21cbf commit 557cc6f

File tree

4 files changed

+93
-50
lines changed

4 files changed

+93
-50
lines changed

src/providers/gpx/qgsgpxfeatureiterator.cpp

+55-35
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@
2525
#include <cstring>
2626

2727

28-
QgsGPXFeatureIterator::QgsGPXFeatureIterator( QgsGPXProvider* p, const QgsFeatureRequest& request )
29-
: QgsAbstractFeatureIterator( request )
30-
, P( p )
28+
QgsGPXFeatureIterator::QgsGPXFeatureIterator( QgsGPXFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
29+
: QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
3130
{
32-
P->mActiveIterators << this;
3331
rewind();
3432
}
3533

@@ -49,12 +47,12 @@ bool QgsGPXFeatureIterator::rewind()
4947
}
5048
else
5149
{
52-
if ( P->mFeatureType == QgsGPXProvider::WaypointType )
53-
mWptIter = P->data->waypointsBegin();
54-
else if ( P->mFeatureType == QgsGPXProvider::RouteType )
55-
mRteIter = P->data->routesBegin();
56-
else if ( P->mFeatureType == QgsGPXProvider::TrackType )
57-
mTrkIter = P->data->tracksBegin();
50+
if ( mSource->mFeatureType == QgsGPXProvider::WaypointType )
51+
mWptIter = mSource->data->waypointsBegin();
52+
else if ( mSource->mFeatureType == QgsGPXProvider::RouteType )
53+
mRteIter = mSource->data->routesBegin();
54+
else if ( mSource->mFeatureType == QgsGPXProvider::TrackType )
55+
mTrkIter = mSource->data->tracksBegin();
5856
}
5957

6058
return true;
@@ -65,7 +63,7 @@ bool QgsGPXFeatureIterator::close()
6563
if ( mClosed )
6664
return false;
6765

68-
P->mActiveIterators.remove( this );
66+
iteratorClosed();
6967

7068
mClosed = true;
7169
return true;
@@ -85,11 +83,11 @@ bool QgsGPXFeatureIterator::fetchFeature( QgsFeature& feature )
8583
return res;
8684
}
8785

88-
if ( P->mFeatureType == QgsGPXProvider::WaypointType )
86+
if ( mSource->mFeatureType == QgsGPXProvider::WaypointType )
8987
{
9088
// go through the list of waypoints and return the first one that is in
9189
// the bounds rectangle
92-
for ( ; mWptIter != P->data->waypointsEnd(); ++mWptIter )
90+
for ( ; mWptIter != mSource->data->waypointsEnd(); ++mWptIter )
9391
{
9492
if ( readWaypoint( *mWptIter, feature ) )
9593
{
@@ -98,11 +96,11 @@ bool QgsGPXFeatureIterator::fetchFeature( QgsFeature& feature )
9896
}
9997
}
10098
}
101-
else if ( P->mFeatureType == QgsGPXProvider::RouteType )
99+
else if ( mSource->mFeatureType == QgsGPXProvider::RouteType )
102100
{
103101
// go through the routes and return the first one that is in the bounds
104102
// rectangle
105-
for ( ; mRteIter != P->data->routesEnd(); ++mRteIter )
103+
for ( ; mRteIter != mSource->data->routesEnd(); ++mRteIter )
106104
{
107105
if ( readRoute( *mRteIter, feature ) )
108106
{
@@ -111,11 +109,11 @@ bool QgsGPXFeatureIterator::fetchFeature( QgsFeature& feature )
111109
}
112110
}
113111
}
114-
else if ( P->mFeatureType == QgsGPXProvider::TrackType )
112+
else if ( mSource->mFeatureType == QgsGPXProvider::TrackType )
115113
{
116114
// go through the tracks and return the first one that is in the bounds
117115
// rectangle
118-
for ( ; mTrkIter != P->data->tracksEnd(); ++mTrkIter )
116+
for ( ; mTrkIter != mSource->data->tracksEnd(); ++mTrkIter )
119117
{
120118
if ( readTrack( *mTrkIter, feature ) )
121119
{
@@ -138,9 +136,9 @@ bool QgsGPXFeatureIterator::readFid( QgsFeature& feature )
138136
mFetchedFid = true;
139137
QgsFeatureId fid = mRequest.filterFid();
140138

141-
if ( P->mFeatureType == QgsGPXProvider::WaypointType )
139+
if ( mSource->mFeatureType == QgsGPXProvider::WaypointType )
142140
{
143-
for ( QgsGPSData::WaypointIterator it = P->data->waypointsBegin() ; it != P->data->waypointsEnd(); ++it )
141+
for ( QgsGPSData::WaypointIterator it = mSource->data->waypointsBegin() ; it != mSource->data->waypointsEnd(); ++it )
144142
{
145143
if ( it->id == fid )
146144
{
@@ -149,9 +147,9 @@ bool QgsGPXFeatureIterator::readFid( QgsFeature& feature )
149147
}
150148
}
151149
}
152-
else if ( P->mFeatureType == QgsGPXProvider::RouteType )
150+
else if ( mSource->mFeatureType == QgsGPXProvider::RouteType )
153151
{
154-
for ( QgsGPSData::RouteIterator it = P->data->routesBegin() ; it != P->data->routesEnd(); ++it )
152+
for ( QgsGPSData::RouteIterator it = mSource->data->routesBegin() ; it != mSource->data->routesEnd(); ++it )
155153
{
156154
if ( it->id == fid )
157155
{
@@ -160,9 +158,9 @@ bool QgsGPXFeatureIterator::readFid( QgsFeature& feature )
160158
}
161159
}
162160
}
163-
else if ( P->mFeatureType == QgsGPXProvider::TrackType )
161+
else if ( mSource->mFeatureType == QgsGPXProvider::TrackType )
164162
{
165-
for ( QgsGPSData::TrackIterator it = P->data->tracksBegin() ; it != P->data->tracksEnd(); ++it )
163+
for ( QgsGPSData::TrackIterator it = mSource->data->tracksBegin() ; it != mSource->data->tracksEnd(); ++it )
166164
{
167165
if ( it->id == fid )
168166
{
@@ -192,8 +190,8 @@ bool QgsGPXFeatureIterator::readWaypoint( const QgsWaypoint& wpt, QgsFeature& fe
192190
}
193191
feature.setFeatureId( wpt.id );
194192
feature.setValid( true );
195-
feature.setFields( &P->attributeFields ); // allow name-based attribute lookups
196-
feature.initAttributes( P->attributeFields.count() );
193+
feature.setFields( &mSource->mFields ); // allow name-based attribute lookups
194+
feature.initAttributes( mSource->mFields.count() );
197195

198196
readAttributes( feature, wpt );
199197

@@ -232,8 +230,8 @@ bool QgsGPXFeatureIterator::readRoute( const QgsRoute& rte, QgsFeature& feature
232230
}
233231
feature.setFeatureId( rte.id );
234232
feature.setValid( true );
235-
feature.setFields( &P->attributeFields ); // allow name-based attribute lookups
236-
feature.initAttributes( P->attributeFields.count() );
233+
feature.setFields( &mSource->mFields ); // allow name-based attribute lookups
234+
feature.initAttributes( mSource->mFields.count() );
237235

238236
readAttributes( feature, rte );
239237

@@ -271,8 +269,8 @@ bool QgsGPXFeatureIterator::readTrack( const QgsTrack& trk, QgsFeature& feature
271269
}
272270
feature.setFeatureId( trk.id );
273271
feature.setValid( true );
274-
feature.setFields( &P->attributeFields ); // allow name-based attribute lookups
275-
feature.initAttributes( P->attributeFields.count() );
272+
feature.setFields( &mSource->mFields ); // allow name-based attribute lookups
273+
feature.initAttributes( mSource->mFields.count() );
276274

277275
readAttributes( feature, trk );
278276

@@ -283,9 +281,9 @@ bool QgsGPXFeatureIterator::readTrack( const QgsTrack& trk, QgsFeature& feature
283281
void QgsGPXFeatureIterator::readAttributes( QgsFeature& feature, const QgsWaypoint& wpt )
284282
{
285283
// add attributes if they are wanted
286-
for ( int i = 0; i < P->attributeFields.count(); ++i )
284+
for ( int i = 0; i < mSource->mFields.count(); ++i )
287285
{
288-
switch ( P->indexToAttr[i] )
286+
switch ( mSource->indexToAttr[i] )
289287
{
290288
case QgsGPXProvider::NameAttr:
291289
feature.setAttribute( i, QVariant( wpt.name ) );
@@ -319,9 +317,9 @@ void QgsGPXFeatureIterator::readAttributes( QgsFeature& feature, const QgsWaypoi
319317
void QgsGPXFeatureIterator::readAttributes( QgsFeature& feature, const QgsRoute& rte )
320318
{
321319
// add attributes if they are wanted
322-
for ( int i = 0; i < P->attributeFields.count(); ++i )
320+
for ( int i = 0; i < mSource->mFields.count(); ++i )
323321
{
324-
switch ( P->indexToAttr[i] )
322+
switch ( mSource->indexToAttr[i] )
325323
{
326324
case QgsGPXProvider::NameAttr:
327325
feature.setAttribute( i, QVariant( rte.name ) );
@@ -353,9 +351,9 @@ void QgsGPXFeatureIterator::readAttributes( QgsFeature& feature, const QgsRoute&
353351
void QgsGPXFeatureIterator::readAttributes( QgsFeature& feature, const QgsTrack& trk )
354352
{
355353
// add attributes if they are wanted
356-
for ( int i = 0; i < P->attributeFields.count(); ++i )
354+
for ( int i = 0; i < mSource->mFields.count(); ++i )
357355
{
358-
switch ( P->indexToAttr[i] )
356+
switch ( mSource->indexToAttr[i] )
359357
{
360358
case QgsGPXProvider::NameAttr:
361359
feature.setAttribute( i, QVariant( trk.name ) );
@@ -469,3 +467,25 @@ QgsGeometry* QgsGPXFeatureIterator::readTrackGeometry( const QgsTrack& trk )
469467
theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * totalPoints );
470468
return theGeometry;
471469
}
470+
471+
472+
// ------------
473+
474+
QgsGPXFeatureSource::QgsGPXFeatureSource( const QgsGPXProvider* p )
475+
: mFileName( p->mFileName )
476+
, mFeatureType( p->mFeatureType )
477+
, indexToAttr( p->indexToAttr )
478+
, mFields( p->attributeFields )
479+
{
480+
data = QgsGPSData::getData( mFileName );
481+
}
482+
483+
QgsGPXFeatureSource::~QgsGPXFeatureSource()
484+
{
485+
QgsGPSData::releaseData( mFileName );
486+
}
487+
488+
QgsFeatureIterator QgsGPXFeatureSource::getFeatures( const QgsFeatureRequest& request )
489+
{
490+
return QgsFeatureIterator( new QgsGPXFeatureIterator( this, false, request ) );
491+
}

src/providers/gpx/qgsgpxfeatureiterator.h

+23-3
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,34 @@
1818
#include "qgsfeatureiterator.h"
1919

2020
#include "gpsdata.h"
21+
#include "qgsgpxprovider.h"
2122

2223
class QgsGPXProvider;
2324

24-
class QgsGPXFeatureIterator : public QgsAbstractFeatureIterator
25+
26+
class QgsGPXFeatureSource : public QgsAbstractFeatureSource
27+
{
28+
public:
29+
QgsGPXFeatureSource( const QgsGPXProvider* p );
30+
~QgsGPXFeatureSource();
31+
32+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request );
33+
34+
protected:
35+
QString mFileName;
36+
QgsGPXProvider::DataType mFeatureType;
37+
QgsGPSData* data;
38+
QVector<int> indexToAttr;
39+
QgsFields mFields;
40+
41+
friend class QgsGPXFeatureIterator;
42+
};
43+
44+
45+
class QgsGPXFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsGPXFeatureSource>
2546
{
2647
public:
27-
QgsGPXFeatureIterator( QgsGPXProvider* p, const QgsFeatureRequest& request );
48+
QgsGPXFeatureIterator( QgsGPXFeatureSource* source, bool ownSource, const QgsFeatureRequest& request );
2849

2950
~QgsGPXFeatureIterator();
3051

@@ -54,7 +75,6 @@ class QgsGPXFeatureIterator : public QgsAbstractFeatureIterator
5475
void readAttributes( QgsFeature& feature, const QgsTrack& trk );
5576

5677
protected:
57-
QgsGPXProvider* P;
5878

5979
//! Current waypoint iterator
6080
QgsGPSData::WaypointIterator mWptIter;

src/providers/gpx/qgsgpxprovider.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,14 @@ QgsGPXProvider::QgsGPXProvider( QString uri )
113113

114114
QgsGPXProvider::~QgsGPXProvider()
115115
{
116-
while ( !mActiveIterators.empty() )
117-
{
118-
QgsGPXFeatureIterator *it = *mActiveIterators.begin();
119-
QgsDebugMsg( "closing active iterator" );
120-
it->close();
121-
}
122-
123116
QgsGPSData::releaseData( mFileName );
124117
}
125118

119+
QgsAbstractFeatureSource* QgsGPXProvider::featureSource() const
120+
{
121+
return new QgsGPXFeatureSource( this );
122+
}
123+
126124

127125
QString QgsGPXProvider::storageType() const
128126
{
@@ -190,7 +188,7 @@ bool QgsGPXProvider::isValid()
190188

191189
QgsFeatureIterator QgsGPXProvider::getFeatures( const QgsFeatureRequest& request )
192190
{
193-
return QgsFeatureIterator( new QgsGPXFeatureIterator( this, request ) );
191+
return QgsFeatureIterator( new QgsGPXFeatureIterator( new QgsGPXFeatureSource( this ), true, request ) );
194192
}
195193

196194

src/providers/gpx/qgsgpxprovider.h

+9-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* *
1818
***************************************************************************/
1919

20+
#ifndef QGSGPXPROVIDER_H
21+
#define QGSGPXPROVIDER_H
2022

2123
#include "qgsvectordataprovider.h"
2224
#include "gpsdata.h"
@@ -47,6 +49,8 @@ class QgsGPXProvider : public QgsVectorDataProvider
4749

4850
/* Functions inherited from QgsVectorDataProvider */
4951

52+
virtual QgsAbstractFeatureSource* featureSource() const;
53+
5054
/**
5155
* Returns the permanent storage type for this layer as a friendly name.
5256
*/
@@ -127,8 +131,6 @@ class QgsGPXProvider : public QgsVectorDataProvider
127131
bool addFeature( QgsFeature& f );
128132

129133

130-
private:
131-
132134
enum DataType
133135
{
134136
WaypointType = 1,
@@ -144,6 +146,8 @@ class QgsGPXProvider : public QgsVectorDataProvider
144146
CmtAttr, DscAttr, SrcAttr, URLAttr, URLNameAttr
145147
};
146148

149+
private:
150+
147151
QgsGPSData* data;
148152

149153
//! Fields
@@ -172,6 +176,7 @@ class QgsGPXProvider : public QgsVectorDataProvider
172176
};
173177
wkbPoint mWKBpt;
174178

175-
friend class QgsGPXFeatureIterator;
176-
QSet< QgsGPXFeatureIterator * > mActiveIterators;
179+
friend class QgsGPXFeatureSource;
177180
};
181+
182+
#endif

0 commit comments

Comments
 (0)