252 changes: 182 additions & 70 deletions src/providers/wfs/qgswfsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

#define WFS_THRESHOLD 200

#include "qgis.h"
#include "qgsapplication.h"
#include "qgsmaplayerregistry.h"
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
Expand Down Expand Up @@ -49,9 +51,13 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )
mNetworkRequestFinished( true ),
mEncoding( QgsWFSProvider::GET ),
mUseIntersect( false ),
mWKBType( QGis::WKBUnknown ),
mSourceCRS( 0 ),
mFeatureCount( 0 ),
mValid( true )
mValid( true ),
mLayer( 0 ),
mGetRenderedOnly( false ),
mInitGro( false )
{
mSpatialIndex = 0;
if ( uri.isEmpty() )
Expand All @@ -60,7 +66,39 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )
return;
}

reloadData();
//Local url or HTTP? [WBC 111221] refactored from getFeature()
if ( uri.startsWith( "http" ) )
{
mEncoding = QgsWFSProvider::GET;
}
else
{
mEncoding = QgsWFSProvider::FILE;
}

//create mSourceCRS from url if possible [WBC 111221] refactored from GetFeatureGET()
QString srsname = parameterFromUrl( "SRSNAME" );
if ( !srsname.isEmpty() )
{
mSourceCRS.createFromOgcWmsCrs( srsname );
}

//fetch attributes of layer and type of its geometry attribute
//WBC 111221: extracting geometry type here instead of getFeature allows successful
//layer creation even when no features are retrieved (due to, e.g., BBOX or FILTER)
if ( describeFeatureType( uri, mGeometryAttribute, mFields, mWKBType ) )
{
mValid = false;
QgsDebugMsg( QString( "describeFeatureType failed, URI=%1" ).arg( uri ) );
QMessageBox( QMessageBox::Warning, "DescribeFeatureType failed!",
QString( "Layer cannot be created from\n%1" ).arg( uri ) );
return;
}

if ( ! uri.contains( "BBOX" ) )
{ //"Cache Features" option; get all features in layer immediately
reloadData();
} //otherwise, defer feature retrieval until layer is first rendered

