QgsRasterIdentifyResult QgsGrassRasterProvider::identify( const QgsPoint & thePoint, QgsRaster::IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight, int /*theDpi*/ )
{
  Q_UNUSED( theExtent );
  Q_UNUSED( theWidth );
  Q_UNUSED( theHeight );
  QgsDebugMsg( "Entered" );
  QMap<int, QVariant> results;
  QMap<int, QVariant> noDataResults;
  noDataResults.insert( 1, QVariant() );
  QgsRasterIdentifyResult noDataResult( QgsRaster::IdentifyFormatValue, results );

  if ( theFormat != QgsRaster::IdentifyFormatValue )
  {
    return QgsRasterIdentifyResult( QGS_ERROR( tr( "Format not supported" ) ) );
  }

  if ( !extent().contains( thePoint ) )
  {
    return noDataResult;
  }

  // TODO: use doubles instead of strings

  // attention, value tool does his own tricks with grass identify() so it stops to refresh values outside extent or null values e.g.

  bool ok;
  double value = mRasterValue.value( thePoint.x(), thePoint.y(), &ok );

  if ( !ok )
  {
    return QgsRasterIdentifyResult( QGS_ERROR( tr( "Cannot read data" ) ) );
  }

  // no data?
  if ( qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue ) )
  {
    return noDataResult;
  }

  // Apply user no data
  QgsRasterRangeList myNoDataRangeList = userNoDataValues( 1 );
  if ( QgsRasterRange::contains( value, myNoDataRangeList ) )
  {
    return noDataResult;
  }

  results.insert( 1, value );

  return QgsRasterIdentifyResult( QgsRaster::IdentifyFormatValue, results );
}
// Default implementation for values
QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox, int width, int height, int /*dpi*/ )
{
  QgsDebugMsgLevel( "Entered", 4 );
  QMap<int, QVariant> results;

  if ( format != QgsRaster::IdentifyFormatValue || !( capabilities() & IdentifyValue ) )
  {
    QgsDebugMsg( "Format not supported" );
    return QgsRasterIdentifyResult( ERR( tr( "Format not supported" ) ) );
  }

  if ( !extent().contains( point ) )
  {
    // Outside the raster
    for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
    {
      results.insert( bandNo, QVariant() );
    }
    return QgsRasterIdentifyResult( QgsRaster::IdentifyFormatValue, results );
  }

  QgsRectangle finalExtent = boundingBox;
  if ( finalExtent.isEmpty() )
    finalExtent = extent();

  if ( width == 0 )
  {
    width = capabilities() & Size ? xSize() : 1000;
  }
  if ( height == 0 )
  {
    height = capabilities() & Size ? ySize() : 1000;
  }

  // Calculate the row / column where the point falls
  double xres = ( finalExtent.width() ) / width;
  double yres = ( finalExtent.height() ) / height;

  int col = static_cast< int >( std::floor( ( point.x() - finalExtent.xMinimum() ) / xres ) );
  int row = static_cast< int >( std::floor( ( finalExtent.yMaximum() - point.y() ) / yres ) );

  double xMin = finalExtent.xMinimum() + col * xres;
  double xMax = xMin + xres;
  double yMax = finalExtent.yMaximum() - row * yres;
  double yMin = yMax - yres;
  QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );

  for ( int i = 1; i <= bandCount(); i++ )
  {
    QgsRasterBlock *myBlock = block( i, pixelExtent, 1, 1 );

    if ( myBlock )
    {
      double value = myBlock->value( 0 );

      results.insert( i, value );
      delete myBlock;
    }
    else
    {
      results.insert( i, QVariant() );
    }
  }
  return QgsRasterIdentifyResult( QgsRaster::IdentifyFormatValue, results );
}
// Default implementation for values
QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPoint & thePoint, QgsRaster::IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
  QgsDebugMsg( "Entered" );
  QMap<int, QVariant> results;

  if ( theFormat != QgsRaster::IdentifyFormatValue || !( capabilities() & IdentifyValue ) )
  {
    QgsDebugMsg( "Format not supported" );
    return QgsRasterIdentifyResult( ERR( tr( "Format not supported" ) ) );
  }

  if ( !extent().contains( thePoint ) )
  {
    // Outside the raster
    for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
    {
      results.insert( bandNo, QVariant() );
    }
    return QgsRasterIdentifyResult( QgsRaster::IdentifyFormatValue, results );
  }

  QgsRectangle myExtent = theExtent;
  if ( myExtent.isEmpty() )  myExtent = extent();

  if ( theWidth == 0 )
  {
    theWidth = capabilities() & Size ? xSize() : 1000;
  }
  if ( theHeight == 0 )
  {
    theHeight = capabilities() & Size ? ySize() : 1000;
  }

  // Calculate the row / column where the point falls
  double xres = ( myExtent.width() ) / theWidth;
  double yres = ( myExtent.height() ) / theHeight;

  int col = ( int ) floor(( thePoint.x() - myExtent.xMinimum() ) / xres );
  int row = ( int ) floor(( myExtent.yMaximum() - thePoint.y() ) / yres );

  double xMin = myExtent.xMinimum() + col * xres;
  double xMax = xMin + xres;
  double yMax = myExtent.yMaximum() - row * yres;
  double yMin = yMax - yres;
  QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );

  for ( int i = 1; i <= bandCount(); i++ )
  {
    QgsRasterBlock * myBlock = block( i, pixelExtent, 1, 1 );

    if ( myBlock )
    {
      double value = myBlock->value( 0 );

      results.insert( i, value );
      delete myBlock;
    }
    else
    {
      results.insert( i, QVariant() );
    }
  }
  return QgsRasterIdentifyResult( QgsRaster::IdentifyFormatValue, results );
}
Exemple #4
0
QgsRasterIdentifyResult QgsAmsProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &extent, int width, int height, int dpi )
{
  // http://resources.arcgis.com/en/help/rest/apiref/identify.html
  QgsDataSourceUri dataSource( dataSourceUri() );
  QUrl queryUrl( dataSource.param( QStringLiteral( "url" ) ) + "/identify" );
  queryUrl.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "json" ) );
  queryUrl.addQueryItem( QStringLiteral( "geometryType" ), QStringLiteral( "esriGeometryPoint" ) );
  queryUrl.addQueryItem( QStringLiteral( "geometry" ), QStringLiteral( "{x: %1, y: %2}" ).arg( point.x(), 0, 'f' ).arg( point.y(), 0, 'f' ) );
