QgsVectorLayer* QgsRemoteDataSourceBuilder::vectorLayerFromRemoteVDS( const QDomElement& remoteVDSElem, const QString& layerName, QList<QTemporaryFile*>& filesToRemove, QList<QgsMapLayer*>& layersToRemove, bool allowCaching ) const { QString providerString; QString formatString = remoteVDSElem.attribute( "format" ); if ( formatString.compare( "gml", Qt::CaseInsensitive ) == 0 ) { providerString = "WFS"; } else { providerString = formatString; } //load file with QgsHttpTransaction QByteArray fileContents; QString uri = remoteVDSElem.text(); QgsVectorLayer* vl = 0; if ( loadData( uri, fileContents ) != 0 ) { return 0; } //store content into temporary file QTemporaryFile* tmpFile = new QTemporaryFile(); if ( tmpFile->open() ) { tmpFile->write( fileContents ); tmpFile->flush(); } else { delete tmpFile; return 0; } //create vector layer //SOS has a special datasource key... if ( formatString.compare( "SOS", Qt::CaseInsensitive ) == 0 ) { QString url = "url=" + tmpFile->fileName() + " method=FILE xml="; vl = new QgsVectorLayer( url, layerNameFromUri( tmpFile->fileName() ), providerString ); } else { vl = new QgsVectorLayer( tmpFile->fileName(), layerNameFromUri( tmpFile->fileName() ), providerString ); } if ( !( vl->isValid() ) ) { QgsMapServerLogger::instance()->printMessage( "vl is not valid" ); } layersToRemove.push_back( vl ); filesToRemove.push_back( tmpFile ); return vl; }
QgsVectorLayer* QgsSentDataSourceBuilder::vectorLayerFromSentVDS( const QDomElement& sentVDSElem, QList<QTemporaryFile*>& filesToRemove, QList<QgsMapLayer*>& layersToRemove ) const { if ( sentVDSElem.attribute( "format" ) == "GML" ) { QTemporaryFile* tmpFile = new QTemporaryFile(); if ( tmpFile->open() ) { filesToRemove.push_back( tmpFile ); //make sure the temporary file gets deleted after each request QTextStream tempFileStream( tmpFile ); sentVDSElem.save( tempFileStream, 4 ); tmpFile->close(); } else { return 0; } QgsVectorLayer* theVectorLayer = new QgsVectorLayer( tmpFile->fileName(), layerNameFromUri( tmpFile->fileName() ), "WFS" ); if ( !theVectorLayer || !theVectorLayer->isValid() ) { QgsMSDebugMsg( "invalid maplayer" ); return 0; } QgsMSDebugMsg( "returning maplayer" ); layersToRemove.push_back( theVectorLayer ); //make sure the layer gets deleted after each request if ( !theVectorLayer || !theVectorLayer->isValid() ) { return 0; } return theVectorLayer; } return 0; }
QgsRasterLayer* QgsRemoteDataSourceBuilder::rasterLayerFromRemoteRDS( const QDomElement& remoteRDSElem, const QString& layerName, QList<QTemporaryFile*>& filesToRemove, QList<QgsMapLayer*>& layersToRemove, bool allowCaching ) const { QgsMSDebugMsg( "entering." ); //load file with QgsHttpTransaction or QgsFtpTransaction QByteArray fileContents; QString uri = remoteRDSElem.text(); QgsRasterLayer* rl = 0; if ( loadData( uri, fileContents ) != 0 ) { return 0; } QTemporaryFile* tmpFile = new QTemporaryFile(); if ( tmpFile->open() ) { tmpFile->write( fileContents ); tmpFile->flush(); } else { QgsMSDebugMsg( "Error, creation of temp file failed" ); delete tmpFile; return 0; } //create rasterlayer rl = new QgsRasterLayer( tmpFile->fileName(), layerNameFromUri( tmpFile->fileName() ) ); layersToRemove.push_back( rl ); filesToRemove.push_back( tmpFile ); clearRasterSymbology( rl ); return rl; }
QgsMapLayer* QgsHostedRDSBuilder::createMapLayer( const QDomElement& elem, const QString& layerName, QList<QTemporaryFile*>& filesToRemove, QList<QgsMapLayer*>& layersToRemove, bool allowCaching ) const { QgsMSDebugMsg( "entering." ); if ( elem.isNull() ) { return 0; } QString uri = elem.attribute( "uri", "not found" ); if ( uri == "not found" ) { QgsMSDebugMsg( "Uri not found" ); return 0; } else { QgsMSDebugMsg( "Trying to get hostedrds layer from cache with uri: " + uri ); QgsRasterLayer* rl = 0; if ( allowCaching ) { rl = dynamic_cast<QgsRasterLayer*>( QgsMSLayerCache::instance()->searchLayer( uri, layerName ) ); } if ( !rl ) { QgsMSDebugMsg( "hostedrds layer not in cache, so create and insert it" ); rl = new QgsRasterLayer( uri, layerNameFromUri( uri ) ); if ( allowCaching ) { QgsMSLayerCache::instance()->insertLayer( uri, layerName, rl ); } else { layersToRemove.push_back( rl ); } } clearRasterSymbology( rl ); //projection if ( rl ) { QString epsg = elem.attribute( "epsg" ); if ( !epsg.isEmpty() ) { bool conversionOk; int epsgnr = epsg.toInt( &conversionOk ); if ( conversionOk ) { //set spatial ref sys QgsCoordinateReferenceSystem srs; srs.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( epsgnr ) ); rl->setCrs( srs ); } } } return rl; } }
QgsRasterLayer* QgsSentDataSourceBuilder::rasterLayerFromSentRDS( const QDomElement& sentRDSElem, QList<QTemporaryFile*>& filesToRemove, QList<QgsMapLayer*>& layersToRemove ) const { QgsMSDebugMsg( "Entering" ); QString tempFilePath = createTempFile(); if ( tempFilePath.isEmpty() ) { return 0; } QFile tempFile( tempFilePath ); QTemporaryFile* tmpFile = new QTemporaryFile(); QString encoding = sentRDSElem.attribute( "encoding" ); if ( encoding == "base64" ) { if ( tmpFile->open() ) { QByteArray binaryContent = QByteArray::fromBase64( sentRDSElem.text().toAscii() ); QDataStream ds( tmpFile ); ds.writeRawData( binaryContent.data(), binaryContent.length() ); } else { delete tmpFile; return 0; } } else //assume text (e.g. ascii grid) { if ( tmpFile->open() ) { QTextStream tempFileStream( tmpFile ); tempFileStream << sentRDSElem.text(); } else { delete tmpFile; return 0; } } QgsMSDebugMsg( "TempFilePath is: " + tempFilePath ); tmpFile->close(); QgsRasterLayer* rl = new QgsRasterLayer( tmpFile->fileName(), layerNameFromUri( tmpFile->fileName() ) ); filesToRemove.push_back( tmpFile ); //make sure the temporary file gets deleted after each request layersToRemove.push_back( rl ); //make sure the layer gets deleted after each request return rl; }
QgsMapLayer *QgsHostedVDSBuilder::createMapLayer( const QDomElement &elem, const QString &layerName, QList<QTemporaryFile *> &filesToRemove, QList<QgsMapLayer *> &layersToRemove, bool allowCaching ) const { Q_UNUSED( filesToRemove ); if ( elem.isNull() ) { return nullptr; } QString providerType = elem.attribute( QStringLiteral( "providerType" ), QStringLiteral( "not found" ) ); QString uri = elem.attribute( QStringLiteral( "uri" ), QStringLiteral( "not found" ) ); if ( providerType == QLatin1String( "not found" ) || uri == QLatin1String( "not found" ) ) { QgsDebugMsg( "error, provider type not found" ); return nullptr; } QgsMapLayer *ml = nullptr; if ( allowCaching ) //take layer from cache if allowed { QgsDebugMsg( "Taking hostedvds layer from cash" ); ml = QgsMSLayerCache::instance()->searchLayer( uri, layerName ); } if ( !ml ) { QgsDebugMsg( "hostedvds layer not in cash, so create and insert it" ); ml = new QgsVectorLayer( uri, layerNameFromUri( uri ), providerType ); if ( !ml || !ml->isValid() ) { QgsDebugMsg( "error, VectorLayer is 0 or invalid" ); delete ml; return nullptr; } if ( allowCaching ) { QgsMSLayerCache::instance()->insertLayer( uri, layerName, ml ); } else { layersToRemove.push_back( ml ); } } //projection if ( ml ) { QString epsg = elem.attribute( QStringLiteral( "epsg" ) ); if ( !epsg.isEmpty() ) { bool conversionOk; int epsgnr = epsg.toInt( &conversionOk ); if ( conversionOk ) { //set spatial ref sys QgsCoordinateReferenceSystem srs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( epsgnr ) ); ml->setCrs( srs ); } } } return ml; }
QgsMapLayer* QgsRemoteOWSBuilder::createMapLayer( const QDomElement& elem, const QString& layerName, QList<QTemporaryFile*>& filesToRemove, QList<QgsMapLayer*>& layersToRemove, bool allowCaching ) const { if ( elem.isNull() ) { return nullptr; } //parse service element QDomNode serviceNode = elem.namedItem( QStringLiteral( "Service" ) ); if ( serviceNode.isNull() ) { QgsDebugMsg( "No <Service> node found, returning 0" ); return nullptr; //service node is necessary } //parse OnlineResource element QDomNode onlineResourceNode = elem.namedItem( QStringLiteral( "OnlineResource" ) ); if ( onlineResourceNode.isNull() ) { QgsDebugMsg( "No <OnlineResource> element, returning 0" ); return nullptr; } //get uri QDomElement onlineResourceElement = onlineResourceNode.toElement(); QString url = onlineResourceElement.attribute( QStringLiteral( "href" ) ); QgsMapLayer* result = nullptr; QString serviceName = serviceNode.toElement().text(); //append missing ? or & at the end of the url, but only for WFS and WMS if ( serviceName == QLatin1String( "WFS" ) || serviceName == QLatin1String( "WMS" ) ) { if ( !url.endsWith( QLatin1String( "?" ) ) && !url.endsWith( QLatin1String( "&" ) ) ) { if ( url.contains( QLatin1String( "?" ) ) ) { url.append( "&" ); } else { url.append( "?" ); } } } if ( serviceName == QLatin1String( "WFS" ) ) { //support for old format where type is explicitly given and not part of url QString tname = onlineResourceElement.attribute( QStringLiteral( "type" ) ); if ( !tname.isEmpty() ) { url.append( "SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=" + tname ); } if ( allowCaching ) { result = QgsMSLayerCache::instance()->searchLayer( url, layerName ); } if ( result ) { return result; } result = new QgsVectorLayer( url, layerNameFromUri( url ), QStringLiteral( "WFS" ) ); if ( result->isValid() ) { if ( allowCaching ) { QgsMSLayerCache::instance()->insertLayer( url, layerName, result ); } else { layersToRemove.push_back( result ); } } } else if ( serviceName == QLatin1String( "WMS" ) ) { result = wmsLayerFromUrl( url, layerName, layersToRemove, allowCaching ); } else if ( serviceName == QLatin1String( "WCS" ) ) { QgsDebugMsg( "Trying to get WCS layer" ); result = wcsLayerFromUrl( url, layerName, filesToRemove, layersToRemove ); } else if ( serviceName == QLatin1String( "SOS" ) ) { result = sosLayer( elem, url, layerName, layersToRemove, allowCaching ); } if ( !result || !result->isValid() ) { QgsDebugMsg( "Error, maplayer is 0 or invalid" ); if ( result ) { delete result; } return nullptr; } return result; }
QgsRasterLayer* QgsRemoteOWSBuilder::wcsLayerFromUrl( const QString &url, const QString &layerName, QList<QTemporaryFile*> &filesToRemove, QList<QgsMapLayer*> &layersToRemove, bool allowCaching ) const { Q_UNUSED( layerName ); Q_UNUSED( allowCaching ); #if QT_VERSION < 0x050000 QgsDebugMsg( "Entering" ); //write server url and coverage name to a temporary file QString fileName = createTempFile(); if ( fileName.isEmpty() ) { return nullptr; } QFile tempFile( fileName ); QTemporaryFile* tmpFile = new QTemporaryFile(); if ( !tmpFile->open() ) { delete tmpFile; return nullptr; } filesToRemove.push_back( tmpFile ); //make sure the temporary file gets deleted after each request QgsDebugMsg( "opening successful" ); QgsDebugMsg( "url: " + url ); //extract server url and coverage name from string QStringList serverSplit = url.split( "?" ); if ( serverSplit.size() < 2 ) { QgsDebugMsg( "error, no '?' contained in url" ); return nullptr; } QString serverUrl = serverSplit.at( 0 ); QString request = serverSplit.at( 1 ); QStringList parameterSplit = request.split( "&" ); QString coverageName; QString format; for ( int i = 0; i < parameterSplit.size(); ++i ) { if ( parameterSplit.at( i ).startsWith( "COVERAGE", Qt::CaseInsensitive ) ) { coverageName = parameterSplit.at( i ).split( "=" ).at( 1 ); } else if ( parameterSplit.at( i ).startsWith( "FORMAT", Qt::CaseInsensitive ) ) { format = parameterSplit.at( i ).split( "=" ).at( 1 ); } } if ( coverageName.isEmpty() ) { QgsDebugMsg( "coverage name is empty" ); return nullptr; } if ( format.isEmpty() ) { format = "GeoTIFF"; //use geotiff as default } QgsDebugMsg( "wcs server url: " + serverUrl ); QgsDebugMsg( "coverage name: " + coverageName ); //fetch WCS layer in the current resolution as geotiff QString wcsRequest = serverUrl + "?SERVICE=WCS&VERSION=1.0.0&REQUEST=GetCoverage&COVERAGE=" + coverageName + "&FORMAT=" + format; //CRS (or SRS) QString crs = mParameterMap.value( "CRS", mParameterMap.value( "SRS" ) ); if ( crs.isEmpty() ) { QgsDebugMsg( "No CRS or SRS parameter found for wcs layer, returning 0" ); return nullptr; } wcsRequest += "&CRS=" + crs; //width QString width = mParameterMap.value( "WIDTH" ); if ( width.isEmpty() ) { QgsDebugMsg( "No WIDTH parameter found for wcs layer, returning 0" ); return nullptr; } wcsRequest += "&WIDTH=" + width; //height QString height = mParameterMap.value( "HEIGHT" ); if ( height.isEmpty() ) { QgsDebugMsg( "No HEIGHT parameter found for wcs layer, returning 0" ); return nullptr; } wcsRequest += "&HEIGHT=" + height; //bbox QString bbox = mParameterMap.value( "BBOX" ); if ( bbox.isEmpty() ) { QgsDebugMsg( "No BBOX parameter found for wcs layer, returning 0" ); return nullptr; } wcsRequest += "&BBOX=" + bbox; QgsDebugMsg( "WCS request is: " + wcsRequest ); //make request and store byte array into temporary file QgsHttpTransaction httpTransaction( wcsRequest ); QByteArray result; if ( !httpTransaction.getSynchronously( result ) ) { return nullptr; } QDataStream tempFileStream( &tempFile ); tempFileStream.writeRawData( result.data(), result.size() ); tempFile.close(); QgsRasterLayer* rl = new QgsRasterLayer( fileName, layerNameFromUri( fileName ) ); layersToRemove.push_back( rl ); //make sure the layer gets deleted after each request return rl; #else Q_UNUSED( url ) Q_UNUSED( filesToRemove ) Q_UNUSED( layersToRemove ) QgsDebugMsg( "remote http not supported with Qt5" ); return nullptr; #endif }