Skip to content

Commit 003f833

Browse files
committedSep 21, 2012
Merge branch 'master' of github.com:qgis/Quantum-GIS
2 parents 6ac8792 + dd36727 commit 003f833

File tree

11 files changed

+269
-161
lines changed

11 files changed

+269
-161
lines changed
 

‎doc/index.dox

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,21 @@ fixes, bug reports, contributed documentation, advocacy and supporting other
1919
users on our mailing lists and forums. Financial contributions are also
2020
welcome.
2121

22-
\section index_APIStability API Stability
22+
\section index_APIStability Earlier versions of the API
2323

24-
Versions of QGIS prior to 1.0 did not guarantee API stability since the
25-
application was undergoing rapid development of new features and we did not
26-
want to commit ourselves to a fixed API. With the release of QGIS 1.0 we
27-
guarantee a backwards compatible API for the 1.x and 1.0.x release series. 1.x
28-
releases will be our 'unstable' development builds and 1.0.x releases our
29-
'stable' (bugfixes and very minor tweaks only).
24+
Earlier version of the documentation are also available on the Quantum GIS
25+
website:
26+
27+
<ul>
28+
<li><a href="http://qgis.org/api/1.8">1.8</a>
29+
<li><a href="http://qgis.org/api/1.7">1.7</a>
30+
<li><a href="http://qgis.org/api/1.6">1.6</a>
31+
</ul>
3032

3133
\section index_maillist Mailing Lists
3234
<ul>
3335
<li>For support we encourage you to join our <a
34-
href="http://qgis.osgeo.org/community/mailing-lists.html">mailing lists</a> for
36+
href="http://qgis.org/en/community/mailing-lists.html">mailing lists</a> for
3537
developers.</li> </ul>
3638

3739
\section index_bugs Bug Reporting

‎src/mapserver/qgsconfigparser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class QgsConfigParser
4444

4545
virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const = 0;
4646

47+
virtual void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const = 0;
48+
4749
/**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.
4850
If no layers/style are found, an empty list is returned
4951
@param allowCache true if layer can be read from / written to cache*/

‎src/mapserver/qgsprojectparser.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "qgsrasterlayer.h"
2626
#include "qgsrenderer.h"
2727
#include "qgsvectorlayer.h"
28+
#include "qgsvectordataprovider.h"
2829

2930
#include "qgscomposition.h"
3031
#include "qgscomposerarrow.h"
@@ -206,6 +207,151 @@ void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument
206207
return;
207208
}
208209