if ( mValid )
{
Expand Down Expand Up @@ -231,72 +269,88 @@ void QgsWFSProvider::select( QgsAttributeList fetchAttributes,
mAttributesToFetch = fetchAttributes;
mFetchGeom = fetchGeometry;

QString dsURI = dataSourceUri();
if ( dsURI.contains( "BBOX" ) )
{
QUrl url( dsURI );
url.removeQueryItem( "BBOX" );
url.addQueryItem( "BBOX", QString::number( rect.xMinimum() ) + "," + QString::number( rect.yMinimum() ) + ","
+ QString::number( rect.xMaximum() ) + "," + QString::number( rect.yMaximum() ) );
setDataSourceUri( url.toString() );
reloadData();
if ( rect.isEmpty() )
{ //select all features
mSpatialFilter = mExtent;
mSelectedFeatures = mFeatures.keys();
mSpatialFilter = rect;
}
else
{
if ( rect.isEmpty() )
{
mSpatialFilter = mExtent;
mSelectedFeatures = mFeatures.keys();
}
else
{
mSpatialFilter = rect;
mSelectedFeatures = mSpatialIndex->intersects( mSpatialFilter );
{ //select features intersecting caller's extent
QString dsURI = dataSourceUri();
//first time through, initialize GetRenderedOnly args
//ctor cannot initialize because layer object not available then
if ( ! mInitGro )
{ //did user check "Cache Features" in WFS layer source selection?
if ( dsURI.contains( "BBOX" ) )
{ //no: initialize incremental getFeature
if ( initGetRenderedOnly( rect ) )
{
mGetRenderedOnly = true;
}
else
{ //initialization failed;
QgsDebugMsg( QString( "GetRenderedOnly initialization failed; incorrect operation may occur\n%1" )
.arg( dataSourceUri() ) );
QMessageBox( QMessageBox::Warning, "Non-Cached layer initialization failed!",
QString( "Incorrect operation may occur:\n%1" ).arg( dataSourceUri() ) );
}
}
mInitGro = true;
}

if ( mGetRenderedOnly )
{ //"Cache Features" was not selected for this layer
//has rendered extent expanded beyond last-retrieved WFS extent?
//NB: "intersect" instead of "contains" tolerates rounding errors;
// avoids unnecessary second fetch on zoom-in/zoom-out sequences
QgsRectangle olap( rect );
olap = olap.intersect( &mGetExtent );
if ( doubleNear( rect.width(), olap.width() ) && doubleNear( rect.height(), olap.height() ) )
{ //difference between canvas and layer extents is within rounding error: do not re-fetch
QgsDebugMsg( QString( "Layer %1 GetRenderedOnly: no fetch required" ).arg( mLayer->name() ) );
}
else
{ //combined old and new extents might speed up local panning & zooming
mGetExtent.combineExtentWith( &rect );
//but see if the combination is useless or too big
double pArea = mGetExtent.width() * mGetExtent.height();
double cArea = rect.width() * rect.height();
if ( olap.isEmpty() || pArea > ( cArea * 4.0 ) )
{ //new canvas extent does not overlap or combining old and new extents would
//fetch > 4 times the area to be rendered; get only what will be rendered
mGetExtent = rect;
}
QgsDebugMsg( QString( "Layer %1 GetRenderedOnly: fetching extent %2" )
.arg( mLayer->name(), mGetExtent.asWktCoordinates() ) );
dsURI = dsURI.replace( QRegExp( "BBOX=[^&]*" ),
QString( "BBOX=%1,%2,%3,%4" )
.arg( mGetExtent.xMinimum(), 0, 'f' )
.arg( mGetExtent.yMinimum(), 0, 'f' )
.arg( mGetExtent.xMaximum(), 0, 'f' )
.arg( mGetExtent.yMaximum(), 0, 'f' ) );
//TODO: BBOX may not be combined with FILTER. WFS spec v. 1.1.0, sec. 14.7.3 ff.
// if a FILTER is present, the BBOX must be merged into it, capabilities permitting.
// Else one criterion must be abandoned and the user warned. [WBC 111221]
setDataSourceUri( dsURI );
reloadData();
mLayer->updateExtents();
}
}

mSpatialFilter = rect;
mSelectedFeatures = mSpatialIndex->intersects( mSpatialFilter );
}

mFeatureIterator = mSelectedFeatures.begin();
}

int QgsWFSProvider::getFeature( const QString& uri )
{
QString geometryAttribute;

//Local url or HTTP?
if ( uri.startsWith( "http" ) )
{
mEncoding = QgsWFSProvider::GET;
}
else
{
mEncoding = QgsWFSProvider::FILE;
}

if ( mEncoding == QgsWFSProvider::FILE )
{
//guess geometry attribute and other attributes from schema or from .gml file
if ( describeFeatureTypeFile( uri, mGeometryAttribute, mFields ) != 0 )
{
return 1;
}
}
else //take schema with describeFeatureType request
{
QString describeFeatureUri = uri;
describeFeatureUri.replace( QString( "GetFeature" ), QString( "DescribeFeatureType" ) );
if ( describeFeatureType( describeFeatureUri, mGeometryAttribute, mFields ) != 0 )
{
return 1;
}
}

if ( mEncoding == QgsWFSProvider::GET )
{
return getFeatureGET( uri, mGeometryAttribute );
}
else//local file
else //local file
{
return getFeatureFILE( uri, mGeometryAttribute ); //read the features from disk
}
Expand Down Expand Up @@ -658,16 +712,27 @@ bool QgsWFSProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
}
}

int QgsWFSProvider::describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
int QgsWFSProvider::describeFeatureType( const QString& uri, QString& geometryAttribute,
QgsFieldMap& fields, QGis::WkbType& geomType )
//NB: also called from QgsWFSSourceSelect::on_treeWidget_itemDoubleClicked() to build filters.
// a temporary provider object is constructed with a null URI, which bypasses much provider
// instantiation logic: refresh(), getFeature(), etc. therefore, many provider class members
// are only default values or uninitialized when running under the source select dialog!
{
fields.clear();
//Local url or HTTP? WBC111221 refactored here from getFeature()
switch ( mEncoding )
{
case QgsWFSProvider::GET:
return describeFeatureTypeGET( uri, geometryAttribute, fields );
{
return describeFeatureTypeGET( uri, geometryAttribute, fields, geomType );
}
case QgsWFSProvider::FILE:
return describeFeatureTypeFile( uri, geometryAttribute, fields );
{
return describeFeatureTypeFile( uri, geometryAttribute, fields, geomType );
}
}
QgsDebugMsg( "SHOULD NOT OCCUR: mEncoding undefined" );
return 1;
}

Expand All @@ -682,13 +747,6 @@ int QgsWFSProvider::getFeatureGET( const QString& uri, const QString& geometryAt
thematicAttributes.insert( it.value().name(), qMakePair( it.key(), it.value() ) );
}

//create mSourceCRS from url if possible
QString srsname = parameterFromUrl( "SRSNAME" );
if ( !srsname.isEmpty() )
{
mSourceCRS.createFromOgcWmsCrs( srsname );
}

QgsWFSData dataReader( uri, &mExtent, mFeatures, mIdMap, geometryAttribute, thematicAttributes, &mWKBType );
QObject::connect( &dataReader, SIGNAL( dataProgressAndSteps( int , int ) ), this, SLOT( handleWFSProgressMessage( int, int ) ) );

Expand Down Expand Up @@ -765,7 +823,7 @@ int QgsWFSProvider::getFeatureFILE( const QString& uri, const QString& geometryA
return 0;
}

int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields, QGis::WkbType& geomType )
{
if ( !mNetworkRequestFinished )
{
Expand All @@ -774,7 +832,9 @@ int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometr

mNetworkRequestFinished = false;

QNetworkRequest request( uri );
QString describeFeatureUri = uri;
describeFeatureUri.replace( QString( "GetFeature" ), QString( "DescribeFeatureType" ) );
QNetworkRequest request( describeFeatureUri );
QNetworkReply* reply = QgsNetworkAccessManager::instance()->get( request );
connect( reply, SIGNAL( finished() ), this, SLOT( networkRequestFinished() ) );
while ( !mNetworkRequestFinished )
Expand All @@ -792,8 +852,10 @@ int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometr
return 2;
}

if ( readAttributesFromSchema( describeFeatureDocument, geometryAttribute, fields ) != 0 )
if ( readAttributesFromSchema( describeFeatureDocument,
geometryAttribute, fields, geomType ) != 0 )
{
QgsDebugMsg( QString( "FAILED: readAttributesFromSchema" ) );
return 3;
}

Expand All @@ -805,7 +867,7 @@ void QgsWFSProvider::networkRequestFinished()
mNetworkRequestFinished = true;
}

int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields, QGis::WkbType& geomType )
{
//first look in the schema file
QString noExtension = uri;
Expand All @@ -821,7 +883,7 @@ int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geomet
return 1; //xml file not readable or not valid
}

if ( readAttributesFromSchema( schemaDoc, geometryAttribute, fields ) != 0 )
if ( readAttributesFromSchema( schemaDoc, geometryAttribute, fields, geomType ) != 0 )
{
return 2;
}
Expand All @@ -846,7 +908,7 @@ int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geomet
return 0;
}

