Skip to content

Commit

Permalink
Advertised WFS URL
Browse files Browse the repository at this point in the history
Like WMS services, users can configure an advertised URL for WFS
services.
If no advertised WFS URL is specified, QGIS-Server looked at the
advertised WMS URL.
rldhont committed May 30, 2013

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent d841ccf commit ca86153
Showing 7 changed files with 143 additions and 88 deletions.
2 changes: 2 additions & 0 deletions src/app/qgsprojectproperties.cpp
Original file line number Diff line number Diff line change
@@ -347,6 +347,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
mMaxHeightLineEdit->setText( QString::number( maxHeight ) );
}

mWFSUrlLineEdit->setText( QgsProject::instance()->readEntry( "WFSUrl", "/", "" ) );
QStringList wfsLayerIdList = QgsProject::instance()->readListEntry( "WFSLayers", "/" );
QStringList wfstUpdateLayerIdList = QgsProject::instance()->readListEntry( "WFSTLayers", "Update" );
QStringList wfstInsertLayerIdList = QgsProject::instance()->readListEntry( "WFSTLayers", "Insert" );
@@ -740,6 +741,7 @@ void QgsProjectProperties::apply()
QgsProject::instance()->writeEntry( "WMSMaxHeight", "/", maxHeightText.toInt() );
}

QgsProject::instance()->writeEntry( "WFSUrl", "/", mWFSUrlLineEdit->text() );
QStringList wfsLayerList;
QStringList wfstUpdateLayerList;
QStringList wfstInsertLayerList;
1 change: 1 addition & 0 deletions src/mapserver/qgsconfigparser.h
Original file line number Diff line number Diff line change
@@ -125,6 +125,7 @@ class QgsConfigParser

/**Returns service address (or empty string if not defined in the configuration*/
virtual QString serviceUrl() const { return QString(); }
virtual QString wfsServiceUrl() const { return QString(); }

QColor selectionColor() const { return mSelectionColor; }
void setSelectionColor( const QColor& c ) { mSelectionColor = c; }
62 changes: 50 additions & 12 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Diff line number Diff line change
@@ -677,22 +677,39 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
featListUrlFormatElem.appendChild( featListUrlFormatText );
featListUrlElem.appendChild( featListUrlFormatElem );

QDomNodeList getCapNodeList = doc.elementsByTagName( "GetCapabilities" );
if ( getCapNodeList.count() > 0 )
QString hrefString = wfsServiceUrl();
if ( hrefString.isEmpty() )
{
QDomElement getCapElem = getCapNodeList.at( 0 ).toElement();
QDomNodeList getCapORNodeList = getCapElem.elementsByTagName( "OnlineResource" );
if ( getCapORNodeList.count() > 0 )
hrefString = serviceUrl();
}
if ( hrefString.isEmpty() )
{
QDomNodeList getCapNodeList = doc.elementsByTagName( "GetCapabilities" );
if ( getCapNodeList.count() > 0 )
{
QString getCapUrl = getCapORNodeList.at( 0 ).toElement().attribute( "xlink:href", "" );
QString featListUrl = getCapUrl + "SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=" + currentLayer->name() + "&OUPUTFORMAT=GML2";
QDomElement featListUrlORElem = doc.createElement( "OnlineResource" );
featListUrlORElem.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
featListUrlORElem.setAttribute( "xlink:type", "simple" );
featListUrlORElem.setAttribute( "xlink:href", featListUrl );
featListUrlElem.appendChild( featListUrlORElem );
QDomElement getCapElem = getCapNodeList.at( 0 ).toElement();
QDomNodeList getCapORNodeList = getCapElem.elementsByTagName( "OnlineResource" );
if ( getCapORNodeList.count() > 0 )
{
hrefString = getCapORNodeList.at( 0 ).toElement().attribute( "xlink:href", "" );
}
}
}
if ( !hrefString.isEmpty() )
{
QUrl mapUrl( hrefString );
mapUrl.addQueryItem( "SERVICE", "WFS" );
mapUrl.addQueryItem( "VERSION", "1.0.0" );
mapUrl.addQueryItem( "REQUEST", "GetFeature" );
mapUrl.addQueryItem( "TYPENAME", currentLayer->name() );
mapUrl.addQueryItem( "OUTPUTFORMAT", "GML2" );
hrefString = mapUrl.toString();
QDomElement featListUrlORElem = doc.createElement( "OnlineResource" );
featListUrlORElem.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
featListUrlORElem.setAttribute( "xlink:type", "simple" );
featListUrlORElem.setAttribute( "xlink:href", hrefString );
featListUrlElem.appendChild( featListUrlORElem );
}

layerElem.appendChild( featListUrlElem );
}
@@ -2200,6 +2217,27 @@ QString QgsProjectParser::serviceUrl() const
return url;
}

QString QgsProjectParser::wfsServiceUrl() const
{
QString url;

if ( !mXMLDoc )
{
return url;
}

QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( !propertiesElem.isNull() )
{
QDomElement wfsUrlElem = propertiesElem.firstChildElement( "WFSUrl" );
if ( !wfsUrlElem.isNull() )
{
url = wfsUrlElem.text();
}
}
return url;
}

