// static function- pointer set in driver GDALDataset *KEADataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char ** papszParmList ) { H5::H5File *keaImgH5File = CreateLL( pszFilename, nXSize, nYSize, nBands, eType, papszParmList ); if( keaImgH5File == NULL ) return NULL; bool bThematic = CPLTestBool(CSLFetchNameValueDef( papszParmList, "THEMATIC", "FALSE" )); try { // create our dataset object KEADataset *pDataset = new KEADataset( keaImgH5File, GA_Update ); pDataset->SetDescription( pszFilename ); // set all to thematic if asked if( bThematic ) { for( int nCount = 0; nCount < nBands; nCount++ ) { GDALRasterBand *pBand = pDataset->GetRasterBand(nCount+1); pBand->SetMetadataItem("LAYER_TYPE", "thematic"); } } return pDataset; } catch (kealib::KEAIOException &e) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed. Error: %s\n", pszFilename, e.what() ); return NULL; } }
GDALDataset *KEADataset::CreateCopy( const char * pszFilename, GDALDataset *pSrcDs, CPL_UNUSED int bStrict, char ** papszParmList, GDALProgressFunc pfnProgress, void *pProgressData ) { // get the data out of the input dataset int nXSize = pSrcDs->GetRasterXSize(); int nYSize = pSrcDs->GetRasterYSize(); int nBands = pSrcDs->GetRasterCount(); GDALDataType eType = (nBands == 0) ? GDT_Unknown : pSrcDs->GetRasterBand(1)->GetRasterDataType(); H5::H5File *keaImgH5File = CreateLL( pszFilename, nXSize, nYSize, nBands, eType, papszParmList ); if( keaImgH5File == NULL ) return NULL; bool bThematic = CSLTestBoolean(CSLFetchNameValueDef( papszParmList, "THEMATIC", "FALSE" )); try { // create the imageio kealib::KEAImageIO *pImageIO = new kealib::KEAImageIO(); // open the file pImageIO->openKEAImageHeader( keaImgH5File ); // copy file if( !KEACopyFile( pSrcDs, pImageIO, pfnProgress, pProgressData) ) { delete pImageIO; return NULL; } // close it try { pImageIO->close(); } catch (kealib::KEAIOException &e) { } delete pImageIO; // now open it again - because the constructor loads all the info // in we need to copy the data first.... keaImgH5File = kealib::KEAImageIO::openKeaH5RW( pszFilename ); // and wrap it in a dataset KEADataset *pDataset = new KEADataset( keaImgH5File, GA_Update ); pDataset->SetDescription( pszFilename ); // set all to thematic if asked - overrides whatever set by CopyFile if( bThematic ) { for( int nCount = 0; nCount < nBands; nCount++ ) { GDALRasterBand *pBand = pDataset->GetRasterBand(nCount+1); pBand->SetMetadataItem("LAYER_TYPE", "thematic"); } } for( int nCount = 0; nCount < nBands; nCount++ ) { pDataset->GetRasterBand(nCount+1)->SetColorInterpretation( pSrcDs->GetRasterBand(nCount+1)->GetColorInterpretation()); } // KEA has no concept of per-dataset mask band for now. for( int nCount = 0; nCount < nBands; nCount++ ) { if( pSrcDs->GetRasterBand(nCount+1)->GetMaskFlags() == 0 ) // Per-band mask { pDataset->GetRasterBand(nCount+1)->CreateMaskBand(0); GDALRasterBandCopyWholeRaster( (GDALRasterBandH)pSrcDs->GetRasterBand(nCount+1)->GetMaskBand(), (GDALRasterBandH)pDataset->GetRasterBand(nCount+1)->GetMaskBand(), NULL, NULL, NULL); } } return pDataset; } catch (kealib::KEAException &e) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed. Error: %s\n", pszFilename, e.what() ); return NULL; } }
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 ); }