Beispiel #1
0
void OGRWarpedLayer::SetSpatialFilter( int iGeomField, OGRGeometry *poGeom )
{
    if( iGeomField < 0 || iGeomField >= GetLayerDefn()->GetGeomFieldCount() )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                    "Invalid geometry field index : %d", iGeomField);
        return;
    }

    m_iGeomFieldFilter = iGeomField;
    if( InstallFilter( poGeom ) )
        ResetReading();

    if( m_iGeomFieldFilter == m_iGeomField )
    {
        if( poGeom == NULL || m_poReversedCT == NULL )
        {
            m_poDecoratedLayer->SetSpatialFilter(m_iGeomFieldFilter,
                                                NULL);
        }
        else
        {
            OGREnvelope sEnvelope;
            poGeom->getEnvelope(&sEnvelope);
            if( CPLIsInf(sEnvelope.MinX) && CPLIsInf(sEnvelope.MinY) &&
                CPLIsInf(sEnvelope.MaxX) && CPLIsInf(sEnvelope.MaxY) )
            {
                m_poDecoratedLayer->SetSpatialFilterRect(m_iGeomFieldFilter,
                                                        sEnvelope.MinX,
                                                        sEnvelope.MinY,
                                                        sEnvelope.MaxX,
                                                        sEnvelope.MaxY);
            }
            else if( ReprojectEnvelope(&sEnvelope, m_poReversedCT) )
            {
                m_poDecoratedLayer->SetSpatialFilterRect(m_iGeomFieldFilter,
                                                        sEnvelope.MinX,
                                                        sEnvelope.MinY,
                                                        sEnvelope.MaxX,
                                                        sEnvelope.MaxY);
            }
            else
            {
                m_poDecoratedLayer->SetSpatialFilter(m_iGeomFieldFilter,
                                                    NULL);
            }
        }
    }
    else
    {
        m_poDecoratedLayer->SetSpatialFilter(m_iGeomFieldFilter,
                                             poGeom);
    }
}
json_object* OGRGeoJSONWriteCoords( double const& fX, double const& fY, int nCoordPrecision )
{
    json_object* poObjCoords = NULL;
    if( CPLIsInf(fX) || CPLIsInf(fY) ||
        CPLIsNan(fX) || CPLIsNan(fY) )
    {
        CPLError(CE_Warning, CPLE_AppDefined, "Infinite or NaN coordinate encountered");
        return NULL;
    }
    poObjCoords = json_object_new_array();
    json_object_array_add( poObjCoords, json_object_new_double_with_precision( fX, nCoordPrecision ) );
    json_object_array_add( poObjCoords, json_object_new_double_with_precision( fY, nCoordPrecision ) );

    return poObjCoords;
}
Beispiel #3
0
bool GDALNoDataMaskBand::IsNoDataInRange(double dfNoDataValue,
                                         GDALDataType eDataType)
{
    GDALDataType eWrkDT = GetWorkDataType( eDataType );
    switch( eWrkDT )
    {
      case GDT_Byte:
      {
          return GDALIsValueInRange<GByte>(dfNoDataValue);
      }

      case GDT_UInt32:
      {
          return GDALIsValueInRange<GUInt32>(dfNoDataValue);
      }

      case GDT_Int32:
      {
          return GDALIsValueInRange<GInt32>(dfNoDataValue);
      }

      case GDT_Float32:
      {
          return CPLIsNan(dfNoDataValue) ||
                 CPLIsInf(dfNoDataValue) ||
                 GDALIsValueInRange<float>(dfNoDataValue);
      }

      case GDT_Float64:
      {
          return true;
      }

      default:
        CPLAssert( false );
        return false;
    }
}
Beispiel #4
0
GDALDataset * AAIGDataset::CreateCopy(
    const char *pszFilename, GDALDataset *poSrcDS,
    int /* bStrict */,
    char **papszOptions,
    GDALProgressFunc pfnProgress, void *pProgressData )
{
    const int nBands = poSrcDS->GetRasterCount();
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    // Some rudimentary checks.
    if( nBands != 1 )
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "AAIG driver doesn't support %d bands.  Must be 1 band.",
                 nBands);

        return nullptr;
    }

    if( !pfnProgress(0.0, nullptr, pProgressData) )
        return nullptr;

    // Create the dataset.
    VSILFILE *fpImage = VSIFOpenL(pszFilename, "wt");
    if( fpImage == nullptr )
    {
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Unable to create file %s.",
                 pszFilename);
        return nullptr;
    }

    // Write ASCII Grid file header.
    double adfGeoTransform[6] = {};
    char szHeader[2000] = {};
    const char *pszForceCellsize =
        CSLFetchNameValue(papszOptions, "FORCE_CELLSIZE");

    poSrcDS->GetGeoTransform(adfGeoTransform);

    if( std::abs(adfGeoTransform[1] + adfGeoTransform[5]) < 0.0000001 ||
        std::abs(adfGeoTransform[1]-adfGeoTransform[5]) < 0.0000001 ||
        (pszForceCellsize && CPLTestBool(pszForceCellsize)) )
    {
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "cellsize     %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] - nYSize * adfGeoTransform[1],
            adfGeoTransform[1]);
    }
    else
    {
        if( pszForceCellsize == nullptr )
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Producing a Golden Surfer style file with DX and DY "
                     "instead of CELLSIZE since the input pixels are "
                     "non-square.  Use the FORCE_CELLSIZE=TRUE creation "
                     "option to force use of DX for even though this will "
                     "be distorted.  Most ASCII Grid readers (ArcGIS "
                     "included) do not support the DX and DY parameters.");
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "dx           %.12f\n"
            "dy           %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] + nYSize * adfGeoTransform[5],
            adfGeoTransform[1],
            fabs(adfGeoTransform[5]));
    }

    // Builds the format string used for printing float values.
    char szFormatFloat[32] = { '\0' };
    strcpy(szFormatFloat, " %.20g");
    const char *pszDecimalPrecision =
        CSLFetchNameValue(papszOptions, "DECIMAL_PRECISION");
    const char *pszSignificantDigits =
        CSLFetchNameValue(papszOptions, "SIGNIFICANT_DIGITS");
    bool bIgnoreSigDigits = false;
    if( pszDecimalPrecision && pszSignificantDigits )
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Conflicting precision arguments, using DECIMAL_PRECISION");
        bIgnoreSigDigits = true;
    }
    int nPrecision;
    if ( pszSignificantDigits && !bIgnoreSigDigits )
    {
        nPrecision = atoi(pszSignificantDigits);
        if (nPrecision >= 0)
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%dg",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }
    else if( pszDecimalPrecision )
    {
        nPrecision = atoi(pszDecimalPrecision);
        if ( nPrecision >= 0 )
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%df",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }

    // Handle nodata (optionally).
    GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
    const bool bReadAsInt =
        poBand->GetRasterDataType() == GDT_Byte ||
        poBand->GetRasterDataType() == GDT_Int16 ||
        poBand->GetRasterDataType() == GDT_UInt16 ||
        poBand->GetRasterDataType() == GDT_Int32;

    // Write `nodata' value to header if it is exists in source dataset
    int bSuccess = FALSE;
    const double dfNoData = poBand->GetNoDataValue(&bSuccess);
    if ( bSuccess )
    {
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "NODATA_value ");
        if( bReadAsInt )
            snprintf(szHeader + strlen(szHeader),
                     sizeof(szHeader) - strlen(szHeader), "%d",
                     static_cast<int>(dfNoData));
        else
            CPLsnprintf(szHeader + strlen(szHeader),
                        sizeof(szHeader) - strlen(szHeader),
                        szFormatFloat, dfNoData);
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "\n");
    }

    if( VSIFWriteL(szHeader, strlen(szHeader), 1, fpImage) != 1)
    {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }

    // Loop over image, copying image data.

    // Write scanlines to output file
    int *panScanline = bReadAsInt
                           ? static_cast<int *>(CPLMalloc(
                                 nXSize * GDALGetDataTypeSizeBytes(GDT_Int32)))
                           : nullptr;

    double *padfScanline =
        bReadAsInt ? nullptr
                   : static_cast<double *>(CPLMalloc(
                         nXSize * GDALGetDataTypeSizeBytes(GDT_Float64)));

    CPLErr eErr = CE_None;

    bool bHasOutputDecimalDot = false;
    for( int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ )
    {
        CPLString osBuf;
        eErr = poBand->RasterIO(
            GF_Read, 0, iLine, nXSize, 1,
            bReadAsInt ? reinterpret_cast<void *>(panScanline) :
            reinterpret_cast<void *>(padfScanline),
            nXSize, 1, bReadAsInt ? GDT_Int32 : GDT_Float64,
            0, 0, nullptr);

        if( bReadAsInt )
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                snprintf(szHeader, sizeof(szHeader),
                         " %d", panScanline[iPixel]);
                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                    if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                    fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        else
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                CPLsnprintf(szHeader, sizeof(szHeader),
                            szFormatFloat, padfScanline[iPixel]);

                // Make sure that as least one value has a decimal point (#6060)
                if( !bHasOutputDecimalDot )
                {
                    if( strchr(szHeader, '.') || strchr(szHeader, 'e') ||
                        strchr(szHeader, 'E') )
                    {
                        bHasOutputDecimalDot = true;
                    }
                    else if( !CPLIsInf(padfScanline[iPixel]) &&
                             !CPLIsNan(padfScanline[iPixel]) )
                    {
                        strcat(szHeader, ".0");
                        bHasOutputDecimalDot = true;
                    }
                }

                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                  if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                  fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        if( VSIFWriteL("\n", 1, 1, fpImage) != 1 )
            eErr = CE_Failure;

        if( eErr == CE_None &&
            !pfnProgress((iLine + 1) / static_cast<double>(nYSize), nullptr,
                         pProgressData) )
        {
            eErr = CE_Failure;
            CPLError(CE_Failure, CPLE_UserInterrupt,
                     "User terminated CreateCopy()");
        }
    }

    CPLFree(panScanline);
    CPLFree(padfScanline);
    if( VSIFCloseL(fpImage) != 0 )
        eErr = CE_Failure;

    if( eErr != CE_None )
        return nullptr;

    // Try to write projection file.
    const char *pszOriginalProjection = poSrcDS->GetProjectionRef();
    if( !EQUAL(pszOriginalProjection, "") )
    {
        char *pszDirname = CPLStrdup(CPLGetPath(pszFilename));
        char *pszBasename = CPLStrdup(CPLGetBasename(pszFilename));
        char *pszPrjFilename =
            CPLStrdup(CPLFormFilename(pszDirname, pszBasename, "prj"));
        VSILFILE *fp = VSIFOpenL(pszPrjFilename, "wt");
        if (fp != nullptr)
        {
            OGRSpatialReference oSRS;
            oSRS.importFromWkt(pszOriginalProjection);
            oSRS.morphToESRI();
            char *pszESRIProjection = nullptr;
            oSRS.exportToWkt(&pszESRIProjection);
            CPL_IGNORE_RET_VAL(VSIFWriteL(pszESRIProjection, 1,
                                          strlen(pszESRIProjection), fp));

            CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
            CPLFree(pszESRIProjection);
        }
        else
        {
            CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.",
                     pszPrjFilename);
        }
        CPLFree(pszDirname);
        CPLFree(pszBasename);
        CPLFree(pszPrjFilename);
    }

    // Re-open dataset, and copy any auxiliary pam information.

    // If writing to stdout, we can't reopen it, so return
    // a fake dataset to make the caller happy.
    CPLPushErrorHandler(CPLQuietErrorHandler);
    GDALPamDataset *poDS =
        reinterpret_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly));
    CPLPopErrorHandler();
    if (poDS)
    {
        poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT);
        return poDS;
    }

    CPLErrorReset();

    AAIGDataset *poAAIG_DS = new AAIGDataset();
    poAAIG_DS->nRasterXSize = nXSize;
    poAAIG_DS->nRasterYSize = nYSize;
    poAAIG_DS->nBands = 1;
    poAAIG_DS->SetBand(1, new AAIGRasterBand(poAAIG_DS, 1));
    return poAAIG_DS;
}
Beispiel #5
0
int AAIGDataset::ParseHeader(const char *pszHeader, const char *pszDataType)
{
    char **papszTokens = CSLTokenizeString2(pszHeader, " \n\r\t", 0);
    const int nTokens = CSLCount(papszTokens);

    int i = 0;
    if ( (i = CSLFindString(papszTokens, "ncols")) < 0 ||
         i + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }
    nRasterXSize = atoi(papszTokens[i + 1]);
    if ( (i = CSLFindString(papszTokens, "nrows")) < 0 ||
         i + 1 >= nTokens)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }
    nRasterYSize = atoi(papszTokens[i + 1]);

    if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize))
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    // TODO(schwehr): Would be good to also factor the file size into the max.
    // TODO(schwehr): Allow the user to disable this check.
    // The driver allocates a panLineOffset array based on nRasterYSize
    constexpr int kMaxDimSize = 10000000;  // 1e7 cells.
    if (nRasterXSize > kMaxDimSize || nRasterYSize > kMaxDimSize)
    {
        CSLDestroy(papszTokens);
        return FALSE;
    }

    double dfCellDX = 0.0;
    double dfCellDY = 0.0;
    if ( (i = CSLFindString(papszTokens, "cellsize")) < 0 )
    {
        int iDX, iDY;
        if( (iDX = CSLFindString(papszTokens, "dx")) < 0 ||
            (iDY = CSLFindString(papszTokens, "dy")) < 0 ||
            iDX + 1 >= nTokens ||
            iDY + 1 >= nTokens )
        {
            CSLDestroy(papszTokens);
            return FALSE;
        }

        dfCellDX = CPLAtofM(papszTokens[iDX + 1]);
        dfCellDY = CPLAtofM(papszTokens[iDY + 1]);
    }
    else
    {
        if (i + 1 >= nTokens)
        {
            CSLDestroy(papszTokens);
            return FALSE;
        }
        dfCellDY = CPLAtofM(papszTokens[i + 1]);
        dfCellDX = dfCellDY;
    }

    int j = 0;
    if ((i = CSLFindString(papszTokens, "xllcorner")) >= 0 &&
        (j = CSLFindString(papszTokens, "yllcorner")) >= 0 &&
        i + 1 < nTokens && j + 1 < nTokens)
    {
        adfGeoTransform[0] = CPLAtofM(papszTokens[i + 1]);

        // Small hack to compensate from insufficient precision in cellsize
        // parameter in datasets of
        // http://ccafs-climate.org/data/A2a_2020s/hccpr_hadcm3
        if ((nRasterXSize % 360) == 0 &&
            fabs(adfGeoTransform[0] - (-180.0)) < 1e-12 &&
            dfCellDX == dfCellDY &&
            fabs(dfCellDX - (360.0 / nRasterXSize)) < 1e-9)
        {
            dfCellDY = 360.0 / nRasterXSize;
            dfCellDX = dfCellDY;
        }

        adfGeoTransform[1] = dfCellDX;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] =
            CPLAtofM(papszTokens[j + 1]) + nRasterYSize * dfCellDY;
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = -dfCellDY;
    }
    else if ((i = CSLFindString(papszTokens, "xllcenter")) >= 0 &&
             (j = CSLFindString(papszTokens, "yllcenter")) >= 0 &&
             i + 1 < nTokens && j + 1 < nTokens)
    {
        SetMetadataItem(GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT);

        adfGeoTransform[0] = CPLAtofM(papszTokens[i + 1]) - 0.5 * dfCellDX;
        adfGeoTransform[1] = dfCellDX;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] = CPLAtofM(papszTokens[j + 1]) - 0.5 * dfCellDY +
                             nRasterYSize * dfCellDY;
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = -dfCellDY;
    }
    else
    {
        adfGeoTransform[0] = 0.0;
        adfGeoTransform[1] = dfCellDX;
        adfGeoTransform[2] = 0.0;
        adfGeoTransform[3] = 0.0;
        adfGeoTransform[4] = 0.0;
        adfGeoTransform[5] = -dfCellDY;
    }

    if( (i = CSLFindString( papszTokens, "NODATA_value" )) >= 0 &&
        i + 1 < nTokens)
    {
        const char *pszNoData = papszTokens[i + 1];

        bNoDataSet = true;
        dfNoDataValue = CPLAtofM(pszNoData);
        if( pszDataType == nullptr &&
            (strchr(pszNoData, '.') != nullptr ||
             strchr(pszNoData, ',') != nullptr ||
             std::numeric_limits<int>::min() > dfNoDataValue ||
             dfNoDataValue > std::numeric_limits<int>::max()) )
        {
            eDataType = GDT_Float32;
            if( !CPLIsInf(dfNoDataValue) &&
                (fabs(dfNoDataValue) < std::numeric_limits<float>::min() ||
                 fabs(dfNoDataValue) > std::numeric_limits<float>::max()) )
            {
                eDataType = GDT_Float64;
            }
        }
        if( eDataType == GDT_Float32 )
        {
            dfNoDataValue = MapNoDataToFloat(dfNoDataValue);
        }
    }

    CSLDestroy(papszTokens);

    return TRUE;
}
Beispiel #6
0
CPLErr GDALNoDataMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff,
                                       void * pImage )

