Skip to content

Commit ca86153

Browse files
committed
Advertised WFS URL
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.
1 parent d841ccf commit ca86153

File tree

7 files changed

+143
-88
lines changed

7 files changed

+143
-88
lines changed

src/app/qgsprojectproperties.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
347347
mMaxHeightLineEdit->setText( QString::number( maxHeight ) );
348348
}
349349

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

744+
QgsProject::instance()->writeEntry( "WFSUrl", "/", mWFSUrlLineEdit->text() );
743745
QStringList wfsLayerList;
744746
QStringList wfstUpdateLayerList;
745747
QStringList wfstInsertLayerList;

src/mapserver/qgsconfigparser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class QgsConfigParser
125125

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

129130
QColor selectionColor() const { return mSelectionColor; }
130131
void setSelectionColor( const QColor& c ) { mSelectionColor = c; }

src/mapserver/qgsprojectparser.cpp

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -677,22 +677,39 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
677677
featListUrlFormatElem.appendChild( featListUrlFormatText );
678678
featListUrlElem.appendChild( featListUrlFormatElem );
679679

680-
QDomNodeList getCapNodeList = doc.elementsByTagName( "GetCapabilities" );
681-
if ( getCapNodeList.count() > 0 )
680+
QString hrefString = wfsServiceUrl();
681+
if ( hrefString.isEmpty() )
682682
{
683-
QDomElement getCapElem = getCapNodeList.at( 0 ).toElement();
684-
QDomNodeList getCapORNodeList = getCapElem.elementsByTagName( "OnlineResource" );
685-
if ( getCapORNodeList.count() > 0 )
683+
hrefString = serviceUrl();
684+
}
685+
if ( hrefString.isEmpty() )
686+
{
687+
QDomNodeList getCapNodeList = doc.elementsByTagName( "GetCapabilities" );
688+
if ( getCapNodeList.count() > 0 )
686689
{
687-
QString getCapUrl = getCapORNodeList.at( 0 ).toElement().attribute( "xlink:href", "" );
688-
QString featListUrl = getCapUrl + "SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=" + currentLayer->name() + "&OUPUTFORMAT=GML2";
689-
QDomElement featListUrlORElem = doc.createElement( "OnlineResource" );
690-
featListUrlORElem.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
691-
featListUrlORElem.setAttribute( "xlink:type", "simple" );
692-
featListUrlORElem.setAttribute( "xlink:href", featListUrl );
693-
featListUrlElem.appendChild( featListUrlORElem );
690+
QDomElement getCapElem = getCapNodeList.at( 0 ).toElement();
691+
QDomNodeList getCapORNodeList = getCapElem.elementsByTagName( "OnlineResource" );
692+
if ( getCapORNodeList.count() > 0 )
693+
{
694+
hrefString = getCapORNodeList.at( 0 ).toElement().attribute( "xlink:href", "" );
695+
}
694696
}
695697
}
698+
if ( !hrefString.isEmpty() )
699+
{
700+
QUrl mapUrl( hrefString );
701+
mapUrl.addQueryItem( "SERVICE", "WFS" );
702+
mapUrl.addQueryItem( "VERSION", "1.0.0" );
703+
mapUrl.addQueryItem( "REQUEST", "GetFeature" );
704+
mapUrl.addQueryItem( "TYPENAME", currentLayer->name() );
705+
mapUrl.addQueryItem( "OUTPUTFORMAT", "GML2" );
706+
hrefString = mapUrl.toString();
707+
QDomElement featListUrlORElem = doc.createElement( "OnlineResource" );
708+
featListUrlORElem.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
709+
featListUrlORElem.setAttribute( "xlink:type", "simple" );
710+
featListUrlORElem.setAttribute( "xlink:href", hrefString );
711+
featListUrlElem.appendChild( featListUrlORElem );
712+
}
696713

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

