Skip to content

Commit c034a4d

Browse files
committedDec 16, 2013
Merge pull request #1025 from rldhont/wcs
[FEATURE][QGIS-Server] Add Web Coverage Service support : funded Ifremer
2 parents b192f64 + 2573cc2 commit c034a4d

11 files changed

+952
-1
lines changed
 

‎src/mapserver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SET ( qgis_mapserv_SRCS
2626
qgssldparser.cpp
2727
qgswmsserver.cpp
2828
qgswfsserver.cpp
29+
qgswcsserver.cpp
2930
qgsmapserviceexception.cpp
3031
qgsmslayercache.cpp
3132
qgsfilter.cpp

‎src/mapserver/qgis_map_serv.cpp

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ map service syntax for SOAP/HTTP POST
2727
#include "qgslogger.h"
2828
#include "qgswmsserver.h"
2929
#include "qgswfsserver.h"
30+
#include "qgswcsserver.h"
3031
#include "qgsmaprenderer.h"
3132
#include "qgsmapserviceexception.h"
3233
#include "qgspallabeling.h"
@@ -348,7 +349,99 @@ int main( int argc, char * argv[] )
348349
}
349350

350351
QgsWMSServer* theServer = 0;
351-
if ( serviceString == "WFS" )
352+
if ( serviceString == "WCS" )
353+
{
354+
delete theServer;
355+
QgsWCSServer* theServer = 0;
356+
try
357+
{
358+
theServer = new QgsWCSServer( parameterMap );
359+
}
360+
catch ( QgsMapServiceException e ) //admin.sld may be invalid
361+
{
362+
theRequestHandler->sendServiceException( e );
363+
continue;
364+
}
365+
366+
theServer->setAdminConfigParser( adminConfigParser );
367+
368+
369+
//request type
370+
QString request = parameterMap.value( "REQUEST" );
371+
if ( request.isEmpty() )
372+
{
373+
//do some error handling
374+
QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
375+
theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
376+
delete theRequestHandler;
377+
delete theServer;
378+
continue;
379+
}
380+
381+
if ( request.compare( "GetCapabilities", Qt::CaseInsensitive ) == 0 )
382+
{
383+
QDomDocument capabilitiesDocument;
384+
try
385+
{
386+
capabilitiesDocument = theServer->getCapabilities();
387+
}
388+
catch ( QgsMapServiceException& ex )
389+
{
390+
theRequestHandler->sendServiceException( ex );
391+
delete theRequestHandler;
392+
delete theServer;
393+
continue;
394+
}
395+
QgsDebugMsg( "sending GetCapabilities response" );
396+
theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument );
397+
delete theRequestHandler;
398+
delete theServer;
399+
continue;
400+
}
401+
else if ( request.compare( "DescribeCoverage", Qt::CaseInsensitive ) == 0 )
402+
{
403+
QDomDocument describeDocument;
404+
try
405+
{
406+
describeDocument = theServer->describeCoverage();
407+
}
408+
catch ( QgsMapServiceException& ex )
409+
{
410+
theRequestHandler->sendServiceException( ex );
411+
delete theRequestHandler;
412+
delete theServer;
413+
continue;
414+
}
415+
QgsDebugMsg( "sending GetCapabilities response" );
416+
theRequestHandler->sendGetCapabilitiesResponse( describeDocument );
417+
delete theRequestHandler;
418+
delete theServer;
419+
continue;
420+
}
421+
else if ( request.compare( "GetCoverage", Qt::CaseInsensitive ) == 0 )
422+
{
423+
QByteArray* coverageOutput;
424+
try
425+
{
426+
coverageOutput = theServer->getCoverage();
427+
}
428+
catch ( QgsMapServiceException& ex )
429+
{
430+
theRequestHandler->sendServiceException( ex );
431+
delete theRequestHandler;
432+
delete theServer;
433+
continue;
434+
}
435+
if ( coverageOutput )
436+
{
437+
theRequestHandler->sendGetCoverageResponse( coverageOutput );
438+
}
439+
delete theRequestHandler;
440+
delete theServer;
441+
continue;
442+
}
443+
}
444+
else if ( serviceString == "WFS" )
352445
{
353446
delete theServer;
354447
QgsWFSServer* theServer = 0;

‎src/mapserver/qgsconfigparser.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,19 @@ class QgsConfigParser
4949

5050
virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const = 0;
5151

52+
virtual void wcsContentMetadata( QDomElement& parentElement, QDomDocument& doc ) const = 0;
53+
5254
virtual void owsGeneralAndResourceList( QDomElement& parentElement, QDomDocument& doc, const QString& strHref ) const = 0;
5355

5456
virtual void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const = 0;
57+
58+
virtual void describeCoverage( const QString& aCoveName, QDomElement& parentElement, QDomDocument& doc ) const = 0;
5559
/**Returns one or possibly several maplayers for a given type name. If no layers are found, an empty list is returned*/
5660
virtual QList<QgsMapLayer*> mapLayerFromTypeName( const QString& tName, bool useCache = true ) const = 0;
5761

62+
/**Returns one or possibly several maplayers for a given type name. If no layers are found, an empty list is returned*/
63+
virtual QList<QgsMapLayer*> mapLayerFromCoverage( const QString& cName, bool useCache = true ) const = 0;
64+
5865
/**Returns one or possibly several maplayers for a given layer name and style. If there are several layers, the layers should be drawn in inverse list order.
5966
If no layers/style are found, an empty list is returned
6067
@param allowCache true if layer can be read from / written to cache*/

‎src/mapserver/qgshttprequesthandler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,11 @@ void QgsHttpRequestHandler::endGetFeatureResponse( QByteArray* ba ) const
362362
fwrite( ba->data(), ba->size(), 1, FCGI_stdout );
363363
}
364364