int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldMap& fields )
int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldMap& fields, QGis::WkbType& geomType )
{
//get the <schema> root element
QDomNodeList schemaNodeList = schemaDoc.elementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "schema" );
Expand Down Expand Up @@ -921,9 +983,11 @@ int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString&

//is it a geometry attribute?
//MH 090428: sometimes the <element> tags for geometry attributes have only attribute ref="gml:polygonProperty" and no name
if (( type.startsWith( "gml:" ) && type.endsWith( "PropertyType" ) ) || name.isEmpty() )
QRegExp gmlPT( "gml:(.*)PropertyType" );
if ( type.indexOf( gmlPT ) == 0 || name.isEmpty() )
{
geometryAttribute = name;
geomType = geomTypeFromPropertyType( geometryAttribute, gmlPT.cap( 1 ) );
}
else //todo: distinguish between numerical and non-numerical types
{
Expand Down Expand Up @@ -2288,6 +2352,54 @@ void QgsWFSProvider::appendSupportedOperations( const QDomElement& operationsEle
}
}

//initialization for getRenderedOnly option
//(formerly "Only request features overlapping the current view extent")
bool QgsWFSProvider::initGetRenderedOnly( const QgsRectangle rect )
{ //find our layer
QMap<QString, QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers();
QMap<QString, QgsMapLayer*>::const_iterator layersIt = layers.begin();
for ( ; layersIt != layers.end() ; ++layersIt )
{
if (( mLayer = dynamic_cast<QgsVectorLayer*>( layersIt.value() ) ) )
{
if ( mLayer->dataProvider() == this )
{
QgsDebugMsg( QString( "found layer %1" ).arg( mLayer->name() ) );
break;
}
}
}
if ( layersIt == layers.end() )
{
QgsDebugMsg( "SHOULD NOT OCCUR: initialize() did not find layer." );
return false;
}
return true;
}