210+
void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const
211+
{
212+
if ( mProjectLayerElements.size() < 1 )
213+
{
214+
return;
215+
}
216+
217+
QStringList wfsLayersId = wfsLayers();
218+
QMap< QString, QMap< int, QString > > aliasInfo = layerAliasInfo();
219+
QMap< QString, QSet<QString> > hiddenAttrs = hiddenAttributes();
220+
221+
foreach( const QDomElement &elem, mProjectLayerElements )
222+
{
223+
QString type = elem.attribute( "type" );
224+
if ( type == "vector" )
225+
{
226+
QgsMapLayer *mLayer = createLayerFromElement( elem );
227+
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( mLayer );
228+
if ( layer && wfsLayersId.contains( layer->id() ) && ( aTypeName == "" || layer->name() == aTypeName ) )
229+
{
230+
//do a select with searchRect and go through all the features
231+
QgsVectorDataProvider* provider = layer->dataProvider();
232+
if ( !provider )
233+
{
234+
continue;
235+
}
236+
237+
//is there alias info for this vector layer?
238+
QMap< int, QString > layerAliasInfo;
239+
QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( mLayer->id() );
240+
if ( aliasIt != aliasInfo.constEnd() )
241+
{
242+
layerAliasInfo = aliasIt.value();
243+
}
244+
245+
//hidden attributes for this layer
246+
QSet<QString> layerHiddenAttributes;
247+
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttrs.find( mLayer->id() );
248+
if ( hiddenIt != hiddenAttrs.constEnd() )
249+
{
250+
layerHiddenAttributes = hiddenIt.value();
251+
}
252+
253+
QString typeName = layer->name();
254+
typeName = typeName.replace( QString( " " ), QString( "_" ) );
255+
256+
//xsd:element
257+
QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ );
258+
elementElem.setAttribute( "name", typeName );
259+
elementElem.setAttribute( "type", "qgs:" + typeName + "Type" );
260+
elementElem.setAttribute( "substitutionGroup", "gml:_Feature" );
261+
parentElement.appendChild( elementElem );
262+
263+
//xsd:complexType
264+
QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ );
265+
complexTypeElem.setAttribute( "name", typeName + "Type" );
266+
parentElement.appendChild( complexTypeElem );
267+
268+
//xsd:complexType
269+
QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ );
270+
complexTypeElem.appendChild( complexContentElem );
271+
272+
//xsd:extension
273+
QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ );
274+
extensionElem.setAttribute( "base", "gml:AbstractFeatureType" );
275+
complexContentElem.appendChild( extensionElem );
276+
277+
//xsd:sequence
278+
QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ );
279+
extensionElem.appendChild( sequenceElem );
280+
281+
//xsd:element
282+
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
283+
geomElem.setAttribute( "name", "geometry" );
284+
QGis::WkbType wkbType = layer->wkbType();
285+
switch ( wkbType )
286+
{
287+
case QGis::WKBPoint25D:
288+
case QGis::WKBPoint:
289+
geomElem.setAttribute( "type", "gml:PointPropertyType" );
290+
break;
291+
case QGis::WKBLineString25D:
292+
case QGis::WKBLineString:
293+
geomElem.setAttribute( "type", "gml:LineStringPropertyType" );
294+
break;
295+
case QGis::WKBPolygon25D:
296+
case QGis::WKBPolygon:
297+
geomElem.setAttribute( "type", "gml:PolygonPropertyType" );
298+
break;
299+
case QGis::WKBMultiPoint25D:
300+
case QGis::WKBMultiPoint:
301+
geomElem.setAttribute( "type", "gml:MultiPointPropertyType" );
302+
break;
303+
case QGis::WKBMultiLineString25D:
304+
case QGis::WKBMultiLineString:
305+
geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" );
306+
break;
307+
case QGis::WKBMultiPolygon25D:
308+
case QGis::WKBMultiPolygon:
309+
geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" );
310+
break;
311+
default:
312+
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
313+
break;
314+
}
315+
geomElem.setAttribute( "minOccurs", "0" );
316+
geomElem.setAttribute( "maxOccurs", "1" );
317+
sequenceElem.appendChild( geomElem );
318+
319+
const QgsFieldMap& fields = provider->fields();
320+
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
321+
{
322+
323+
QString attributeName = it.value().name();
324+
//skip attribute if it has edit type 'hidden'
325+
if ( layerHiddenAttributes.contains( attributeName ) )
326+
{
327+
continue;
328+
}
329+
330+
//xsd:element
331+
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
332+
geomElem.setAttribute( "name", attributeName );
333+
if ( it.value().type() == 2 )
334+
geomElem.setAttribute( "type", "integer" );
335+
else if ( it.value().type() == 6 )
336+
geomElem.setAttribute( "type", "double" );
337+
else
338+
geomElem.setAttribute( "type", "string" );
339+
340+
sequenceElem.appendChild( geomElem );
341+
342+
//check if the attribute name should be replaced with an alias
343+
QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() );
344+
if ( aliasIt != layerAliasInfo.constEnd() )
345+
{
346+
geomElem.setAttribute( "alias", aliasIt.value() );
347+
}
348+
}
349+
}
350+
}
351+
}
352+
return;
353+
}
354+
209355
void QgsProjectParser::addLayers( QDomDocument &doc,
210356
QDomElement &parentElem,
211357
const QDomElement &legendElem,

‎src/mapserver/qgsprojectparser.h

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

4141
virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const;
4242

43+
virtual void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const;
44+
4345
int numberOfLayers() const;
4446

4547
/**Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/

‎src/mapserver/qgssldparser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class QgsSLDParser: public QgsConfigParser
5757
void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
5858

5959
void featureTypeList( QDomElement &, QDomDocument & ) const {};
60+
61+
void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const {};
6062

6163
/**Returns number of layers in configuration*/
6264
int numberOfLayers() const;

‎src/mapserver/qgswfsserver.cpp

Lines changed: 2 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -262,143 +262,9 @@ QDomDocument QgsWFSServer::describeFeatureType()
262262
}
263263
else
264264
{
265-
return doc;
265+
typeName = "";
266266
}
267-
268-
QStringList wfsLayersId = mConfigParser->wfsLayers();
269-
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo();
270-
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes();
271-
272-
QList<QgsMapLayer*> layerList;
273-
QgsMapLayer* currentLayer = 0;
274-
275-
layerList = mConfigParser->mapLayerFromStyle( typeName, "" );
276-
currentLayer = layerList.at( 0 );
277-
278-
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( currentLayer );
279-
if ( layer && wfsLayersId.contains( layer->id() ) )
280-
{
281-
//is there alias info for this vector layer?
282-
QMap< int, QString > layerAliasInfo;
283-
QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() );
284-
if ( aliasIt != aliasInfo.constEnd() )
285-
{
286-
layerAliasInfo = aliasIt.value();
287-
}
288-
289-
//hidden attributes for this layer
290-
QSet<QString> layerHiddenAttributes;
291-
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() );
292-
if ( hiddenIt != hiddenAttributes.constEnd() )
293-
{
294-
layerHiddenAttributes = hiddenIt.value();
295-
}
296-
297-
//do a select with searchRect and go through all the features
298-
QgsVectorDataProvider* provider = layer->dataProvider();
299-
if ( !provider )
300-
{
301-
return doc;
302-
}
303-
304-
typeName = typeName.replace( QString( " " ), QString( "_" ) );
305-
306-
//xsd:element
307-
QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ );
308-
elementElem.setAttribute( "name", typeName );
309-
elementElem.setAttribute( "type", "qgs:" + typeName + "Type" );
310-
elementElem.setAttribute( "substitutionGroup", "gml:_Feature" );
311-
schemaElement.appendChild( elementElem );
312-
313-
//xsd:complexType
314-
QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ );
315-
complexTypeElem.setAttribute( "name", typeName + "Type" );
316-
schemaElement.appendChild( complexTypeElem );
317-
318-
//xsd:complexType
319-
QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ );
320-
complexTypeElem.appendChild( complexContentElem );
321-
322-
//xsd:extension
323-
QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ );
324-
extensionElem.setAttribute( "base", "gml:AbstractFeatureType" );
325-
complexContentElem.appendChild( extensionElem );
326-
327-
//xsd:sequence
328-
QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ );
329-
extensionElem.appendChild( sequenceElem );
330-
331-
//xsd:element
332-
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
333-
geomElem.setAttribute( "name", "geometry" );
334-
QGis::WkbType wkbType = layer->wkbType();
335-
switch ( wkbType )
336-
{
337-
case QGis::WKBPoint25D:
338-
case QGis::WKBPoint:
339-
geomElem.setAttribute( "type", "gml:PointPropertyType" );
340-
break;
341-
case QGis::WKBLineString25D:
342-
case QGis::WKBLineString:
343-
geomElem.setAttribute( "type", "gml:LineStringPropertyType" );
344-
break;
345-
case QGis::WKBPolygon25D:
346-
case QGis::WKBPolygon:
347-
geomElem.setAttribute( "type", "gml:PolygonPropertyType" );
348-
break;
349-
case QGis::WKBMultiPoint25D:
350-
case QGis::WKBMultiPoint:
351-
geomElem.setAttribute( "type", "gml:MultiPointPropertyType" );
352-
break;
353-
case QGis::WKBMultiLineString25D:
354-
case QGis::WKBMultiLineString:
355-
geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" );
356-
break;
357-
case QGis::WKBMultiPolygon25D:
358-
case QGis::WKBMultiPolygon:
359-
geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" );
360-
break;
361-
default:
362-
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
363-
break;
364-
}
365-
geomElem.setAttribute( "minOccurs", "0" );
366-
geomElem.setAttribute( "maxOccurs", "1" );
367-
sequenceElem.appendChild( geomElem );
368-
369-
const QgsFieldMap& fields = provider->fields();
370-
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
371-
{
372-
373-
QString attributeName = it.value().name();
374-
//skip attribute if it has edit type 'hidden'
375-
if ( layerHiddenAttributes.contains( attributeName ) )
376-
{
377-
continue;
378-
}
379-
380-
//xsd:element
381-
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
382-
geomElem.setAttribute( "name", attributeName );
383-
if ( it.value().type() == 2 )
384-
geomElem.setAttribute( "type", "integer" );
385-
else if ( it.value().type() == 6 )
386-
geomElem.setAttribute( "type", "double" );
387-
else
388-
geomElem.setAttribute( "type", "string" );
389-
390-
sequenceElem.appendChild( geomElem );
391-
392-
//check if the attribute name should be replaced with an alias
393-
QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() );
394-
if ( aliasIt != layerAliasInfo.constEnd() )
395-
{
396-
geomElem.setAttribute( "alias", aliasIt.value() );
397-
}
398-
399-
}
400-
}
401-
267+
mConfigParser->describeFeatureType( typeName, schemaElement, doc);
402268
return doc;
403269
}
404270