365+
void QgsHttpRequestHandler::sendGetCoverageResponse( QByteArray* ba ) const
366+
{
367+
sendHttpResponse( ba, "image/tiff" );
368+
}
369+
365370
void QgsHttpRequestHandler::requestStringToParameterMap( const QString& request, QMap<QString, QString>& parameters )
366371
{
367372
parameters.clear();

‎src/mapserver/qgshttprequesthandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class QgsHttpRequestHandler: public QgsRequestHandler
4242
virtual bool startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) const;
4343
virtual void sendGetFeatureResponse( QByteArray* ba ) const;
4444
virtual void endGetFeatureResponse( QByteArray* ba ) const;
45+
virtual void sendGetCoverageResponse( QByteArray* ba ) const;
4546

4647
protected:
4748
void sendHttpResponse( QByteArray* ba, const QString& format ) const;

‎src/mapserver/qgsprojectparser.cpp

Lines changed: 396 additions & 0 deletions
Large diffs are not rendered by default.

‎src/mapserver/qgsprojectparser.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,19 @@ class QgsProjectParser: public QgsConfigParser
4545

4646
virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const;
4747

48+
virtual void wcsContentMetadata( QDomElement& parentElement, QDomDocument& doc ) const;
49+
4850
virtual void owsGeneralAndResourceList( QDomElement& parentElement, QDomDocument& doc, const QString& strHref ) const;
4951

5052
virtual void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const;
53+
54+
virtual void describeCoverage( const QString& aCoveName, QDomElement& parentElement, QDomDocument& doc ) const;
5155
/**Returns one or possibly several maplayers for a given type name. If no layers/style are found, an empty list is returned*/
5256
virtual QList<QgsMapLayer*> mapLayerFromTypeName( const QString& tName, bool useCache = true ) const;
5357

58+
/**Returns one or possibly several maplayers for a given type name. If no layers/style are found, an empty list is returned*/
59+
virtual QList<QgsMapLayer*> mapLayerFromCoverage( const QString& cName, bool useCache = true ) const;
60+
5461
int numberOfLayers() const;
5562

5663
/**Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/
@@ -274,6 +281,10 @@ class QgsProjectParser: public QgsConfigParser
274281
* This is for WFS Services
275282
**/
276283
void serviceWFSCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
284+
/**Reads service metadata from projectfile or falls back to parent class method if not there
285+
* This is for WCS Services
286+
**/
287+
void serviceWCSCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
277288
};
278289

279290
#endif // QGSPROJECTPARSER_H

‎src/mapserver/qgsrequesthandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class QgsRequestHandler
4444
virtual bool startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) const = 0;
4545
virtual void sendGetFeatureResponse( QByteArray* ba ) const = 0;
4646
virtual void endGetFeatureResponse( QByteArray* ba ) const = 0;
47+
virtual void sendGetCoverageResponse( QByteArray* ba ) const = 0;
4748
QString format() const { return mFormat; }
4849
protected:
4950
/**This is set by the parseInput methods of the subclasses (parameter FORMAT, e.g. 'FORMAT=PNG')*/

