void EnvisatDataset::ScanForGCPs_MERIS() { int nDatasetIndex, nNumDSR, nDSRSize, iRecord; /* -------------------------------------------------------------------- */ /* Do we have a meaningful geolocation grid? Seach for a */ /* DS_TYPE=A and a name containing "geolocation" or "tie */ /* points". */ /* -------------------------------------------------------------------- */ nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, "Tie points ADS" ); if( nDatasetIndex == -1 ) return; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, NULL, NULL, NULL, NULL, NULL, &nNumDSR, &nDSRSize ) != SUCCESS ) return; if( nNumDSR == 0 ) return; /* -------------------------------------------------------------------- */ /* Figure out the tiepoint space, and how many we have. */ /* -------------------------------------------------------------------- */ int nLinesPerTiePoint, nSamplesPerTiePoint; int nTPPerLine, nTPPerColumn = nNumDSR; if( nNumDSR == 0 ) return; nLinesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "LINES_PER_TIE_PT", 0 ); nSamplesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "SAMPLES_PER_TIE_PT", 0 ); if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 ) return; nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1) / nSamplesPerTiePoint; if( (GetRasterYSize() + nLinesPerTiePoint - 1) / nLinesPerTiePoint != nTPPerColumn ) { CPLDebug( "EnvisatDataset", "Got %d instead of %d nTPPerColumn.", (GetRasterYSize()+nLinesPerTiePoint-1)/nLinesPerTiePoint, nTPPerColumn ); return; } if( 50*nTPPerLine + 13 != nDSRSize ) { CPLDebug( "EnvisatDataset", "DSRSize=%d instead of expected %d for tiepoints ADS.", nDSRSize, 50*nTPPerLine + 13 ); return; } /* -------------------------------------------------------------------- */ /* Collect the first GCP set from each record. */ /* -------------------------------------------------------------------- */ GByte *pabyRecord = (GByte *) CPLMalloc(nDSRSize); int iGCP; GUInt32 unValue; nGCPCount = 0; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nNumDSR * nTPPerLine); for( iRecord = 0; iRecord < nNumDSR; iRecord++ ) { if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex, iRecord, pabyRecord ) != SUCCESS ) continue; memcpy( &unValue, pabyRecord + 13, 4 ); for( iGCP = 0; iGCP < nTPPerLine; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); memcpy( &unValue, pabyRecord + 13 + nTPPerLine*4 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001; memcpy( &unValue, pabyRecord + 13 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001; pasGCPList[nGCPCount].dfGCPZ = 0.0; pasGCPList[nGCPCount].dfGCPLine = iRecord*nLinesPerTiePoint + 0.5; pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5; nGCPCount++; } } CPLFree( pabyRecord ); }
void EnvisatDataset::ScanForGCPs_MERIS() { int nDatasetIndex, nNumDSR, nDSRSize; bool isBrowseProduct ; /* -------------------------------------------------------------------- */ /* Do we have a meaningful geolocation grid? Seach for a */ /* DS_TYPE=A and a name containing "geolocation" or "tie */ /* points". */ /* -------------------------------------------------------------------- */ nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, "Tie points ADS" ); if( nDatasetIndex == -1 ) return; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, NULL, NULL, NULL, NULL, NULL, &nNumDSR, &nDSRSize ) != SUCCESS ) return; if( nNumDSR == 0 ) return; /* -------------------------------------------------------------------- */ /* Figure out the tiepoint space, and how many we have. */ /* -------------------------------------------------------------------- */ int nLinesPerTiePoint, nSamplesPerTiePoint; int nTPPerLine, nTPPerColumn = nNumDSR; if( nNumDSR == 0 ) return; nLinesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "LINES_PER_TIE_PT", 0 ); nSamplesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "SAMPLES_PER_TIE_PT", 0 ); if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 ) return; nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1) / nSamplesPerTiePoint; /* -------------------------------------------------------------------- */ /* Find a Mesurement type dataset to use as a reference raster */ /* band. */ /* -------------------------------------------------------------------- */ int nMDSIndex; for( nMDSIndex = 0; TRUE; nMDSIndex++ ) { char *pszDSType; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nMDSIndex, NULL, &pszDSType, NULL, NULL, NULL, NULL, NULL ) == FAILURE ) { CPLDebug("EnvisatDataset", "Unable to find MDS in Envisat file.") ; return ; } if( EQUAL(pszDSType,"M") ) break; } /* -------------------------------------------------------------------- */ /* Get subset of TP ADS records matching the MDS records */ /* -------------------------------------------------------------------- */ /* get the MDS line sampling time interval */ TimeDelta tdMDSSamplingInterval( 0 , 0 , EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "LINE_TIME_INTERVAL", 0 ) ); /* get range of TiePoint ADS records matching the measurements */ ADSRangeLastAfter arTP( *hEnvisatFile , nDatasetIndex, nMDSIndex , tdMDSSamplingInterval ) ; /* check if there are any TPs to be used */ if ( arTP.getDSRCount() <= 0 ) { CPLDebug( "EnvisatDataset" , "No tiepoint covering " "the measurement records." ) ; return; /* No TPs - no extraction. */ } /* check if TPs cover the whole range of MDSRs */ if(( arTP.getFirstOffset() < 0 )||( arTP.getLastOffset() < 0 )) { CPLDebug( "EnvisatDataset" , "The tiepoints do not cover " "whole range of measurement records." ) ; /* Not good but we can still extract some of the TPS, can we? */ } /* check TP records spacing */ if ((1+(arTP.getFirstOffset()+arTP.getLastOffset()+GetRasterYSize()-1) / nLinesPerTiePoint ) != arTP.getDSRCount() ) { CPLDebug( "EnvisatDataset", "Not enough tieponts per column! " "received=%d expected=%d", nTPPerColumn , 1 + (arTP.getFirstOffset()+arTP.getLastOffset()+ GetRasterYSize()-1) / nLinesPerTiePoint ) ; return; /* That is far more serious - we risk missplaces TPs. */ } if ( 50*nTPPerLine + 13 == nDSRSize ) /* regular product */ { isBrowseProduct = false ; } else if ( 8*nTPPerLine + 13 == nDSRSize ) /* browse product */ { /* although BPs are rare there is no reason not to support them */ isBrowseProduct = true ; } else { CPLDebug( "EnvisatDataset", "Unexpectd size of 'Tie points ADS' !" " received=%d expected=%d or %d" , nDSRSize , 50*nTPPerLine+13, 8*nTPPerLine+13 ) ; return; } /* -------------------------------------------------------------------- */ /* Collect the first GCP set from each record. */ /* -------------------------------------------------------------------- */ GByte *pabyRecord = (GByte *) CPLMalloc(nDSRSize-13); int iGCP; GUInt32 *tpLat = ((GUInt32*)pabyRecord) + nTPPerLine*0 ; /* latitude */ GUInt32 *tpLon = ((GUInt32*)pabyRecord) + nTPPerLine*1 ; /* longitude */ GUInt32 *tpLtc = ((GUInt32*)pabyRecord) + nTPPerLine*4 ; /* lat. DEM correction */ GUInt32 *tpLnc = ((GUInt32*)pabyRecord) + nTPPerLine*5 ; /* lon. DEM correction */ nGCPCount = 0; pasGCPList = (GDAL_GCP *) CPLCalloc( sizeof(GDAL_GCP), arTP.getDSRCount() * nTPPerLine ); for( int ir = 0 ; ir < arTP.getDSRCount() ; ir++ ) { int iRecord = ir + arTP.getFirstIndex() ; double dfGCPLine = 0.5 + ( iRecord*nLinesPerTiePoint - arTP.getFirstOffset() ) ; if( EnvisatFile_ReadDatasetRecordChunk( hEnvisatFile, nDatasetIndex, iRecord , pabyRecord, 13 , -1 ) != SUCCESS ) continue; for( iGCP = 0; iGCP < nTPPerLine; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); #define INT32(x) ((GInt32)CPL_MSBWORD32(x)) pasGCPList[nGCPCount].dfGCPX = 1e-6*INT32(tpLon[iGCP]) ; pasGCPList[nGCPCount].dfGCPY = 1e-6*INT32(tpLat[iGCP]) ; pasGCPList[nGCPCount].dfGCPZ = 0.0; if( !isBrowseProduct ) /* add DEM corrections */ { pasGCPList[nGCPCount].dfGCPX += 1e-6*INT32(tpLnc[iGCP]) ; pasGCPList[nGCPCount].dfGCPY += 1e-6*INT32(tpLtc[iGCP]) ; } #undef INT32 pasGCPList[nGCPCount].dfGCPLine = dfGCPLine ; pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5; nGCPCount++; } } CPLFree( pabyRecord ); }
void EnvisatDataset::ScanForGCPs_ASAR() { int nDatasetIndex, nNumDSR, nDSRSize, iRecord; /* -------------------------------------------------------------------- */ /* Do we have a meaningful geolocation grid? */ /* -------------------------------------------------------------------- */ nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, "GEOLOCATION GRID ADS" ); if( nDatasetIndex == -1 ) return; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, NULL, NULL, NULL, NULL, NULL, &nNumDSR, &nDSRSize ) != SUCCESS ) return; if( nNumDSR == 0 || nDSRSize != 521 ) return; /* -------------------------------------------------------------------- */ /* Collect the first GCP set from each record. */ /* -------------------------------------------------------------------- */ GByte abyRecord[521]; int nRange=0, nSample, iGCP, nRangeOffset=0; GUInt32 unValue; nGCPCount = 0; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),(nNumDSR+1) * 11); for( iRecord = 0; iRecord < nNumDSR; iRecord++ ) { if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex, iRecord, abyRecord ) != SUCCESS ) continue; memcpy( &unValue, abyRecord + 13, 4 ); nRange = CPL_MSBWORD32( unValue ) + nRangeOffset; if((iRecord>1) && (int(pasGCPList[nGCPCount-1].dfGCPLine+0.5) > nRange)) { int delta = (int) (pasGCPList[nGCPCount-1].dfGCPLine - pasGCPList[nGCPCount-12].dfGCPLine); nRange = int(pasGCPList[nGCPCount-1].dfGCPLine+0.5) + delta; nRangeOffset = nRange-1; } for( iGCP = 0; iGCP < 11; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); memcpy( &unValue, abyRecord + 25 + iGCP*4, 4 ); nSample = CPL_MSBWORD32(unValue); memcpy( &unValue, abyRecord + 25 + 176 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001; memcpy( &unValue, abyRecord + 25 + 132 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001; pasGCPList[nGCPCount].dfGCPZ = 0.0; pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5; pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5; nGCPCount++; } } /* -------------------------------------------------------------------- */ /* We also collect the bottom GCPs from the last granule. */ /* -------------------------------------------------------------------- */ memcpy( &unValue, abyRecord + 17, 4 ); nRange = nRange + CPL_MSBWORD32( unValue ) - 1; for( iGCP = 0; iGCP < 11; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); memcpy( &unValue, abyRecord + 279 + iGCP*4, 4 ); nSample = CPL_MSBWORD32(unValue); memcpy( &unValue, abyRecord + 279 + 176 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001; memcpy( &unValue, abyRecord + 279 + 132 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001; pasGCPList[nGCPCount].dfGCPZ = 0.0; pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5; pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5; nGCPCount++; } }
int main( int argc, char ** argv ) { EnvisatFile *es_file; int ds_index; int ds_offset, ds_size, num_dsr, dsr_size, i_record; if( argc != 2 ) { printf( "Usage: dumpgeo filename\n" ); exit( 1 ); } if( EnvisatFile_Open( &es_file, argv[1], "r" ) != 0 ) { printf( "EnvisatFile_Open(%s) failed.\n", argv[1] ); exit( 2 ); } ds_index = EnvisatFile_GetDatasetIndex( es_file, "GEOLOCATION GRID ADS" ); if( ds_index == -1 ) { printf( "Can't find geolocation grid ads.\n" ); exit( 3 ); } EnvisatFile_GetDatasetInfo( es_file, ds_index, NULL, NULL, NULL, &ds_offset, &ds_size, &num_dsr, &dsr_size ); if( ds_offset == 0 ) { printf( "No data for geolocation grid ads.\n" ); exit( 4 ); } CPLAssert( dsr_size == 521 ); for( i_record = 0; i_record < num_dsr; i_record++ ) { GByte abyRecord[521]; GUInt32 unValue; float fValue; int sample; EnvisatFile_ReadDatasetRecord( es_file, ds_index, i_record, abyRecord ); printf( "<====================== Record %d ==================>\n", i_record ); /* field 1 */ CPL_SWAP32PTR( abyRecord + 0 ); CPL_SWAP32PTR( abyRecord + 4 ); CPL_SWAP32PTR( abyRecord + 8 ); printf( "start line: mjd_days = %d, sec = %d, msec = %d\n", ((int *) abyRecord)[0], ((unsigned int *) abyRecord)[1], ((unsigned int *) abyRecord)[2] ); /* field 2 */ printf( "Attachment flag = %d\n", abyRecord[12] ); /* field 3 */ memcpy( &unValue, abyRecord + 13, 4 ); printf( "range line (first in granule) = %d\n", CPL_SWAP32( unValue ) ); /* field 4 */ memcpy( &unValue, abyRecord + 17, 4 ); printf( "lines in granule = %d\n", CPL_SWAP32( unValue ) ); /* field 5 */ memcpy( &fValue, abyRecord + 21, 4 ); CPL_SWAP32PTR( &fValue ); printf( "track heading (first line) = %f\n", fValue ); /* field 6 */ printf( "first line of granule:\n" ); for( sample = 0; sample < 11; sample++ ) { memcpy( &unValue, abyRecord + 25 + sample*4, 4 ); printf( " sample=%d ", CPL_SWAP32(unValue) ); memcpy( &fValue, abyRecord + 25 + 44 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "time=%g ", fValue ); memcpy( &fValue, abyRecord + 25 + 88 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "angle=%g ", fValue ); memcpy( &unValue, abyRecord + 25 + 132 + sample*4, 4 ); printf( "(%.9f,", ((int) CPL_SWAP32(unValue)) * 0.000001 ); memcpy( &unValue, abyRecord + 25 + 176 + sample*4, 4 ); printf( "%.9f)\n", ((int) CPL_SWAP32(unValue)) * 0.000001 ); } /* field 8 */ CPL_SWAP32PTR( abyRecord + 267 ); CPL_SWAP32PTR( abyRecord + 271 ); CPL_SWAP32PTR( abyRecord + 275 ); printf( "end line: mjd_days = %d, sec = %d, msec = %d\n", ((int *) (abyRecord + 267))[0], ((unsigned int *) (abyRecord + 267))[1], ((unsigned int *) (abyRecord + 267))[2] ); /* field 9 */ printf( "final line of granule:\n" ); for( sample = 0; sample < 11; sample++ ) { memcpy( &unValue, abyRecord + 279 + sample*4, 4 ); printf( " sample=%d ", CPL_SWAP32(unValue) ); memcpy( &fValue, abyRecord + 279 + 44 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "time=%g ", fValue ); memcpy( &fValue, abyRecord + 279 + 88 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "angle=%g ", fValue ); memcpy( &unValue, abyRecord + 279 + 132 + sample*4, 4 ); printf( "(%.9f,", ((int) CPL_SWAP32(unValue)) * 0.000001 ); memcpy( &unValue, abyRecord + 279 + 176 + sample*4, 4 ); printf( "%.9f)\n", ((int) CPL_SWAP32(unValue)) * 0.000001 ); } } EnvisatFile_Close( es_file ); exit( 0 ); }