2220+
QString QgsProjectParser::wfsServiceUrl() const
2221+
{
2222+
QString url;
2223+
2224+
if ( !mXMLDoc )
2225+
{
2226+
return url;
2227+
}
2228+
2229+
QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
2230+
if ( !propertiesElem.isNull() )
2231+
{
2232+
QDomElement wfsUrlElem = propertiesElem.firstChildElement( "WFSUrl" );
2233+
if ( !wfsUrlElem.isNull() )
2234+
{
2235+
url = wfsUrlElem.text();
2236+
}
2237+
}
2238+
return url;
2239+
}
2240+
22032241
QStringList QgsProjectParser::wfsLayerNames() const
22042242
{
22052243
QStringList layerNameList;

src/mapserver/qgsprojectparser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class QgsProjectParser: public QgsConfigParser
113113

114114
QString serviceUrl() const;
115115

116+
QString wfsServiceUrl() const;
117+
116118
/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
117119
QStringList wfsLayerNames() const;
118120

src/mapserver/qgswfsserver.cpp

Lines changed: 71 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -117,65 +117,21 @@ QDomDocument QgsWFSServer::getCapabilities()
117117
getCapabilitiesElement.appendChild( dcpTypeElement );
118118
QDomElement httpElement = doc.createElement( "HTTP"/*wfs:HTTP*/ );
119119
dcpTypeElement.appendChild( httpElement );
120-
120+
121121
//Prepare url
122-
//Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable
123-
QString hrefString;
124-
QString requestUrl = getenv( "REQUEST_URI" );
125-
QUrl mapUrl( requestUrl );
126-
mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) );
127-
128-
//Add non-default ports to url
129-
QString portString = getenv( "SERVER_PORT" );
130-
if ( !portString.isEmpty() )
131-
{
132-
bool portOk;
133-
int portNumber = portString.toInt( &portOk );
134-
if ( portOk )
135-
{
136-
if ( portNumber != 80 )
137-
{
138-
mapUrl.setPort( portNumber );
139-
}
140-
}
141-
}
142-
143-
if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
122+
QString hrefString = mConfigParser->wfsServiceUrl();
123+
if ( hrefString.isEmpty() )
144124
{
145-
mapUrl.setScheme( "https" );
125+
hrefString = mConfigParser->serviceUrl();
146126
}
147-
else
127+
if ( hrefString.isEmpty() )
148128
{
149-
mapUrl.setScheme( "http" );
129+
hrefString = serviceUrl();
150130
}
151131

152-
QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
153-
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
154-
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
155-
{
156-
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
157-
{
158-
mapUrl.removeQueryItem( queryIt->first );
159-
}
160-
else if ( queryIt->first.compare( "VERSION", Qt::CaseInsensitive ) == 0 )
161-
{
162-
mapUrl.removeQueryItem( queryIt->first );
163-
}
164-
else if ( queryIt->first.compare( "SERVICE", Qt::CaseInsensitive ) == 0 )
165-
{
166-
mapUrl.removeQueryItem( queryIt->first );
167-
}
168-
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
169-
{
170-
mapUrl.removeQueryItem( queryIt->first );
171-
}
172-
}
173-
hrefString = mapUrl.toString();
174-
175132
//only Get supported for the moment
176133
QDomElement getElement = doc.createElement( "Get"/*wfs:Get*/ );
177134
httpElement.appendChild( getElement );
178-
requestUrl.truncate( requestUrl.indexOf( "?" ) + 1 );
179135
getElement.setAttribute( "onlineResource", hrefString );
180136
QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
181137
getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( "Post" );
@@ -1025,35 +981,18 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
1025981
else
1026982
{
1027983
//Prepare url
1028-
//Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable
1029-
QString hrefString;
1030-
QString requestUrl = getenv( "REQUEST_URI" );
1031-
QUrl mapUrl( requestUrl );
1032-
mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) );
1033-
1034-
//Add non-default ports to url
1035-
QString portString = getenv( "SERVER_PORT" );
1036-
if ( !portString.isEmpty() )
1037-
{
1038-
bool portOk;
1039-
int portNumber = portString.toInt( &portOk );
1040-
if ( portOk )
1041-
{
1042-
if ( portNumber != 80 )
1043-
{
1044-
mapUrl.setPort( portNumber );
1045-
}
1046-
}
1047-
}
1048-
1049-
if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
984+
QString hrefString = mConfigParser->wfsServiceUrl();
985+
if ( hrefString.isEmpty() )
1050986
{
1051-
mapUrl.setScheme( "https" );
987+
hrefString = mConfigParser->serviceUrl();
1052988
}
1053-
else
989+
if ( hrefString.isEmpty() )
1054990
{
1055-
mapUrl.setScheme( "http" );
991+
hrefString = serviceUrl();
1056992
}
993+
QUrl mapUrl( hrefString );
994+
mapUrl.addQueryItem( "SERVICE", "WFS" );
995+
mapUrl.addQueryItem( "VERSION", "1.0.0" );
1057996