‎src/mapserver/qgssldparser.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,19 @@ class QgsSLDParser: public QgsConfigParser
5050

5151
void featureTypeList( QDomElement&, QDomDocument& ) const {}
5252

53+
void wcsContentMetadata( QDomElement&, QDomDocument& ) const {}
54+
5355
void owsGeneralAndResourceList( QDomElement&, QDomDocument& , const QString& ) const {}
5456

5557
void describeFeatureType( const QString& , QDomElement& , QDomDocument& ) const {}
58+
59+
void describeCoverage( const QString& , QDomElement& , QDomDocument& ) const {}
5660
/**Returns one or possibly several maplayers for a given type name. If no layers/style are found, an empty list is returned*/
5761
QList<QgsMapLayer*> mapLayerFromTypeName( const QString&, bool ) const { QList<QgsMapLayer*> layerList; return layerList; }
5862

63+
/**Returns one or possibly several maplayers for a given type name. If no layers/style are found, an empty list is returned*/
64+
QList<QgsMapLayer*> mapLayerFromCoverage( const QString&, bool ) const { QList<QgsMapLayer*> layerList; return layerList; }
65+
5966
/**Returns number of layers in configuration*/
6067
int numberOfLayers() const;
6168

‎src/mapserver/qgswcsserver.cpp

Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
/***************************************************************************
2+
qgswcsserver.cpp
3+
-------------------
4+
begin : December 9, 2013
5+
copyright : (C) 2013 by René-Luc D'Hont
6+
email : rldhont at 3liz dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
#include "qgswcsserver.h"
18+
#include "qgsconfigparser.h"
19+
#include "qgscrscache.h"
20+
#include "qgsrasterlayer.h"
21+
#include "qgsrasterpipe.h"
22+
#include "qgsrasterprojector.h"
23+
#include "qgsrasterfilewriter.h"
24+
#include "qgslogger.h"
25+
#include "qgsmapserviceexception.h"
26+
27+
#include <QUrl>
28+
29+
#ifndef Q_WS_WIN
30+
#include <netinet/in.h>
31+
#else
32+
#include <winsock.h>
33+
#endif
34+
35+
static const QString WCS_NAMESPACE = "http://www.opengis.net/wcs";
36+
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
37+
static const QString OGC_NAMESPACE = "http://www.opengis.net/ogc";
38+
39+
QgsWCSServer::QgsWCSServer( QMap<QString, QString> parameters )
40+
: mParameterMap( parameters )
41+
, mConfigParser( 0 )
42+
{
43+
}
44+
45+
QgsWCSServer::~QgsWCSServer()
46+
{
47+
}
48+
49+
QgsWCSServer::QgsWCSServer()
50+
{
51+
}
52+
53+
QDomDocument QgsWCSServer::getCapabilities()
54+
{
55+
QgsDebugMsg( "Entering." );
56+
QDomDocument doc;
57+
//wcs:WCS_Capabilities element
58+
QDomElement wcsCapabilitiesElement = doc.createElement( "WCS_Capabilities"/*wcs:WCS_Capabilities*/ );
59+
wcsCapabilitiesElement.setAttribute( "xmlns", WCS_NAMESPACE );
60+
wcsCapabilitiesElement.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
61+
wcsCapabilitiesElement.setAttribute( "xsi:schemaLocation", WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
62+
wcsCapabilitiesElement.setAttribute( "xmlns:gml", GML_NAMESPACE );
63+
wcsCapabilitiesElement.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
64+
wcsCapabilitiesElement.setAttribute( "version", "1.0.0" );
65+
wcsCapabilitiesElement.setAttribute( "updateSequence", "0" );
66+
doc.appendChild( wcsCapabilitiesElement );
67+
68+
if ( mConfigParser )
69+
{
70+
mConfigParser->serviceCapabilities( wcsCapabilitiesElement, doc );
71+
}
72+
73+
//INSERT Service
74+
75+
//wcs:Capability element
76+
QDomElement capabilityElement = doc.createElement( "Capability"/*wcs:Capability*/ );
77+
wcsCapabilitiesElement.appendChild( capabilityElement );
78+
79+
//wcs:Request element
80+
QDomElement requestElement = doc.createElement( "Request"/*wcs:Request*/ );
81+
capabilityElement.appendChild( requestElement );
82+
83+
//wcs:GetCapabilities
84+
QDomElement getCapabilitiesElement = doc.createElement( "GetCapabilities"/*wcs:GetCapabilities*/ );
85+
requestElement.appendChild( getCapabilitiesElement );
86+
87+
QDomElement dcpTypeElement = doc.createElement( "DCPType"/*wcs:DCPType*/ );
88+
getCapabilitiesElement.appendChild( dcpTypeElement );
89+
QDomElement httpElement = doc.createElement( "HTTP"/*wcs:HTTP*/ );
90+
dcpTypeElement.appendChild( httpElement );
91+
92+
//Prepare url
93+
QString hrefString = mConfigParser->wfsServiceUrl();
94+
if ( hrefString.isEmpty() )
95+
{
96+
hrefString = mConfigParser->serviceUrl();
97+
}
98+
if ( hrefString.isEmpty() )
99+
{
100+
hrefString = serviceUrl();
101+
}
102+
103+
QDomElement getElement = doc.createElement( "Get"/*wcs:Get*/ );
104+
httpElement.appendChild( getElement );
105+
QDomElement onlineResourceElement = doc.createElement( "OnlineResource"/*wcs:OnlineResource*/ );
106+
onlineResourceElement.setAttribute( "xlink:type", "simple" );
107+
onlineResourceElement.setAttribute( "xlink:href", hrefString );
108+
getElement.appendChild( onlineResourceElement );
109+
110+
QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
111+
getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( "Post" );
112+
getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );
113+
114+
QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
115+
describeCoverageElement.setTagName( "DescribeCoverage" );
116+
requestElement.appendChild( describeCoverageElement );
117+
118+
QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
119+
getCoverageElement.setTagName( "GetCoverage" );
120+
requestElement.appendChild( getCoverageElement );
121+
122+
/*
123+
* Adding layer list in ContentMetadata
124+
*/
125+
QDomElement contentMetadataElement = doc.createElement( "ContentMetadata"/*wcs:ContentMetadata*/ );
126+
wcsCapabilitiesElement.appendChild( contentMetadataElement );
127+
/*
128+
* Adding layer liste in contentMetadataElement
129+
*/
130+
if ( mConfigParser )
131+
{
132+
mConfigParser->wcsContentMetadata( contentMetadataElement, doc );
133+
}
134+
135+
return doc;
136+
}
137+
138+
QDomDocument QgsWCSServer::describeCoverage()
139+
{
140+
QgsDebugMsg( "Entering." );
141+
QDomDocument doc;
142+
//wcs:WCS_Capabilities element
143+
QDomElement coveDescElement = doc.createElement( "CoverageDescription"/*wcs:CoverageDescription*/ );
144+
coveDescElement.setAttribute( "xmlns", WCS_NAMESPACE );
145+
coveDescElement.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
146+
coveDescElement.setAttribute( "xsi:schemaLocation", WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" );
147+
coveDescElement.setAttribute( "xmlns:gml", GML_NAMESPACE );
148+
coveDescElement.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
149+
coveDescElement.setAttribute( "version", "1.0.0" );
150+
coveDescElement.setAttribute( "updateSequence", "0" );
151+
doc.appendChild( coveDescElement );
152+
153+
//defining coverage name
154+
QString coveName = "";
155+
//read COVERAGE
156+
QMap<QString, QString>::const_iterator cove_name_it = mParameterMap.find( "COVERAGE" );
157+
if ( cove_name_it != mParameterMap.end() )
158+
{
159+
coveName = cove_name_it.value();
160+
}
161+
if ( coveName == "" ) {
162+
QMap<QString, QString>::const_iterator cove_name_it = mParameterMap.find( "IDENTIFIER" );
163+
if ( cove_name_it != mParameterMap.end() )
164+
{
165+
coveName = cove_name_it.value();
166+
}
167+
}
168+
mConfigParser->describeCoverage( coveName, coveDescElement, doc );
169+
return doc;
170+
}
171+
172+
QByteArray* QgsWCSServer::getCoverage()
173+
{
174+
QList<QgsMapLayer*> layerList;
175+
176+
QStringList mErrors = QStringList();
177+
178+
//defining coverage name
179+
QString coveName = "";
180+
//read COVERAGE
181+
QMap<QString, QString>::const_iterator cove_name_it = mParameterMap.find( "COVERAGE" );
182+
if ( cove_name_it != mParameterMap.end() )
183+
{
184+
coveName = cove_name_it.value();
185+
}
186+
if ( coveName == "" ) {
187+
QMap<QString, QString>::const_iterator cove_name_it = mParameterMap.find( "IDENTIFIER" );
188+
if ( cove_name_it != mParameterMap.end() )
189+
{
190+
coveName = cove_name_it.value();
191+
}
192+
}
193+
194+
if ( coveName == "" ) {
195+
mErrors << QString( "COVERAGE is mandatory" );
196+
}
197+
198+
layerList = mConfigParser->mapLayerFromCoverage( coveName );
199+
if ( layerList.size() < 1 )
200+
{
201+
mErrors << QString( "The layer for the COVERAGE '%1' is not found" ).arg( coveName );
202+
}
203+
204+
bool conversionSuccess;
205+
// BBOX
206+
bool bboxOk = false;
207+
double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
208+
// WIDTh and HEIGHT
209+
int width = 0, height = 0;
210+
// CRS
211+
QString crs = "";
212+
213+
// read BBOX
214+
QMap<QString, QString>::const_iterator bbIt = mParameterMap.find( "BBOX" );
215+
if ( bbIt == mParameterMap.end() )
216+
{
217+
minx = 0; miny = 0; maxx = 0; maxy = 0;
218+
}
219+
else
220+
{
221+
bboxOk = true;
222+
QString bbString = bbIt.value();
223+
minx = bbString.section( ",", 0, 0 ).toDouble( &conversionSuccess );
224+
if ( !conversionSuccess ) {bboxOk = false;}
225+
miny = bbString.section( ",", 1, 1 ).toDouble( &conversionSuccess );
226+
if ( !conversionSuccess ) {bboxOk = false;}
227+
maxx = bbString.section( ",", 2, 2 ).toDouble( &conversionSuccess );
228+
if ( !conversionSuccess ) {bboxOk = false;}
229+
maxy = bbString.section( ",", 3, 3 ).toDouble( &conversionSuccess );
230+
if ( !conversionSuccess ) {bboxOk = false;}
231+
}
232+
if ( !bboxOk )
233+
{
234+
mErrors << QString( "The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy" );
235+
}
236+
237+
// read WIDTH
238+
width = mParameterMap.value( "WIDTH", "0" ).toInt( &conversionSuccess );
239+
if ( !conversionSuccess )
240+
width = 0;
241+
// read HEIGHT
242+
height = mParameterMap.value( "HEIGHT", "0" ).toInt( &conversionSuccess );
243+
if ( !conversionSuccess )
244+
{
245+
height = 0;
246+
}
247+
248+
if ( width < 0 || height < 0 )
249+
{
250+
mErrors << QString( "The WIDTH and HEIGHT are mandatory and have to be integer" );
251+
}
252+
253+
crs = mParameterMap.value( "CRS", "" );
254+
if ( crs == "" )
255+
{
256+
mErrors << QString( "The CRS is mandatory" );
257+
}
258+
QgsCoordinateReferenceSystem outputCRS = QgsCRSCache::instance()->crsByAuthId( crs );
259+
if ( !outputCRS.isValid() )
260+
{
261+
mErrors << QString( "Could not create output CRS" );
262+
}
263+
264+
if ( mErrors.count() != 0 )
265+
{
266+
throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
267+
}
268+
269+
QgsRectangle rect( minx, miny, maxx, maxy );
270+
271+
QgsMapLayer* layer = layerList.at( 0 );
272+
QgsRasterLayer* rLayer = dynamic_cast<QgsRasterLayer*>( layer );
273+
if ( rLayer ) {
274+
QTemporaryFile tempFile;
275+
tempFile.open();
276+
QgsRasterFileWriter fileWriter( tempFile.fileName() );
277+
278+
// clone pipe/provider
279+
QgsRasterPipe* pipe = new QgsRasterPipe();
280+
if ( !pipe->set( rLayer->dataProvider()->clone() ) )
281+
{
282+
mErrors << QString( "Cannot set pipe provider" );
283+
throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
284+
}
285+
286+
// add projector if necessary
287+
if ( outputCRS != rLayer->crs() )
288+
{
289+
QgsRasterProjector * projector = new QgsRasterProjector;
290+
projector->setCRS( rLayer->crs(), outputCRS );
291+
if ( !pipe->insert( 2, projector ) )
292+
{
293+
mErrors << QString( "Cannot set pipe projector" );
294+
throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
295+
}
296+
}
297+
298+
QgsRasterFileWriter::WriterError err = fileWriter.writeRaster( pipe, width, height, rect, outputCRS );
299+
if ( err != QgsRasterFileWriter::NoError )
300+
{
301+
mErrors << QString( "Cannot write raster error code: %1" ).arg( err );
302+
throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
303+
}
304+
delete pipe;
305+
QByteArray* ba = 0;
306+
ba = new QByteArray();
307+
*ba = tempFile.readAll();
308+
309+
return ba;
310+
}
311+
return 0;
312+
}
313+
314+
QString QgsWCSServer::serviceUrl() const
315+
{
316+
QUrl mapUrl( getenv( "REQUEST_URI" ) );
317+
mapUrl.setHost( getenv( "SERVER_NAME" ) );
318+
319+
//Add non-default ports to url
320+
QString portString = getenv( "SERVER_PORT" );
321+
if ( !portString.isEmpty() )
322+
{
323+
bool portOk;
324+
int portNumber = portString.toInt( &portOk );
325+
if ( portOk )
326+
{
327+
if ( portNumber != 80 )
328+
{
329+
mapUrl.setPort( portNumber );
330+
}
331+
}
332+
}
333+
334+
if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
335+
{
336+
mapUrl.setScheme( "https" );
337+
}
338+
else
339+
{
340+
mapUrl.setScheme( "http" );
341+
}
342+
343+
QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
344+
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
345+
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
346+
{
347+
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
348+
{
349+
mapUrl.removeQueryItem( queryIt->first );
350+
}
351+
else if ( queryIt->first.compare( "VERSION", Qt::CaseInsensitive ) == 0 )
352+
{
353+
mapUrl.removeQueryItem( queryIt->first );
354+
}
355+
else if ( queryIt->first.compare( "SERVICE", Qt::CaseInsensitive ) == 0 )
356+
{
357+
mapUrl.removeQueryItem( queryIt->first );
358+
}
359+
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
360+
{
361+
mapUrl.removeQueryItem( queryIt->first );
362+
}
363+
}
364+
return mapUrl.toString();
365+
}

‎src/mapserver/qgswcsserver.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/***************************************************************************
2+
qgswcsserver.h
3+
-------------------
4+
begin : December 9, 2013
5+
copyright : (C) 2013 by René-Luc D'Hont
6+
email : rldhont at 3liz dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSWCSSERVER_H
19+
#define QGSWCSSERVER_H
20+
21+
#include <QDomDocument>
22+
#include <QMap>
23+
#include <QString>
24+
#include <map>
25+
#include "qgis.h"
26+
27+
class QgsConfigParser;
28+
class QgsRequestHandler;
29+
30+
/**This class handles all the wcs server requests. The parameters and values have to be passed in the form of
31+
a map<QString, QString>. This map is usually generated by a subclass of QgsWMSRequestHandler, which makes QgsWCSServer
32+
independent from any server side technology*/
33+
34+
class QgsWCSServer
35+
{
36+
public:
37+
/**Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
38+
QgsWCSServer( QMap<QString, QString> parameters );
39+
~QgsWCSServer();
40+
/**Returns an XML file with the capabilities description (as described in the WFS specs)*/
41+
QDomDocument getCapabilities();
42+
43+
/**Returns an XML file with the describe Coverage (as described in the WCS specs)*/
44+
QDomDocument describeCoverage();
45+
46+
/**Creates a file which is the result of the getCoverage request.*/
47+
QByteArray* getCoverage();
48+
49+
/**Sets configuration parser for administration settings. Does not take ownership*/
50+
void setAdminConfigParser( QgsConfigParser* parser ) { mConfigParser = parser; }
51+
52+
private:
53+
/**Don't use the default constructor*/
54+
QgsWCSServer();
55+
56+
/**Get service address from REQUEST_URI if not specified in the configuration*/
57+
QString serviceUrl() const;
58+
59+
/**Map containing the WMS parameters*/
60+
QMap<QString, QString> mParameterMap;
61+
QgsConfigParser* mConfigParser;
62+
};
63+
64+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.