Skip to content

Commit 64f2903

Browse files
elpasodakcarto
authored andcommitted
Avoid crash when WFS converted to offline
Fixes #14010 Converting to Offline Editing of WFS-T layer causes minidump Funded by Boundless (cherry-picked from eeb9bdd)
1 parent 5738292 commit 64f2903

File tree

2 files changed

+16
-93
lines changed

2 files changed

+16
-93
lines changed

src/core/qgsofflineediting.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ QgsOfflineEditing::~QgsOfflineEditing()
6565
/**
6666
* convert current project to offline project
6767
* returns offline project file path
68+
*
69+
* Workflow:
70+
* - copy layers to spatialite
71+
* - create spatialite db at offlineDataPath
72+
* - create table for each layer
73+
* - add new spatialite layer
74+
* - copy features
75+
* - save as offline project
76+
* - mark offline layers
77+
* - remove remote layers
78+
* - mark as offline project
6879
*/
6980
bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath, const QString& offlineDbFile, const QStringList& layerIds )
7081
{
@@ -129,6 +140,9 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
129140
if ( newLayer )
130141
{
131142
layerIdMapping.insert( origLayerId, newLayer );
143+
// remove remote layer
144+
QgsMapLayerRegistry::instance()->removeMapLayers(
145+
QStringList() << vl->id() );
132146
}
133147
}
134148

@@ -172,19 +186,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
172186
return true;
173187
}
174188
}
175-
176189
return false;
177-
178-
// Workflow:
179-
// copy layers to spatialite
180-
// create spatialite db at offlineDataPath
181-
// create table for each layer
182-
// add new spatialite layer
183-
// copy features
184-
// save as offline project
185-
// mark offline layers
186-
// remove remote layers
187-
// mark as offline project
188190
}
189191

190192
bool QgsOfflineEditing::isOfflineProject()
@@ -655,10 +657,6 @@ QgsVectorLayer* QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlit
655657
{
656658
showWarning( newLayer->commitErrors().join( "\n" ) );
657659
}
658-
659-
// remove remote layer
660-
QgsMapLayerRegistry::instance()->removeMapLayers(
661-
QStringList() << layer->id() );
662660
}
663661
return newLayer;
664662
}

src/providers/wfs/qgswfsprovider.cpp

Lines changed: 2 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,7 @@ void QgsWFSProvider::reloadData()
168168
void QgsWFSProvider::deleteData()
169169
{
170170
mSelectedFeatures.clear();
171-
for ( int i = 0; i < mFeatures.size(); i++ )
172-
{
173-
delete mFeatures[i];
174-
}
171+
qDeleteAll( mFeatures );
175172
mFeatures.clear();
176173
}
177174

@@ -213,85 +210,13 @@ bool QgsWFSProvider::isValid()
213210

214211
QgsFeatureIterator QgsWFSProvider::getFeatures( const QgsFeatureRequest& request )
215212
{
216-
#if 0
217-
if ( !( request.flags() & QgsFeatureRequest::NoGeometry ) )
218-
{
219-
QgsRectangle rect = request.filterRect();
220-
if ( !rect.isEmpty() )
221-
{
222-
QString dsURI = dataSourceUri();
223-
//first time through, initialize GetRenderedOnly args
224-
//ctor cannot initialize because layer object not available then
225-
if ( ! mInitGro )
226-
{ //did user check "Cache Features" in WFS layer source selection?
227-
if ( dsURI.contains( "BBOX=" ) )
228-
{ //no: initialize incremental getFeature
229-
if ( initGetRenderedOnly( rect ) )
230-
{
231-
mGetRenderedOnly = true;
232-
}
233-
else
234-
{ //initialization failed;
235-
QgsDebugMsg( QString( "GetRenderedOnly initialization failed; incorrect operation may occur\n%1" )
236-
.arg( dataSourceUri() ) );
237-
QMessageBox( QMessageBox::Warning, "Non-Cached layer initialization failed!",
238-
QString( "Incorrect operation may occur:\n%1" ).arg( dataSourceUri() ) );
239-
}
240-
}
241-
mInitGro = true;
242-
}
243-
244-
if ( mGetRenderedOnly )
245-
{ //"Cache Features" was not selected for this layer
246-
//has rendered extent expanded beyond last-retrieved WFS extent?
247-
//NB: "intersect" instead of "contains" tolerates rounding errors;
248-
// avoids unnecessary second fetch on zoom-in/zoom-out sequences
249-
QgsRectangle olap( rect );
250-
olap = olap.intersect( &mGetExtent );
251-
if ( qgsDoubleNear( rect.width(), olap.width() ) && qgsDoubleNear( rect.height(), olap.height() ) )
252-
{ //difference between canvas and layer extents is within rounding error: do not re-fetch
253-
QgsDebugMsg( QString( "Layer %1 GetRenderedOnly: no fetch required" ).arg( mLayer->name() ) );
254-
}
255-
else
256-
{ //combined old and new extents might speed up local panning & zooming
257-
mGetExtent.combineExtentWith( &rect );
258-
//but see if the combination is useless or too big
259-
double pArea = mGetExtent.width() * mGetExtent.height();
260-
double cArea = rect.width() * rect.height();
261-
if ( olap.isEmpty() || pArea > ( cArea * 4.0 ) )
262-
{ //new canvas extent does not overlap or combining old and new extents would
263-
//fetch > 4 times the area to be rendered; get only what will be rendered
264-
mGetExtent = rect;
265-
}
266-
QgsDebugMsg( QString( "Layer %1 GetRenderedOnly: fetching extent %2" )
267-
.arg( mLayer->name(), mGetExtent.asWktCoordinates() ) );
268-
dsURI = dsURI.replace( QRegExp( "BBOX=[^&]*" ),
269-
QString( "BBOX=%1,%2,%3,%4" )
270-
.arg( qgsDoubleToString( mGetExtent.xMinimum() ) )
271-
.arg( qgsDoubleToString( mGetExtent.yMinimum() ) )
272-
.arg( qgsDoubleToString( mGetExtent.xMaximum() ) )
273-
.arg( qgsDoubleToString( mGetExtent.yMaximum() ) ) );
274-
//TODO: BBOX may not be combined with FILTER. WFS spec v. 1.1.0, sec. 14.7.3 ff.
275-
// if a FILTER is present, the BBOX must be merged into it, capabilities permitting.
276-
// Else one criterion must be abandoned and the user warned. [WBC 111221]
277-
setDataSourceUri( dsURI );
278-
reloadData();
279-
mLayer->updateExtents();
280-
}
281-
}
282-
}
283-
284-
}
285-
return new QgsWFSFeatureIterator( new QgsWFSFeatureSource( this ), true, request );
286-
#else
287213
QgsRectangle rect = request.filterRect();
288214
if ( !( request.flags() & QgsFeatureRequest::NoGeometry ) && !rect.isEmpty() )
289215
{
290216
deleteData();
291217
reloadData();
292218
}
293-
return new QgsWFSFeatureIterator( new QgsWFSFeatureSource( this ), true, request );
294-
#endif
219+
return QgsFeatureIterator( new QgsWFSFeatureIterator( new QgsWFSFeatureSource( this ), true, request ) );
295220
}
296221

297222
int QgsWFSProvider::getFeature( const QString& uri )

0 commit comments

Comments
 (0)