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.
  • Loading branch information
rldhont committed May 30, 2013
1 parent d841ccf commit ca86153
Show file tree
Hide file tree
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
Expand Up @@ -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" );
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/mapserver/qgsconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
62 changes: 50 additions & 12 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/mapserver/qgsprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
147 changes: 71 additions & 76 deletions src/mapserver/qgswfsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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" );
Expand Down Expand Up @@ -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();
Expand All @@ -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 )
{
Expand All @@ -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 );
Expand All @@ -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();
Expand Down Expand Up @@ -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
Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions src/ui/qgsprojectpropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit ca86153

Please sign in to comment.