예제 #1
0
void QgsRasterInterface::initStatistics( QgsRasterBandStats &theStatistics,
    int theBandNo,
    int theStats,
    const QgsRectangle & theExtent,
    int theSampleSize )
{
  QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );

  theStatistics.bandNumber = theBandNo;
  theStatistics.statsGathered = theStats;

  QgsRectangle myExtent;
  if ( theExtent.isEmpty() )
  {
    myExtent = extent();
  }
  else
  {
    myExtent = extent().intersect( &theExtent );
  }
  theStatistics.extent = myExtent;

  if ( theSampleSize > 0 )
  {
    // Calc resolution from theSampleSize
    double xRes, yRes;
    xRes = yRes = sqrt(( myExtent.width() * myExtent.height() ) / theSampleSize );

    // But limit by physical resolution
    if ( capabilities() & Size )
    {
      double srcXRes = extent().width() / xSize();
      double srcYRes = extent().height() / ySize();
      if ( xRes < srcXRes ) xRes = srcXRes;
      if ( yRes < srcYRes ) yRes = srcYRes;
    }
    QgsDebugMsg( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ) );

    theStatistics.width = static_cast <int>( myExtent.width() / xRes );
    theStatistics.height = static_cast <int>( myExtent.height() / yRes );
  }
  else
  {
    if ( capabilities() & Size )
    {
      theStatistics.width = xSize();
      theStatistics.height = ySize();
    }
    else
    {
      theStatistics.width = 1000;
      theStatistics.height = 1000;
    }
  }
  QgsDebugMsg( QString( "theStatistics.width = %1 theStatistics.height = %2" ).arg( theStatistics.width ).arg( theStatistics.height ) );
}
예제 #2
0
void QgsRasterInterface::initStatistics( QgsRasterBandStats &statistics,
    int bandNo,
    int stats,
    const QgsRectangle &boundingBox,
    int sampleSize )
{
  QgsDebugMsgLevel( QString( "theBandNo = %1 sampleSize = %2" ).arg( bandNo ).arg( sampleSize ), 4 );

  statistics.bandNumber = bandNo;
  statistics.statsGathered = stats;

  QgsRectangle finalExtent;
  if ( boundingBox.isEmpty() )
  {
    finalExtent = extent();
  }
  else
  {
    finalExtent = extent().intersect( boundingBox );
  }
  statistics.extent = finalExtent;

  if ( sampleSize > 0 )
  {
    // Calc resolution from theSampleSize
    double xRes, yRes;
    xRes = yRes = std::sqrt( ( finalExtent.width() * finalExtent.height() ) / sampleSize );

    // But limit by physical resolution
    if ( capabilities() & Size )
    {
      double srcXRes = extent().width() / xSize();
      double srcYRes = extent().height() / ySize();
      if ( xRes < srcXRes ) xRes = srcXRes;
      if ( yRes < srcYRes ) yRes = srcYRes;
    }
    QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );

    statistics.width = static_cast <int>( finalExtent.width() / xRes );
    statistics.height = static_cast <int>( finalExtent.height() / yRes );
  }
  else
  {
    if ( capabilities() & Size )
    {
      statistics.width = xSize();
      statistics.height = ySize();
    }
    else
    {
      statistics.width = 1000;
      statistics.height = 1000;
    }
  }
  QgsDebugMsgLevel( QString( "theStatistics.width = %1 statistics.height = %2" ).arg( statistics.width ).arg( statistics.height ), 4 );
}
예제 #3
0
void LineSegmentPlot::updateDataLimits()
{
    qDebug() << Q_FUNC_INFO;
    int xLen = xSize(), yLen = ySize(), endXLen = m_endX.size(), endYLen = m_endY.size();
    int N = qMin( qMin(xLen, yLen), qMin(endXLen, endYLen) );
    m_dataSize = N;

    qreal minX = Inf, maxX = -Inf, minY = Inf, maxY = -Inf;
    // Calculate the y limits
    RangeValues yrng = ArrayUtil::limits(yData());
    minY = yrng.min;
    maxY = yrng.max;

    yrng = ArrayUtil::limits(m_endY);
    minY = qMin(minY, yrng.min);
    maxY = qMax(maxY, yrng.max);

    RangeValues xrng = ArrayUtil::limits(xData());
    minX = xrng.min;
    maxX = xrng.max;

    xrng = ArrayUtil::limits(m_endX);
    minX = qMin(minX, xrng.min);
    maxX = qMax(maxX, xrng.max);

    QRectF newLim;
    newLim.setLeft(minX);
    newLim.setTop(minY);
    newLim.setRight(maxX);
    newLim.setBottom(maxY);
    setDataLimits(newLim);
}
예제 #4
0
// Default implementation for values
QMap<int, QVariant> QgsRasterDataProvider::identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
  QgsDebugMsg( "Entered" );
  QMap<int, QVariant> results;

  if ( theFormat != IdentifyFormatValue || !( capabilities() & IdentifyValue ) )
  {
    QgsDebugMsg( "Format not supported" );
    return results;
  }

  if ( !extent().contains( thePoint ) )
  {
    // Outside the raster
    for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
    {
      results.insert( bandNo, noDataValue( bandNo ) );
    }
    return 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 );

    double value = noDataValue( i );
    if ( myBlock ) value = myBlock->value( 0 );

    results.insert( i, value );
  }
  return results;
}
예제 #5
0
QgsRasterBandStats QgsGrassRasterProvider::bandStatistics( int bandNo, int stats, const QgsRectangle &boundingBox, int sampleSize, QgsRasterBlockFeedback * )
{
  QgsDebugMsg( QString( "theBandNo = %1 sampleSize = %2" ).arg( bandNo ).arg( sampleSize ) );
  QgsRasterBandStats myRasterBandStats;
  initStatistics( myRasterBandStats, bandNo, stats, boundingBox, sampleSize );

  const auto constMStatistics = mStatistics;
  for ( const QgsRasterBandStats &stats : constMStatistics )
  {
    if ( stats.contains( myRasterBandStats ) )
    {
      QgsDebugMsg( "Using cached statistics." );
      return stats;
    }
  }

  QgsRectangle extent = myRasterBandStats.extent;

  int sampleRows = myRasterBandStats.height;
  int sampleCols = myRasterBandStats.width;

  // With stats we have to be careful about timeout, empirical value,
  // 0.001 / cell should be sufficient using 0.005 to be sure + constant (ms)
  int timeout = 30000 + 0.005 * xSize() * ySize();

  QString error;
  QHash<QString, QString> info = QgsGrass::info( mGisdbase, mLocation, mMapset, mMapName, QgsGrassObject::Raster,
                                 QStringLiteral( "stats" ), extent, sampleRows, sampleCols, timeout, error );

  if ( info.isEmpty() || !error.isEmpty() )
  {
    return myRasterBandStats;
  }

  myRasterBandStats.sum = info[QStringLiteral( "SUM" )].toDouble();
  myRasterBandStats.elementCount = info[QStringLiteral( "COUNT" )].toInt();
  myRasterBandStats.minimumValue = info[QStringLiteral( "MIN" )].toDouble();
  myRasterBandStats.maximumValue = info[QStringLiteral( "MAX" )].toDouble();
  myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
  myRasterBandStats.sumOfSquares = info[QStringLiteral( "SQSUM" )].toDouble();
  myRasterBandStats.mean = info[QStringLiteral( "MEAN" )].toDouble();
  myRasterBandStats.stdDev = info[QStringLiteral( "STDEV" )].toDouble();

  QgsDebugMsg( QString( "min = %1" ).arg( myRasterBandStats.minimumValue ) );
  QgsDebugMsg( QString( "max = %1" ).arg( myRasterBandStats.maximumValue ) );
  QgsDebugMsg( QString( "count = %1" ).arg( myRasterBandStats.elementCount ) );
  QgsDebugMsg( QString( "stdev = %1" ).arg( myRasterBandStats.stdDev ) );

  myRasterBandStats.statsGathered = QgsRasterBandStats::Min | QgsRasterBandStats::Max |
                                    QgsRasterBandStats::Range | QgsRasterBandStats::Mean |
                                    QgsRasterBandStats::Sum | QgsRasterBandStats::SumOfSquares |
                                    QgsRasterBandStats::StdDev;

  mStatistics.append( myRasterBandStats );
  return myRasterBandStats;
}
QgsRasterBandStats QgsGrassRasterProvider::bandStatistics( int theBandNo, int theStats, const QgsRectangle & theExtent, int theSampleSize )
{
  QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
  QgsRasterBandStats myRasterBandStats;
  initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );

  foreach ( QgsRasterBandStats stats, mStatistics )
  {
    if ( stats.contains( myRasterBandStats ) )
    {
      QgsDebugMsg( "Using cached statistics." );
      return stats;
    }
  }

  QgsRectangle extent = myRasterBandStats.extent;

  int sampleRows = myRasterBandStats.height;
  int sampleCols = myRasterBandStats.width;

  // With stats we have to be careful about timeout, empirical value,
  // 0.001 / cell should be sufficient using 0.005 to be sure + constant (ms)
  int timeout = 30000 + 0.005 * xSize() * ySize();

  QHash<QString, QString> info = QgsGrass::info( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, "stats", extent, sampleRows, sampleCols, timeout );

  if ( info.isEmpty() )
  {
    return myRasterBandStats;
  }

  myRasterBandStats.sum = info["SUM"].toDouble();
  myRasterBandStats.elementCount = info["COUNT"].toInt();
  myRasterBandStats.minimumValue = info["MIN"].toDouble();
  myRasterBandStats.maximumValue = info["MAX"].toDouble();
  myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
  myRasterBandStats.sumOfSquares = info["SQSUM"].toDouble();
  myRasterBandStats.mean = info["MEAN"].toDouble();
  myRasterBandStats.stdDev = info["STDEV"].toDouble();

  QgsDebugMsg( QString( "min = %1" ).arg( myRasterBandStats.minimumValue ) );
  QgsDebugMsg( QString( "max = %1" ).arg( myRasterBandStats.maximumValue ) );
  QgsDebugMsg( QString( "count = %1" ).arg( myRasterBandStats.elementCount ) );
  QgsDebugMsg( QString( "stdev = %1" ).arg( myRasterBandStats.stdDev ) );

  myRasterBandStats.statsGathered = QgsRasterBandStats::Min | QgsRasterBandStats::Max |
                                    QgsRasterBandStats::Range | QgsRasterBandStats::Mean |
                                    QgsRasterBandStats::Sum | QgsRasterBandStats::SumOfSquares |
                                    QgsRasterBandStats::StdDev;

  mStatistics.append( myRasterBandStats );
  return myRasterBandStats;
}
예제 #7
0
void Field::reallocateRobot(boost::shared_ptr<Robot> robot)
{
    removeRobot(robot);
    Field *nextField=_ourEther->findFieldWithCoords(_xCoord+robot->getNextFieldXPos(),
                                                    _yCoord+robot->getNextFieldYPos());
    if (nextField!=NULL) {
        nextField->addRobot(robot);
        robot->setPrevFieldXPos(_xCoord);
        robot->setPrevFieldYPos(_yCoord);
        robot->setXPos(robot->getXPos()-xSize()*robot->getNextFieldXPos());
        robot->setYPos(robot->getYPos()-ySize()*robot->getNextFieldYPos());
    }
    else {
        std::cerr << "Error: robot appears to have gone out of scene bounds. Rofl." << std::endl;
    }
}
예제 #8
0
int FileMcIDAS::DiskWrite(int channel){  
  
  McIDAS_LineDoc mline;

  mline.ValidityCode = 0 ;
  mline.BlockHeaderCRC = gvar.crc();
  memcpy(&mline.ScanStatus,&imagerDoc.Iscan,4); 
  memcpy(mline.Time,&imagerDoc.T_sps_current,sizeof(imagerDoc.T_sps_current) );  
  memcpy(mline.BlockHeader,&gvar.Hdr, 30);
  memcpy(mline.LineDoc, lineDoc, 32);

  write(Bin[channel],&mline, 80);
  write(Bin[channel],DataPtr(channel,0,0), 
	xSize(channel)*wordSize(channel));
  
  return(0);
}
예제 #9
0
bool RenderThemeWinCE::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
    Color buttonColor = (o->node() && o->node()->active()) ? Color(138, 138, 138) : Color(186, 186, 186);

    IntSize cancelSize(10, 10);
    IntSize cancelRadius(cancelSize.width() / 2, cancelSize.height() / 2);
    int x = r.x() + (r.width() - cancelSize.width()) / 2;
    int y = r.y() + (r.height() - cancelSize.height()) / 2 + 1;
    IntRect cancelBounds(IntPoint(x, y), cancelSize);
    paintInfo.context->save();
    paintInfo.context->addRoundedRectClip(RoundedRect(cancelBounds, cancelRadius, cancelRadius, cancelRadius, cancelRadius));
    paintInfo.context->fillRect(cancelBounds, buttonColor, ColorSpaceDeviceRGB);

    // Draw the 'x'
    IntSize xSize(3, 3);
    IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize);
    paintInfo.context->setStrokeColor(Color::white, ColorSpaceDeviceRGB);
    paintInfo.context->drawLine(xBounds.location(),  xBounds.location() + xBounds.size());
    paintInfo.context->drawLine(IntPoint(xBounds.maxX(), xBounds.y()),  IntPoint(xBounds.x(), xBounds.maxY()));

    paintInfo.context->restore();
    return false;
}
예제 #10
0
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qint64 xSize(400), ySize(440);

    QString locale = QLocale::system().name().section('_', 0, 0);
    QString programLanguage = locale;

    QFileInfo configurationFile("WALoader.ini");
    QSettings programGenericSettings("WALoader.ini", QSettings::IniFormat);

    if (!configurationFile.exists())
    {
        // Let's create the file
        programGenericSettings.beginGroup("Program");
        programGenericSettings.setValue("Language", locale);
        programGenericSettings.setValue("XSize", 400);
        programGenericSettings.setValue("YSize", 440);
        programGenericSettings.endGroup();
    }
    else
    {
        programGenericSettings.beginGroup("Program");

        if (programGenericSettings.contains("Language"))
        {
            programLanguage = programGenericSettings.value("Language").toString();
        }
        else
        {
            programGenericSettings.setValue("Language", QVariant(locale));
        }

        if (programGenericSettings.contains("XSize"))
        {
            xSize = programGenericSettings.value("XSize").toInt();
        }
        else
        {
            programGenericSettings.setValue("XSize", QVariant(xSize));
        }

        if (programGenericSettings.contains("YSize"))
        {
            ySize = programGenericSettings.value("YSize").toInt();
        }
        else
        {
            programGenericSettings.setValue("YSize", QVariant(ySize));
        }

        programGenericSettings.endGroup();
    }

    QTranslator customTranslationFile;
    customTranslationFile.load(QString("WALoader_") + programLanguage);
    app.installTranslator(&customTranslationFile);

    QTranslator qtTranslationFile;
    qtTranslationFile.load(QString("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    app.installTranslator(&qtTranslationFile);

    WaLoaderWindow appWindow(xSize, ySize);
    appWindow.show();

    return app.exec();
}
예제 #11
0
void QgsRasterInterface::initHistogram( QgsRasterHistogram &theHistogram,
                                        int theBandNo,
                                        int theBinCount,
                                        double theMinimum, double theMaximum,
                                        const QgsRectangle & theExtent,
                                        int theSampleSize,
                                        bool theIncludeOutOfRange )
{
  theHistogram.bandNumber = theBandNo;
  theHistogram.minimum = theMinimum;
  theHistogram.maximum = theMaximum;
  theHistogram.includeOutOfRange = theIncludeOutOfRange;

  int mySrcDataType = srcDataType( theBandNo );

  if ( qIsNaN( theHistogram.minimum ) )
  {
    // TODO: this was OK when stats/histogram were calced in provider,
    // but what TODO in other interfaces? Check for mInput for now.
    if ( !mInput && mySrcDataType == QGis::Byte )
    {
      theHistogram.minimum = 0; // see histogram() for shift for rounding
    }
    else
    {
      // We need statistics -> avoid histogramDefaults in hasHistogram if possible
      // TODO: use approximated statistics if aproximated histogram is requested
      // (theSampleSize > 0)
      QgsRasterBandStats stats =  bandStatistics( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
      theHistogram.minimum = stats.minimumValue;
    }
  }
  if ( qIsNaN( theHistogram.maximum ) )
  {
    if ( !mInput && mySrcDataType == QGis::Byte )
    {
      theHistogram.maximum = 255;
    }
    else
    {
      QgsRasterBandStats stats =  bandStatistics( theBandNo, QgsRasterBandStats::Max, theExtent, theSampleSize );
      theHistogram.maximum = stats.maximumValue;
    }
  }

  QgsRectangle myExtent;
  if ( theExtent.isEmpty() )
  {
    myExtent = extent();
  }
  else
  {
    myExtent = extent().intersect( &theExtent );
  }
  theHistogram.extent = myExtent;

  if ( theSampleSize > 0 )
  {
    // Calc resolution from theSampleSize
    double xRes, yRes;
    xRes = yRes = sqrt(( myExtent.width() * myExtent.height() ) / theSampleSize );

    // But limit by physical resolution
    if ( capabilities() & Size )
    {
      double srcXRes = extent().width() / xSize();
      double srcYRes = extent().height() / ySize();
      if ( xRes < srcXRes ) xRes = srcXRes;
      if ( yRes < srcYRes ) yRes = srcYRes;
    }
    QgsDebugMsg( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ) );

    theHistogram.width = static_cast <int>( myExtent.width() / xRes );
    theHistogram.height = static_cast <int>( myExtent.height() / yRes );
  }
  else
  {
    if ( capabilities() & Size )
    {
      theHistogram.width = xSize();
      theHistogram.height = ySize();
    }
    else
    {
      theHistogram.width = 1000;
      theHistogram.height = 1000;
    }
  }
  QgsDebugMsg( QString( "theHistogram.width = %1 theHistogram.height = %2" ).arg( theHistogram.width ).arg( theHistogram.height ) );

  int myBinCount = theBinCount;
  if ( myBinCount == 0 )
  {
    // TODO: this was OK when stats/histogram were calced in provider,
    // but what TODO in other interfaces? Check for mInput for now.
    if ( !mInput && mySrcDataType == QGis::Byte )
    {
      myBinCount = 256; // Cannot store more values in byte
    }
    else
    {
      // There is no best default value, to display something reasonable in histogram chart, binCount should be small, OTOH, to get precise data for cumulative cut, the number should be big. Because it is easier to define fixed lower value for the chart, we calc optimum binCount for higher resolution (to avoid calculating that where histogram() is used. In any any case, it does not make sense to use more than width*height;
      myBinCount = theHistogram.width * theHistogram.height;
      if ( myBinCount > 1000 )  myBinCount = 1000;

      // for Int16/Int32 make sure bin count <= actual range, because there is no sense in having
      // bins at fractional values
      if ( !mInput && (
             mySrcDataType == QGis::Int16 || mySrcDataType == QGis::Int32 ||
             mySrcDataType == QGis::UInt16 || mySrcDataType == QGis::UInt32 ) )
      {
        if ( myBinCount > theHistogram.maximum - theHistogram.minimum + 1 )
          myBinCount = int( ceil( theHistogram.maximum - theHistogram.minimum + 1 ) );
      }
    }
  }
  theHistogram.binCount = myBinCount;
  QgsDebugMsg( QString( "theHistogram.binCount = %1" ).arg( theHistogram.binCount ) );
}
예제 #12
0
// 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 );
}
예제 #13
0
void test( const std::string & meshFile )
{
   auto mesh = make_shared< MeshType >();
   mesh::readAndBroadcast( meshFile, *mesh);

   auto aabb = computeAABB( *mesh );

   using Scalar = typename MeshType::Scalar;

   Vector3<Scalar> translation( numeric_cast<Scalar>( aabb.xSize() ) * Scalar(2) * Scalar( MPIManager::instance()->rank() ), Scalar(0), Scalar(0) );
   translate( *mesh, translation );

   mesh->request_face_normals();
   mesh->request_vertex_normals();
   mesh->update_normals();

   mesh->request_face_status();

   bool b = true;
   for( auto it = mesh->faces_begin(); it != mesh->faces_end(); ++it )
   {
      mesh->status( *it ).set_tagged( b );
      b =  !b;
   }

   mesh->request_vertex_status();

   b = true;
   for( auto it = mesh->vertices_begin(); it != mesh->vertices_end(); ++it )
   {
      mesh->status( *it ).set_tagged( b );
      b = !b;
   }

   std::vector< typename MeshType::Color > colors;
   colors.push_back( typename MeshType::Color( 255,0,0 ) );
   colors.push_back( typename MeshType::Color( 0,255,0 ) );
   colors.push_back( typename MeshType::Color( 0,0,255 ) );
   auto colorIt = colors.begin();

   mesh->request_vertex_colors();
   for( auto it = mesh->vertices_begin(); it != mesh->vertices_end(); ++it )
   {
      mesh->set_color( *it, *colorIt );

      ++colorIt;
      if( colorIt == colors.end() )
         colorIt = colors.begin();
   }

   mesh->request_face_colors();
   for( auto it = mesh->faces_begin(); it != mesh->faces_end(); ++it )
   {
      mesh->set_color( *it, *colorIt );

      ++colorIt;
      if( colorIt == colors.end() )
         colorIt = colors.begin();
   }

   DistributedVTKMeshWriter< MeshType > meshWriter( mesh, "distributed_mesh_vtk_test_unfiltered", 1 );
   meshWriter.addDataSource( make_shared< NormalsVertexDataSource< MeshType > >() );
   meshWriter.addDataSource( make_shared< NormalsFaceDataSource  < MeshType > >() );

   meshWriter.addDataSource( make_shared< AreaFaceDataSource     < MeshType > >() );

   meshWriter.addDataSource( make_shared< StatusBitFaceDataSource  < MeshType > >( OpenMesh::Attributes::TAGGED, "tagged" ) );
   meshWriter.addDataSource( make_shared< StatusBitVertexDataSource< MeshType > >( OpenMesh::Attributes::TAGGED, "tagged" ) );

   meshWriter.addDataSource( make_shared< ColorFaceDataSource  < MeshType > >() );
   meshWriter.addDataSource( make_shared< ColorVertexDataSource< MeshType > >() );

   meshWriter.addDataSource( make_shared< IndexFaceDataSource  < MeshType > >() );
   meshWriter.addDataSource( make_shared< IndexVertexDataSource< MeshType > >() );

   meshWriter.addDataSource( make_shared< RankFaceDataSource  < MeshType > >() );
   meshWriter.addDataSource( make_shared< RankVertexDataSource< MeshType > >() );

   meshWriter();


   DistributedVTKMeshWriter< MeshType > meshWriterAABBfiltered( mesh, "distributed_mesh_vtk_test_aabb_filter", 1 );
   meshWriterAABBfiltered.addDataSource( make_shared< NormalsVertexDataSource< MeshType > >() );
   meshWriterAABBfiltered.addDataSource( make_shared< NormalsFaceDataSource  < MeshType > >() );

   meshWriterAABBfiltered.addDataSource( make_shared< AreaFaceDataSource     < MeshType > >() );

   meshWriterAABBfiltered.addDataSource( make_shared< StatusBitFaceDataSource  < MeshType > >( OpenMesh::Attributes::TAGGED, "tagged" ) );
   meshWriterAABBfiltered.addDataSource( make_shared< StatusBitVertexDataSource< MeshType > >( OpenMesh::Attributes::TAGGED, "tagged" ) );

   meshWriterAABBfiltered.addDataSource( make_shared< ColorFaceDataSource  < MeshType > >() );
   meshWriterAABBfiltered.addDataSource( make_shared< ColorVertexDataSource< MeshType > >() );

   meshWriterAABBfiltered.addDataSource( make_shared< IndexFaceDataSource  < MeshType > >() );
   meshWriterAABBfiltered.addDataSource( make_shared< IndexVertexDataSource< MeshType > >() );

   meshWriterAABBfiltered.addDataSource( make_shared< RankFaceDataSource  < MeshType > >() );
   meshWriterAABBfiltered.addDataSource( make_shared< RankVertexDataSource< MeshType > >() );

   meshWriterAABBfiltered.setFaceFilter( mesh::AABBFaceFilter< MeshType >(aabb) );

   meshWriterAABBfiltered();


   DistributedVTKMeshWriter< MeshType > meshWriterStatusfiltered( mesh, "distributed_mesh_vtk_test_status_filter", 1 );
   meshWriterStatusfiltered.addDataSource( make_shared< NormalsVertexDataSource< MeshType > >() );
   meshWriterStatusfiltered.addDataSource( make_shared< NormalsFaceDataSource  < MeshType > >() );

   meshWriterStatusfiltered.addDataSource( make_shared< AreaFaceDataSource     < MeshType > >() );

   meshWriterStatusfiltered.addDataSource( make_shared< StatusBitFaceDataSource  < MeshType > >( OpenMesh::Attributes::TAGGED, "tagged" ) );
   meshWriterStatusfiltered.addDataSource( make_shared< StatusBitVertexDataSource< MeshType > >( OpenMesh::Attributes::TAGGED, "tagged" ) );

   meshWriterStatusfiltered.addDataSource( make_shared< ColorFaceDataSource  < MeshType > >() );
   meshWriterStatusfiltered.addDataSource( make_shared< ColorVertexDataSource< MeshType > >() );

   meshWriterStatusfiltered.addDataSource( make_shared< IndexFaceDataSource  < MeshType > >() );
   meshWriterStatusfiltered.addDataSource( make_shared< IndexVertexDataSource< MeshType > >() );

   meshWriterStatusfiltered.addDataSource( make_shared< RankFaceDataSource  < MeshType > >() );
   meshWriterStatusfiltered.addDataSource( make_shared< RankVertexDataSource< MeshType > >() );

   meshWriterStatusfiltered.setFaceFilter( mesh::StatusFaceFilter< MeshType >( OpenMesh::Attributes::TAGGED ) );

   meshWriterStatusfiltered();
}
int TwoDimensionState::size()
{
    return ySize() * xSize();
}
예제 #15
0
QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle  const & theExtent, int theWidth, int theHeight )
{
  QgsDebugMsg( QString( "theBandNo = %1 theWidth = %2 theHeight = %3" ).arg( theBandNo ).arg( theWidth ).arg( theHeight ) );
  QgsDebugMsg( QString( "theExtent = %1" ).arg( theExtent.toString() ) );

  QgsRasterBlock *block = new QgsRasterBlock( dataType( theBandNo ), theWidth, theHeight, noDataValue( theBandNo ) );

  if ( block->isEmpty() )
  {
    QgsDebugMsg( "Couldn't create raster block" );
    return block;
  }

  // Read necessary extent only
  QgsRectangle tmpExtent = extent().intersect( &theExtent );

  if ( tmpExtent.isEmpty() )
  {
    QgsDebugMsg( "Extent outside provider extent" );
    block->setIsNoData();
    return block;
  }

  double xRes = theExtent.width() / theWidth;
  double yRes = theExtent.height() / theHeight;
  double tmpXRes, tmpYRes;
  double providerXRes = 0;
  double providerYRes = 0;
  if ( capabilities() & ExactResolution )
  {
    providerXRes = extent().width() / xSize();
    providerYRes = extent().height() / ySize();
    tmpXRes = qMax( providerXRes, xRes );
    tmpYRes = qMax( providerYRes, yRes );
    if ( doubleNear( tmpXRes, xRes ) ) tmpXRes = xRes;
    if ( doubleNear( tmpYRes, yRes ) ) tmpYRes = yRes;
  }
  else
  {
    tmpXRes = xRes;
    tmpYRes = yRes;
  }

  if ( tmpExtent != theExtent ||
       tmpXRes > xRes || tmpYRes > yRes )
  {
    // Read smaller extent or lower resolution

    // Calculate row/col limits (before tmpExtent is aligned)
    int fromRow = qRound(( theExtent.yMaximum() - tmpExtent.yMaximum() ) / yRes );
    int toRow = qRound(( theExtent.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1;
    int fromCol = qRound(( tmpExtent.xMinimum() - theExtent.xMinimum() ) / xRes ) ;
    int toCol = qRound(( tmpExtent.xMaximum() - theExtent.xMinimum() ) / xRes ) - 1;

    QgsDebugMsg( QString( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ) );

    if ( fromRow < 0 || fromRow >= theHeight || toRow < 0 || toRow >= theHeight ||
         fromCol < 0 || fromCol >= theWidth || toCol < 0 || toCol >= theWidth )
    {
      // Should not happen
      QgsDebugMsg( "Row or column limits out of range" );
      return block;
    }

    // If lower source resolution is used, the extent must beS aligned to original
    // resolution to avoid possible shift due to resampling
    if ( tmpXRes > xRes )
    {
      int col = floor(( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes );
      tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes );
      col = ceil(( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes );
      tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes );
    }
    if ( tmpYRes > yRes )
    {
      int row = floor(( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes );
      tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes );
      row = ceil(( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes );
      tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes );
    }
    int tmpWidth = qRound( tmpExtent.width() / tmpXRes );
    int tmpHeight = qRound( tmpExtent.height() / tmpYRes );
    tmpXRes = tmpExtent.width() / tmpWidth;
    tmpYRes = tmpExtent.height() / tmpHeight;

    QgsDebugMsg( QString( "Reading smaller block tmpWidth = %1 theHeight = %2" ).arg( tmpWidth ).arg( tmpHeight ) );
    QgsDebugMsg( QString( "tmpExtent = %1" ).arg( tmpExtent.toString() ) );

    block->setIsNoData();

    QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( theBandNo ), tmpWidth, tmpHeight, noDataValue( theBandNo ) );

    readBlock( theBandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->data() );

    int pixelSize = dataTypeSize( theBandNo );

    double xMin = theExtent.xMinimum();
    double yMax = theExtent.yMaximum();
    double tmpXMin = tmpExtent.xMinimum();
    double tmpYMax = tmpExtent.yMaximum();

    for ( int row = fromRow; row <= toRow; row++ )
    {
      double y = yMax - ( row + 0.5 ) * yRes;
      int tmpRow = floor(( tmpYMax - y ) / tmpYRes );

      for ( int col = fromCol; col <= toCol; col++ )
      {
        double x = xMin + ( col + 0.5 ) * xRes;
        int tmpCol = floor(( x - tmpXMin ) / tmpXRes );

        if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
        {
          QgsDebugMsg( "Source row or column limits out of range" );
          block->setIsNoData(); // so that the problem becomes obvious and fixed
          delete tmpBlock;
          return block;
        }

        size_t tmpIndex = tmpRow * tmpWidth + tmpCol;
        size_t index = row * theWidth + col;

        char *tmpBits = tmpBlock->bits( tmpIndex );
        char *bits = block->bits( index );
        if ( !tmpBits )
        {
          QgsDebugMsg( QString( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
          continue;
        }
        if ( !bits )
        {
          QgsDebugMsg( "Cannot set output block data." );
          continue;
        }
        memcpy( bits, tmpBits, pixelSize );
      }
    }

    delete tmpBlock;
  }
  else
  {
    readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() );
  }

  // apply user no data values
  // TODO: there are other readBlock methods where no data are not applied
  block->applyNodataValues( userNoDataValue( theBandNo ) );
  return block;
}
QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo )
{
  double myNoDataValue = noDataValue();
  QgsRasterBandStats myRasterBandStats;
  myRasterBandStats.elementCount = 0; // because we'll be counting only VALID pixels later
  myRasterBandStats.bandName = generateBandName( theBandNo );
  myRasterBandStats.bandNumber = theBandNo;

  int myDataType = dataType( theBandNo );

  int  myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
  myXBlockSize = xBlockSize();
  myYBlockSize = yBlockSize();

  myNXBlocks = ( xSize() + myXBlockSize - 1 ) / myXBlockSize;
  myNYBlocks = ( ySize() + myYBlockSize - 1 ) / myYBlockSize;

  void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( dataTypeSize( theBandNo ) / 8 ) );

  // unfortunately we need to make two passes through the data to calculate stddev
  bool myFirstIterationFlag = true;

  int myBandXSize = xSize();
  int myBandYSize = ySize();
  for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
  {
    for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
    {
      int  nXValid, nYValid;
      readBlock( theBandNo, iXBlock, iYBlock, myData );

      // Compute the portion of the block that is valid
      // for partial edge blocks.
      if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
        nXValid = myBandXSize - iXBlock * myXBlockSize;
      else
        nXValid = myXBlockSize;

      if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
        nYValid = myBandYSize - iYBlock * myYBlockSize;
      else
        nYValid = myYBlockSize;

      // Collect the histogram counts.
      for ( int iY = 0; iY < nYValid; iY++ )
      {
        for ( int iX = 0; iX < nXValid; iX++ )
        {
          double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
          //QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (iX).arg(iY).arg( myValue ) );

          if ( mValidNoDataValue && ( qAbs( myValue - myNoDataValue ) <= TINY_VALUE ) )
          {
            continue; // NULL
          }

          myRasterBandStats.sum += myValue;
          ++myRasterBandStats.elementCount;
          //only use this element if we have a non null element
          if ( myFirstIterationFlag )
          {
            //this is the first iteration so initialise vars
            myFirstIterationFlag = false;
            myRasterBandStats.minimumValue = myValue;
            myRasterBandStats.maximumValue = myValue;
          }               //end of true part for first iteration check
          else
          {
            //this is done for all subsequent iterations
            if ( myValue < myRasterBandStats.minimumValue )
            {
              myRasterBandStats.minimumValue = myValue;
            }
            if ( myValue > myRasterBandStats.maximumValue )
            {
              myRasterBandStats.maximumValue = myValue;
            }
          } //end of false part for first iteration check
        }
      }
    } //end of column wise loop
  } //end of row wise loop


  //end of first pass through data now calculate the range
  myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
  //calculate the mean
  myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;

  //for the second pass we will get the sum of the squares / mean
  for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
  {
    for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
    {
      int  nXValid, nYValid;

      readBlock( theBandNo, iXBlock, iYBlock, myData );

      // Compute the portion of the block that is valid
      // for partial edge blocks.
      if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
        nXValid = myBandXSize - iXBlock * myXBlockSize;
      else
        nXValid = myXBlockSize;

      if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
        nYValid = myBandYSize - iYBlock * myYBlockSize;
      else
        nYValid = myYBlockSize;

      // Collect the histogram counts.
      for ( int iY = 0; iY < nYValid; iY++ )
      {
        for ( int iX = 0; iX < nXValid; iX++ )
        {
          double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
          //QgsDebugMsg ( "myValue = " + QString::number(myValue) );

          if ( mValidNoDataValue && ( qAbs( myValue - myNoDataValue ) <= TINY_VALUE ) )
          {
            continue; // NULL
          }

          myRasterBandStats.sumOfSquares += static_cast < double >
                                            ( pow( myValue - myRasterBandStats.mean, 2 ) );
        }
      }
    } //end of column wise loop
  } //end of row wise loop

  //divide result by sample size - 1 and get square root to get stdev
  myRasterBandStats.stdDev = static_cast < double >( sqrt( myRasterBandStats.sumOfSquares /
                             ( myRasterBandStats.elementCount - 1 ) ) );

#ifdef QGISDEBUG
  QgsLogger::debug( "************ STATS **************", 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "VALID NODATA", mValidNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "NULL", noDataValue() , 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "MIN", myRasterBandStats.minimumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "MAX", myRasterBandStats.maximumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "RANGE", myRasterBandStats.range, 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "MEAN", myRasterBandStats.mean, 1, __FILE__, __FUNCTION__, __LINE__ );
  QgsLogger::debug( "STDDEV", myRasterBandStats.stdDev, 1, __FILE__, __FUNCTION__, __LINE__ );
#endif

  CPLFree( myData );
  myRasterBandStats.statsGathered = true;
  return myRasterBandStats;
}
void QgsRasterDataProvider::readBlock( int bandNo, QgsRectangle
                                       const & viewExtent, int width,
                                       int height,
                                       QgsCoordinateReferenceSystem theSrcCRS,
                                       QgsCoordinateReferenceSystem theDestCRS,
                                       void *data )
{
  QgsDebugMsg( "Entered" );
  QgsDebugMsg( "viewExtent = " + viewExtent.toString() );

  if ( ! theSrcCRS.isValid() || ! theDestCRS.isValid() || theSrcCRS == theDestCRS )
  {
    readBlock( bandNo, viewExtent, width, height, data );
    return;
  }

  QTime time;
  time.start();

  double mMaxSrcXRes = 0;
  double mMaxSrcYRes = 0;

  if ( capabilities() & QgsRasterDataProvider::ExactResolution )
  {
    mMaxSrcXRes = extent().width() / xSize();
    mMaxSrcYRes = extent().height() / ySize();
  }

  QgsRasterProjector myProjector( theSrcCRS, theDestCRS, viewExtent, height, width, mMaxSrcXRes, mMaxSrcYRes, extent() );

  QgsDebugMsg( QString( "create projector time  (ms): %1" ).arg( time.elapsed() ) );

  // TODO: init data by nulls

  // If we zoom out too much, projector srcRows / srcCols maybe 0, which can cause problems in providers
  if ( myProjector.srcRows() <= 0 || myProjector.srcCols() <= 0 )
    return;

  // Allocate memory for not projected source data
  int mySize = dataTypeSize( bandNo ) / 8;
  void *mySrcData = malloc( mySize * myProjector.srcRows() * myProjector.srcCols() );

  time.restart();

  readBlock( bandNo, myProjector.srcExtent(), myProjector.srcCols(), myProjector.srcRows(), mySrcData );

  QgsDebugMsg( QString( "read not projected block time  (ms): %1" ).arg( time.elapsed() ) );
  time.restart();

  // Project data from source
  int mySrcRow;
  int mySrcCol;
  int mySrcOffset;
  int myDestOffset;
  for ( int r = 0; r < height; r++ )
  {
    for ( int c = 0; c < width; c++ )
    {
      myProjector.srcRowCol( r, c, &mySrcRow, &mySrcCol );
      mySrcOffset = mySize * ( mySrcRow * myProjector.srcCols() + mySrcCol );
      myDestOffset = mySize * ( r * width + c );
      // retype to char is just to avoid g++ warning
      memcpy(( char* ) data + myDestOffset, ( char* )mySrcData + mySrcOffset, mySize );
    }
  }
  QgsDebugMsg( QString( "reproject block time  (ms): %1" ).arg( time.elapsed() ) );

  free( mySrcData );
}
예제 #18
0
QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle  const &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback )
{
  QgsDebugMsgLevel( QString( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
  QgsDebugMsgLevel( QString( "boundingBox = %1" ).arg( boundingBox.toString() ), 4 );

  QgsRasterBlock *block = new QgsRasterBlock( dataType( bandNo ), width, height );
  if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
  {
    block->setNoDataValue( sourceNoDataValue( bandNo ) );
  }

  if ( block->isEmpty() )
  {
    QgsDebugMsg( "Couldn't create raster block" );
    return block;
  }

  // Read necessary extent only
  QgsRectangle tmpExtent = extent().intersect( &boundingBox );

  if ( tmpExtent.isEmpty() )
  {
    QgsDebugMsg( "Extent outside provider extent" );
    block->setIsNoData();
    return block;
  }

  double xRes = boundingBox.width() / width;
  double yRes = boundingBox.height() / height;
  double tmpXRes, tmpYRes;
  double providerXRes = 0;
  double providerYRes = 0;
  if ( capabilities() & Size )
  {
    providerXRes = extent().width() / xSize();
    providerYRes = extent().height() / ySize();
    tmpXRes = std::max( providerXRes, xRes );
    tmpYRes = std::max( providerYRes, yRes );
    if ( qgsDoubleNear( tmpXRes, xRes ) ) tmpXRes = xRes;
    if ( qgsDoubleNear( tmpYRes, yRes ) ) tmpYRes = yRes;
  }
  else
  {
    tmpXRes = xRes;
    tmpYRes = yRes;
  }

  if ( tmpExtent != boundingBox ||
       tmpXRes > xRes || tmpYRes > yRes )
  {
    // Read smaller extent or lower resolution

    if ( !extent().contains( boundingBox ) )
    {
      QRect subRect = QgsRasterBlock::subRect( boundingBox, width, height, extent() );
      block->setIsNoDataExcept( subRect );
    }

    // Calculate row/col limits (before tmpExtent is aligned)
    int fromRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMaximum() ) / yRes );
    int toRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1;
    int fromCol = std::round( ( tmpExtent.xMinimum() - boundingBox.xMinimum() ) / xRes );
    int toCol = std::round( ( tmpExtent.xMaximum() - boundingBox.xMinimum() ) / xRes ) - 1;

    QgsDebugMsgLevel( QString( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );

    if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
         fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
    {
      // Should not happen
      QgsDebugMsg( "Row or column limits out of range" );
      return block;
    }

    // If lower source resolution is used, the extent must beS aligned to original
    // resolution to avoid possible shift due to resampling
    if ( tmpXRes > xRes )
    {
      int col = std::floor( ( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes );
      tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes );
      col = std::ceil( ( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes );
      tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes );
    }
    if ( tmpYRes > yRes )
    {
      int row = std::floor( ( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes );
      tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes );
      row = std::ceil( ( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes );
      tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes );
    }
    int tmpWidth = std::round( tmpExtent.width() / tmpXRes );
    int tmpHeight = std::round( tmpExtent.height() / tmpYRes );
    tmpXRes = tmpExtent.width() / tmpWidth;
    tmpYRes = tmpExtent.height() / tmpHeight;

    QgsDebugMsgLevel( QString( "Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
    QgsDebugMsgLevel( QString( "tmpExtent = %1" ).arg( tmpExtent.toString() ), 4 );

    QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( bandNo ), tmpWidth, tmpHeight );
    if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
    {
      tmpBlock->setNoDataValue( sourceNoDataValue( bandNo ) );
    }

    readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback );

    int pixelSize = dataTypeSize( bandNo );

    double xMin = boundingBox.xMinimum();
    double yMax = boundingBox.yMaximum();
    double tmpXMin = tmpExtent.xMinimum();
    double tmpYMax = tmpExtent.yMaximum();

    for ( int row = fromRow; row <= toRow; row++ )
    {
      double y = yMax - ( row + 0.5 ) * yRes;
      int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );

      for ( int col = fromCol; col <= toCol; col++ )
      {
        double x = xMin + ( col + 0.5 ) * xRes;
        int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );

        if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
        {
          QgsDebugMsg( "Source row or column limits out of range" );
          block->setIsNoData(); // so that the problem becomes obvious and fixed
          delete tmpBlock;
          return block;
        }

        qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
        qgssize index = row * static_cast< qgssize >( width ) + col;

        char *tmpBits = tmpBlock->bits( tmpIndex );
        char *bits = block->bits( index );
        if ( !tmpBits )
        {
          QgsDebugMsg( QString( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
          continue;
        }
        if ( !bits )
        {
          QgsDebugMsg( "Cannot set output block data." );
          continue;
        }
        memcpy( bits, tmpBits, pixelSize );
      }
    }

    delete tmpBlock;
  }
  else
  {
    readBlock( bandNo, boundingBox, width, height, block->bits(), feedback );
  }

  // apply scale and offset
  block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) );
  // apply user no data values
  block->applyNoDataValues( userNoDataValues( bandNo ) );
  return block;
}
예제 #19
0
void FileMcIDAS::InitMcIDAS(ImagerDoc & DOC /*block 0*/, int channel){

  mcidas.W1 = 0 ;           // W1

  mcidas.AreaFormat = 4 ;   // W2 always 4

  mcidas.SSS = McIDASImager_SatelliteID[DOC.spcid() - 8 ]; 
  // W3 Satellite Id #

  mcidas.YYDDD = ((DOC.T_sps_current.year()-1900) * 1000 
		  + DOC.T_sps_current.day() );
  // W4 Nominal Year and Julian day of area

  mcidas.HHMMSS = ( DOC.T_sps_current.hrs()*10000 
		   + DOC.T_sps_current.min() * 100 
		   + DOC.T_sps_current.sec() );
  // W5 Nominal time of image

  mcidas.UpperLeftLine = yStart(channel);
  // W6 image line for area line0, elem0

  mcidas.UpperLeftElem = xStart(channel) ;
  // W7 image elem for area line0, elem0

  mcidas.W8 = 1 ;           // W8 not used

  mcidas.Nlines = (long)ySize(channel);
  // W9 number of lines in area

  mcidas.Neles  = (long)xSize(channel);
  // W10 number of elements in each line

  mcidas.Elesiz = wordSize(channel);  
  // W11 number of bytes/element

  mcidas.Lineres = (int) yStride(channel); 
  // W12 spcng in img lns btwn cons area lines
  
  mcidas.Eleres  = (int) xStride(channel);  
  // W13 spcng in img ele bten cons area elems

  mcidas.Nchans = 1 ;
  // W14 max # bands/line of area

  mcidas.Presiz = 80;
  // W15 length of line prefix in bytes

  mcidas.Proj = 0 ; 
  // W16 McIDAS user project #

  time_t now = time(NULL);
  struct tm * local =  localtime(&now);
  
  mcidas.CreationDate = (local->tm_year* 1000 
			 + local->tm_yday);
  // W17 Area creation date in YYDDD

  mcidas.CreationTime = (local->tm_hour * 10000 
			 + local->tm_min * 100 
			 + local->tm_sec );
  // W18 Area creation date in HHMMSS

  mcidas.FilterMap = 1<<channel;
  // W19 for multi-channel images 32 bit vector
  
  int i;
  for( i = 0; i < 5; i++)
    mcidas.W20_24[i] = 0 ; 
  // W20-24 for internal use

  for(i = 0; i < 8; i++)
    mcidas.W25_32[i] = 0 ;    // W25-32 Memo, Comments

  for(i = 0; i < 3; i++)
    mcidas.W33_35[i] = 0 ;    // W33_35 for internal use
  mcidas.W33_35[2] = 256;

  mcidas.ValidityCode= 0 ;
  // W36 Validity Code
  
  for(i=0; i<8; i++)
    mcidas.W37_44[i] = 0;  
  // W37-44 PDL indicates packed byte format
  
  mcidas.W45 = 0 ;
  // W45 for mode AA
  
  mcidas.SSS = McIDASImager_SatelliteID[DOC.spcid() - 8 ]; 
  // W3 Satellite Id #

  mcidas.ActualStartDate = mcidas.YYDDD;
  // W46 YYDDD
  
  mcidas.ActualStartTime = mcidas.HHMMSS;
  // W47 HHMMSS
  
  mcidas.ActualStartScan = DOC.N_line_of_frame; // W48 

  mcidas.LinePrefixBytes = 76 ;
  // W49 Line prefix doc in bytes

  mcidas.LinePrefixCal = 0 ;
  // W50 Line prefix calibration in bytes

  mcidas.LinePrefixMap = 0 ;
  // W51 Line prefix level map in bytes

  mcidas.ImageSourceType = 1196835154 ; // 'GVAR'
  // W52 'VISR' || 'GVAR' || 'AAA' || 'ERBE'

  mcidas.CalibrationType = 1380013856; // 'RAW'
  // W53 'RAW' || 'TEMP' || 'BRIT'

  for(i=0;i<11;i++)
    mcidas.W54_64[i] = 0;     // W54-64 Intenal use only

  // Navigation 

  mcidas.NavigationType = 1196835154; // 'GVAR'
  // W1 'GVAR'

  mcidas.ImcFlag = 0; // DOC.imc(); 
  // W2 IMC flag (0-active, 1-inactive)

  for(i=0;i<3;i++)
    mcidas.W3_5[i] = 0 ;        // W3-5 Not used

  mcidas.RefLongitude = (int)( (float)DOC.ReferenceLongitude * 1E7 );
  // W6 Ref Longitude (rad * 10^7 )

  mcidas.RefNomDist = (int)( (float) DOC.ReferenceRadialDistance * 1E7);
  // W7 Ref distance from nominal (km *10^7)

  mcidas.RefLatitude = (int)((double) DOC.ReferenceLatitude * 1E7);
  // W8 Ref Latitude  (rad * 10^7 )

  mcidas.RefYaw = (int)((double)DOC.ReferenceOrbitYaw *1E7);
  // W9 Ref Yaw       (rad * 10^7 )

  mcidas.RefAttitudeRoll = (int)((double)DOC.ReferenceAttitudeRoll *1E7);
  // W10 Ref  attitude roll (rad * 10^7 )

  mcidas.RefAttitudePitch = (int)((double)DOC.ReferenceAttitudePitch * 1E7);
  // W11 Ref attitude pitch (rad * 10^7 )

  mcidas.RefAttitudeYaw = (int)((double)DOC.ReferenceAttitudeYaw * 1E7);
  // W12 Ref attitude yaw (rad * 10^7 )

  memcpy(mcidas.EpochTimeDate,&DOC.EpochDate,sizeof(DOC.EpochDate) );
  // W13-14 Epoch time data BCD format

  mcidas.DeltafromEpochTime = (int)((double)DOC.IMCenableFromEpoch*100);
  // W14 (minutes * 100 )

  mcidas.IMCroll = (int)((double)DOC.CompensationRoll*1E7);
  // W15 img motion comp roll (rad * 10^7)

  mcidas.IMCpitch = (int)((double)DOC.CompensationPitch*1E7);
  // W16 img motion comp pitch (rad * 10^7)

  mcidas.IMCyaw = (int)((double)DOC.CompensationYaw*1E7);
  // W18 img motion comp yaw (rad * 10^7)

  for(i=0;i<13;i++)
    mcidas.ChangeLongitude[i] =
      (int)((double)DOC.ChangeLongitude[i]*1E7) ;
  //W19-31 long delta from ref (rad*10^7)
  
  for(i=0;i<11;i++)
    mcidas.ChangeRadialDist[i] = 
      (int)((double)DOC.ChangeRadialDistance[i]*1E7);
  //W32-42 r dist delta from ref (rad*10^7)
  
  for(i=0;i<9;i++)
    mcidas.SineGeoCentricLat[i] =
      (int)((double)DOC.SineGeocentricLatitude[i]*1E7);
  //W43-51 (nounits *10^7)

  for(i=0;i<9;i++)
    mcidas.SineOrbitYaw[i] =
      (int)((double)DOC.SineOrbitYaw[i]*1E7);
  //W52-60 (nounits * 10^7)

  mcidas.DailySolarRate = 
    (int)((double)DOC.DailySolarRate*1E7);
  //W61 (rad/min * 10^7)
  
  mcidas.ExpStartFromEpoch = 
    (int)((double)DOC.ExponentialStartFromEpoch*100);
  // W62 (min * 100 )

  DOC.RollAngle.toMcIDASNavigation(mcidas.RollAttitudeAngle);
  //W63-117
  
  for(i=0;i<10;i++ )
    mcidas.W127_118[i]=0;   // W127-118 

  mcidas.W128 = 1297044037 ; // W128 'MORE'

  mcidas. W129 =  1196835154; // W129 'GVAR'
  
  DOC.PitchAngle.toMcIDASNavigation(mcidas.PitchAngle); // W130_184
     
  DOC.YawAngle.toMcIDASNavigation(mcidas.YawAngle);   // W185_239

  for(i=0;i<16;i++)
    mcidas.W240_255[i] = 0; //240-255

  mcidas.W256 = 1297044037;  // W256 'MORE'

  mcidas.W257 =  1196835154; //  W257 'GVAR'

  DOC.RollMisalignment.toMcIDASNavigation(mcidas.RollMisalignmentAngle); // W258-312
     
  DOC.PitchMisalignment.toMcIDASNavigation(mcidas.PitchMisalignmentAngle); // W313-367

  mcidas.InstrumentFlag = 1; //W368 (1=imager; 2 = sounder)

  mcidas.W369_YYDDD = mcidas.YYDDD; //W369
     
  mcidas.W370_HHMMSS = mcidas.HHMMSS; //W370

  for(i=0;i<13;i++)
    mcidas.W371_383[i] = 0; //W371-383 

  mcidas.W384 = 1297044037; //W384 'MORE'

  mcidas.W385 =  1196835154; //W385 'GVAR'

  for(i=0;i<125;i++)
    mcidas.W386_510[i] = 0; // W386-510

  mcidas.W511 = 1297044037; // W511 'MORE'

  mcidas.W512 =  1196835154; // W512 'GVAR'

  for(i=0;i<128;i++)
    mcidas.W513_640[i] = 0; //W513-640

  // Calibration 
     
  for(i=0;i<8;i++){
    mcidas.VisibleBias[i] = (float) DOC.Ivcrb[i]; // W1-8
    mcidas.VisibleFirstOrderGain[i] = (float) DOC.Ivcr1[i]; //W9-16
    mcidas.VisibleSecOrderGain[i] = (float) DOC.Ivcr2[i];   //W17-24
  }

  mcidas.VisibleRadianceToAlbedo = (float) DOC.Ivral; //W25
  
  mcidas.Side1IRBias[0] = (float) DOC.Iisfb[0][4]; // W26
  mcidas.Side1IRBias[1] = (float) DOC.Iisfb[0][6]; // W27
  mcidas.Side1IRBias[2] = (float) DOC.Iisfb[0][0]; // W28
  mcidas.Side1IRBias[3] = (float) DOC.Iisfb[0][2]; // W29

  mcidas.Side2IRBias[0] = (float) DOC.Iisfb[1][4]; // W30
  mcidas.Side2IRBias[1] = (float) DOC.Iisfb[1][6]; // W31
  mcidas.Side2IRBias[2] = (float) DOC.Iisfb[1][0]; // W32
  mcidas.Side2IRBias[3] = (float) DOC.Iisfb[1][2]; // W33

  mcidas.Side1IRGain[0] = (float) DOC.Iisf1[0][4]; // W34
  mcidas.Side1IRGain[1] = (float) DOC.Iisf1[0][6]; // W35
  mcidas.Side1IRGain[2] = (float) DOC.Iisf1[0][0]; // W36
  mcidas.Side1IRGain[3] = (float) DOC.Iisf1[0][2]; // W37
  
  mcidas.Side2IRGain[0] = (float) DOC.Iisf1[1][4]; // W38
  mcidas.Side2IRGain[1] = (float) DOC.Iisf1[1][6]; // W39
  mcidas.Side2IRGain[2] = (float) DOC.Iisf1[1][0]; // W40
  mcidas.Side2IRGain[3] = (float) DOC.Iisf1[1][2]; // W41


  for(i=0;i<87;i++)
    mcidas.W128_42[i] = 0; 
}