{
    GDALDataType eWrkDT = GDT_Unknown;

/* -------------------------------------------------------------------- */
/*      Decide on a working type.                                       */
/* -------------------------------------------------------------------- */
    switch( poParent->GetRasterDataType() )
    {
      case GDT_Byte:
        eWrkDT = GDT_Byte;
        break;

      case GDT_UInt16:
      case GDT_UInt32:
        eWrkDT = GDT_UInt32;
        break;

      case GDT_Int16:
      case GDT_Int32:
      case GDT_CInt16:
      case GDT_CInt32:
        eWrkDT = GDT_Int32;
        break;

      case GDT_Float32:
      case GDT_CFloat32:
        eWrkDT = GDT_Float32;
        break;

      case GDT_Float64:
      case GDT_CFloat64:
        eWrkDT = GDT_Float64;
        break;

      default:
        CPLAssert( false );
        eWrkDT = GDT_Float64;
        break;
    }

/* -------------------------------------------------------------------- */
/*      Read the image data.                                            */
/* -------------------------------------------------------------------- */
    // TODO(schwehr): pabySrc would probably be better as a void ptr.
    GByte *pabySrc = static_cast<GByte *>(
        VSI_MALLOC3_VERBOSE( GDALGetDataTypeSizeBytes(eWrkDT),
                             nBlockXSize, nBlockYSize ) );
    if (pabySrc == nullptr)
    {
        return CE_Failure;
    }

    int nXSizeRequest = nBlockXSize;
    if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize)
        nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize;
    int nYSizeRequest = nBlockYSize;
    if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize)
        nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize;

    if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize)
    {
        // memset the whole buffer to avoid Valgrind warnings in case RasterIO
        // fetches a partial block.
        memset( pabySrc, 0,
                GDALGetDataTypeSizeBytes(eWrkDT) * nBlockXSize * nBlockYSize );
    }

    CPLErr eErr =
        poParent->RasterIO( GF_Read,
                            nXBlockOff * nBlockXSize,
                            nYBlockOff * nBlockYSize,
                            nXSizeRequest, nYSizeRequest,
                            pabySrc, nXSizeRequest, nYSizeRequest,
                            eWrkDT, 0,
                            nBlockXSize * GDALGetDataTypeSizeBytes(eWrkDT),
                            nullptr );
    if( eErr != CE_None )
    {
        CPLFree(pabySrc);
        return eErr;
    }

    const bool bIsNoDataNan = CPLIsNan(dfNoDataValue) != 0;