QGis::WkbType QgsWFSProvider::geomTypeFromPropertyType( QString attName, QString propType )
{
const QStringList geomTypes = ( QStringList()
//all GML v.2.1.3 _geometryProperty group members, except MultiGeometryPropertyType
//sequence must exactly match enum Qgis::WkbType
<< "" // unknown geometry, enum 0
<< "Point"
<< "LineString"
<< "Polygon"
<< "MultiPoint"
<< "MultiLineString"
<< "MultiPolygon" );

QgsDebugMsg( QString( "DescribeFeatureType geometry attribute \"%1\" type is \"%2\"" )
.arg( attName, propType ) );
int i = geomTypes.indexOf( propType );
if ( i <= 0 )
{ // feature type missing or unknown
i = ( int ) QGis::WKBUnknown;
}
return ( QGis::WkbType ) i;
}

void QgsWFSProvider::handleException( const QDomDocument& serverResponse ) const
{
QDomElement exceptionElem = serverResponse.documentElement();
Expand Down
25 changes: 20 additions & 5 deletions src/providers/wfs/qgswfsprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "qgsrectangle.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsvectordataprovider.h"
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"

class QgsRectangle;
class QgsSpatialIndex;
Expand Down Expand Up @@ -140,8 +142,9 @@ class QgsWFSProvider: public QgsVectorDataProvider
synchronize with changes in the data source*/
virtual void reloadData();

/**Collects information about the field types. Is called internally from QgsWFSProvider::getFeature. The method delegates the work to request specific ones and gives back the name of the geometry attribute and the thematic attributes with their types*/
int describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
/**Collects information about the field types. Is called internally from QgsWFSProvider ctor. The method delegates the work to request specific ones and gives back the name of the geometry attribute and the thematic attributes with their types*/
int describeFeatureType( const QString& uri, QString& geometryAttribute,
QgsFieldMap& fields, QGis::WkbType& geomType );

signals:
void dataReadProgressMessage( QString message );
Expand Down Expand Up @@ -191,20 +194,28 @@ class QgsWFSProvider: public QgsVectorDataProvider
QString mWfsNamespace;
/**Server capabilities for this layer (generated from capabilities document)*/
int mCapabilities;
/**GetRenderedOnly: layer asociated with this provider*/
QgsVectorLayer *mLayer;
/**GetRenderedOnly: fetch only features within canvas extent to be rendered*/
bool mGetRenderedOnly;
/**GetRenderedOnly initializaiton flat*/
bool mInitGro;
/**if GetRenderedOnly, extent specified in WFS getFeatures; else empty (no constraint)*/
QgsRectangle mGetExtent;

//encoding specific methods of getFeature
int getFeatureGET( const QString& uri, const QString& geometryAttribute );
int getFeaturePOST( const QString& uri, const QString& geometryAttribute );
int getFeatureSOAP( const QString& uri, const QString& geometryAttribute );
int getFeatureFILE( const QString& uri, const QString& geometryAttribute );
//encoding specific methods of describeFeatureType
int describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
int describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields, QGis::WkbType& geomType );
int describeFeatureTypePOST( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
int describeFeatureTypeSOAP( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
int describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
int describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields, QGis::WkbType& geomType );

/**Reads the name of the geometry attribute, the thematic attributes and their types from a dom document. Returns 0 in case of success*/
int readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldMap& fields );
int readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldMap& fields, QGis::WkbType& geomType );
/**This method tries to guess the geometry attribute and the other attribute names from the .gml file if no schema is present. Returns 0 in case of success*/
int guessAttributesFromFile( const QString& uri, QString& geometryAttribute, std::list<QString>& thematicAttributes ) const;