1058997
QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
1059998
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
@@ -1062,7 +1001,6 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
10621001
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
10631002
{
10641003
mapUrl.removeQueryItem( queryIt->first );
1065-
mapUrl.addQueryItem( queryIt->first, "DescribeFeatureType" );
10661004
}
10671005
else if ( queryIt->first.compare( "FORMAT", Qt::CaseInsensitive ) == 0 )
10681006
{
@@ -1088,6 +1026,10 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
10881026
{
10891027
mapUrl.removeQueryItem( queryIt->first );
10901028
}
1029+
else if ( queryIt->first.compare( "EXP_FILTER", Qt::CaseInsensitive ) == 0 )
1030+
{
1031+
mapUrl.removeQueryItem( queryIt->first );
1032+
}
10911033
else if ( queryIt->first.compare( "MAXFEATURES", Qt::CaseInsensitive ) == 0 )
10921034
{
10931035
mapUrl.removeQueryItem( queryIt->first );
@@ -1101,6 +1043,7 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
11011043
mapUrl.removeQueryItem( queryIt->first );
11021044
}
11031045
}
1046+
mapUrl.addQueryItem( "REQUEST", "DescribeFeatureType" );
11041047
mapUrl.addQueryItem( "TYPENAME", mTypeNames.join( "," ) );
11051048
mapUrl.addQueryItem( "OUTPUTFORMAT", "XMLSCHEMA" );
11061049
hrefString = mapUrl.toString();
@@ -1804,3 +1747,55 @@ QDomElement QgsWFSServer::createFeatureGML3( QgsFeature* feat, QDomDocument& doc
18041747
return featureElement;
18051748
}
18061749

1750+
QString QgsWFSServer::serviceUrl() const
1751+
{
1752+
QUrl mapUrl( getenv( "REQUEST_URI" ) );
1753+
mapUrl.setHost( getenv( "SERVER_NAME" ) );
1754+
1755+
//Add non-default ports to url
1756+
QString portString = getenv( "SERVER_PORT" );
1757+
if ( !portString.isEmpty() )
1758+
{
1759+
bool portOk;
1760+
int portNumber = portString.toInt( &portOk );
1761+
if ( portOk )
1762+
{
1763+
if ( portNumber != 80 )
1764+
{
1765+
mapUrl.setPort( portNumber );
1766+
}
1767+
}
1768+
}
1769+
1770+
if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
1771+
{
1772+
mapUrl.setScheme( "https" );
1773+
}
1774+
else
1775+
{
1776+
mapUrl.setScheme( "http" );
1777+
}
1778+
1779+
QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
1780+
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
1781+
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
1782+
{
1783+
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
1784+
{
1785+
mapUrl.removeQueryItem( queryIt->first );
1786+
}
1787+
else if ( queryIt->first.compare( "VERSION", Qt::CaseInsensitive ) == 0 )
1788+
{
1789+
mapUrl.removeQueryItem( queryIt->first );
1790+
}
1791+
else if ( queryIt->first.compare( "SERVICE", Qt::CaseInsensitive ) == 0 )
1792+
{
1793+
mapUrl.removeQueryItem( queryIt->first );
1794+
}
1795+
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
1796+
{
1797+
mapUrl.removeQueryItem( queryIt->first );
1798+
}
1799+
}
1800+
return mapUrl.toString();
1801+
}

src/mapserver/qgswfsserver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class QgsWFSServer
8181
/**Don't use the default constructor*/
8282
QgsWFSServer();
8383

84+
/**Get service address from REQUEST_URI if not specified in the configuration*/
85+
QString serviceUrl() const;
86+
8487
/**Map containing the WMS parameters*/
8588
QMap<QString, QString> mParameterMap;
8689
QgsConfigParser* mConfigParser;

src/ui/qgsprojectpropertiesbase.ui

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,20 @@
18641864
</property>
18651865
</widget>
18661866
</item>
1867+
<item row="3" column="0" colspan="2">
1868+
<layout class="QHBoxLayout" name="horizontalLayout_3">
1869+
<item>
1870+
<widget class="QLabel" name="mWFSUrlLabel">
1871+
<property name="text">
1872+
<string>Advertised URL</string>
1873+
</property>
1874+
</widget>
1875+
</item>
1876+
<item>
1877+
<widget class="QLineEdit" name="mWFSUrlLineEdit"/>
1878+
</item>
1879+
</layout>
1880+
</item>
18671881
</layout>
18681882
</widget>
18691883
</item>

0 commit comments

Comments
 (0)