GDALDataset *AAIGDataset::CommonOpen( GDALOpenInfo *poOpenInfo, GridFormat eFormat ) { if( poOpenInfo->fpL == nullptr ) return nullptr; // Create a corresponding GDALDataset. AAIGDataset *poDS = nullptr; if (eFormat == FORMAT_AAIG) poDS = new AAIGDataset(); else poDS = new GRASSASCIIDataset(); const char *pszDataTypeOption = eFormat == FORMAT_AAIG ? "AAIGRID_DATATYPE" : "GRASSASCIIGRID_DATATYPE"; const char *pszDataType = CPLGetConfigOption(pszDataTypeOption, nullptr); if( pszDataType == nullptr ) pszDataType = CSLFetchNameValue(poOpenInfo->papszOpenOptions, "DATATYPE"); if (pszDataType != nullptr) { poDS->eDataType = GDALGetDataTypeByName(pszDataType); if (!(poDS->eDataType == GDT_Int32 || poDS->eDataType == GDT_Float32 || poDS->eDataType == GDT_Float64)) { CPLError(CE_Warning, CPLE_NotSupported, "Unsupported value for %s : %s", pszDataTypeOption, pszDataType); poDS->eDataType = GDT_Int32; pszDataType = nullptr; } } // Parse the header. if (!poDS->ParseHeader((const char *)poOpenInfo->pabyHeader, pszDataType)) { delete poDS; return nullptr; } poDS->fp = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; // Find the start of real data. int nStartOfData = 0; for( int i = 2; true; i++ ) { if( poOpenInfo->pabyHeader[i] == '\0' ) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't find data values in ASCII Grid file."); delete poDS; return nullptr; } if( poOpenInfo->pabyHeader[i - 1] == '\n' || poOpenInfo->pabyHeader[i - 2] == '\n' || poOpenInfo->pabyHeader[i - 1] == '\r' || poOpenInfo->pabyHeader[i - 2] == '\r' ) { if( !isalpha(poOpenInfo->pabyHeader[i]) && poOpenInfo->pabyHeader[i] != '\n' && poOpenInfo->pabyHeader[i] != '\r') { nStartOfData = i; // Beginning of real data found. break; } } } // Recognize the type of data. CPLAssert(nullptr != poDS->fp); if( pszDataType == nullptr && poDS->eDataType != GDT_Float32 && poDS->eDataType != GDT_Float64) { // Allocate 100K chunk + 1 extra byte for NULL character. constexpr size_t nChunkSize = 1024 * 100; GByte *pabyChunk = static_cast<GByte *>( VSI_CALLOC_VERBOSE(nChunkSize + 1, sizeof(GByte))); if (pabyChunk == nullptr) { delete poDS; return nullptr; } pabyChunk[nChunkSize] = '\0'; if( VSIFSeekL(poDS->fp, nStartOfData, SEEK_SET) < 0 ) { delete poDS; VSIFree(pabyChunk); return nullptr; } // Scan for dot in subsequent chunks of data. while( !VSIFEofL(poDS->fp) ) { CPL_IGNORE_RET_VAL(VSIFReadL(pabyChunk, nChunkSize, 1, poDS->fp)); for( int i = 0; i < static_cast<int>(nChunkSize); i++) { GByte ch = pabyChunk[i]; if (ch == '.' || ch == ',' || ch == 'e' || ch == 'E') { poDS->eDataType = GDT_Float32; break; } } } // Deallocate chunk. VSIFree(pabyChunk); } // Create band information objects. AAIGRasterBand *band = new AAIGRasterBand(poDS, nStartOfData); poDS->SetBand(1, band); if (band->panLineOffset == nullptr) { delete poDS; return nullptr; } // Try to read projection file. char *const pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); char *const pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "prj"); int nRet = 0; { VSIStatBufL sStatBuf; nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf); } if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename) ) { poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "PRJ"); VSIStatBufL sStatBuf; nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf); } if( nRet == 0 ) { poDS->papszPrj = CSLLoad(poDS->osPrjFilename); CPLDebug("AAIGrid", "Loaded SRS from %s", poDS->osPrjFilename.c_str()); OGRSpatialReference oSRS; if( oSRS.importFromESRI(poDS->papszPrj) == OGRERR_NONE ) { // If geographic values are in seconds, we must transform. // Is there a code for minutes too? if( oSRS.IsGeographic() && EQUAL(OSR_GDS(poDS->papszPrj, "Units", ""), "DS") ) { poDS->adfGeoTransform[0] /= 3600.0; poDS->adfGeoTransform[1] /= 3600.0; poDS->adfGeoTransform[2] /= 3600.0; poDS->adfGeoTransform[3] /= 3600.0; poDS->adfGeoTransform[4] /= 3600.0; poDS->adfGeoTransform[5] /= 3600.0; } CPLFree(poDS->pszProjection); oSRS.exportToWkt(&(poDS->pszProjection)); } } CPLFree(pszDirname); CPLFree(pszBasename); // Initialize any PAM information. poDS->SetDescription(poOpenInfo->pszFilename); poDS->TryLoadXML(); // Check for external overviews. poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles()); return poDS; }
void LANDataset::CheckForStatistics() { /* -------------------------------------------------------------------- */ /* Do we have a statistics file? */ /* -------------------------------------------------------------------- */ osSTAFilename = CPLResetExtension(GetDescription(),"sta"); VSILFILE *fpSTA = VSIFOpenL( osSTAFilename, "r" ); if( fpSTA == NULL && VSIIsCaseSensitiveFS(osSTAFilename) ) { osSTAFilename = CPLResetExtension(GetDescription(),"STA"); fpSTA = VSIFOpenL( osSTAFilename, "r" ); } if( fpSTA == NULL ) { osSTAFilename = ""; return; } /* -------------------------------------------------------------------- */ /* Read it one band at a time. */ /* -------------------------------------------------------------------- */ GByte abyBandInfo[1152] = { '\0' }; for( int iBand = 0; iBand < nBands; iBand++ ) { if( VSIFReadL( abyBandInfo, 1152, 1, fpSTA ) != 1 ) break; const int nBandNumber = abyBandInfo[7]; GDALRasterBand *poBand = GetRasterBand(nBandNumber); if( poBand == NULL ) break; GInt16 nMin = 0; GInt16 nMax = 0; if( poBand->GetRasterDataType() != GDT_Byte ) { memcpy( &nMin, abyBandInfo + 28, 2 ); memcpy( &nMax, abyBandInfo + 30, 2 ); CPL_LSBPTR16( &nMin ); CPL_LSBPTR16( &nMax ); } else { nMin = abyBandInfo[9]; nMax = abyBandInfo[8]; } float fMean = 0.0; float fStdDev = 0.0; memcpy( &fMean, abyBandInfo + 12, 4 ); memcpy( &fStdDev, abyBandInfo + 24, 4 ); CPL_LSBPTR32( &fMean ); CPL_LSBPTR32( &fStdDev ); poBand->SetStatistics( nMin, nMax, fMean, fStdDev ); } CPL_IGNORE_RET_VAL(VSIFCloseL( fpSTA )); }
GDALDataset *SIGDEMDataset::Open(GDALOpenInfo * poOpenInfo) { VSILFILE* fp = poOpenInfo->fpL; SIGDEMHeader sHeader; if (SIGDEMDataset::Identify(poOpenInfo) != TRUE || fp == nullptr) { return nullptr; } sHeader.Read(poOpenInfo->pabyHeader); if (!GDALCheckDatasetDimensions(sHeader.nCols, sHeader.nRows)) { return nullptr; } OGRSpatialReference oSRS; if (sHeader.nCoordinateSystemId > 0) { if (oSRS.importFromEPSG(sHeader.nCoordinateSystemId) != OGRERR_NONE) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM unable to find coordinateSystemId=%d.", sHeader.nCoordinateSystemId); return nullptr; } } else { CPLString osPrjFilename = CPLResetExtension(poOpenInfo->pszFilename, "prj"); VSIStatBufL sStatBuf; int nRet = VSIStatL(osPrjFilename, &sStatBuf); if (nRet != 0 && VSIIsCaseSensitiveFS(osPrjFilename)) { osPrjFilename = CPLResetExtension(poOpenInfo->pszFilename, "PRJ"); nRet = VSIStatL(osPrjFilename, &sStatBuf); } if (nRet == 0) { char** papszPrj = CSLLoad(osPrjFilename); if (oSRS.importFromESRI(papszPrj) != OGRERR_NONE) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM unable to read projection from %s.", osPrjFilename.c_str()); CSLDestroy(papszPrj); return nullptr; } CSLDestroy(papszPrj); } else { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM unable to find projection."); return nullptr; } } if (sHeader.nCols > std::numeric_limits<int>::max() / (CELL_SIZE_MEM)) { CPLError(CE_Failure, CPLE_AppDefined, "Int overflow occurred."); return nullptr; } if( !RAWDatasetCheckMemoryUsage(sHeader.nCols, sHeader.nRows, 1, 4, 4, 4 * sHeader.nCols, 0, 0, poOpenInfo->fpL) ) { return nullptr; } SIGDEMDataset *poDS = new SIGDEMDataset(sHeader); CPLFree(poDS->pszProjection); oSRS.exportToWkt(&(poDS->pszProjection)); poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; poDS->eAccess = poOpenInfo->eAccess; poDS->SetDescription(poOpenInfo->pszFilename); poDS->PamInitialize(); poDS->nBands = 1; CPLErrorReset(); SIGDEMRasterBand *poBand = new SIGDEMRasterBand(poDS, poDS->fpImage, sHeader.dfMinZ, sHeader.dfMaxZ); poDS->SetBand(1, poBand); if (CPLGetLastErrorType() != CE_None) { poDS->nBands = 1; delete poDS; return nullptr; } // Initialize any PAM information. poDS->TryLoadXML(); // Check for overviews. poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); return poDS; }
const char *CPLFormCIFilename( const char * pszPath, const char * pszBasename, const char * pszExtension ) { // On case insensitive filesystems, just default to // CPLFormFilename() if( !VSIIsCaseSensitiveFS(pszPath) ) return CPLFormFilename( pszPath, pszBasename, pszExtension ); const char *pszAddedExtSep = ""; char *pszFilename; const char *pszFullPath; int nLen = strlen(pszBasename)+2, i; VSIStatBufL sStatBuf; int nStatRet; if( pszExtension != NULL ) nLen += strlen(pszExtension); pszFilename = (char *) CPLMalloc(nLen); if( pszExtension == NULL ) pszExtension = ""; else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 ) pszAddedExtSep = "."; sprintf( pszFilename, "%s%s%s", pszBasename, pszAddedExtSep, pszExtension ); pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL ); nStatRet = VSIStatExL( pszFullPath, &sStatBuf, VSI_STAT_EXISTS_FLAG ); if( nStatRet != 0 ) { for( i = 0; pszFilename[i] != '\0'; i++ ) { if( islower(pszFilename[i]) ) pszFilename[i] = (char) toupper(pszFilename[i]); } pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL ); nStatRet = VSIStatExL( pszFullPath, &sStatBuf, VSI_STAT_EXISTS_FLAG ); } if( nStatRet != 0 ) { for( i = 0; pszFilename[i] != '\0'; i++ ) { if( isupper(pszFilename[i]) ) pszFilename[i] = (char) tolower(pszFilename[i]); } pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL ); nStatRet = VSIStatExL( pszFullPath, &sStatBuf, VSI_STAT_EXISTS_FLAG ); } if( nStatRet != 0 ) pszFullPath = CPLFormFilename( pszPath, pszBasename, pszExtension ); CPLFree( pszFilename ); return pszFullPath; }
GDALDataset *LCPDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Verify that this is a FARSITE LCP file */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The LCP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ LCPDataset *poDS; VSILFILE *fpImage; fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fpImage == NULL) return NULL; poDS = new LCPDataset(); poDS->fpImage = fpImage; /* -------------------------------------------------------------------- */ /* Read the header and extract some information. */ /* -------------------------------------------------------------------- */ int bHaveCrownFuels, bHaveGroundFuels; int nBands, i; long nWidth = -1, nHeight = -1; int nTemp, nTemp2; char szTemp[32]; char* pszList; VSIFSeekL( poDS->fpImage, 0, SEEK_SET ); if (VSIFReadL( poDS->pachHeader, 1, LCP_HEADER_SIZE, poDS->fpImage ) != LCP_HEADER_SIZE) { CPLError(CE_Failure, CPLE_FileIO, "File too short"); delete poDS; return NULL; } nWidth = CPL_LSBINT32PTR (poDS->pachHeader + 4164); nHeight = CPL_LSBINT32PTR (poDS->pachHeader + 4168); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } // crown fuels = canopy height, canopy base height, canopy bulk density // 21 = have them, 20 = don't have them bHaveCrownFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 0) - 20 ); // ground fuels = duff loading, coarse woody bHaveGroundFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 4) - 20 ); if( bHaveCrownFuels ) { if( bHaveGroundFuels ) nBands = 10; else nBands = 8; } else { if( bHaveGroundFuels ) nBands = 7; else nBands = 5; } // add dataset-level metadata nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 8); sprintf(szTemp, "%d", nTemp); poDS->SetMetadataItem( "LATITUDE", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 4204); if ( nTemp == 0 ) poDS->SetMetadataItem( "LINEAR_UNIT", "Meters" ); if ( nTemp == 1 ) poDS->SetMetadataItem( "LINEAR_UNIT", "Feet" ); poDS->pachHeader[LCP_HEADER_SIZE-1] = '\0'; poDS->SetMetadataItem( "DESCRIPTION", poDS->pachHeader + 6804 ); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int iPixelSize; iPixelSize = nBands * 2; int bNativeOrder; if (nWidth > INT_MAX / iPixelSize) { CPLError( CE_Failure, CPLE_AppDefined, "Int overflow occured"); delete poDS; return NULL; } #ifdef CPL_LSB bNativeOrder = TRUE; #else bNativeOrder = FALSE; #endif pszList = (char*)CPLMalloc(2048); for( int iBand = 1; iBand <= nBands; iBand++ ) { GDALRasterBand *poBand = NULL; poBand = new RawRasterBand( poDS, iBand, poDS->fpImage, LCP_HEADER_SIZE + ((iBand-1)*2), iPixelSize, iPixelSize * nWidth, GDT_Int16, bNativeOrder, TRUE ); poDS->SetBand(iBand, poBand); switch ( iBand ) { case 1: poBand->SetDescription("Elevation"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4224); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Meters" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Feet" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 44); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 48); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 52); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4244 + 255) = '\0'; poBand->SetMetadataItem( "ELEVATION_FILE", poDS->pachHeader + 4244 ); break; case 2: poBand->SetDescription("Slope"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4226); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Degrees" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Percent" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 456); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 460); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 464); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4500 + 255) = '\0'; poBand->SetMetadataItem( "SLOPE_FILE", poDS->pachHeader + 4500 ); break; case 3: poBand->SetDescription("Aspect"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4228); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass categories" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass degrees" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Azimuth degrees" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 868); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 872); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 876); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4756 + 255) = '\0'; poBand->SetMetadataItem( "ASPECT_FILE", poDS->pachHeader + 4756 ); break; case 4: int nMinFM, nMaxFM; poBand->SetDescription("Fuel models"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4230); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "FUEL_MODEL_OPTION", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models AND no conversion file needed" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models BUT no conversion file needed" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models BUT conversion file needed" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models AND conversion file needed" ); nMinFM = CPL_LSBINT32PTR (poDS->pachHeader + 1280); sprintf(szTemp, "%d", nMinFM); poBand->SetMetadataItem( "FUEL_MODEL_MIN", szTemp ); nMaxFM = CPL_LSBINT32PTR (poDS->pachHeader + 1284); sprintf(szTemp, "%d", nMaxFM); poBand->SetMetadataItem( "FUEL_MODEL_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1288); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "FUEL_MODEL_NUM_CLASSES", szTemp ); if (nTemp > 0 && nTemp <= 100) { strcpy(pszList, ""); for ( i = 0; i <= nTemp; i++ ) { nTemp2 = CPL_LSBINT32PTR (poDS->pachHeader + (1292+(i*4))) ; if ( nTemp2 >= nMinFM && nTemp2 <= nMaxFM ) { sprintf(szTemp, "%d", nTemp2); strcat(pszList, szTemp); if (i < (nTemp) ) strcat(pszList, ","); } } } poBand->SetMetadataItem( "FUEL_MODEL_VALUES", pszList ); *(poDS->pachHeader + 5012 + 255) = '\0'; poBand->SetMetadataItem( "FUEL_MODEL_FILE", poDS->pachHeader + 5012 ); break; case 5: poBand->SetDescription("Canopy cover"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4232); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Categories (0-4)" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Percent" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1692); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1696); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1700); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5268 + 255) = '\0'; poBand->SetMetadataItem( "CANOPY_COV_FILE", poDS->pachHeader + 5268 ); break; case 6: if(bHaveCrownFuels) { poBand->SetDescription("Canopy height"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4234); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters x 10" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet x 10" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2104); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2108); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2112); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5524 + 255) = '\0'; poBand->SetMetadataItem( "CANOPY_HT_FILE", poDS->pachHeader + 5524 ); } else { poBand->SetDescription("Duff"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6292 + 255) = '\0'; poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 ); } break; case 7: if(bHaveCrownFuels) { poBand->SetDescription("Canopy base height"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4236); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters x 10" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet x 10" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2516); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2520); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2524); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5780 + 255) = '\0'; poBand->SetMetadataItem( "CBH_FILE", poDS->pachHeader + 5780 ); } else { poBand->SetDescription("Coarse woody debris"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_OPTION", szTemp ); //if ( nTemp == 1 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); //if ( nTemp == 2 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6548 + 255) = '\0'; poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 ); } break; case 8: poBand->SetDescription("Canopy bulk density"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4238); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3 x 100" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3 x 1000" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2928); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2932); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2936); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6036 + 255) = '\0'; poBand->SetMetadataItem( "CBD_FILE", poDS->pachHeader + 6036 ); break; case 9: poBand->SetDescription("Duff"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6292 + 255) = '\0'; poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 ); break; case 10: poBand->SetDescription("Coarse woody debris"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_OPTION", szTemp ); //if ( nTemp == 1 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); //if ( nTemp == 2 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6548 + 255) = '\0'; poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 ); break; } } /* -------------------------------------------------------------------- */ /* Try to read projection file. */ /* -------------------------------------------------------------------- */ char *pszDirname, *pszBasename; VSIStatBufL sStatBuf; pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "prj" ); int nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf ); if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename)) { poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "PRJ" ); nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf ); } if( nRet == 0 ) { OGRSpatialReference oSRS; char** papszPrj = CSLLoad( poDS->osPrjFilename ); CPLDebug( "LCP", "Loaded SRS from %s", poDS->osPrjFilename.c_str() ); if( oSRS.importFromESRI( papszPrj ) == OGRERR_NONE ) { oSRS.exportToWkt( &(poDS->pszProjection) ); } CSLDestroy(papszPrj); } CPLFree( pszDirname ); CPLFree( pszBasename ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); CPLFree(pszList); return( poDS ); }