Expand Down Expand Up @@ -284,6 +295,10 @@ class QgsWFSProvider: public QgsVectorDataProvider
void appendSupportedOperations( const QDomElement& operationsElem, int& capabilities ) const;
/**Shows a message box with the exception string (or does nothing if the xml document is not an exception)*/
void handleException( const QDomDocument& serverResponse ) const;
/**Initializes "Cache Features" inactive processing*/
bool initGetRenderedOnly( QgsRectangle );
/**Converts DescribeFeatureType schema geometry property type to WKBType*/
QGis::WkbType geomTypeFromPropertyType( QString attName, QString propType );

void deleteData();
};
Expand Down
90 changes: 52 additions & 38 deletions src/providers/wfs/qgswfssourceselect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
* *
***************************************************************************/

#include "qgisinterface.h"
#include "qgswfssourceselect.h"
#include "qgswfsconnection.h"
#include "qgswfsprovider.h"
Expand All @@ -25,6 +24,7 @@
#include "qgscontexthelp.h"
#include "qgsproject.h"
#include "qgscoordinatereferencesystem.h"
#include "qgscoordinatetransform.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h" //for current view extent
#include "qgsmanageconnectionsdialog.h"
Expand Down Expand Up @@ -263,22 +263,57 @@ void QgsWFSSourceSelect::addLayer()

QList<QTreeWidgetItem*> selectedItems = treeWidget->selectedItems();
QList<QTreeWidgetItem*>::const_iterator sIt = selectedItems.constBegin();
for ( ; sIt != selectedItems.constEnd(); ++sIt )
QgsWFSConnection conn( cmbConnections->currentText() );
QString pCrsString( labelCoordRefSys->text() );
QgsCoordinateReferenceSystem pCrs( pCrsString );
//prepare canvas extent info for layers with "cache features" option not set
QgsRectangle extent;
QVariant extentVariant = property( "MapExtent" );
if ( extentVariant.isValid() )
{
QString typeName = ( *sIt )->text( 1 );
QString crs = labelCoordRefSys->text();
QString filter = ( *sIt )->text( 4 );

QgsRectangle currentRectangle;
if (( *sIt )->checkState( 3 ) == Qt::Unchecked )
QString crs;
QgsCoordinateTransform xform;
QString extentString = extentVariant.toString();
QStringList minMaxSplit = extentString.split( ":" );
if ( minMaxSplit.size() > 1 )
{
currentRectangle = mExtent;
QStringList xyMinSplit = minMaxSplit[0].split( "," );
QStringList xyMaxSplit = minMaxSplit[1].split( "," );
if ( xyMinSplit.size() > 1 && xyMaxSplit.size() > 1 )
{
extent.set( xyMinSplit[0].toDouble(), xyMinSplit[1].toDouble(),
xyMaxSplit[0].toDouble(), xyMaxSplit[1].toDouble() );
}
}
//does canvas have "on the fly" reprojection set?
QVariant crsVariant = property( "MapCRS" );
if ( crsVariant.isValid() )
{ //transform between provider CRS set in source select dialog and canvas CRS
QgsCoordinateReferenceSystem cCrs( crsVariant.toString() );
if ( pCrs.isValid() && cCrs.isValid() )
{
QgsCoordinateTransform xform( pCrs, cCrs );
extent = xform.transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
QgsDebugMsg( QString( "canvas transform: Canvas CRS=%1, Provider CRS=%2, BBOX=%3" )
.arg( cCrs.authid(), pCrs.authid(), extent.asWktCoordinates() ) );
}
}

//add a wfs layer to the map
QgsWFSConnection conn( cmbConnections->currentText() );
QString uri = conn.uriGetFeature( typeName, crs, filter, currentRectangle );
emit addWfsLayer( uri, typeName );
}
//create layers that user selected from this WFS source
for ( ; sIt != selectedItems.constEnd(); ++sIt )
{ //add a wfs layer to the map
QString typeName = ( *sIt )->text( 1 ); //WFS repository's name for layer
QString filter = ( *sIt )->text( 4 ); //optional filter specified by user
//is "cache features" checked?
if (( *sIt )->checkState( 3 ) == Qt::Checked )
{ //yes: entire WFS layer will be retrieved and cached
mUri = conn.uriGetFeature( typeName, pCrsString, filter );
}
else
{ //no: include BBOX of current canvas extent in URI
mUri = conn.uriGetFeature( typeName, pCrsString, filter, extent );
}
emit addWfsLayer( mUri, typeName );
}
accept();
}
Expand Down Expand Up @@ -365,18 +400,18 @@ void QgsWFSSourceSelect::on_treeWidget_itemDoubleClicked( QTreeWidgetItem* item,
if ( item && column == 4 )
{
//get available fields for wfs layer
QgsWFSProvider p( "" );
QgsWFSProvider p( "" ); //bypasses most provider instantiation logic
QgsWFSConnection conn( cmbConnections->currentText() );
QString uri = conn.uriDescribeFeatureType( item->text( 1 ) );

QgsFieldMap fields;
QString geometryAttribute;
if ( p.describeFeatureType( uri, geometryAttribute, fields ) != 0 )
QGis::WkbType geomType;
if ( p.describeFeatureType( uri, geometryAttribute, fields, geomType ) != 0 )
{
return;
}


//show expression builder
QgsExpressionBuilderDialog d( 0, item->text( 3 ) );

Expand All @@ -399,24 +434,3 @@ void QgsWFSSourceSelect::on_treeWidget_itemDoubleClicked( QTreeWidgetItem* item,
}
}
}