‎src/providers/grass/qgis.d.rast.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <stdio.h>
2929
#include <string.h>
3030
#include <math.h>
31+
#include <assert.h>
3132
#ifdef WIN32
3233
#include <fcntl.h>
3334
#include <io.h>
@@ -36,6 +37,12 @@
3637
#include <grass/raster.h>
3738
#include <grass/display.h>
3839

40+
#ifdef _MSC_VER
41+
#include <float.h>
42+
#define INFINITY (DBL_MAX+DBL_MAX)
43+
#define NAN (INFINITY-INFINITY)
44+
#endif
45+
3946
int display( char *name, char *mapset, RASTER_MAP_TYPE data_type, char *format );
4047

4148
int main( int argc, char **argv )
@@ -151,6 +158,9 @@ static int cell_draw( char *name,
151158
// and 0./0. if all fails
152159
#endif
153160

161+
assert( dnul != dnul );
162+
assert( fnul != fnul );
163+
154164
big_endian = !( *(( char * )( &one ) ) );
155165

156166
ncols = G_window_cols();

‎src/providers/wcs/qgswcscapabilities.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ bool QgsWcsCapabilities::retrieveServerCapabilities( )
229229
// We prefer 1.0 because 1.1 has many issues, each server implements it in defferent
230230
// way with various particularities
231231
// It may happen that server supports 1.1.0 but gives error for 1.1
232-
versions << "VERSION=1.0.0" << "AcceptVersions=1.1.0,1.0.0";
232+
versions << "1.0.0" << "1.1.0,1.0.0";
233233
}
234234

