Example #1
0
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;
}
Example #3
0
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;
}
Example #4
0
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
  }