void QgsWFSSourceSelect::showEvent( QShowEvent* event )
{
Q_UNUSED( event );
QVariant extentVariant = property( "MapExtent" );
if ( extentVariant.isValid() )
{
QString extentString = extentVariant.toString();
QStringList minMaxSplit = extentString.split( ":" );
if ( minMaxSplit.size() > 1 )
{
QStringList xyMinSplit = minMaxSplit[0].split( "," );
QStringList xyMaxSplit = minMaxSplit[1].split( "," );
if ( xyMinSplit.size() > 1 && xyMaxSplit.size() > 1 )
{
mExtent.set( xyMinSplit[0].toDouble(), xyMinSplit[1].toDouble(), xyMaxSplit[0].toDouble(), xyMaxSplit[1].toDouble() );
return;
}
}
}
}
5 changes: 1 addition & 4 deletions src/providers/wfs/qgswfssourceselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#include "ui_qgswfssourceselectbase.h"
#include "qgscontexthelp.h"
#include "qgsrectangle.h"

class QgsGenericProjectionSelector;
class QgsWFSConnection;
Expand All @@ -47,7 +46,7 @@ class QgsWFSSourceSelect: public QDialog, private Ui::QgsWFSSourceSelectBase
std::map<QString, std::list<QString> > mAvailableCRS;
QAbstractButton* btnAdd;
QgsWFSConnection* mConn;
QgsRectangle mExtent;
QString mUri; // data source URI

void populateConnectionList();

Expand All @@ -74,8 +73,6 @@ class QgsWFSSourceSelect: public QDialog, private Ui::QgsWFSSourceSelectBase

void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }

protected:
void showEvent( QShowEvent* event );
};

#endif
14 changes: 12 additions & 2 deletions src/ui/qgswfssourceselectbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>552</width>
<width>592</width>
<height>439</height>
</rect>
</property>
Expand Down Expand Up @@ -114,6 +114,12 @@
<property name="columnCount">
<number>5</number>
</property>
<attribute name="headerMinimumSectionSize">
<number>27</number>
</attribute>
<attribute name="headerMinimumSectionSize">
<number>27</number>
</attribute>
<column>
<property name="text">
<string>Title</string>
Expand All @@ -131,7 +137,11 @@
</column>
<column>
<property name="text">
<string>cache features</string>
<string>Cache
Features</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</column>
<column>
Expand Down