QgsAfsProvider::QgsAfsProvider( const QString &uri ) : QgsVectorDataProvider( uri ) , mValid( false ) , mObjectIdFieldIdx( -1 ) { mSharedData.reset( new QgsAfsSharedData() ); mSharedData->mGeometryType = QgsWkbTypes::Unknown; mSharedData->mDataSource = QgsDataSourceUri( uri ); // Set CRS mSharedData->mSourceCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( mSharedData->mDataSource.param( QStringLiteral( "crs" ) ) ); // Get layer info QString errorTitle, errorMessage; const QVariantMap layerData = QgsArcGisRestUtils::getLayerInfo( mSharedData->mDataSource.param( QStringLiteral( "url" ) ), errorTitle, errorMessage ); if ( layerData.isEmpty() ) { pushError( errorTitle + ": " + errorMessage ); appendError( QgsErrorMessage( tr( "getLayerInfo failed" ), QStringLiteral( "AFSProvider" ) ) ); return; } mLayerName = layerData[QStringLiteral( "name" )].toString(); mLayerDescription = layerData[QStringLiteral( "description" )].toString(); // Set extent QStringList coords = mSharedData->mDataSource.param( QStringLiteral( "bbox" ) ).split( ',' ); if ( coords.size() == 4 ) { bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; mSharedData->mExtent.setXMinimum( coords[0].toDouble( &xminOk ) ); mSharedData->mExtent.setYMinimum( coords[1].toDouble( &yminOk ) ); mSharedData->mExtent.setXMaximum( coords[2].toDouble( &xmaxOk ) ); mSharedData->mExtent.setYMaximum( coords[3].toDouble( &ymaxOk ) ); if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) mSharedData->mExtent = QgsRectangle(); } const QVariantMap layerExtentMap = layerData[QStringLiteral( "extent" )].toMap(); bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; QgsRectangle originalExtent; originalExtent.setXMinimum( layerExtentMap[QStringLiteral( "xmin" )].toDouble( &xminOk ) ); originalExtent.setYMinimum( layerExtentMap[QStringLiteral( "ymin" )].toDouble( &yminOk ) ); originalExtent.setXMaximum( layerExtentMap[QStringLiteral( "xmax" )].toDouble( &xmaxOk ) ); originalExtent.setYMaximum( layerExtentMap[QStringLiteral( "ymax" )].toDouble( &ymaxOk ) ); if ( mSharedData->mExtent.isEmpty() && ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) ) { appendError( QgsErrorMessage( tr( "Could not retrieve layer extent" ), QStringLiteral( "AFSProvider" ) ) ); return; } QgsCoordinateReferenceSystem extentCrs = QgsArcGisRestUtils::parseSpatialReference( layerExtentMap[QStringLiteral( "spatialReference" )].toMap() ); if ( mSharedData->mExtent.isEmpty() && !extentCrs.isValid() ) { appendError( QgsErrorMessage( tr( "Could not parse spatial reference" ), QStringLiteral( "AFSProvider" ) ) ); return; } if ( xminOk && yminOk && xmaxOk && ymaxOk ) { QgsLayerMetadata::SpatialExtent spatialExtent; spatialExtent.bounds = QgsBox3d( originalExtent ); spatialExtent.extentCrs = extentCrs; QgsLayerMetadata::Extent metadataExtent; metadataExtent.setSpatialExtents( QList< QgsLayerMetadata::SpatialExtent >() << spatialExtent ); mLayerMetadata.setExtent( metadataExtent ); } if ( extentCrs.isValid() ) { mLayerMetadata.setCrs( extentCrs ); } if ( mSharedData->mExtent.isEmpty() ) { mSharedData->mExtent = originalExtent; Q_NOWARN_DEPRECATED_PUSH mSharedData->mExtent = QgsCoordinateTransform( extentCrs, mSharedData->mSourceCRS ).transformBoundingBox( mSharedData->mExtent ); Q_NOWARN_DEPRECATED_POP }
QString QgsLayerMetadataFormatter::extentSectionHtml() const { QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" ); myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + QObject::tr( "CRS" ) + QStringLiteral( "</td><td>" ) + mMetadata.crs().authid() + QStringLiteral( " - " ); myMetadata += mMetadata.crs().description() + QStringLiteral( " - " ); if ( mMetadata.crs().isGeographic() ) myMetadata += QObject::tr( "Geographic" ); else myMetadata += QObject::tr( "Projected" ); myMetadata += QLatin1String( "</td></tr>\n" ); const QgsLayerMetadata::Extent extent = mMetadata.extent(); myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + QObject::tr( "Spatial Extent" ) + QStringLiteral( "</td><td>" ); const QList< QgsLayerMetadata::SpatialExtent > spatialExtents = extent.spatialExtents(); bool notFirstRow = false; for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : spatialExtents ) { if ( notFirstRow ) { myMetadata += QLatin1String( "<br />\n" ); } myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "CRS" ) + QStringLiteral( ": </strong>" ) + spatialExtent.extentCrs.authid() + QStringLiteral( " - " ); myMetadata += spatialExtent.extentCrs.description() + QStringLiteral( " - " ); if ( spatialExtent.extentCrs.isGeographic() ) myMetadata += QObject::tr( "Geographic" ); else myMetadata += QObject::tr( "Projected" ); myMetadata += QStringLiteral( "<br />" ); myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "X Minimum" ) + QStringLiteral( ": </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMinimum() ) + QStringLiteral( "<br />" ); myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "Y Minimum" ) + QStringLiteral( ": </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMinimum() ) + QStringLiteral( "<br />" ); myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "X Maximum" ) + QStringLiteral( ": </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMaximum() ) + QStringLiteral( "<br />" ); myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "Y Maximum" ) + QStringLiteral( ": </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMaximum() ) + QStringLiteral( "<br />" ); if ( spatialExtent.bounds.zMinimum() || spatialExtent.bounds.zMinimum() ) { myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "Z Minimum" ) + QStringLiteral( ": </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMinimum() ) + QStringLiteral( "<br />" ); myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "Z Maximum" ) + QStringLiteral( ": </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMaximum() ); } notFirstRow = true; } myMetadata += QLatin1String( "</td></tr>\n" ); myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + QObject::tr( "Temporal Extent" ) + QStringLiteral( "</td><td>" ); const QList< QgsDateTimeRange > temporalExtents = extent.temporalExtents(); notFirstRow = false; for ( const QgsDateTimeRange &temporalExtent : temporalExtents ) { if ( notFirstRow ) { myMetadata += QLatin1String( "<br />\n" ); } if ( temporalExtent.isInstant() ) { myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "Instant" ) + QStringLiteral( ": </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ); } else { myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "Start" ) + QStringLiteral( ": </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) + QStringLiteral( "<br />\n" ); myMetadata += QStringLiteral( "<strong>" ) + QObject::tr( "End" ) + QStringLiteral( ": </strong>" ) + temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ); } notFirstRow = true; } myMetadata += QLatin1String( "</td></tr>\n" ); myMetadata += QLatin1String( "</table>\n" ); return myMetadata; }
bool QgsLayerMetadata::readMetadataXml( const QDomElement &metadataElement ) { QDomNode mnl; QDomElement mne; // set identifier mnl = metadataElement.namedItem( QStringLiteral( "identifier" ) ); mIdentifier = mnl.toElement().text(); // set parent identifier mnl = metadataElement.namedItem( QStringLiteral( "parentidentifier" ) ); mParentIdentifier = mnl.toElement().text(); // set language mnl = metadataElement.namedItem( QStringLiteral( "language" ) ); mLanguage = mnl.toElement().text(); // set type mnl = metadataElement.namedItem( QStringLiteral( "type" ) ); mType = mnl.toElement().text(); // set title mnl = metadataElement.namedItem( QStringLiteral( "title" ) ); mTitle = mnl.toElement().text(); // set abstract mnl = metadataElement.namedItem( QStringLiteral( "abstract" ) ); mAbstract = mnl.toElement().text(); // set keywords QDomNodeList keywords = metadataElement.elementsByTagName( QStringLiteral( "keywords" ) ); mKeywords.clear(); for ( int i = 0; i < keywords.size(); i++ ) { QStringList keywordsList; mnl = keywords.at( i ); mne = mnl.toElement(); QDomNodeList el = mne.elementsByTagName( QStringLiteral( "keyword" ) ); for ( int j = 0; j < el.size(); j++ ) { keywordsList.append( el.at( j ).toElement().text() ); } addKeywords( mne.attribute( QStringLiteral( "vocabulary" ) ), keywordsList ); } // set fees mnl = metadataElement.namedItem( QStringLiteral( "fees" ) ); mFees = mnl.toElement().text(); // constraints QDomNodeList constraintsList = metadataElement.elementsByTagName( QStringLiteral( "constraints" ) ); mConstraints.clear(); for ( int i = 0; i < constraintsList.size(); i++ ) { mnl = constraintsList.at( i ); mne = mnl.toElement(); addConstraint( QgsLayerMetadata::Constraint( mne.text(), mne.attribute( QStringLiteral( "type" ) ) ) ); } // rights QDomNodeList rightsNodeList = metadataElement.elementsByTagName( QStringLiteral( "rights" ) ); QStringList rightsList; for ( int i = 0; i < rightsNodeList.size(); i++ ) { mnl = rightsNodeList.at( i ); mne = mnl.toElement(); rightsList.append( mne.text() ); } setRights( rightsList ); // licenses QDomNodeList licensesNodeList = metadataElement.elementsByTagName( QStringLiteral( "license" ) ); QStringList licensesList; for ( int i = 0; i < licensesNodeList.size(); i++ ) { mnl = licensesNodeList.at( i ); mne = mnl.toElement(); licensesList.append( mne.text() ); } setLicenses( licensesList ); // encoding mnl = metadataElement.namedItem( QStringLiteral( "encoding" ) ); mEncoding = mnl.toElement().text(); // crs mnl = metadataElement.namedItem( QStringLiteral( "crs" ) ); if ( !mCrs.readXml( mnl ) ) mCrs = QgsCoordinateReferenceSystem(); // extent mnl = metadataElement.namedItem( QStringLiteral( "extent" ) ); QgsLayerMetadata::Extent metadataExtent; // spatial extent QDomNodeList spatialList = mnl.toElement().elementsByTagName( QStringLiteral( "spatial" ) ); QList< QgsLayerMetadata::SpatialExtent > metadataSpatialExtents; for ( int i = 0; i < spatialList.size(); i++ ) { mnl = spatialList.at( i ); mne = mnl.toElement(); QgsLayerMetadata::SpatialExtent se = QgsLayerMetadata::SpatialExtent(); se.extentCrs = QgsCoordinateReferenceSystem( mne.attribute( QStringLiteral( "crs" ) ) ); se.bounds = QgsBox3d(); se.bounds.setXMinimum( mne.attribute( QStringLiteral( "minx" ) ).toDouble() ); se.bounds.setYMinimum( mne.attribute( QStringLiteral( "miny" ) ).toDouble() ); se.bounds.setZMinimum( mne.attribute( QStringLiteral( "minz" ) ).toDouble() ); se.bounds.setXMaximum( mne.attribute( QStringLiteral( "maxx" ) ).toDouble() ); se.bounds.setYMaximum( mne.attribute( QStringLiteral( "maxy" ) ).toDouble() ); se.bounds.setZMaximum( mne.attribute( QStringLiteral( "maxz" ) ).toDouble() ); metadataSpatialExtents.append( se ); } metadataExtent.setSpatialExtents( metadataSpatialExtents ); // temporal extent mnl = metadataElement.namedItem( QStringLiteral( "extent" ) ); QDomNodeList temporalList = mnl.toElement().elementsByTagName( QStringLiteral( "temporal" ) ); QList<QgsDateTimeRange> metadataDates; for ( int j = 0; j < temporalList.size(); j++ ) { mnl = temporalList.at( j ); QDomNodeList instantList = mnl.toElement().elementsByTagName( QStringLiteral( "instant" ) ); for ( int i = 0; i < instantList.size(); i++ ) { mnl = instantList.at( i ); QDateTime d = QDateTime().fromString( mnl.toElement().text(), Qt::ISODate ); QgsDateTimeRange date = QgsDateTimeRange( d, d ); metadataDates << date; } QDomNodeList periodList = mnl.toElement().elementsByTagName( QStringLiteral( "period" ) ); for ( int i = 0; i < periodList.size(); i++ ) { QDomNode begin = periodList.at( i ).namedItem( QStringLiteral( "start" ) ); QDomNode end = periodList.at( i ).namedItem( QStringLiteral( "end" ) ); QDateTime beginDate = QDateTime().fromString( begin.toElement().text(), Qt::ISODate ); QDateTime endDate = QDateTime().fromString( end.toElement().text(), Qt::ISODate ); QgsDateTimeRange date = QgsDateTimeRange( beginDate, endDate ); metadataDates << date; } } metadataExtent.setTemporalExtents( metadataDates ); setExtent( metadataExtent ); // contact QDomNodeList contactsList = metadataElement.elementsByTagName( QStringLiteral( "contact" ) ); mContacts.clear(); for ( int i = 0; i < contactsList.size(); i++ ) { mnl = contactsList.at( i ); mne = mnl.toElement(); QgsLayerMetadata::Contact oneContact; oneContact.name = mne.namedItem( QStringLiteral( "name" ) ).toElement().text(); oneContact.organization = mne.namedItem( QStringLiteral( "organization" ) ).toElement().text(); oneContact.position = mne.namedItem( QStringLiteral( "position" ) ).toElement().text(); oneContact.voice = mne.namedItem( QStringLiteral( "voice" ) ).toElement().text(); oneContact.fax = mne.namedItem( QStringLiteral( "fax" ) ).toElement().text(); oneContact.email = mne.namedItem( QStringLiteral( "email" ) ).toElement().text(); oneContact.role = mne.namedItem( QStringLiteral( "role" ) ).toElement().text(); QList< QgsLayerMetadata::Address > addresses; QDomNodeList addressList = mne.elementsByTagName( QStringLiteral( "contactAddress" ) ); for ( int j = 0; j < addressList.size(); j++ ) { QDomElement addressElement = addressList.at( j ).toElement(); QgsLayerMetadata::Address oneAddress; oneAddress.address = addressElement.namedItem( QStringLiteral( "address" ) ).toElement().text(); oneAddress.administrativeArea = addressElement.namedItem( QStringLiteral( "administrativearea" ) ).toElement().text(); oneAddress.city = addressElement.namedItem( QStringLiteral( "city" ) ).toElement().text(); oneAddress.country = addressElement.namedItem( QStringLiteral( "country" ) ).toElement().text(); oneAddress.postalCode = addressElement.namedItem( QStringLiteral( "postalcode" ) ).toElement().text(); oneAddress.type = addressElement.namedItem( QStringLiteral( "type" ) ).toElement().text(); addresses << oneAddress; } oneContact.addresses = addresses; addContact( oneContact ); } // links mnl = metadataElement.namedItem( QStringLiteral( "links" ) ); mne = mnl.toElement(); mLinks.clear(); QDomNodeList el = mne.elementsByTagName( QStringLiteral( "link" ) ); for ( int i = 0; i < el.size(); i++ ) { mne = el.at( i ).toElement(); QgsLayerMetadata::Link oneLink; oneLink.name = mne.attribute( QStringLiteral( "name" ) ); oneLink.type = mne.attribute( QStringLiteral( "type" ) ); oneLink.url = mne.attribute( QStringLiteral( "url" ) ); oneLink.description = mne.attribute( QStringLiteral( "description" ) ); oneLink.format = mne.attribute( QStringLiteral( "format" ) ); oneLink.mimeType = mne.attribute( QStringLiteral( "mimeType" ) ); oneLink.size = mne.attribute( QStringLiteral( "size" ) ); addLink( oneLink ); } // history QDomNodeList historyNodeList = metadataElement.elementsByTagName( QStringLiteral( "history" ) ); QStringList historyList; for ( int i = 0; i < historyNodeList.size(); i++ ) { mnl = historyNodeList.at( i ); mne = mnl.toElement(); historyList.append( mne.text() ); } setHistory( historyList ); return true; }
QgsAfsProvider::QgsAfsProvider( const QString &uri, const ProviderOptions &options ) : QgsVectorDataProvider( uri, options ) { mSharedData.reset( new QgsAfsSharedData() ); mSharedData->mGeometryType = QgsWkbTypes::Unknown; mSharedData->mDataSource = QgsDataSourceUri( uri ); const QString authcfg = mSharedData->mDataSource.authConfigId(); // Set CRS mSharedData->mSourceCRS.createFromString( mSharedData->mDataSource.param( QStringLiteral( "crs" ) ) ); // Get layer info QString errorTitle, errorMessage; const QString referer = mSharedData->mDataSource.param( QStringLiteral( "referer" ) ); if ( !referer.isEmpty() ) mRequestHeaders[ QStringLiteral( "Referer" )] = referer; const QVariantMap layerData = QgsArcGisRestUtils::getLayerInfo( mSharedData->mDataSource.param( QStringLiteral( "url" ) ), authcfg, errorTitle, errorMessage, mRequestHeaders ); if ( layerData.isEmpty() ) { pushError( errorTitle + ": " + errorMessage ); appendError( QgsErrorMessage( tr( "getLayerInfo failed" ), QStringLiteral( "AFSProvider" ) ) ); return; } mLayerName = layerData[QStringLiteral( "name" )].toString(); mLayerDescription = layerData[QStringLiteral( "description" )].toString(); // Set extent QStringList coords = mSharedData->mDataSource.param( QStringLiteral( "bbox" ) ).split( ',' ); bool limitBbox = false; if ( coords.size() == 4 ) { bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; mSharedData->mExtent.setXMinimum( coords[0].toDouble( &xminOk ) ); mSharedData->mExtent.setYMinimum( coords[1].toDouble( &yminOk ) ); mSharedData->mExtent.setXMaximum( coords[2].toDouble( &xmaxOk ) ); mSharedData->mExtent.setYMaximum( coords[3].toDouble( &ymaxOk ) ); if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) mSharedData->mExtent = QgsRectangle(); else { // user has set a bounding box limit on the layer - so we only EVER fetch features from this extent limitBbox = true; } } const QVariantMap layerExtentMap = layerData[QStringLiteral( "extent" )].toMap(); bool xminOk = false, yminOk = false, xmaxOk = false, ymaxOk = false; QgsRectangle originalExtent; originalExtent.setXMinimum( layerExtentMap[QStringLiteral( "xmin" )].toDouble( &xminOk ) ); originalExtent.setYMinimum( layerExtentMap[QStringLiteral( "ymin" )].toDouble( &yminOk ) ); originalExtent.setXMaximum( layerExtentMap[QStringLiteral( "xmax" )].toDouble( &xmaxOk ) ); originalExtent.setYMaximum( layerExtentMap[QStringLiteral( "ymax" )].toDouble( &ymaxOk ) ); if ( mSharedData->mExtent.isEmpty() && ( !xminOk || !yminOk || !xmaxOk || !ymaxOk ) ) { appendError( QgsErrorMessage( tr( "Could not retrieve layer extent" ), QStringLiteral( "AFSProvider" ) ) ); return; } QgsCoordinateReferenceSystem extentCrs = QgsArcGisRestUtils::parseSpatialReference( layerExtentMap[QStringLiteral( "spatialReference" )].toMap() ); if ( mSharedData->mExtent.isEmpty() && !extentCrs.isValid() ) { appendError( QgsErrorMessage( tr( "Could not parse spatial reference" ), QStringLiteral( "AFSProvider" ) ) ); return; } if ( xminOk && yminOk && xmaxOk && ymaxOk ) { QgsLayerMetadata::SpatialExtent spatialExtent; spatialExtent.bounds = QgsBox3d( originalExtent ); spatialExtent.extentCrs = extentCrs; QgsLayerMetadata::Extent metadataExtent; metadataExtent.setSpatialExtents( QList< QgsLayerMetadata::SpatialExtent >() << spatialExtent ); mLayerMetadata.setExtent( metadataExtent ); } if ( extentCrs.isValid() ) { mLayerMetadata.setCrs( extentCrs ); } if ( mSharedData->mExtent.isEmpty() ) { mSharedData->mExtent = originalExtent; Q_NOWARN_DEPRECATED_PUSH mSharedData->mExtent = QgsCoordinateTransform( extentCrs, mSharedData->mSourceCRS ).transformBoundingBox( mSharedData->mExtent ); Q_NOWARN_DEPRECATED_POP }