235235
foreach ( QString v, versions )

‎tests/src/providers/testqgswcspublicservers.cpp

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <QObject>
1919
#include <QPainter>
2020
#include <QSet>
21+
#include <QSettings>
2122
#include <QString>
2223
#include <QStringList>
2324
#include <QTextStream>
@@ -56,16 +57,29 @@ TestQgsWcsPublicServers::TestQgsWcsPublicServers( const QString & cacheDirPath,
5657
, mCoverage( coverage )
5758
, mVersion( version )
5859
, mForce( force )
60+
, mTimeout( 60000 )
5961
{
6062

6163
}
6264

65+
TestQgsWcsPublicServers::~TestQgsWcsPublicServers()
66+
{
67+
QSettings settings;
68+
settings.setValue( "/qgis/networkAndProxy/networkTimeout", mOrigTimeout );
69+
}
70+
6371
//runs before all tests
6472
void TestQgsWcsPublicServers::init()
6573
{
6674
// init QGIS's paths - true means that all path will be inited from prefix
6775
QgsDebugMsg( "Entered" );
6876

77+
// Unfortunately this seems to be the only way to set timeout, we try to reset it
78+
// at the end but it can be canceled before ...
79+
QSettings settings;
80+
mOrigTimeout = settings.value( "/qgis/networkAndProxy/networkTimeout", "20000" ).toInt();
81+
settings.setValue( "/qgis/networkAndProxy/networkTimeout", mTimeout );
82+
6983
//mCacheDir = QDir( "./wcstestcache" );
7084
mCacheDir = QDir( mCacheDirPath );
7185
if ( !mCacheDir.exists() )
@@ -79,21 +93,24 @@ void TestQgsWcsPublicServers::init()
7993
}
8094

8195
mHead << "Coverage";
82-
mHead << "Has size";
8396

8497
QStringList providers;
8598
providers << "wcs" << "gdal";
8699
foreach ( QString provider, providers )
87100
{
88101
QString prefix = provider == "gdal" ? "GDAL " : "";
89102
mHead << prefix + "CRS";
103+
mHead << prefix + "Width";
104+
mHead << prefix + "Height";
105+
mHead << prefix + "Extent";
90106
mHead << prefix + "Snap";
91107
mHead << prefix + "Bands";
92108
mHead << prefix + "Type";
93109
mHead << prefix + "Min";
94110
mHead << prefix + "Max";
95111
mHead << prefix + "Values";
96112
mHead << prefix + "Colors";
113+
mHead << prefix + "Time (s)";
97114
}
98115

99116
// read servers + issues list
@@ -379,6 +396,8 @@ void TestQgsWcsPublicServers::test( )
379396

380397
foreach ( QString provider, providers )
381398
{
399+
QTime time;
400+
time.start();
382401
QString uri;
383402
if ( provider == "wcs" )
384403
{
@@ -394,7 +413,7 @@ void TestQgsWcsPublicServers::test( )
394413
myStream << " <ServiceURL>" + serverUrl + "?" + "</ServiceURL>\n";
395414
myStream << " <CoverageName>" + myCoverage.identifier + "</CoverageName>\n";
396415
myStream << " <Version>" + version + "</Version>\n";
397-
myStream << " <Timeout>60</Version>\n";
416+
myStream << QString( " <Timeout>%1</Timeout>\n" ).arg( mTimeout / 1000., 0, 'd' ) ;
398417
myStream << "</WCS_GDAL>\n";
399418

400419
myGdalXmlFile.close();
@@ -404,6 +423,14 @@ void TestQgsWcsPublicServers::test( )
404423
if ( myLayer->isValid() )
405424
{
406425
myLog << provider + "_crs:" + myLayer->dataProvider()->crs().authid();
426+
myLog << provider + "_width:" + QString::number( myLayer->dataProvider()->xSize() );
427+
myLog << provider + "_height:" + QString::number( myLayer->dataProvider()->ySize() );
428+
QgsRectangle extent = myLayer->dataProvider()->extent();
429+
myLog << provider + "_extent:"
430+
+ QgsRasterInterface::printValue( extent.xMinimum() ) + ","
431+
+ QgsRasterInterface::printValue( extent.yMinimum() ) + ","
432+
+ QgsRasterInterface::printValue( extent.xMaximum() ) + ","
433+
+ QgsRasterInterface::printValue( extent.yMaximum() ) + ",";
407434
int myBandCount = myLayer->dataProvider()->bandCount();
408435
myLog << provider + "_bandCount:" + QString::number( myBandCount );
409436
if ( myBandCount > 0 )
@@ -478,6 +505,9 @@ void TestQgsWcsPublicServers::test( )
478505
QgsDebugMsg( "Layer is not valid" );
479506
myLog << provider + "_error:Layer is not valid";
480507
}
508+
myLog << provider + QString( "_time:%1" ).arg( time.elapsed() / 1000., 0, 'f', 2 );
509+
// Generate report for impatient people
510+
report();
481511
}
482512

483513
QFile myLogFile( myLogPath );
@@ -594,29 +624,33 @@ void TestQgsWcsPublicServers::report()
594624

595625
QStringList myValues;
596626
myValues << QString( "<a href='%1'>%2</a>" ).arg( myLog.value( "describeCoverageUrl" ) ).arg( myLog.value( "identifier" ) );
597-
myValues << myLog.value( "hasSize" );
598-
myVersionReport += cells( myValues );
627+
//myValues << myLog.value( "hasSize" );
628+
myVersionReport += cells( myValues, "", 1, 2 );
599629
myValues.clear();
600630

631+
QStringList issues = issueDescriptions( myServerLog.value( "server" ), myLog.value( "identifier" ), myLog.value( "version" ) );
632+
QString issuesString = issues.join( "<br>" );
633+
601634
QStringList providers;
602635
providers << "wcs" << "gdal";
603636

637+
bool hasErr = false;
604638
foreach ( QString provider, providers )
605639
{
606-
607640
QString imgPath = myVersionDir.absolutePath() + QDir::separator() + QFileInfo( myLogPath ).completeBaseName() + "-" + provider + ".png";
608641

642+
609643
if ( !myLog.value( provider + "_error" ).isEmpty() )
610644
{
611645
myValues << myLog.value( provider + "_error" );
612646
int offender = NoOffender;
613647
if ( provider == "wcs" )
614648
{
615-
QStringList issues = issueDescriptions( myServerLog.value( "server" ), myLog.value( "identifier" ), myLog.value( "version" ) );
616-
myValues << issues.join( "<br>" );
649+
myValues << issuesString;;
617650

618651
offender = issueOffender( myServerLog.value( "server" ), myLog.value( "identifier" ), myLog.value( "version" ) );
619652
myVersionErrCount++;
653+
hasErr = true;
620654
}
621655
QString cls;
622656
if ( offender == ServerOffender )
@@ -631,19 +665,23 @@ void TestQgsWcsPublicServers::report()
631665
{
632666
cls = "cell-err";
633667
}
634-
myVersionReport += cells( myValues, cls, 8 );
668+
myVersionReport += cells( myValues, cls, 12 );
635669
myValues.clear();
636670
}
637671
else
638672
{
639673
myValues << myLog.value( provider + "_crs" );
674+
myValues << myLog.value( provider + "_width" );
675+
myValues << myLog.value( provider + "_height" );
676+
myValues << QString( myLog.value( provider + "_extent" ) ).replace( ",", "<br>" );
640677
myValues << "<img src='" + imgPath + "'>";
641678
myValues << myLog.value( provider + "_bandCount" );
642679
myValues << myLog.value( provider + "_srcType" );
643680
myValues << myLog.value( provider + "_min" );
644681
myValues << myLog.value( provider + "_max" );
645682
myValues << myLog.value( provider + "_valuesCount" );
646683
myValues << myLog.value( provider + "_colorsCount" );
684+
myValues << myLog.value( provider + "_time" );
647685

648686
QString cls;
649687
int myValuesCount = myLog.value( provider + "_valuesCount" ).toInt();
@@ -671,6 +709,19 @@ void TestQgsWcsPublicServers::report()
671709
}
672710
}
673711
myVersionReport += "<tr>\n";
712+
QString cls;
713+
if ( !issuesString.isEmpty() && !hasErr )
714+
{
715+
myValues << issuesString;
716+
}
717+
else
718+
{
719+
myValues << "";
720+
cls = "cell-empty";
721+
}
722+
myVersionReport += cells( myValues, cls, 24 );
723+
myValues.clear();
724+
myVersionReport += "</tr>\n";
674725
} // coverages
675726
myVersionReport += "</table>\n";
676727
// prepend counts
@@ -696,7 +747,7 @@ void TestQgsWcsPublicServers::report()
696747
myRep += "<style>";
697748
myRep += ".tab { border-spacing: 0px; border-width: 1px 1px 0 0; border-style: solid; }";
698749
myRep += ".cell { border-width: 0 0 1px 1px; border-style: solid; font-size: smaller; text-align: center}";
699-
//myReport += ".cell-ok { background: #00ff00; }";
750+
myRep += ".cell-empty { border-width: 0; height:0; padding:0 }";
700751
myRep += ".cell-ok { background: #ffffff; }";
701752
myRep += ".cell-warn { background: #ffcc00; }";
702753
myRep += ".cell-err { background: #ff0000; }";
@@ -744,18 +795,22 @@ QString TestQgsWcsPublicServers::error( QString theMessage )
744795
return myRow;
745796
}
746797

