void replace(CPLString& str, const char *from, const char *to) { if(strlen(from) == 0) return; size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, strlen(from), to); start_pos += strlen(to); // In case 'to' contains 'from', like replacing 'x' with 'yx' } }
CPLErr GDALWriteRPCTXTFile( const char *pszFilename, char **papszMD ) { CPLString osRPCFilename = pszFilename; CPLString soPt("."); size_t found = osRPCFilename.rfind(soPt); if (found == CPLString::npos) return CE_Failure; osRPCFilename.replace (found, osRPCFilename.size() - found, "_RPC.TXT"); /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( osRPCFilename, "w" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create %s for writing.\n%s", osRPCFilename.c_str(), CPLGetLastErrorMsg() ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Write RPC values from our RPC metadata. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; apszRPCTXTSingleValItems[i] != NULL; i ++ ) { const char *pszRPCVal = CSLFetchNameValue( papszMD, apszRPCTXTSingleValItems[i] ); if( pszRPCVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s field missing in metadata, %s file not written.", apszRPCTXTSingleValItems[i], osRPCFilename.c_str() ); VSIFCloseL( fp ); VSIUnlink( osRPCFilename ); return CE_Failure; } VSIFPrintfL( fp, "%s: %s\n", apszRPCTXTSingleValItems[i], pszRPCVal ); } for( i = 0; apszRPCTXT20ValItems[i] != NULL; i ++ ) { const char *pszRPCVal = CSLFetchNameValue( papszMD, apszRPCTXT20ValItems[i] ); if( pszRPCVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s field missing in metadata, %s file not written.", apszRPCTXTSingleValItems[i], osRPCFilename.c_str() ); VSIFCloseL( fp ); VSIUnlink( osRPCFilename ); return CE_Failure; } char **papszItems = CSLTokenizeStringComplex( pszRPCVal, " ,", FALSE, FALSE ); if( CSLCount(papszItems) != 20 ) { CPLError( CE_Failure, CPLE_AppDefined, "%s field is corrupt (not 20 values), %s file not written.\n%s = %s", apszRPCTXT20ValItems[i], osRPCFilename.c_str(), apszRPCTXT20ValItems[i], pszRPCVal ); VSIFCloseL( fp ); VSIUnlink( osRPCFilename ); CSLDestroy( papszItems ); return CE_Failure; } int j; for( j = 0; j < 20; j++ ) { VSIFPrintfL( fp, "%s_%d: %s\n", apszRPCTXT20ValItems[i], j+1, papszItems[j] ); } CSLDestroy( papszItems ); } VSIFCloseL( fp ); return CE_None; }
char **CPL_STDCALL GDALLoadRPCFile( const char *pszFilename, char **papszSiblingFiles ) { /* -------------------------------------------------------------------- */ /* Try to identify the RPC file in upper or lower case. */ /* -------------------------------------------------------------------- */ CPLString osTarget; /* Is this already a _RPC.TXT file ? */ if (strlen(pszFilename) > 8 && EQUAL(pszFilename + strlen(pszFilename) - 8, "_RPC.TXT")) osTarget = pszFilename; else { CPLString osSrcPath = pszFilename; CPLString soPt("."); size_t found = osSrcPath.rfind(soPt); if (found == CPLString::npos) return NULL; osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.txt"); CPLString osTarget = osSrcPath; if( papszSiblingFiles == NULL ) { VSIStatBufL sStatBuf; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osSrcPath = pszFilename; osSrcPath.replace (found, osSrcPath.size() - found, "_RPC.TXT"); osTarget = osSrcPath; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osSrcPath = pszFilename; osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.TXT"); osTarget = osSrcPath; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { return NULL; } } } } else { int iSibling = CSLFindString( papszSiblingFiles, CPLGetFilename(osTarget) ); if( iSibling < 0 ) return NULL; osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling])); osTarget += papszSiblingFiles[iSibling]; } } /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ char **papszLines = CSLLoad2( osTarget, 100, 100, NULL ); if(!papszLines) return NULL; char **papszMD = NULL; /* From LINE_OFF to HEIGHT_SCALE */ for(size_t i = 0; i < 19; i += 2 ) { const char *pszRPBVal = CSLFetchNameValue(papszLines, apszRPBMap[i] ); if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s file found, but missing %s field (and possibly others).", osTarget.c_str(), apszRPBMap[i]); CSLDestroy( papszMD ); CSLDestroy( papszLines ); return NULL; } else { papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], pszRPBVal ); } } /* For LINE_NUM_COEFF, LINE_DEN_COEFF, SAMP_NUM_COEFF, SAMP_DEN_COEFF */ /* parameters that have 20 values each */ for(size_t i = 20; apszRPBMap[i] != NULL; i += 2 ) { CPLString soVal; for(int j = 1; j <= 20; j++) { CPLString soRPBMapItem; soRPBMapItem.Printf("%s_%d", apszRPBMap[i], j); const char *pszRPBVal = CSLFetchNameValue(papszLines, soRPBMapItem.c_str() ); if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s file found, but missing %s field (and possibly others).", osTarget.c_str(), soRPBMapItem.c_str() ); CSLDestroy( papszMD ); CSLDestroy( papszLines ); return NULL; } else { soVal += pszRPBVal; soVal += " "; } } papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], soVal.c_str() ); } CSLDestroy( papszLines ); return papszMD; }