/* -------------------------------------------------------------------- */
/*      Process different cases.                                        */
/* -------------------------------------------------------------------- */
    switch( eWrkDT )
    {
      case GDT_Byte:
      {
          if( !GDALIsValueInRange<GByte>(dfNoDataValue) )
          {
              memset(pImage, 255, nBlockXSize * nBlockYSize);
          }
          else
          {
            GByte byNoData = static_cast<GByte>( dfNoDataValue );

            for( int i = 0; i < nBlockXSize * nBlockYSize; i++ )
            {
                static_cast<GByte *>(pImage)[i] = pabySrc[i] == byNoData ? 0: 255;
            }
          }
      }
      break;

      case GDT_UInt32:
      {
          if( !GDALIsValueInRange<GUInt32>(dfNoDataValue) )
          {
              memset(pImage, 255, nBlockXSize * nBlockYSize);
          }
          else
          {
            GUInt32 nNoData = static_cast<GUInt32>( dfNoDataValue );

            for( int i = 0; i < nBlockXSize * nBlockYSize; i++ )
            {
                static_cast<GByte *>(pImage)[i] =
                    reinterpret_cast<GUInt32 *>(pabySrc)[i] == nNoData ? 0 : 255;
            }
          }
      }
      break;

      case GDT_Int32:
      {
          if( !GDALIsValueInRange<GInt32>(dfNoDataValue) )
          {
              memset(pImage, 255, nBlockXSize * nBlockYSize);
          }
          else
          {
            GInt32 nNoData = static_cast<GInt32>( dfNoDataValue );

            for( int i = 0; i < nBlockXSize * nBlockYSize; i++ )
            {
                static_cast<GByte *>(pImage)[i] =
                    reinterpret_cast<GInt32 *>(pabySrc)[i] == nNoData ? 0 : 255;
            }
          }
      }
      break;

      case GDT_Float32:
      {
          if( !bIsNoDataNan && !CPLIsInf(dfNoDataValue) &&
              !GDALIsValueInRange<float>(dfNoDataValue) )
          {
              memset(pImage, 255, nBlockXSize * nBlockYSize);
          }
          else
          {
            float fNoData = static_cast<float>( dfNoDataValue );

            for( int i = 0; i < nBlockXSize * nBlockYSize; i++ )
            {
                const float fVal = reinterpret_cast<float *>(pabySrc)[i];
                if( bIsNoDataNan && CPLIsNan(fVal))
                    static_cast<GByte *>(pImage)[i] = 0;
                else if( ARE_REAL_EQUAL(fVal, fNoData) )
                    static_cast<GByte *>(pImage)[i] = 0;
                else
                    static_cast<GByte *>(pImage)[i] = 255;
            }
          }
      }
      break;

      case GDT_Float64:
      {
          for( int i = 0; i < nBlockXSize * nBlockYSize; i++ )
          {
              const double dfVal = reinterpret_cast<double *>(pabySrc)[i];
              if( bIsNoDataNan && CPLIsNan(dfVal))
                  static_cast<GByte *>(pImage)[i] = 0;
              else if( ARE_REAL_EQUAL(dfVal, dfNoDataValue) )
                  static_cast<GByte *>(pImage)[i] = 0;
              else
                  static_cast<GByte *>(pImage)[i] = 255;
          }
      }
      break;

      default:
        CPLAssert( false );
        break;
    }

    CPLFree( pabySrc );

    return CE_None;
}
void OGRPGDumpLayer::AppendFieldValue(CPLString& osCommand,
                                      OGRFeature* poFeature, int i)
{
    int nOGRFieldType = poFeatureDefn->GetFieldDefn(i)->GetType();

    // We need special formatting for integer list values.
    if(  nOGRFieldType == OFTIntegerList )
    {
        int nCount, nOff = 0, j;
        const int *panItems = poFeature->GetFieldAsIntegerList(i,&nCount);
        char *pszNeedToFree = NULL;

        pszNeedToFree = (char *) CPLMalloc(nCount * 13 + 10);
        strcpy( pszNeedToFree, "'{" );
        for( j = 0; j < nCount; j++ )
        {
            if( j != 0 )
                strcat( pszNeedToFree+nOff, "," );

            nOff += strlen(pszNeedToFree+nOff);
            sprintf( pszNeedToFree+nOff, "%d", panItems[j] );
        }
        strcat( pszNeedToFree+nOff, "}'" );

        osCommand += pszNeedToFree;
        CPLFree(pszNeedToFree);

        return;
    }

    // We need special formatting for real list values.
    else if( nOGRFieldType == OFTRealList )
    {
        int nCount, nOff = 0, j;
        const double *padfItems =poFeature->GetFieldAsDoubleList(i,&nCount);
        char *pszNeedToFree = NULL;

        pszNeedToFree = (char *) CPLMalloc(nCount * 40 + 10);
        strcpy( pszNeedToFree, "'{" );
        for( j = 0; j < nCount; j++ )
        {
            if( j != 0 )
                strcat( pszNeedToFree+nOff, "," );

            nOff += strlen(pszNeedToFree+nOff);
            //Check for special values. They need to be quoted.
            if( CPLIsNan(padfItems[j]) )
                sprintf( pszNeedToFree+nOff, "NaN" );
            else if( CPLIsInf(padfItems[j]) )
                sprintf( pszNeedToFree+nOff, (padfItems[j] > 0) ? "Infinity" : "-Infinity" );
            else
                sprintf( pszNeedToFree+nOff, "%.16g", padfItems[j] );

        }
        strcat( pszNeedToFree+nOff, "}'" );

        osCommand += pszNeedToFree;
        CPLFree(pszNeedToFree);

        return;
    }

    // We need special formatting for string list values.
    else if( nOGRFieldType == OFTStringList )
    {
        char **papszItems = poFeature->GetFieldAsStringList(i);

        osCommand += OGRPGDumpEscapeStringList(papszItems, TRUE);

        return;
    }

    // Binary formatting
    else if( nOGRFieldType == OFTBinary )
    {
        osCommand += "'";

        int nLen = 0;
        GByte* pabyData = poFeature->GetFieldAsBinary( i, &nLen );
        char* pszBytea = GByteArrayToBYTEA( pabyData, nLen);

        osCommand += pszBytea;

        CPLFree(pszBytea);
        osCommand += "'";

        return;
    }

    // Flag indicating NULL or not-a-date date value
    // e.g. 0000-00-00 - there is no year 0
    OGRBoolean bIsDateNull = FALSE;

    const char *pszStrValue = poFeature->GetFieldAsString(i);

    // Check if date is NULL: 0000-00-00
    if( nOGRFieldType == OFTDate )
    {
        if( EQUALN( pszStrValue, "0000", 4 ) )
        {
            pszStrValue = "NULL";
            bIsDateNull = TRUE;
        }
    }
    else if ( nOGRFieldType == OFTReal )
    {
        char* pszComma = strchr((char*)pszStrValue, ',');
        if (pszComma)
            *pszComma = '.';
        //Check for special values. They need to be quoted.
        double dfVal = poFeature->GetFieldAsDouble(i);
        if( CPLIsNan(dfVal) )
            pszStrValue = "'NaN'";
        else if( CPLIsInf(dfVal) )
            pszStrValue = (dfVal > 0) ? "'Infinity'" : "'-Infinity'";
    }

    if( nOGRFieldType != OFTInteger && nOGRFieldType != OFTReal
            && !bIsDateNull )
    {
        osCommand += OGRPGDumpEscapeString( pszStrValue,
                                            poFeatureDefn->GetFieldDefn(i)->GetWidth(),
                                            poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
    }
    else
    {
        osCommand += pszStrValue;
    }
}
OGRErr OGRPGDumpLayer::CreateFeatureViaCopy( OGRFeature *poFeature )
{
    int                  i;
    CPLString            osCommand;

    /* First process geometry */
    for( i = 0; i < poFeature->GetGeomFieldCount(); i++ )
    {
        OGRGeometry *poGeometry = poFeature->GetGeomFieldRef(i);
        char *pszGeom = NULL;
        if ( NULL != poGeometry /* && (bHasWkb || bHasPostGISGeometry || bHasPostGISGeography) */)
        {
            OGRPGDumpGeomFieldDefn* poGFldDefn =
                (OGRPGDumpGeomFieldDefn*) poFeature->GetGeomFieldDefnRef(i);

            poGeometry->closeRings();
            poGeometry->setCoordinateDimension( poGFldDefn->nCoordDimension );

            //CheckGeomTypeCompatibility(poGeometry);

            /*if (bHasWkb)
                pszGeom = GeometryToBYTEA( poGeometry );
            else*/
            pszGeom = OGRGeometryToHexEWKB( poGeometry, poGFldDefn->nSRSId );
        }

        if (osCommand.size() > 0)
            osCommand += "\t";
        if ( pszGeom )
        {
            osCommand += pszGeom,
                         CPLFree( pszGeom );
        }
        else
        {
            osCommand += "\\N";
        }
    }

    /* Next process the field id column */
    int nFIDIndex = -1;
    if( bFIDColumnInCopyFields )
    {
        if (osCommand.size() > 0)
            osCommand += "\t";

        nFIDIndex = poFeatureDefn->GetFieldIndex( pszFIDColumn );

        /* Set the FID */
        if( poFeature->GetFID() != OGRNullFID )
        {
            osCommand += CPLString().Printf("%ld ", poFeature->GetFID());
        }
        else
        {
            osCommand += "\\N" ;
        }
    }


    /* Now process the remaining fields */

    int nFieldCount = poFeatureDefn->GetFieldCount();
    int bAddTab = osCommand.size() > 0;

    for( i = 0; i < nFieldCount;  i++ )
    {
        if (i == nFIDIndex)
            continue;

        const char *pszStrValue = poFeature->GetFieldAsString(i);
        char *pszNeedToFree = NULL;

        if (bAddTab)
            osCommand += "\t";
        bAddTab = TRUE;

        if( !poFeature->IsFieldSet( i ) )
        {
            osCommand += "\\N" ;

            continue;
        }

        int nOGRFieldType = poFeatureDefn->GetFieldDefn(i)->GetType();

        // We need special formatting for integer list values.
        if( nOGRFieldType == OFTIntegerList )
        {
            int nCount, nOff = 0, j;
            const int *panItems = poFeature->GetFieldAsIntegerList(i,&nCount);

            pszNeedToFree = (char *) CPLMalloc(nCount * 13 + 10);
            strcpy( pszNeedToFree, "{" );
            for( j = 0; j < nCount; j++ )
            {
                if( j != 0 )
                    strcat( pszNeedToFree+nOff, "," );

                nOff += strlen(pszNeedToFree+nOff);
                sprintf( pszNeedToFree+nOff, "%d", panItems[j] );
            }
            strcat( pszNeedToFree+nOff, "}" );
            pszStrValue = pszNeedToFree;
        }

        // We need special formatting for real list values.
        else if( nOGRFieldType == OFTRealList )
        {
            int nCount, nOff = 0, j;
            const double *padfItems =poFeature->GetFieldAsDoubleList(i,&nCount);

            pszNeedToFree = (char *) CPLMalloc(nCount * 40 + 10);
            strcpy( pszNeedToFree, "{" );
            for( j = 0; j < nCount; j++ )
            {
                if( j != 0 )
                    strcat( pszNeedToFree+nOff, "," );

                nOff += strlen(pszNeedToFree+nOff);
                //Check for special values. They need to be quoted.
                if( CPLIsNan(padfItems[j]) )
                    sprintf( pszNeedToFree+nOff, "NaN" );
                else if( CPLIsInf(padfItems[j]) )
                    sprintf( pszNeedToFree+nOff, (padfItems[j] > 0) ? "Infinity" : "-Infinity" );
                else
                    sprintf( pszNeedToFree+nOff, "%.16g", padfItems[j] );

            }
            strcat( pszNeedToFree+nOff, "}" );
            pszStrValue = pszNeedToFree;
        }


        // We need special formatting for string list values.
        else if( nOGRFieldType == OFTStringList )
        {
            CPLString osStr;
            char **papszItems = poFeature->GetFieldAsStringList(i);

            pszStrValue = pszNeedToFree = CPLStrdup(OGRPGDumpEscapeStringList(papszItems, FALSE));
        }

        // Binary formatting
        else if( nOGRFieldType == OFTBinary )
        {
            int nLen = 0;
            GByte* pabyData = poFeature->GetFieldAsBinary( i, &nLen );
            char* pszBytea = GByteArrayToBYTEA( pabyData, nLen);

            pszStrValue = pszNeedToFree = pszBytea;
        }

        else if( nOGRFieldType == OFTReal )
        {
            char* pszComma = strchr((char*)pszStrValue, ',');
            if (pszComma)
                *pszComma = '.';
            //Check for special values. They need to be quoted.
            double dfVal = poFeature->GetFieldAsDouble(i);
            if( CPLIsNan(dfVal) )
                pszStrValue = "NaN";
            else if( CPLIsInf(dfVal) )
                pszStrValue = (dfVal > 0) ? "Infinity" : "-Infinity";
        }

        if( nOGRFieldType != OFTIntegerList &&
                nOGRFieldType != OFTRealList &&
                nOGRFieldType != OFTInteger &&
                nOGRFieldType != OFTReal &&
                nOGRFieldType != OFTBinary )
        {
            int         iChar;
            int         iUTFChar = 0;
            int         nMaxWidth = poFeatureDefn->GetFieldDefn(i)->GetWidth();

            for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                //count of utf chars
                if ((pszStrValue[iChar] & 0xc0) != 0x80)
                {
                    if( nMaxWidth > 0 && iUTFChar == nMaxWidth )
                    {
                        CPLDebug( "PG",
                                  "Truncated %s field value, it was too long.",
                                  poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                        break;
                    }
                    iUTFChar++;
                }

                /* Escape embedded \, \t, \n, \r since they will cause COPY
                   to misinterpret a line of text and thus abort */
                if( pszStrValue[iChar] == '\\' ||
                        pszStrValue[iChar] == '\t' ||
                        pszStrValue[iChar] == '\r' ||
                        pszStrValue[iChar] == '\n'   )
                {
                    osCommand += '\\';
                }

                osCommand += pszStrValue[iChar];
            }
        }
        else
        {
            osCommand += pszStrValue;
        }

        if( pszNeedToFree )
            CPLFree( pszNeedToFree );
    }

    /* Add end of line marker */
    //osCommand += "\n";


    /* ------------------------------------------------------------ */
    /*      Execute the copy.                                       */
    /* ------------------------------------------------------------ */

    OGRErr result = OGRERR_NONE;

    poDS->Log(osCommand, FALSE);

    return result;
}
Beispiel #9
0
int CPL_STDCALL 
GDALChecksumImage( GDALRasterBandH hBand, 
                   int nXOff, int nYOff, int nXSize, int nYSize )

{
    VALIDATE_POINTER1( hBand, "GDALChecksumImage", 0 );

    const static int anPrimes[11] = 
        { 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 };

    int  iLine, i, nChecksum = 0, iPrime = 0, nCount;
    GDALDataType eDataType = GDALGetRasterDataType( hBand );
    int  bComplex = GDALDataTypeIsComplex( eDataType );
    
    if (eDataType == GDT_Float32 || eDataType == GDT_Float64 ||
        eDataType == GDT_CFloat32 || eDataType == GDT_CFloat64)
    {
        double* padfLineData;
        GDALDataType eDstDataType = (bComplex) ? GDT_CFloat64 : GDT_Float64;

        padfLineData = (double *) VSIMalloc2(nXSize, sizeof(double) * 2);
        if (padfLineData == NULL)
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                    "VSIMalloc2(): Out of memory in GDALChecksumImage. "
                    "Checksum value couldn't be computed\n");
            return 0;
        }

        for( iLine = nYOff; iLine < nYOff + nYSize; iLine++ )
        {
            if (GDALRasterIO( hBand, GF_Read, nXOff, iLine, nXSize, 1, 
                              padfLineData, nXSize, 1, eDstDataType, 0, 0 ) != CE_None)
            {
                CPLError( CE_Failure, CPLE_FileIO,
                        "Checksum value couldn't be computed due to I/O read error.\n");
                break;
            }
            nCount = (bComplex) ? nXSize * 2 : nXSize;

            for( i = 0; i < nCount; i++ )
            {
                double dfVal = padfLineData[i];
                int nVal;
                if (CPLIsNan(dfVal) || CPLIsInf(dfVal))
                {
                    /* Most compilers seem to cast NaN or Inf to 0x80000000. */
                    /* but VC7 is an exception. So we force the result */
                    /* of such a cast */
                    nVal = 0x80000000;
                }
                else
                {
                    /* Standard behaviour of GDALCopyWords when converting */
                    /* from floating point to Int32 */
                    dfVal += 0.5;

                    if( dfVal < -2147483647.0 )
                        nVal = -2147483647;
                    else if( dfVal > 2147483647 )
                        nVal = 2147483647;
                    else
                        nVal = (GInt32) floor(dfVal);
                }

                nChecksum += (nVal % anPrimes[iPrime++]);
                if( iPrime > 10 )
                    iPrime = 0;

                nChecksum &= 0xffff;
            }
        }

        CPLFree(padfLineData);
    }
    else
    {
        int  *panLineData;
        GDALDataType eDstDataType = (bComplex) ? GDT_CInt32 : GDT_Int32;

        panLineData = (GInt32 *) VSIMalloc2(nXSize, sizeof(GInt32) * 2);
        if (panLineData == NULL)
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                    "VSIMalloc2(): Out of memory in GDALChecksumImage. "
                    "Checksum value couldn't be computed\n");
            return 0;
        }

        for( iLine = nYOff; iLine < nYOff + nYSize; iLine++ )
        {
            if (GDALRasterIO( hBand, GF_Read, nXOff, iLine, nXSize, 1, 
                            panLineData, nXSize, 1, eDstDataType, 0, 0 ) != CE_None)
            {
                CPLError( CE_Failure, CPLE_FileIO,
                        "Checksum value couldn't be computed due to I/O read error.\n");
                break;
            }
            nCount = (bComplex) ? nXSize * 2 : nXSize;

            for( i = 0; i < nCount; i++ )
            {
                nChecksum += (panLineData[i] % anPrimes[iPrime++]);
                if( iPrime > 10 )
                    iPrime = 0;

                nChecksum &= 0xffff;
            }
        }

        CPLFree( panLineData );
    }

    return nChecksum;
}
CPLErr GDALApplyVSGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                           void * pData )
{
    GDALApplyVSGDataset* poGDS = reinterpret_cast<GDALApplyVSGDataset*>(poDS);

    const int nXOff = nBlockXOff * nBlockXSize;
    const int nReqXSize = ( nXOff > nRasterXSize - nBlockXSize ) ?
                                    nRasterXSize - nXOff : nBlockXSize;
    const int nYOff = nBlockYOff * nBlockYSize;
    const int nReqYSize = ( nYOff > nRasterYSize - nBlockYSize ) ?
                                    nRasterYSize - nYOff : nBlockYSize;

    CPLErr eErr =
        poGDS->m_poSrcDataset->GetRasterBand(1)->RasterIO(GF_Read,
                                                    nXOff, nYOff,
                                                    nReqXSize, nReqYSize,
                                                    m_pafSrcData,
                                                    nReqXSize, nReqYSize,
                                                    GDT_Float32,
                                                    sizeof(float),
                                                    nBlockXSize * sizeof(float),
                                                    nullptr);
    if( eErr == CE_None )
        eErr =  poGDS->m_poReprojectedGrid->GetRasterBand(1)->RasterIO(GF_Read,
                                                    nXOff, nYOff,
                                                    nReqXSize, nReqYSize,
                                                    m_pafGridData,
                                                    nReqXSize, nReqYSize,
                                                    GDT_Float32,
                                                    sizeof(float),
                                                    nBlockXSize * sizeof(float),
                                                    nullptr);
    if( eErr == CE_None )
    {
        const int nDTSize = GDALGetDataTypeSizeBytes(eDataType);
        int bHasNoData = FALSE;
        float fNoDataValue = static_cast<float>(GetNoDataValue(&bHasNoData));
        for( int iY = 0; iY < nReqYSize; iY++ )
        {
            for( int iX = 0; iX < nReqXSize; iX ++ )
            {
                const float fSrcVal = m_pafSrcData[iY * nBlockXSize + iX];
                const float fGridVal = m_pafGridData[iY * nBlockXSize + iX];
                if( bHasNoData && fSrcVal == fNoDataValue )
                {
                }
                else if( CPLIsInf(fGridVal) )
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Missing vertical grid value at source (%d,%d)",
                             nXOff + iX, nYOff + iY);
                    return CE_Failure;
                }
                else if( poGDS->m_bInverse )
                {
                    m_pafSrcData[iY * nBlockXSize + iX] = static_cast<float>(
                        (fSrcVal * poGDS->m_dfSrcUnitToMeter - fGridVal) / 
                                                poGDS->m_dfDstUnitToMeter);
                }
                else
                {
                    m_pafSrcData[iY * nBlockXSize + iX] = static_cast<float>(
                        (fSrcVal * poGDS->m_dfSrcUnitToMeter + fGridVal) / 
                                                poGDS->m_dfDstUnitToMeter);
                }
            }
            GDALCopyWords( m_pafSrcData + iY * nBlockXSize,
                                GDT_Float32, sizeof(float),
                           static_cast<GByte*>(pData) + iY * nBlockXSize *
                                nDTSize, eDataType, nDTSize,
                           nReqXSize );
        }
    }

    return eErr;
}