QStringList QgsProjectParser::wfsLayerNames() const
{
QStringList layerNameList;
2 changes: 2 additions & 0 deletions src/mapserver/qgsprojectparser.h
Original file line number Diff line number Diff line change
@@ -113,6 +113,8 @@ class QgsProjectParser: public QgsConfigParser

QString serviceUrl() const;

QString wfsServiceUrl() const;

/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
QStringList wfsLayerNames() const;

147 changes: 71 additions & 76 deletions src/mapserver/qgswfsserver.cpp
Original file line number Diff line number Diff line change
@@ -117,65 +117,21 @@ QDomDocument QgsWFSServer::getCapabilities()
getCapabilitiesElement.appendChild( dcpTypeElement );
QDomElement httpElement = doc.createElement( "HTTP"/*wfs:HTTP*/ );
dcpTypeElement.appendChild( httpElement );

//Prepare url
//Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable
QString hrefString;
QString requestUrl = getenv( "REQUEST_URI" );
QUrl mapUrl( requestUrl );
mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) );

//Add non-default ports to url
QString portString = getenv( "SERVER_PORT" );
if ( !portString.isEmpty() )
{
bool portOk;
int portNumber = portString.toInt( &portOk );
if ( portOk )
{
if ( portNumber != 80 )
{
mapUrl.setPort( portNumber );
}
}
}

if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
QString hrefString = mConfigParser->wfsServiceUrl();
if ( hrefString.isEmpty() )
{
mapUrl.setScheme( "https" );
hrefString = mConfigParser->serviceUrl();
}
else
if ( hrefString.isEmpty() )
{
mapUrl.setScheme( "http" );
hrefString = serviceUrl();
}

QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
{
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "VERSION", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "SERVICE", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
}
hrefString = mapUrl.toString();

//only Get supported for the moment
QDomElement getElement = doc.createElement( "Get"/*wfs:Get*/ );
httpElement.appendChild( getElement );
requestUrl.truncate( requestUrl.indexOf( "?" ) + 1 );
getElement.setAttribute( "onlineResource", hrefString );
QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( "Post" );
@@ -1025,35 +981,18 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
else
{
//Prepare url
//Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable
QString hrefString;
QString requestUrl = getenv( "REQUEST_URI" );
QUrl mapUrl( requestUrl );
mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) );

//Add non-default ports to url
QString portString = getenv( "SERVER_PORT" );
if ( !portString.isEmpty() )
{
bool portOk;
int portNumber = portString.toInt( &portOk );
if ( portOk )
{
if ( portNumber != 80 )
{
mapUrl.setPort( portNumber );
}
}
}

if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
QString hrefString = mConfigParser->wfsServiceUrl();
if ( hrefString.isEmpty() )
{
mapUrl.setScheme( "https" );
hrefString = mConfigParser->serviceUrl();
}
else
if ( hrefString.isEmpty() )
{
mapUrl.setScheme( "http" );
hrefString = serviceUrl();
}
QUrl mapUrl( hrefString );
mapUrl.addQueryItem( "SERVICE", "WFS" );
mapUrl.addQueryItem( "VERSION", "1.0.0" );

QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
@@ -1062,7 +1001,6 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
mapUrl.addQueryItem( queryIt->first, "DescribeFeatureType" );
}
else if ( queryIt->first.compare( "FORMAT", Qt::CaseInsensitive ) == 0 )
{
@@ -1088,6 +1026,10 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "EXP_FILTER", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "MAXFEATURES", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
@@ -1101,6 +1043,7 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
mapUrl.removeQueryItem( queryIt->first );
}
}
mapUrl.addQueryItem( "REQUEST", "DescribeFeatureType" );
mapUrl.addQueryItem( "TYPENAME", mTypeNames.join( "," ) );
mapUrl.addQueryItem( "OUTPUTFORMAT", "XMLSCHEMA" );
hrefString = mapUrl.toString();
@@ -1804,3 +1747,55 @@ QDomElement QgsWFSServer::createFeatureGML3( QgsFeature* feat, QDomDocument& doc
return featureElement;
}

QString QgsWFSServer::serviceUrl() const
{
QUrl mapUrl( getenv( "REQUEST_URI" ) );
mapUrl.setHost( getenv( "SERVER_NAME" ) );

//Add non-default ports to url
QString portString = getenv( "SERVER_PORT" );
if ( !portString.isEmpty() )
{
bool portOk;
int portNumber = portString.toInt( &portOk );
if ( portOk )
{
if ( portNumber != 80 )
{
mapUrl.setPort( portNumber );
}
}
}

if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
{
mapUrl.setScheme( "https" );
}
else
{
mapUrl.setScheme( "http" );
}

QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
{
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "VERSION", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "SERVICE", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
}
return mapUrl.toString();
}
3 changes: 3 additions & 0 deletions src/mapserver/qgswfsserver.h
Original file line number Diff line number Diff line change
@@ -81,6 +81,9 @@ class QgsWFSServer
/**Don't use the default constructor*/
QgsWFSServer();

/**Get service address from REQUEST_URI if not specified in the configuration*/
QString serviceUrl() const;

/**Map containing the WMS parameters*/
QMap<QString, QString> mParameterMap;
QgsConfigParser* mConfigParser;
14 changes: 14 additions & 0 deletions src/ui/qgsprojectpropertiesbase.ui
Original file line number Diff line number Diff line change
@@ -1864,6 +1864,20 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="mWFSUrlLabel">
<property name="text">
<string>Advertised URL</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mWFSUrlLineEdit"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>

0 comments on commit ca86153

Please sign in to comment.