747-
QString TestQgsWcsPublicServers::cells( QStringList theValues, QString theClass, int colspan )
798+
QString TestQgsWcsPublicServers::cells( QStringList theValues, QString theClass, int colspan, int rowspan )
748799
{
749800
QString myRow;
750801
for ( int i = 0; i < theValues.size(); i++ )
751802
{
752803
QString val = theValues.value( i );
753-
QString colspanStr;
804+
QString colspanStr, rowspanStr;
754805
if ( colspan > 1 && i == theValues.size() - 1 )
755806
{
756807
colspanStr = QString( "colspan=%1" ).arg( colspan - theValues.size() + 1 ) ;
757808
}
758-
myRow += QString( "<td class='cell %1' %2>%3</td>" ).arg( theClass ).arg( colspanStr ).arg( val );
809+
if ( rowspan > 1 )
810+
{
811+
rowspanStr = QString( "rowspan=%1" ).arg( rowspan ) ;
812+
}
813+
myRow += QString( "<td class='cell %1' %2 %3>%4</td>" ).arg( theClass ).arg( colspanStr ).arg( rowspanStr ).arg( val );
759814
}
760815
return myRow;
761816
}

‎tests/src/providers/testqgswcspublicservers.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ class TestQgsWcsPublicServers: public QObject
5959