//  queryUrl.addQueryItem( "sr", mCrs.postgisSrid() );
  queryUrl.addQueryItem( QStringLiteral( "layers" ), QStringLiteral( "all:%1" ).arg( dataSource.param( QStringLiteral( "layer" ) ) ) );
  queryUrl.addQueryItem( QStringLiteral( "imageDisplay" ), QStringLiteral( "%1,%2,%3" ).arg( width ).arg( height ).arg( dpi ) );
  queryUrl.addQueryItem( QStringLiteral( "mapExtent" ), QStringLiteral( "%1,%2,%3,%4" ).arg( extent.xMinimum(), 0, 'f' ).arg( extent.yMinimum(), 0, 'f' ).arg( extent.xMaximum(), 0, 'f' ).arg( extent.yMaximum(), 0, 'f' ) );
  queryUrl.addQueryItem( QStringLiteral( "tolerance" ), QStringLiteral( "10" ) );

  const QString authcfg = dataSource.param( QStringLiteral( "authcfg" ) );
  const QVariantList queryResults = QgsArcGisRestUtils::queryServiceJSON( queryUrl, authcfg, mErrorTitle, mError ).value( QStringLiteral( "results" ) ).toList();

  QMap<int, QVariant> entries;

  if ( format == QgsRaster::IdentifyFormatText )
  {
    for ( const QVariant &result : queryResults )
    {
      const QVariantMap resultMap = result.toMap();
      QVariantMap attributesMap = resultMap[QStringLiteral( "attributes" )].toMap();
      QString valueStr;
      for ( auto it = attributesMap.constBegin(); it != attributesMap.constEnd(); ++it )
      {
        valueStr += QStringLiteral( "%1 = %2\n" ).arg( it.key(), it.value().toString() );
      }
      entries.insert( entries.size(), valueStr );
    }
  }
  else if ( format == QgsRaster::IdentifyFormatFeature )
  {
    for ( const QVariant &result : queryResults )
    {
      const QVariantMap resultMap = result.toMap();

      QgsFields fields;
      const QVariantMap attributesMap = resultMap[QStringLiteral( "attributes" )].toMap();
      QgsAttributes featureAttributes;
      for ( auto it = attributesMap.constBegin(); it != attributesMap.constEnd(); ++it )
      {
        fields.append( QgsField( it.key(), QVariant::String, QStringLiteral( "string" ) ) );
        featureAttributes.append( it.value().toString() );
      }
      QgsCoordinateReferenceSystem crs;
      std::unique_ptr< QgsAbstractGeometry > geometry = QgsArcGisRestUtils::parseEsriGeoJSON( resultMap[QStringLiteral( "geometry" )].toMap(), resultMap[QStringLiteral( "geometryType" )].toString(), false, false, &crs );
      QgsFeature feature( fields );
      feature.setGeometry( QgsGeometry( std::move( geometry ) ) );
      feature.setAttributes( featureAttributes );
      feature.setValid( true );
      QgsFeatureStore store( fields, crs );
      QMap<QString, QVariant> params;
      params[QStringLiteral( "sublayer" )] = resultMap[QStringLiteral( "layerName" )].toString();
      params[QStringLiteral( "featureType" )] = attributesMap[resultMap[QStringLiteral( "displayFieldName" )].toString()].toString();
      store.setParams( params );
      store.addFeature( feature );
      entries.insert( entries.size(), qVariantFromValue( QList<QgsFeatureStore>() << store ) );
    }
  }
  return QgsRasterIdentifyResult( format, entries );
}