mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-18 00:04:02 -04:00
Merge branch 'master' of github.com:qgis/Quantum-GIS
This commit is contained in:
commit
caa342b763
@ -4226,10 +4226,10 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
{
|
{
|
||||||
mWkt += "{ \"type\": \"Point\", \"coordinates\": [";
|
mWkt += "{ \"type\": \"Point\", \"coordinates\": [";
|
||||||
x = ( double * )( mGeometry + 5 );
|
x = ( double * )( mGeometry + 5 );
|
||||||
mWkt += QString::number( *x, 'f', 6 );
|
mWkt += QString::number( *x, 'f' );
|
||||||
mWkt += ", ";
|
mWkt += ", ";
|
||||||
y = ( double * )( mGeometry + 5 + sizeof( double ) );
|
y = ( double * )( mGeometry + 5 + sizeof( double ) );
|
||||||
mWkt += QString::number( *y, 'f', 6 );
|
mWkt += QString::number( *y, 'f' );
|
||||||
mWkt += "] }";
|
mWkt += "] }";
|
||||||
return mWkt;
|
return mWkt;
|
||||||
}
|
}
|
||||||
@ -4256,11 +4256,11 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
}
|
}
|
||||||
mWkt += "[";
|
mWkt += "[";
|
||||||
x = ( double * ) ptr;
|
x = ( double * ) ptr;
|
||||||
mWkt += QString::number( *x, 'f', 6 );
|
mWkt += QString::number( *x, 'f' );
|
||||||
mWkt += ", ";
|
mWkt += ", ";
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
y = ( double * ) ptr;
|
y = ( double * ) ptr;
|
||||||
mWkt += QString::number( *y, 'f', 6 );
|
mWkt += QString::number( *y, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
if ( hasZValue )
|
if ( hasZValue )
|
||||||
{
|
{
|
||||||
@ -4313,11 +4313,11 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
}
|
}
|
||||||
mWkt += "[";
|
mWkt += "[";
|
||||||
x = ( double * ) ptr;
|
x = ( double * ) ptr;
|
||||||
mWkt += QString::number( *x, 'f', 6 );
|
mWkt += QString::number( *x, 'f' );
|
||||||
mWkt += ", ";
|
mWkt += ", ";
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
y = ( double * ) ptr;
|
y = ( double * ) ptr;
|
||||||
mWkt += QString::number( *y, 'f', 6 );
|
mWkt += QString::number( *y, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
if ( hasZValue )
|
if ( hasZValue )
|
||||||
{
|
{
|
||||||
@ -4353,11 +4353,11 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
}
|
}
|
||||||
mWkt += "[";
|
mWkt += "[";
|
||||||
x = ( double * )( ptr );
|
x = ( double * )( ptr );
|
||||||
mWkt += QString::number( *x, 'f', 6 );
|
mWkt += QString::number( *x, 'f' );
|
||||||
mWkt += ", ";
|
mWkt += ", ";
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
y = ( double * )( ptr );
|
y = ( double * )( ptr );
|
||||||
mWkt += QString::number( *y, 'f', 6 );
|
mWkt += QString::number( *y, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
if ( hasZValue )
|
if ( hasZValue )
|
||||||
{
|
{
|
||||||
@ -4399,11 +4399,11 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
}
|
}
|
||||||
mWkt += "[";
|
mWkt += "[";
|
||||||
x = ( double * ) ptr;
|
x = ( double * ) ptr;
|
||||||
mWkt += QString::number( *x, 'f', 6 );
|
mWkt += QString::number( *x, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
mWkt += ", ";
|
mWkt += ", ";
|
||||||
y = ( double * ) ptr;
|
y = ( double * ) ptr;
|
||||||
mWkt += QString::number( *y, 'f', 6 );
|
mWkt += QString::number( *y, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
if ( hasZValue )
|
if ( hasZValue )
|
||||||
{
|
{
|
||||||
@ -4457,11 +4457,11 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
}
|
}
|
||||||
mWkt += "[";
|
mWkt += "[";
|
||||||
x = ( double * ) ptr;
|
x = ( double * ) ptr;
|
||||||
mWkt += QString::number( *x, 'f', 6 );
|
mWkt += QString::number( *x, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
mWkt += ", ";
|
mWkt += ", ";
|
||||||
y = ( double * ) ptr;
|
y = ( double * ) ptr;
|
||||||
mWkt += QString::number( *y, 'f', 6 );
|
mWkt += QString::number( *y, 'f' );
|
||||||
ptr += sizeof( double );
|
ptr += sizeof( double );
|
||||||
if ( hasZValue )
|
if ( hasZValue )
|
||||||
{
|
{
|
||||||
|
@ -331,7 +331,37 @@ QDomDocument QgsWFSServer::describeFeatureType()
|
|||||||
//xsd:element
|
//xsd:element
|
||||||
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
|
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
|
||||||
geomElem.setAttribute( "name", "geometry" );
|
geomElem.setAttribute( "name", "geometry" );
|
||||||
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
|
QGis::WkbType wkbType = layer->wkbType();
|
||||||
|
switch ( wkbType )
|
||||||
|
{
|
||||||
|
case QGis::WKBPoint25D:
|
||||||
|
case QGis::WKBPoint:
|
||||||
|
geomElem.setAttribute( "type", "gml:PointPropertyType" );
|
||||||
|
break;
|
||||||
|
case QGis::WKBLineString25D:
|
||||||
|
case QGis::WKBLineString:
|
||||||
|
geomElem.setAttribute( "type", "gml:LineStringPropertyType" );
|
||||||
|
break;
|
||||||
|
case QGis::WKBPolygon25D:
|
||||||
|
case QGis::WKBPolygon:
|
||||||
|
geomElem.setAttribute( "type", "gml:PolygonPropertyType" );
|
||||||
|
break;
|
||||||
|
case QGis::WKBMultiPoint25D:
|
||||||
|
case QGis::WKBMultiPoint:
|
||||||
|
geomElem.setAttribute( "type", "gml:MultiPointPropertyType" );
|
||||||
|
break;
|
||||||
|
case QGis::WKBMultiLineString25D:
|
||||||
|
case QGis::WKBMultiLineString:
|
||||||
|
geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" );
|
||||||
|
break;
|
||||||
|
case QGis::WKBMultiPolygon25D:
|
||||||
|
case QGis::WKBMultiPolygon:
|
||||||
|
geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
geomElem.setAttribute( "minOccurs", "0" );
|
geomElem.setAttribute( "minOccurs", "0" );
|
||||||
geomElem.setAttribute( "maxOccurs", "1" );
|
geomElem.setAttribute( "maxOccurs", "1" );
|
||||||
sequenceElem.appendChild( geomElem );
|
sequenceElem.appendChild( geomElem );
|
||||||
@ -543,9 +573,11 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( bboxOk )
|
||||||
|
searchRect.set( minx, miny, maxx, maxy );
|
||||||
QgsCoordinateReferenceSystem layerCrs = layer->crs();
|
QgsCoordinateReferenceSystem layerCrs = layer->crs();
|
||||||
|
|
||||||
startGetFeature( request, format );
|
startGetFeature( request, format, layerCrs, &searchRect );
|
||||||
|
|
||||||
if ( fidOk )
|
if ( fidOk )
|
||||||
{
|
{
|
||||||
@ -589,8 +621,6 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( bboxOk )
|
|
||||||
searchRect.set( minx, miny, maxx, maxy );
|
|
||||||
provider->select( attrIndexes, searchRect, mWithGeom, true );
|
provider->select( attrIndexes, searchRect, mWithGeom, true );
|
||||||
while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
|
while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
|
||||||
{
|
{
|
||||||
@ -608,25 +638,102 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& format )
|
void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect )
|
||||||
{
|
{
|
||||||
QByteArray result;
|
QByteArray result;
|
||||||
QString fcString;
|
QString fcString;
|
||||||
if ( format == "GeoJSON" )
|
if ( format == "GeoJSON" )
|
||||||
{
|
{
|
||||||
fcString = "{\"type\": \"FeatureCollection\",\n";
|
fcString = "{\"type\": \"FeatureCollection\",\n";
|
||||||
|
fcString += " \"bbox\": [ "+ QString::number( rect->xMinimum(), 'f' ) +", "+ QString::number( rect->yMinimum(), 'f' ) +", "+ QString::number( rect->xMaximum(), 'f' ) +", "+ QString::number( rect->yMaximum(), 'f' ) +"],\n";
|
||||||
fcString += " \"features\": [\n";
|
fcString += " \"features\": [\n";
|
||||||
result = fcString.toUtf8();
|
result = fcString.toUtf8();
|
||||||
request.startGetFeatureResponse( &result, format );
|
request.startGetFeatureResponse( &result, format );
|
||||||
}
|
}
|
||||||
else
|
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 )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
mapUrl.addQueryItem( queryIt->first, "DescribeFeatureType" );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "FORMAT", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "OUTPUTFORMAT", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "BBOX", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "FEATUREID", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "FILTER", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "MAXFEATURES", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "PROPERTYNAME", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
mapUrl.removeQueryItem( queryIt->first );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mapUrl.addQueryItem( "OUTPUTFORMAT", "XMLSCHEMA" );
|
||||||
|
hrefString = mapUrl.toString();
|
||||||
|
|
||||||
//wfs:FeatureCollection
|
//wfs:FeatureCollection
|
||||||
fcString = "<wfs:FeatureCollection";
|
fcString = "<wfs:FeatureCollection";
|
||||||
fcString += " xmlns=\"http://www.opengis.net/wfs\"";
|
fcString += " xmlns=\"http://www.opengis.net/wfs\"";
|
||||||
fcString += " xmlns:wfs=\"http://www.opengis.net/wfs\"";
|
fcString += " xmlns:wfs=\"http://www.opengis.net/wfs\"";
|
||||||
fcString += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
|
fcString += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
|
||||||
fcString += " xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd\"";
|
fcString += " xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.opengis.net/gml "+ hrefString.replace( "&", "&" ) +"\"";
|
||||||
fcString += " xmlns:ogc=\"http://www.opengis.net/ogc\"";
|
fcString += " xmlns:ogc=\"http://www.opengis.net/ogc\"";
|
||||||
fcString += " xmlns:gml=\"http://www.opengis.net/gml\"";
|
fcString += " xmlns:gml=\"http://www.opengis.net/gml\"";
|
||||||
fcString += " xmlns:ows=\"http://www.opengis.net/ows\"";
|
fcString += " xmlns:ows=\"http://www.opengis.net/ows\"";
|
||||||
@ -635,6 +742,21 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
|
|||||||
fcString += ">";
|
fcString += ">";
|
||||||
result = fcString.toUtf8();
|
result = fcString.toUtf8();
|
||||||
request.startGetFeatureResponse( &result, format );
|
request.startGetFeatureResponse( &result, format );
|
||||||
|
|
||||||
|
QDomDocument doc;
|
||||||
|
QDomElement bbElem = doc.createElement( "gml:boundedBy" );
|
||||||
|
QDomElement boxElem = createBoxElem( rect, doc );
|
||||||
|
if ( !boxElem.isNull() )
|
||||||
|
{
|
||||||
|
if ( crs.isValid() )
|
||||||
|
{
|
||||||
|
boxElem.setAttribute( "srsName", crs.authid() );
|
||||||
|
}
|
||||||
|
bbElem.appendChild( boxElem );
|
||||||
|
doc.appendChild( bbElem );
|
||||||
|
}
|
||||||
|
result = doc.toByteArray();
|
||||||
|
request.sendGetFeatureResponse( &result );
|
||||||
}
|
}
|
||||||
fcString = "";
|
fcString = "";
|
||||||
}
|
}
|
||||||
@ -701,6 +823,10 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateRefer
|
|||||||
QgsGeometry* geom = feat->geometry();
|
QgsGeometry* geom = feat->geometry();
|
||||||
if ( geom && mWithGeom )
|
if ( geom && mWithGeom )
|
||||||
{
|
{
|
||||||
|
QgsRectangle box = geom->boundingBox();
|
||||||
|
|
||||||
|
fStr += " \"bbox\": [ "+ QString::number( box.xMinimum(), 'f' ) +", "+ QString::number( box.yMinimum(), 'f' ) +", "+ QString::number( box.xMaximum(), 'f' ) +", "+ QString::number( box.yMaximum(), 'f' ) +"],\n";
|
||||||
|
|
||||||
fStr += " \"geometry\": ";
|
fStr += " \"geometry\": ";
|
||||||
fStr += geom->exportToGeoJSON();
|
fStr += geom->exportToGeoJSON();
|
||||||
fStr += ",\n";
|
fStr += ",\n";
|
||||||
@ -759,14 +885,25 @@ QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc
|
|||||||
if ( mWithGeom )
|
if ( mWithGeom )
|
||||||
{
|
{
|
||||||
//add geometry column (as gml)
|
//add geometry column (as gml)
|
||||||
|
QgsGeometry* geom = feat->geometry();
|
||||||
|
|
||||||
QDomElement geomElem = doc.createElement( "qgs:geometry" );
|
QDomElement geomElem = doc.createElement( "qgs:geometry" );
|
||||||
QDomElement gmlElem = createGeometryElem( feat->geometry(), doc );
|
QDomElement gmlElem = createGeometryElem( geom, doc );
|
||||||
if ( !gmlElem.isNull() )
|
if ( !gmlElem.isNull() )
|
||||||
{
|
{
|
||||||
|
QgsRectangle box = geom->boundingBox();
|
||||||
|
QDomElement bbElem = doc.createElement( "gml:boundedBy" );
|
||||||
|
QDomElement boxElem = createBoxElem( &box, doc );
|
||||||
|
|
||||||
if ( crs.isValid() )
|
if ( crs.isValid() )
|
||||||
{
|
{
|
||||||
|
boxElem.setAttribute( "srsName", crs.authid() );
|
||||||
gmlElem.setAttribute( "srsName", crs.authid() );
|
gmlElem.setAttribute( "srsName", crs.authid() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bbElem.appendChild( boxElem );
|
||||||
|
typeNameElement.appendChild( bbElem );
|
||||||
|
|
||||||
geomElem.appendChild( gmlElem );
|
geomElem.appendChild( gmlElem );
|
||||||
typeNameElement.appendChild( geomElem );
|
typeNameElement.appendChild( geomElem );
|
||||||
}
|
}
|
||||||
@ -793,6 +930,27 @@ QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc
|
|||||||
return featureElement;
|
return featureElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDomElement QgsWFSServer::createBoxElem( QgsRectangle* box, QDomDocument& doc ) /*const*/
|
||||||
|
{
|
||||||
|
if ( !box )
|
||||||
|
{
|
||||||
|
return QDomElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomElement boxElem = doc.createElement( "gml:Box" );
|
||||||
|
QVector<QgsPoint> v;
|
||||||
|
QgsPoint p1;
|
||||||
|
p1.set( box->xMinimum(), box->yMinimum() );
|
||||||
|
v.append( p1 );
|
||||||
|
QgsPoint p2;
|
||||||
|
p2.set( box->xMaximum(), box->yMaximum() );
|
||||||
|
v.append( p2 );
|
||||||
|
QDomElement coordElem = createCoordinateElem( v, doc );
|
||||||
|
boxElem.appendChild( coordElem );
|
||||||
|
|
||||||
|
return boxElem;
|
||||||
|
}
|
||||||
|
|
||||||
QDomElement QgsWFSServer::createGeometryElem( QgsGeometry* geom, QDomDocument& doc ) /*const*/
|
QDomElement QgsWFSServer::createGeometryElem( QgsGeometry* geom, QDomDocument& doc ) /*const*/
|
||||||
{
|
{
|
||||||
if ( !geom )
|
if ( !geom )
|
||||||
@ -931,13 +1089,13 @@ QDomElement QgsWFSServer::createPolygonElem( QgsGeometry* geom, QDomDocument& do
|
|||||||
QString boundaryName;
|
QString boundaryName;
|
||||||
if ( i == 0 )
|
if ( i == 0 )
|
||||||
{
|
{
|
||||||
boundaryName = "outerBoundaryIs";
|
boundaryName = "gml:outerBoundaryIs";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boundaryName = "innerBoundaryIs";
|
boundaryName = "gml:innerBoundaryIs";
|
||||||
}
|
}
|
||||||
QDomElement boundaryElem = doc.createElementNS( "http://www.opengis.net/gml", boundaryName );
|
QDomElement boundaryElem = doc.createElement( boundaryName );
|
||||||
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
|
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
|
||||||
QDomElement coordElem = createCoordinateElem( poly.at( i ), doc );
|
QDomElement coordElem = createCoordinateElem( poly.at( i ), doc );
|
||||||
ringElem.appendChild( coordElem );
|
ringElem.appendChild( coordElem );
|
||||||
@ -979,7 +1137,7 @@ QDomElement QgsWFSServer::createCoordinateElem( const QVector<QgsPoint> points,
|
|||||||
coordElem.setAttribute( "ts", " " );
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
|
||||||
//precision 4 for meters / feet, precision 8 for degrees
|
//precision 4 for meters / feet, precision 8 for degrees
|
||||||
int precision = 8;
|
int precision = 6;
|
||||||
/*
|
/*
|
||||||
if ( mSourceCRS.mapUnits() == QGis::Meters
|
if ( mSourceCRS.mapUnits() == QGis::Meters
|
||||||
|| mSourceCRS.mapUnits() == QGis::Feet )
|
|| mSourceCRS.mapUnits() == QGis::Feet )
|
||||||
@ -996,9 +1154,9 @@ QDomElement QgsWFSServer::createCoordinateElem( const QVector<QgsPoint> points,
|
|||||||
{
|
{
|
||||||
coordString += " ";
|
coordString += " ";
|
||||||
}
|
}
|
||||||
coordString += QString::number( pointIt->x(), 'f', precision );
|
coordString += QString::number( pointIt->x(), 'f');
|
||||||
coordString += ",";
|
coordString += ",";
|
||||||
coordString += QString::number( pointIt->y(), 'f', precision );
|
coordString += QString::number( pointIt->y(), 'f' );
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
@ -36,6 +36,7 @@ class QgsVectorLayer;
|
|||||||
class QgsCoordinateReferenceSystem;
|
class QgsCoordinateReferenceSystem;
|
||||||
class QgsField;
|
class QgsField;
|
||||||
class QgsFeature;
|
class QgsFeature;
|
||||||
|
class QgsRectangle;
|
||||||
class QgsGeometry;
|
class QgsGeometry;
|
||||||
class QgsSymbol;
|
class QgsSymbol;
|
||||||
class QgsRequestHandler;
|
class QgsRequestHandler;
|
||||||
@ -80,7 +81,7 @@ class QgsWFSServer
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void startGetFeature( QgsRequestHandler& request, const QString& format );
|
void startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect );
|
||||||
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes );
|
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes );
|
||||||
void endGetFeature( QgsRequestHandler& request, const QString& format );
|
void endGetFeature( QgsRequestHandler& request, const QString& format );
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ class QgsWFSServer
|
|||||||
//methods to write GML2
|
//methods to write GML2
|
||||||
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;
|
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;
|
||||||
|
|
||||||
|
QDomElement createBoxElem( QgsRectangle* box, QDomDocument& doc ) /* const */;
|
||||||
QDomElement createGeometryElem( QgsGeometry* g, QDomDocument& doc ) /*const*/;
|
QDomElement createGeometryElem( QgsGeometry* g, QDomDocument& doc ) /*const*/;
|
||||||
QDomElement createLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
|
QDomElement createLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
|
||||||
QDomElement createMultiLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
|
QDomElement createMultiLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
|
||||||
|
@ -754,7 +754,7 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsW
|
|||||||
|
|
||||||
// may be GTiff, GeoTIFF, TIFF, GIF, ....
|
// may be GTiff, GeoTIFF, TIFF, GIF, ....
|
||||||
coverage->supportedFormat = domElementsTexts( coverageOfferingElement, "supportedFormats.formats" );
|
coverage->supportedFormat = domElementsTexts( coverageOfferingElement, "supportedFormats.formats" );
|
||||||
//QgsDebugMsg( "supportedFormat = " + coverage->supportedFormat.join( "," ) );
|
QgsDebugMsg( "supportedFormat = " + coverage->supportedFormat.join( "," ) );
|
||||||
|
|
||||||
// spatialDomain and Grid/RectifiedGrid are optional according to specificationi.
|
// spatialDomain and Grid/RectifiedGrid are optional according to specificationi.
|
||||||
// If missing, we cannot get native resolution and size.
|
// If missing, we cannot get native resolution and size.
|
||||||
|
@ -804,11 +804,17 @@ void QgsWcsProvider::cacheReplyFinished()
|
|||||||
QgsDebugMsg( "contentType: " + contentType );
|
QgsDebugMsg( "contentType: " + contentType );
|
||||||
|
|
||||||
// Exception
|
// Exception
|
||||||
|
// Content type examples: text/xml
|
||||||
|
// application/vnd.ogc.se_xml;charset=UTF-8
|
||||||
|
// application/xml
|
||||||
if ( contentType.startsWith( "text/", Qt::CaseInsensitive ) ||
|
if ( contentType.startsWith( "text/", Qt::CaseInsensitive ) ||
|
||||||
contentType.toLower() == "application/vnd.ogc.se_xml" )
|
contentType.toLower() == "application/xml" ||
|
||||||
|
contentType.startsWith( "application/vnd.ogc.se_xml", Qt::CaseInsensitive ) )
|
||||||
{
|
{
|
||||||
QByteArray text = mCacheReply->readAll();
|
QByteArray text = mCacheReply->readAll();
|
||||||
if (( contentType.toLower() == "text/xml" || contentType.toLower() == "application/vnd.ogc.se_xml" )
|
if (( contentType.toLower() == "text/xml" ||
|
||||||
|
contentType.toLower() == "application/xml" ||
|
||||||
|
contentType.startsWith( "application/vnd.ogc.se_xml", Qt::CaseInsensitive ) )
|
||||||
&& parseServiceExceptionReportDom( text ) )
|
&& parseServiceExceptionReportDom( text ) )
|
||||||
{
|
{
|
||||||
QgsMessageLog::logMessage( tr( "Map request error (Title:%1; Error:%2; URL: %3)" )
|
QgsMessageLog::logMessage( tr( "Map request error (Title:%1; Error:%2; URL: %3)" )
|
||||||
|
@ -54,7 +54,7 @@ class QgsExpressionOGCVisitor : public QgsExpression::Visitor
|
|||||||
case QgsExpression::boEQ: opName = "PropertyIsEqualTo"; break;
|
case QgsExpression::boEQ: opName = "PropertyIsEqualTo"; break;
|
||||||
case QgsExpression::boNE: opName = "PropertyIsNotEqualTo"; break;
|
case QgsExpression::boNE: opName = "PropertyIsNotEqualTo"; break;
|
||||||
case QgsExpression::boLE: opName = "PropertyIsLessThanOrEqualTo"; break;
|
case QgsExpression::boLE: opName = "PropertyIsLessThanOrEqualTo"; break;
|
||||||
case QgsExpression::boGE: opName = "PropertyIsLessThanOrEqualTo"; break;
|
case QgsExpression::boGE: opName = "PropertyIsGreaterThanOrEqualTo"; break;
|
||||||
case QgsExpression::boLT: opName = "PropertyIsLessThan"; break;
|
case QgsExpression::boLT: opName = "PropertyIsLessThan"; break;
|
||||||
case QgsExpression::boGT: opName = "PropertyIsGreaterThan"; break;
|
case QgsExpression::boGT: opName = "PropertyIsGreaterThan"; break;
|
||||||
case QgsExpression::boOr: opName = "Or"; break;
|
case QgsExpression::boOr: opName = "Or"; break;
|
||||||
|
@ -77,17 +77,25 @@ void TestQgsWcsPublicServers::init()
|
|||||||
QCoreApplication::exit( 1 );
|
QCoreApplication::exit( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mHead << "Coverage";
|
mHead << "Coverage";
|
||||||
mHead << "Version";
|
|
||||||
mHead << "Snap";
|
|
||||||
mHead << "Bands";
|
|
||||||
mHead << "Type";
|
|
||||||
mHead << "Min";
|
|
||||||
mHead << "Max";
|
|
||||||
mHead << "Values";
|
|
||||||
mHead << "Colors";
|
|
||||||
mHead << "Has size";
|
mHead << "Has size";
|
||||||
|
|
||||||
|
QStringList providers;
|
||||||
|
providers << "wcs" << "gdal";
|
||||||
|
foreach ( QString provider, providers )
|
||||||
|
{
|
||||||
|
QString prefix = provider == "gdal" ? "GDAL " : "";
|
||||||
|
mHead << prefix + "CRS";
|
||||||
|
mHead << prefix + "Snap";
|
||||||
|
mHead << prefix + "Bands";
|
||||||
|
mHead << prefix + "Type";
|
||||||
|
mHead << prefix + "Min";
|
||||||
|
mHead << prefix + "Max";
|
||||||
|
mHead << prefix + "Values";
|
||||||
|
mHead << prefix + "Colors";
|
||||||
|
}
|
||||||
|
|
||||||
// read servers + issues list
|
// read servers + issues list
|
||||||
QString path = QgsApplication::pkgDataPath() + "/resources/wcs-servers.json";
|
QString path = QgsApplication::pkgDataPath() + "/resources/wcs-servers.json";
|
||||||
QFile file( path );
|
QFile file( path );
|
||||||
@ -109,6 +117,7 @@ void TestQgsWcsPublicServers::init()
|
|||||||
QgsDebugMsg( "serverUrl: " + serverUrl );
|
QgsDebugMsg( "serverUrl: " + serverUrl );
|
||||||
|
|
||||||
Server server( serverUrl );
|
Server server( serverUrl );
|
||||||
|
server.description = serverValue.property( "description" ).toString();
|
||||||
|
|
||||||
QScriptValue issuesValue = serverValue.property( "issues" );
|
QScriptValue issuesValue = serverValue.property( "issues" );
|
||||||
|
|
||||||
@ -122,6 +131,8 @@ void TestQgsWcsPublicServers::init()
|
|||||||
QgsDebugMsg( "description: " + description );
|
QgsDebugMsg( "description: " + description );
|
||||||
Issue issue( description );
|
Issue issue( description );
|
||||||
|
|
||||||
|
issue.offender = issueValue.property( "offender" ).toString();
|
||||||
|
|
||||||
QScriptValue coveragesValue = issueValue.property( "coverages" );
|
QScriptValue coveragesValue = issueValue.property( "coverages" );
|
||||||
QScriptValueIterator coveragesIt( coveragesValue );
|
QScriptValueIterator coveragesIt( coveragesValue );
|
||||||
while ( coveragesIt.hasNext() )
|
while ( coveragesIt.hasNext() )
|
||||||
@ -150,9 +161,18 @@ void TestQgsWcsPublicServers::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList TestQgsWcsPublicServers::issueDescriptions( const QString & url, const QString & coverage, const QString &version )
|
TestQgsWcsPublicServers::Server TestQgsWcsPublicServers::getServer( const QString & url )
|
||||||
{
|
{
|
||||||
QStringList descriptions;
|
foreach ( Server server, mServers )
|
||||||
|
{
|
||||||
|
if ( server.url == url ) return server;
|
||||||
|
}
|
||||||
|
return Server();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<TestQgsWcsPublicServers::Issue> TestQgsWcsPublicServers::issues( const QString & url, const QString & coverage, const QString &version )
|
||||||
|
{
|
||||||
|
QList<Issue> issues;
|
||||||
foreach ( Server server, mServers )
|
foreach ( Server server, mServers )
|
||||||
{
|
{
|
||||||
if ( server.url == url )
|
if ( server.url == url )
|
||||||
@ -162,14 +182,41 @@ QStringList TestQgsWcsPublicServers::issueDescriptions( const QString & url, con
|
|||||||
if (( issue.coverages.size() == 0 || issue.coverages.contains( coverage ) ) &&
|
if (( issue.coverages.size() == 0 || issue.coverages.contains( coverage ) ) &&
|
||||||
( issue.versions.size() == 0 || issue.versions.contains( version ) ) )
|
( issue.versions.size() == 0 || issue.versions.contains( version ) ) )
|
||||||
{
|
{
|
||||||
descriptions << issue.description;
|
issues << issue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return issues;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList TestQgsWcsPublicServers::issueDescriptions( const QString & url, const QString & coverage, const QString &version )
|
||||||
|
{
|
||||||
|
QStringList descriptions;
|
||||||
|
foreach ( Issue myIssue, issues( url, coverage, version ) )
|
||||||
|
{
|
||||||
|
descriptions << myIssue.description;
|
||||||
|
}
|
||||||
return descriptions;
|
return descriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TestQgsWcsPublicServers::issueOffender( const QString & url, const QString & coverage, const QString &version )
|
||||||
|
{
|
||||||
|
int offender = NoOffender;
|
||||||
|
foreach ( Issue myIssue, issues( url, coverage, version ) )
|
||||||
|
{
|
||||||
|
if ( myIssue.offender == "server" )
|
||||||
|
{
|
||||||
|
offender |= ServerOffender;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offender |= QGisOffender;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offender;
|
||||||
|
}
|
||||||
|
|
||||||
void TestQgsWcsPublicServers::test( )
|
void TestQgsWcsPublicServers::test( )
|
||||||
{
|
{
|
||||||
QStringList versions;
|
QStringList versions;
|
||||||
@ -183,7 +230,9 @@ void TestQgsWcsPublicServers::test( )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
versions << "" << "1.0.0" << "1.1.0"; // empty for default
|
//versions << "" << "1.0.0" << "1.1.0"; // empty for default
|
||||||
|
// Empty is version is the same like "1.0.0" because QGIS will try "1.0.0" first
|
||||||
|
versions << "1.0.0" << "1.1.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -263,6 +312,7 @@ void TestQgsWcsPublicServers::test( )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myVersionLog << QString( "totalCoverages:%1" ).arg( myCoverages.size() );
|
||||||
|
|
||||||
int myCoverageCount = 0;
|
int myCoverageCount = 0;
|
||||||
int myStep = myCoverages.size() / qMin( mMaxCoverages, myCoverages.size() );
|
int myStep = myCoverages.size() / qMin( mMaxCoverages, myCoverages.size() );
|
||||||
@ -291,8 +341,6 @@ void TestQgsWcsPublicServers::test( )
|
|||||||
|
|
||||||
QString myPath = myVersionDirPath + QDir::separator() + myCoverage.identifier;
|
QString myPath = myVersionDirPath + QDir::separator() + myCoverage.identifier;
|
||||||
QString myLogPath = myPath + ".log";
|
QString myLogPath = myPath + ".log";
|
||||||
QString myPngPath = myPath + ".png";
|
|
||||||
QgsDebugMsg( "myPngPath = " + myPngPath );
|
|
||||||
|
|
||||||
if ( QFileInfo( myLogPath ).exists() && !mForce )
|
if ( QFileInfo( myLogPath ).exists() && !mForce )
|
||||||
{
|
{
|
||||||
@ -325,80 +373,111 @@ void TestQgsWcsPublicServers::test( )
|
|||||||
}
|
}
|
||||||
myLog << QString( "hasSize:%1" ).arg( myCoverage.hasSize );
|
myLog << QString( "hasSize:%1" ).arg( myCoverage.hasSize );
|
||||||
|
|
||||||
QgsRasterLayer * myLayer = new QgsRasterLayer( myUri.encodedUri(), myCoverage.identifier, "wcs", true );
|
// Test QGIS provider and via GDAL
|
||||||
if ( myLayer->isValid() )
|
QStringList providers;
|
||||||
{
|
providers << "wcs" << "gdal";
|
||||||
int myBandCount = myLayer->dataProvider()->bandCount();
|
|
||||||
myLog << "bandCount:" + QString::number( myBandCount );
|
|
||||||
if ( myBandCount > 0 )
|
|
||||||
{
|
|
||||||
myLog << "srcType:" + QString::number( myLayer->dataProvider()->srcDataType( 1 ) );
|
|
||||||
|
|
||||||
QgsRasterBandStats myStats = myLayer->dataProvider()->bandStatistics( 1, QgsRasterBandStats::All, QgsRectangle(), myWidth * myHeight );
|
foreach ( QString provider, providers )
|
||||||
myLog << "min:" + QString::number( myStats.minimumValue );
|
{
|
||||||
myLog << "max:" + QString::number( myStats.maximumValue );
|
QString uri;
|
||||||
|
if ( provider == "wcs" )
|
||||||
|
{
|
||||||
|
uri = myUri.encodedUri();
|
||||||
|
}
|
||||||
|
else // gdal
|
||||||
|
{
|
||||||
|
uri = myPath + "-gdal.xml";
|
||||||
|
QFile myGdalXmlFile( uri );
|
||||||
|
myGdalXmlFile.open( QIODevice::WriteOnly | QIODevice::Text );
|
||||||
|
QTextStream myStream( &myGdalXmlFile );
|
||||||
|
myStream << "<WCS_GDAL>\n";
|
||||||
|
myStream << " <ServiceURL>" + serverUrl + "?" + "</ServiceURL>\n";
|
||||||
|
myStream << " <CoverageName>" + myCoverage.identifier + "</CoverageName>\n";
|
||||||
|
myStream << " <Version>" + version + "</Version>\n";
|
||||||
|
myStream << " <Timeout>60</Version>\n";
|
||||||
|
myStream << "</WCS_GDAL>\n";
|
||||||
|
|
||||||
|
myGdalXmlFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsMapRenderer myMapRenderer;
|
QgsRasterLayer * myLayer = new QgsRasterLayer( uri, myCoverage.identifier, provider, true );
|
||||||
QList<QgsMapLayer *> myLayersList;
|
if ( myLayer->isValid() )
|
||||||
|
|
||||||
myLayersList.append( myLayer );
|
|
||||||
QgsMapLayerRegistry::instance()->addMapLayers( myLayersList, false );
|
|
||||||
|
|
||||||
QMap<QString, QgsMapLayer*> myLayersMap = QgsMapLayerRegistry::instance()->mapLayers();
|
|
||||||
|
|
||||||
myMapRenderer.setLayerSet( myLayersMap.keys() );
|
|
||||||
|
|
||||||
myMapRenderer.setExtent( myLayer->extent() );
|
|
||||||
|
|
||||||
QImage myImage( myWidth, myHeight, QImage::Format_ARGB32_Premultiplied );
|
|
||||||
myImage.fill( 0 );
|
|
||||||
|
|
||||||
myMapRenderer.setOutputSize( QSize( myWidth, myHeight ), myImage.logicalDpiX() );
|
|
||||||
|
|
||||||
QPainter myPainter( &myImage );
|
|
||||||
myMapRenderer.render( &myPainter );
|
|
||||||
|
|
||||||
// Save rendered image
|
|
||||||
myImage.save( myPngPath );
|
|
||||||
|
|
||||||
// Verify data
|
|
||||||
QSet<QString> myValues; // cannot be QSet<double>
|
|
||||||
void *myData = myLayer->dataProvider()->readBlock( 1, myLayer->extent(), myWidth, myHeight );
|
|
||||||
if ( myData )
|
|
||||||
{
|
{
|
||||||
int myType = myLayer->dataProvider()->dataType( 1 );
|
myLog << provider + "_crs:" + myLayer->dataProvider()->crs().authid();
|
||||||
|
int myBandCount = myLayer->dataProvider()->bandCount();
|
||||||
|
myLog << provider + "_bandCount:" + QString::number( myBandCount );
|
||||||
|
if ( myBandCount > 0 )
|
||||||
|
{
|
||||||
|
myLog << provider + "_srcType:" + QString::number( myLayer->dataProvider()->srcDataType( 1 ) );
|
||||||
|
|
||||||
|
QgsRasterBandStats myStats = myLayer->dataProvider()->bandStatistics( 1, QgsRasterBandStats::All, QgsRectangle(), myWidth * myHeight );
|
||||||
|
myLog << provider + "_min:" + QString::number( myStats.minimumValue );
|
||||||
|
myLog << provider + "_max:" + QString::number( myStats.maximumValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMapRenderer myMapRenderer;
|
||||||
|
QList<QgsMapLayer *> myLayersList;
|
||||||
|
|
||||||
|
myLayersList.append( myLayer );
|
||||||
|
QgsMapLayerRegistry::instance()->addMapLayers( myLayersList, false );
|
||||||
|
|
||||||
|
QMap<QString, QgsMapLayer*> myLayersMap = QgsMapLayerRegistry::instance()->mapLayers();
|
||||||
|
|
||||||
|
myMapRenderer.setLayerSet( myLayersMap.keys() );
|
||||||
|
|
||||||
|
myMapRenderer.setExtent( myLayer->extent() );
|
||||||
|
|
||||||
|
QImage myImage( myWidth, myHeight, QImage::Format_ARGB32_Premultiplied );
|
||||||
|
myImage.fill( 0 );
|
||||||
|
|
||||||
|
myMapRenderer.setOutputSize( QSize( myWidth, myHeight ), myImage.logicalDpiX() );
|
||||||
|
|
||||||
|
QPainter myPainter( &myImage );
|
||||||
|
myMapRenderer.render( &myPainter );
|
||||||
|
|
||||||
|
// Save rendered image
|
||||||
|
QString myPngPath = myPath + "-" + provider + ".png";
|
||||||
|
QgsDebugMsg( "myPngPath = " + myPngPath );
|
||||||
|
myImage.save( myPngPath );
|
||||||
|
|
||||||
|
// Verify data
|
||||||
|
QSet<QString> myValues; // cannot be QSet<double>
|
||||||
|
void *myData = myLayer->dataProvider()->readBlock( 1, myLayer->extent(), myWidth, myHeight );
|
||||||
|
if ( myData )
|
||||||
|
{
|
||||||
|
int myType = myLayer->dataProvider()->dataType( 1 );
|
||||||
|
for ( int row = 0; row < myHeight; row++ )
|
||||||
|
{
|
||||||
|
for ( int col = 0; col < myWidth; col++ )
|
||||||
|
{
|
||||||
|
double value = myLayer->dataProvider()->readValue( myData, myType, row * myWidth + col );
|
||||||
|
QString valueStr = QString::number( value );
|
||||||
|
if ( !myValues.contains( valueStr ) ) myValues.insert( valueStr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free( myData );
|
||||||
|
}
|
||||||
|
QgsDebugMsg( QString( "%1 values" ).arg( myValues.size() ) );
|
||||||
|
myLog << provider + QString( "_valuesCount:%1" ).arg( myValues.size() );
|
||||||
|
|
||||||
|
// Verify image colors
|
||||||
|
QSet<QRgb> myColors;
|
||||||
for ( int row = 0; row < myHeight; row++ )
|
for ( int row = 0; row < myHeight; row++ )
|
||||||
{
|
{
|
||||||
for ( int col = 0; col < myWidth; col++ )
|
for ( int col = 0; col < myWidth; col++ )
|
||||||
{
|
{
|
||||||
double value = myLayer->dataProvider()->readValue( myData, myType, row * myWidth + col );
|
QRgb color = myImage.pixel( col, row );
|
||||||
QString valueStr = QString::number( value );
|
if ( !myColors.contains( color ) ) myColors.insert( color );
|
||||||
if ( !myValues.contains( valueStr ) ) myValues.insert( valueStr );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free( myData );
|
QgsDebugMsg( QString( "%1 colors" ).arg( myColors.size() ) );
|
||||||
|
myLog << provider + QString( "_colorsCount:%1" ).arg( myColors.size() );
|
||||||
}
|
}
|
||||||
QgsDebugMsg( QString( "%1 values" ).arg( myValues.size() ) );
|
else
|
||||||
myLog << QString( "valuesCount:%1" ).arg( myValues.size() );
|
|
||||||
|
|
||||||
// Verify image colors
|
|
||||||
QSet<QRgb> myColors;
|
|
||||||
for ( int row = 0; row < myHeight; row++ )
|
|
||||||
{
|
{
|
||||||
for ( int col = 0; col < myWidth; col++ )
|
QgsDebugMsg( "Layer is not valid" );
|
||||||
{
|
myLog << provider + "_error:Layer is not valid";
|
||||||
QRgb color = myImage.pixel( col, row );
|
|
||||||
if ( !myColors.contains( color ) ) myColors.insert( color );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
QgsDebugMsg( QString( "%1 colors" ).arg( myColors.size() ) );
|
|
||||||
myLog << QString( "colorsCount:%1" ).arg( myColors.size() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "Layer is not valid" );
|
|
||||||
myLog << "error:Layer is not valid";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile myLogFile( myLogPath );
|
QFile myLogFile( myLogPath );
|
||||||
@ -461,6 +540,11 @@ void TestQgsWcsPublicServers::report()
|
|||||||
QMap<QString, QString> myServerLog = readLog( myServerLogPath );
|
QMap<QString, QString> myServerLog = readLog( myServerLogPath );
|
||||||
|
|
||||||
myReport += QString( "<h2>Server: %1</h2>" ).arg( myServerLog.value( "server" ) );
|
myReport += QString( "<h2>Server: %1</h2>" ).arg( myServerLog.value( "server" ) );
|
||||||
|
Server myServer = getServer( myServerLog.value( "server" ) );
|
||||||
|
if ( !myServer.description.isEmpty() )
|
||||||
|
{
|
||||||
|
myReport += myServer.description + "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
QString myServerReport;
|
QString myServerReport;
|
||||||
|
|
||||||
@ -506,52 +590,92 @@ void TestQgsWcsPublicServers::report()
|
|||||||
|
|
||||||
QString myLogPath = myVersionDir.absolutePath() + QDir::separator() + myLogFileName;
|
QString myLogPath = myVersionDir.absolutePath() + QDir::separator() + myLogFileName;
|
||||||
QMap<QString, QString>myLog = readLog( myLogPath );
|
QMap<QString, QString>myLog = readLog( myLogPath );
|
||||||
|
myVersionReport += "<tr>";
|
||||||
|
|
||||||
QStringList myValues;
|
QStringList myValues;
|
||||||
myValues << QString( "<a href='%1'>%2</a>" ).arg( myLog.value( "describeCoverageUrl" ) ).arg( myLog.value( "identifier" ) );
|
myValues << QString( "<a href='%1'>%2</a>" ).arg( myLog.value( "describeCoverageUrl" ) ).arg( myLog.value( "identifier" ) );
|
||||||
myValues << myLog.value( "version" );
|
myValues << myLog.value( "hasSize" );
|
||||||
QString imgPath = myVersionDir.absolutePath() + QDir::separator() + QFileInfo( myLogPath ).completeBaseName() + ".png";
|
myVersionReport += cells( myValues );
|
||||||
|
myValues.clear();
|
||||||
|
|
||||||
if ( !myLog.value( "error" ).isEmpty() )
|
QStringList providers;
|
||||||
|
providers << "wcs" << "gdal";
|
||||||
|
|
||||||
|
foreach ( QString provider, providers )
|
||||||
{
|
{
|
||||||
myValues << myLog.value( "error" );
|
|
||||||
QStringList issues = issueDescriptions( myServerLog.value( "server" ), myLog.value( "identifier" ), myLog.value( "version" ) );
|
|
||||||
myValues << issues.join( "<br>" );
|
|
||||||
myVersionReport += row( myValues, "cellerr" );
|
|
||||||
myVersionErrCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
myValues << "<img src='" + imgPath + "'>";
|
|
||||||
myValues << myLog.value( "bandCount" );
|
|
||||||
myValues << myLog.value( "srcType" );
|
|
||||||
myValues << myLog.value( "min" );
|
|
||||||
myValues << myLog.value( "max" );
|
|
||||||
myValues << myLog.value( "valuesCount" );
|
|
||||||
myValues << myLog.value( "colorsCount" );
|
|
||||||
myValues << myLog.value( "hasSize" );
|
|
||||||
|
|
||||||
QString cls;
|
QString imgPath = myVersionDir.absolutePath() + QDir::separator() + QFileInfo( myLogPath ).completeBaseName() + "-" + provider + ".png";
|
||||||
int myValuesCount = myLog.value( "valuesCount" ).toInt();
|
|
||||||
int myColorsCount = myLog.value( "colorsCount" ).toInt();
|
|
||||||
if ( myValuesCount < 4 )
|
|
||||||
{
|
|
||||||
cls = "cellerr";
|
|
||||||
myVersionErrCount++;
|
|
||||||
myCoverageErrCount++;
|
|
||||||
}
|
|
||||||
else if ( myColorsCount < 4 )
|
|
||||||
{
|
|
||||||
cls = "cellwarn";
|
|
||||||
myVersionWarnCount++;
|
|
||||||
myCoverageWarnCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
myVersionReport += row( myValues, cls );
|
if ( !myLog.value( provider + "_error" ).isEmpty() )
|
||||||
|
{
|
||||||
|
myValues << myLog.value( provider + "_error" );
|
||||||
|
int offender = NoOffender;
|
||||||
|
if ( provider == "wcs" )
|
||||||
|
{
|
||||||
|
QStringList issues = issueDescriptions( myServerLog.value( "server" ), myLog.value( "identifier" ), myLog.value( "version" ) );
|
||||||
|
myValues << issues.join( "<br>" );
|
||||||
|
|
||||||
|
offender = issueOffender( myServerLog.value( "server" ), myLog.value( "identifier" ), myLog.value( "version" ) );
|
||||||
|
myVersionErrCount++;
|
||||||
|
}
|
||||||
|
QString cls;
|
||||||
|
if ( offender == ServerOffender )
|
||||||
|
{
|
||||||
|
cls = "cell-err-server";
|
||||||
|
}
|
||||||
|
else if ( offender == QGisOffender )
|
||||||
|
{
|
||||||
|
cls = "cell-err-qgis";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cls = "cell-err";
|
||||||
|
}
|
||||||
|
myVersionReport += cells( myValues, cls, 8 );
|
||||||
|
myValues.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myValues << myLog.value( provider + "_crs" );
|
||||||
|
myValues << "<img src='" + imgPath + "'>";
|
||||||
|
myValues << myLog.value( provider + "_bandCount" );
|
||||||
|
myValues << myLog.value( provider + "_srcType" );
|
||||||
|
myValues << myLog.value( provider + "_min" );
|
||||||
|
myValues << myLog.value( provider + "_max" );
|
||||||
|
myValues << myLog.value( provider + "_valuesCount" );
|
||||||
|
myValues << myLog.value( provider + "_colorsCount" );
|
||||||
|
|
||||||
|
QString cls;
|
||||||
|
int myValuesCount = myLog.value( provider + "_valuesCount" ).toInt();
|
||||||
|
int myColorsCount = myLog.value( provider + "_colorsCount" ).toInt();
|
||||||
|
if ( myValuesCount < 4 )
|
||||||
|
{
|
||||||
|
cls = "cell-err";
|
||||||
|
if ( provider == "wcs" )
|
||||||
|
{
|
||||||
|
myVersionErrCount++;
|
||||||
|
myCoverageErrCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( myColorsCount < 4 )
|
||||||
|
{
|
||||||
|
cls = "cell-warn";
|
||||||
|
if ( provider == "wcs" )
|
||||||
|
{
|
||||||
|
myVersionWarnCount++;
|
||||||
|
myCoverageWarnCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myVersionReport += cells( myValues, cls );
|
||||||
|
myValues.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
myVersionReport += "<tr>\n";
|
||||||
} // coverages
|
} // coverages
|
||||||
myVersionReport += "</table>\n";
|
myVersionReport += "</table>\n";
|
||||||
// prepend counts
|
// prepend counts
|
||||||
myVersionReport.prepend( QString( "<b>Coverages: %1</b><br>\n" ).arg( myVersionCoverageCount ) +
|
myVersionReport.prepend( QString( "<b>Total coverages: %1</b><br>\n" ).arg( myVersionLog.value( "totalCoverages" ) ) +
|
||||||
|
QString( "<b>Tested coverages: %1</b><br>\n" ).arg( myVersionCoverageCount ) +
|
||||||
QString( "<b>Errors: %1</b><br>\n" ).arg( myVersionErrCount ) +
|
QString( "<b>Errors: %1</b><br>\n" ).arg( myVersionErrCount ) +
|
||||||
QString( "<b>Warnings: %1</b><br><br>" ).arg( myVersionWarnCount ) );
|
QString( "<b>Warnings: %1</b><br><br>" ).arg( myVersionWarnCount ) );
|
||||||
myServerReport += myVersionReport;
|
myServerReport += myVersionReport;
|
||||||
@ -572,10 +696,12 @@ void TestQgsWcsPublicServers::report()
|
|||||||
myRep += "<style>";
|
myRep += "<style>";
|
||||||
myRep += ".tab { border-spacing: 0px; border-width: 1px 1px 0 0; border-style: solid; }";
|
myRep += ".tab { border-spacing: 0px; border-width: 1px 1px 0 0; border-style: solid; }";
|
||||||
myRep += ".cell { border-width: 0 0 1px 1px; border-style: solid; font-size: smaller; text-align: center}";
|
myRep += ".cell { border-width: 0 0 1px 1px; border-style: solid; font-size: smaller; text-align: center}";
|
||||||
//myReport += ".cellok { background: #00ff00; }";
|
//myReport += ".cell-ok { background: #00ff00; }";
|
||||||
myRep += ".cellok { background: #ffffff; }";
|
myRep += ".cell-ok { background: #ffffff; }";
|
||||||
myRep += ".cellwarn { background: #ffcc00; }";
|
myRep += ".cell-warn { background: #ffcc00; }";
|
||||||
myRep += ".cellerr { background: #ff0000; }";
|
myRep += ".cell-err { background: #ff0000; }";
|
||||||
|
myRep += ".cell-err-server { background: #ffff00; }";
|
||||||
|
myRep += ".cell-err-qgis { background: #ff0000; }";
|
||||||
myRep += ".errmsg { color: #ff0000; }";
|
myRep += ".errmsg { color: #ff0000; }";
|
||||||
myRep += "</style>";
|
myRep += "</style>";
|
||||||
|
|
||||||
@ -618,6 +744,22 @@ QString TestQgsWcsPublicServers::error( QString theMessage )
|
|||||||
return myRow;
|
return myRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TestQgsWcsPublicServers::cells( QStringList theValues, QString theClass, int colspan )
|
||||||
|
{
|
||||||
|
QString myRow;
|
||||||
|
for ( int i = 0; i < theValues.size(); i++ )
|
||||||
|
{
|
||||||
|
QString val = theValues.value( i );
|
||||||
|
QString colspanStr;
|
||||||
|
if ( colspan > 1 && i == theValues.size() - 1 )
|
||||||
|
{
|
||||||
|
colspanStr = QString( "colspan=%1" ).arg( colspan - theValues.size() + 1 ) ;
|
||||||
|
}
|
||||||
|
myRow += QString( "<td class='cell %1' %2>%3</td>" ).arg( theClass ).arg( colspanStr ).arg( val );
|
||||||
|
}
|
||||||
|
return myRow;
|
||||||
|
}
|
||||||
|
|
||||||
QString TestQgsWcsPublicServers::row( QStringList theValues, QString theClass )
|
QString TestQgsWcsPublicServers::row( QStringList theValues, QString theClass )
|
||||||
{
|
{
|
||||||
QString myRow = "<tr>";
|
QString myRow = "<tr>";
|
||||||
|
@ -35,6 +35,7 @@ class TestQgsWcsPublicServers: public QObject
|
|||||||
// Known problem
|
// Known problem
|
||||||
struct Issue
|
struct Issue
|
||||||
{
|
{
|
||||||
|
QString offender; // server or empty == qgis
|
||||||
QStringList versions; // version regex
|
QStringList versions; // version regex
|
||||||
QStringList coverages; // coverage regex
|
QStringList coverages; // coverage regex
|
||||||
QString description; // problem description
|
QString description; // problem description
|
||||||
@ -45,9 +46,16 @@ class TestQgsWcsPublicServers: public QObject
|
|||||||
Server( ) {}
|
Server( ) {}
|
||||||
Server( const QString & u ) : url( u ) {}
|
Server( const QString & u ) : url( u ) {}
|
||||||
QString url; // URL
|
QString url; // URL
|
||||||
|
QString description; // notes
|
||||||
QList<TestQgsWcsPublicServers::Issue> issues;
|
QList<TestQgsWcsPublicServers::Issue> issues;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OffenderType
|
||||||
|
{
|
||||||
|
NoOffender = 0,
|
||||||
|
ServerOffender = 1,
|
||||||
|
QGisOffender = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
TestQgsWcsPublicServers( const QString & cacheDirPath, int maxCoverages, const QString & server = QString(), const QString & coverage = QString(), const QString &version = QString(), bool force = false );
|
TestQgsWcsPublicServers( const QString & cacheDirPath, int maxCoverages, const QString & server = QString(), const QString & coverage = QString(), const QString &version = QString(), bool force = false );
|
||||||
|
|
||||||
@ -55,14 +63,20 @@ class TestQgsWcsPublicServers: public QObject
|
|||||||
void test();
|
void test();
|
||||||
void report();
|
void report();
|
||||||
private:
|
private:
|
||||||
|
QString cells( QStringList theValues, QString theClass = QString(), int colspan = 1 );
|
||||||
QString row( QStringList theValues, QString theClass = QString() );
|
QString row( QStringList theValues, QString theClass = QString() );
|
||||||
QString error( QString theMessage );
|
QString error( QString theMessage );
|
||||||
void writeReport( QString theReport );
|
void writeReport( QString theReport );
|
||||||
|
|
||||||
QMap<QString, QString> readLog( QString theFileName );
|
QMap<QString, QString> readLog( QString theFileName );
|
||||||
|
|
||||||
|
Server getServer( const QString & url );
|
||||||
|
|
||||||
|
QList<Issue> issues( const QString & url, const QString & coverage, const QString &version );
|
||||||
QStringList issueDescriptions( const QString & url, const QString & coverage, const QString &version );
|
QStringList issueDescriptions( const QString & url, const QString & coverage, const QString &version );
|
||||||
|
|
||||||
|
int issueOffender( const QString & url, const QString & coverage, const QString &version );
|
||||||
|
|
||||||
QString mCacheDirPath;
|
QString mCacheDirPath;
|
||||||
QDir mCacheDir;
|
QDir mCacheDir;
|
||||||
|
|
||||||
|
@ -1,11 +1,33 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
url: 'http://demo.opengeo.org/geoserver/wcs',
|
url: 'http://demo.opengeo.org/geoserver/wcs',
|
||||||
|
description: 'Does not work at all with gvSIG-1_11-1305-final.',
|
||||||
issues: [
|
issues: [
|
||||||
{
|
{
|
||||||
|
offender: 'server',
|
||||||
coverages: [ 'og:0' ],
|
coverages: [ 'og:0' ],
|
||||||
versions: [ ],
|
versions: [ '1.0.0' ],
|
||||||
description: 'Server fails on DescribeCoverage with: java.io.IOException null Translator error Unexpected error occurred during describe coverage xml encoding ...'
|
description: 'The server fails in DescribeCoverage with: java.io.IOException null Translator error Unexpected error occurred during describe coverage xml encoding ...'
|
||||||
|
},{
|
||||||
|
offender: 'server',
|
||||||
|
coverages: [ 'bm' ],
|
||||||
|
versions: [ '1.1.0' ],
|
||||||
|
description: 'The server fails in DescribeCoverage with: java.io.IOException null Translator error Unexpected error occurred during describe coverage xml encoding ...'
|
||||||
|
},{
|
||||||
|
offender: 'server',
|
||||||
|
coverages: [ 'usgs:nlcd', 'nlcd' ],
|
||||||
|
versions: [ '1.0.0', '1.1.0' ],
|
||||||
|
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 ...'
|
||||||
|
},{
|
||||||
|
offender: 'server',
|
||||||
|
coverages: [ '0', 'naturalearth' ],
|
||||||
|
versions: [ '1.1.0' ],
|
||||||
|
description: "The server fails in GetCoverage with 'java.lang.IllegalArgumentException: xScale:the parameter value is not valid. xScale:the parameter value is not valid.' It fails with BOUNDINGBOX=-2,-6,2,6&GRIDORIGIN=2,-6&GRIDOFFSETS=-2,3 but works with BOUNDINGBOX=-2,-6,2,6&GRIDORIGIN=2,-6&GRIDOFFSETS=2,-3 (GRIDOFFSETS signs switched) other coverages (Arc_Sample e.g.) work OK with the first"
|
||||||
|
},{
|
||||||
|
offender: 'server',
|
||||||
|
coverages: [ 'Img_Sample' ],
|
||||||
|
versions: [ '1.1.0' ],
|
||||||
|
description: "The server fails in GetCoverage with 'java.lang.IllegalArgumentException: The specified dimensional parameter is non-positive. The specified dimensional parameter is non-positive'."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user