6060
TestQgsWcsPublicServers( const QString & cacheDirPath, int maxCoverages, const QString & server = QString(), const QString & coverage = QString(), const QString &version = QString(), bool force = false );
6161

62+
~TestQgsWcsPublicServers();
63+
6264
void init();
6365
void test();
6466
void report();
6567
private:
66-
QString cells( QStringList theValues, QString theClass = QString(), int colspan = 1 );
68+
QString cells( QStringList theValues, QString theClass = QString(), int colspan = 1, int rowspan = 1 );
6769
QString row( QStringList theValues, QString theClass = QString() );
6870
QString error( QString theMessage );
6971
void writeReport( QString theReport );
@@ -94,4 +96,7 @@ class TestQgsWcsPublicServers: public QObject
9496
QStringList mHead;
9597

9698
QList<TestQgsWcsPublicServers::Server> mServers;
99+
100+
int mTimeout;
101+
int mOrigTimeout;
97102
};

‎tests/src/providers/wcs-servers.json

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
[
22
{
33
url: 'http://demo.opengeo.org/geoserver/wcs',
4-
description: 'Does not work at all with gvSIG-1_11-1305-final.',
4+
description: 'It does not work at all with gvSIG-1_11-1305-final. The Coverage usgs:ned is quite slow and it can fail even with timeout 60s',
55
issues: [
66
{
77
offender: 'server',
88
coverages: [ 'og:0' ],
99
versions: [ '1.0.0' ],
1010
description: 'The server fails in DescribeCoverage with: java.io.IOException null Translator error Unexpected error occurred during describe coverage xml encoding ...'
11+
},{
12+
offender: 'server',
13+
coverages: [ 'topp:bluemarble', 'topp:bm' ],
14+
versions: [ '1.0.0' ],
15+
description: "The extent in DescribeCoverage spatialDomain.Envelope is wrong: -187.272,-187.272,187.272,187.272. QGIS does not correct it (we don't know where the limits really are) while GDAL probably cuts longitude for EPSG:4326 to +/-90."
16+
},{
17+
offender: 'server',
18+
coverages: [ 'usgs:ned' ],
19+
versions: [ '1.0.0' ],
20+
description: "The Coverage usgs:ned is very slow and it can fail even with timeout 60s, but even with timeout 300s it usually fails to render. It was seen to rendered in QGIS however."
1121
},{
1222
offender: 'server',
1323
coverages: [ 'bm' ],
@@ -17,7 +27,7 @@
1727
offender: 'server',
1828
coverages: [ 'usgs:nlcd', 'nlcd' ],
1929
versions: [ '1.0.0', '1.1.0' ],
20-
description: 'The server does no offer any CRS in DescribeCoverage supportedCRSs / supportedCRS. QGIS tries to get coverage using EPSG:5070, in which the coverage spatialDomain.Envelope is defined, but server fails reporting error: Could not recognize crs ...'
30+
description: 'The server does not offer any CRS in DescribeCoverage supportedCRSs / supportedCRS. QGIS tries to get coverage using EPSG:5070, in which the coverage spatialDomain.Envelope is defined, but server fails reporting error: Could not recognize crs ...'
2131
},{
2232
offender: 'server',
2333
coverages: [ '0', 'naturalearth' ],
@@ -33,7 +43,15 @@
3343
}, {
3444
url: 'http://demo.geonode.org/geoserver/wcs'
3545
}, {
36-
url: 'http://demo.mapserver.org/cgi-bin/wcs'
46+
url: 'http://demo.mapserver.org/cgi-bin/wcs',
47+
issues: [
48+
{
49+
offender: 'server',
50+
coverages: [ 'modis-001' ],
51+
versions: [ '1.0.0' ],
52+
description: "The server DescribeCoverage advertises temporalDomain.timePosition 2002-001, but GetCoverages fails with 'msWCSGetCoverage(): WCS server error. Underlying layer is not tiled, unable to do temporal subsetting.' if TIME=2002-001 is used."
53+
}
54+
]
3755
}, {
3856
// Some (first) coverages do not advertise any supportedCRS and sever gives
3957
// error both with native CRS (EPSG::561005) and EPSG:4326

0 commit comments

Comments
 (0)
Please sign in to comment.