static GDALDataset * DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { (void) pProgressData; (void) pfnProgress; (void) papszOptions; (void) bStrict; /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "DTED driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "DTED driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Work out the level. */ /* -------------------------------------------------------------------- */ int nLevel; if( poSrcDS->GetRasterYSize() == 121 ) nLevel = 0; else if( poSrcDS->GetRasterYSize() == 1201 ) nLevel = 1; else if( poSrcDS->GetRasterYSize() == 3601 ) nLevel = 2; else { CPLError( CE_Warning, CPLE_AppDefined, "The source does not appear to be a properly formatted cell." ); nLevel = 1; } /* -------------------------------------------------------------------- */ /* Checks the input SRS */ /* -------------------------------------------------------------------- */ OGRSpatialReference ogrsr_input; OGRSpatialReference ogrsr_wgs84; char* c = (char*)poSrcDS->GetProjectionRef(); ogrsr_input.importFromWkt(&c); ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" ); if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "The source projection coordinate system is %s. Only WGS 84 is supported.\n" "The DTED driver will generate a file as if the source was WGS 84 projection coordinate system.", poSrcDS->GetProjectionRef() ); } /* -------------------------------------------------------------------- */ /* Work out the LL origin. */ /* -------------------------------------------------------------------- */ int nLLOriginLat, nLLOriginLong; double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); nLLOriginLat = (int) floor(adfGeoTransform[3] + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5); nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5); if (fabs(nLLOriginLat - (adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 || fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10) { CPLError( CE_Warning, CPLE_AppDefined, "The corner coordinates of the source are not properly " "aligned on plain latitude/longitude boundaries."); } /* -------------------------------------------------------------------- */ /* Check horizontal source size. */ /* -------------------------------------------------------------------- */ int expectedXSize; if( ABS(nLLOriginLat) >= 80 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1; else if( ABS(nLLOriginLat) >= 75 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1; else if( ABS(nLLOriginLat) >= 70 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1; else if( ABS(nLLOriginLat) >= 50 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1; else expectedXSize = poSrcDS->GetRasterYSize(); if (poSrcDS->GetRasterXSize() != expectedXSize) { CPLError( CE_Warning, CPLE_AppDefined, "The horizontal source size is not conformant with the one " "expected by DTED Level %d at this latitude (%d pixels found instead of %d).", nLevel, poSrcDS->GetRasterXSize(), expectedXSize); } /* -------------------------------------------------------------------- */ /* Create the output dted file. */ /* -------------------------------------------------------------------- */ const char *pszError; pszError = DTEDCreate( pszFilename, nLevel, nLLOriginLat, nLLOriginLong ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the DTED file so we can output the data to it. */ /* -------------------------------------------------------------------- */ DTEDInfo *psDTED; psDTED = DTEDOpen( pszFilename, "rb+", FALSE ); if( psDTED == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Read all the data in a single buffer. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); GInt16 *panData; panData = (GInt16 *) VSIMalloc(sizeof(GInt16) * psDTED->nXSize * psDTED->nYSize); if (panData == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); DTEDClose(psDTED); return NULL; } for( int iY = 0; iY < psDTED->nYSize; iY++ ) { poSrcBand->RasterIO( GF_Read, 0, iY, psDTED->nXSize, 1, (void *) (panData + iY * psDTED->nXSize), psDTED->nXSize, 1, GDT_Int16, 0, 0, NULL ); if( pfnProgress && !pfnProgress(0.5 * (iY+1) / (double) psDTED->nYSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } int bSrcBandHasNoData; double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData); /* -------------------------------------------------------------------- */ /* Write all the profiles. */ /* -------------------------------------------------------------------- */ GInt16 anProfData[3601]; int dfNodataCount=0; GByte iPartialCell; for( int iProfile = 0; iProfile < psDTED->nXSize; iProfile++ ) { for( int iY = 0; iY < psDTED->nYSize; iY++ ) { anProfData[iY] = panData[iProfile + iY * psDTED->nXSize]; if ( bSrcBandHasNoData && anProfData[iY] == srcBandNoData) { anProfData[iY] = DTED_NODATA_VALUE; dfNodataCount++; } else if ( anProfData[iY] == DTED_NODATA_VALUE ) dfNodataCount++; } DTEDWriteProfile( psDTED, iProfile, anProfData ); if( pfnProgress && !pfnProgress( 0.5 + 0.5 * (iProfile+1) / (double) psDTED->nXSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } CPLFree( panData ); /* -------------------------------------------------------------------- */ /* Partial cell indicator: 0 for complete coverage; 1-99 for incomplete */ /* -------------------------------------------------------------------- */ char szPartialCell[3]; if ( dfNodataCount == 0 ) iPartialCell = 0; else { iPartialCell = (GByte)int(floor(100.0 - (dfNodataCount*100.0/(psDTED->nXSize * psDTED->nYSize)))); if (iPartialCell < 1) iPartialCell=1; } sprintf(szPartialCell,"%02d",iPartialCell); DTEDSetMetadata(psDTED, DTEDMD_PARTIALCELL_DSI, szPartialCell); /* -------------------------------------------------------------------- */ /* Try to copy any matching available metadata. */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL, poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI, poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL, poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI, poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_DataEdition" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DATA_EDITION, poSrcDS->GetMetadataItem( "DTED_DataEdition" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION, poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DATE, poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE, poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION, poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) ); if( poSrcDS->GetMetadataItem( "DTED_Producer" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_PRODUCER, poSrcDS->GetMetadataItem( "DTED_Producer" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTDATUM, poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZDATUM, poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DIGITIZING_SYS, poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) ); if( poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_COMPILATION_DATE, poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_VERTACCURACY, poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) ); /* -------------------------------------------------------------------- */ /* Try to open the resulting DTED file. */ /* -------------------------------------------------------------------- */ DTEDClose( psDTED ); /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
static int DTEDPtStreamNewTile( DTEDPtStream *psStream, int nCrLong, int nCrLat ) { DTEDInfo *psInfo; char szFile[128]; char chNSHemi, chEWHemi; char *pszFullFilename; const char *pszError; /* work out filename */ if( nCrLat < 0 ) chNSHemi = 's'; else chNSHemi = 'n'; if( nCrLong < 0 ) chEWHemi = 'w'; else chEWHemi = 'e'; sprintf( szFile, "%c%03d%c%03d.dt%d", chEWHemi, ABS(nCrLong), chNSHemi, ABS(nCrLat), psStream->nLevel ); pszFullFilename = CPLStrdup(CPLFormFilename( psStream->pszPath, szFile, NULL )); /* create the dted file */ pszError = DTEDCreate( pszFullFilename, psStream->nLevel, nCrLat, nCrLong ); if( pszError != NULL ) { #ifndef AVOID_CPL CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create DTED file `%s'.\n%s", pszFullFilename, pszError ); #endif return FALSE; } psInfo = DTEDOpen( pszFullFilename, "rb+", FALSE ); if( psInfo == NULL ) { CPLFree( pszFullFilename ); return FALSE; } /* add cached file to stream */ psStream->nOpenFiles++; psStream->pasCF = CPLRealloc(psStream->pasCF, sizeof(DTEDCachedFile)*psStream->nOpenFiles); psStream->pasCF[psStream->nOpenFiles-1].psInfo = psInfo; psStream->pasCF[psStream->nOpenFiles-1].papanProfiles = CPLCalloc(sizeof(GInt16*),psInfo->nXSize); psStream->pasCF[psStream->nOpenFiles-1].pszFilename = pszFullFilename; psStream->pasCF[psStream->nOpenFiles-1].nLLLat = nCrLat; psStream->pasCF[psStream->nOpenFiles-1].nLLLong = nCrLong; psStream->nLastFile = psStream->nOpenFiles-1; return TRUE; }
GDALDataset *DTEDDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; DTEDInfo *psDTED; if (!Identify(poOpenInfo)) return NULL; /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ psDTED = DTEDOpen( poOpenInfo->pszFilename, (poOpenInfo->eAccess == GA_Update) ? "rb+" : "rb", TRUE ); if( psDTED == NULL ) return( NULL ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ DTEDDataset *poDS; poDS = new DTEDDataset(); poDS->SetFileName(poOpenInfo->pszFilename); poDS->eAccess = poOpenInfo->eAccess; poDS->psDTED = psDTED; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = psDTED->nXSize; poDS->nRasterYSize = psDTED->nYSize; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; for( i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new DTEDRasterBand( poDS, i+1 ) ); /* -------------------------------------------------------------------- */ /* Collect any metadata available. */ /* -------------------------------------------------------------------- */ char *pszValue; pszValue = DTEDGetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL ); poDS->SetMetadataItem( "DTED_VerticalAccuracy_UHL", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC ); poDS->SetMetadataItem( "DTED_VerticalAccuracy_ACC", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL ); poDS->SetMetadataItem( "DTED_SecurityCode_UHL", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI ); poDS->SetMetadataItem( "DTED_SecurityCode_DSI", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL ); poDS->SetMetadataItem( "DTED_UniqueRef_UHL", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI ); poDS->SetMetadataItem( "DTED_UniqueRef_DSI", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_DATA_EDITION ); poDS->SetMetadataItem( "DTED_DataEdition", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION ); poDS->SetMetadataItem( "DTED_MatchMergeVersion", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_MAINT_DATE ); poDS->SetMetadataItem( "DTED_MaintenanceDate", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE ); poDS->SetMetadataItem( "DTED_MatchMergeDate", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION ); poDS->SetMetadataItem( "DTED_MaintenanceDescription", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_PRODUCER ); poDS->SetMetadataItem( "DTED_Producer", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_VERTDATUM ); poDS->SetMetadataItem( "DTED_VerticalDatum", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_HORIZDATUM ); poDS->SetMetadataItem( "DTED_HorizontalDatum", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_DIGITIZING_SYS ); poDS->SetMetadataItem( "DTED_DigitizingSystem", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_COMPILATION_DATE ); poDS->SetMetadataItem( "DTED_CompilationDate", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_HORIZACCURACY ); poDS->SetMetadataItem( "DTED_HorizontalAccuracy", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY ); poDS->SetMetadataItem( "DTED_RelHorizontalAccuracy", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_REL_VERTACCURACY ); poDS->SetMetadataItem( "DTED_RelVerticalAccuracy", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_ORIGINLAT ); poDS->SetMetadataItem( "DTED_OriginLatitude", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_ORIGINLONG ); poDS->SetMetadataItem( "DTED_OriginLongitude", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_NIMA_DESIGNATOR ); poDS->SetMetadataItem( "DTED_NimaDesignator", pszValue ); free( pszValue ); pszValue = DTEDGetMetadata( psDTED, DTEDMD_PARTIALCELL_DSI ); poDS->SetMetadataItem( "DTED_PartialCellIndicator", pszValue ); free( pszValue ); poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); // if no SR in xml, try aux const char* pszPrj = poDS->GDALPamDataset::GetProjectionRef(); if( !pszPrj || strlen(pszPrj) == 0 ) { GDALDataset* poAuxDS = GDALFindAssociatedAuxFile( poOpenInfo->pszFilename, GA_ReadOnly, poDS ); if( poAuxDS ) { pszPrj = poAuxDS->GetProjectionRef(); if( pszPrj && strlen(pszPrj) > 0 ) { CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(pszPrj); } GDALClose( poAuxDS ); } } /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }