📄 cpl_csv.cpp
字号:
CSLDestroy( papszFields ); papszFields = NULL; } } return( papszFields );}/************************************************************************//* CSVScanFile() *//* *//* Scan a whole file using criteria similar to above, but also *//* taking care of file opening and closing. *//************************************************************************/char **CSVScanFile( const char * pszFilename, int iKeyField, const char * pszValue, CSVCompareCriteria eCriteria ){ CSVTable *psTable;/* -------------------------------------------------------------------- *//* Get access to the table. *//* -------------------------------------------------------------------- */ CPLAssert( pszFilename != NULL ); if( iKeyField < 0 ) return NULL; psTable = CSVAccess( pszFilename ); if( psTable == NULL ) return NULL; CSVIngest( pszFilename );/* -------------------------------------------------------------------- *//* Does the current record match the criteria? If so, just *//* return it again. *//* -------------------------------------------------------------------- */ if( iKeyField >= 0 && iKeyField < CSLCount(psTable->papszRecFields) && CSVCompare(pszValue,psTable->papszRecFields[iKeyField],eCriteria) ) { return psTable->papszRecFields; }/* -------------------------------------------------------------------- *//* Scan the file from the beginning, replacing the ``current *//* record'' in our structure with the one that is found. *//* -------------------------------------------------------------------- */ psTable->iLastLine = -1; CSLDestroy( psTable->papszRecFields ); if( psTable->pszRawData != NULL ) psTable->papszRecFields = CSVScanLinesIngested( psTable, iKeyField, pszValue, eCriteria ); else { VSIRewind( psTable->fp ); CPLReadLine( psTable->fp ); /* throw away the header line */ psTable->papszRecFields = CSVScanLines( psTable->fp, iKeyField, pszValue, eCriteria ); } return( psTable->papszRecFields );}/************************************************************************//* CPLGetFieldId() *//* *//* Read the first record of a CSV file (rewinding to be sure), *//* and find the field with the indicated name. Returns -1 if *//* it fails to find the field name. Comparison is case *//* insensitive, but otherwise exact. After this function has *//* been called the file pointer will be positioned just after *//* the first record. *//************************************************************************/int CSVGetFieldId( FILE * fp, const char * pszFieldName ){ char **papszFields; int i; CPLAssert( fp != NULL && pszFieldName != NULL ); VSIRewind( fp ); papszFields = CSVReadParseLine( fp ); for( i = 0; papszFields != NULL && papszFields[i] != NULL; i++ ) { if( EQUAL(papszFields[i],pszFieldName) ) { CSLDestroy( papszFields ); return i; } } CSLDestroy( papszFields ); return -1;}/************************************************************************//* CSVGetFileFieldId() *//* *//* Same as CPLGetFieldId(), except that we get the file based *//* on filename, rather than having an existing handle. *//************************************************************************/int CSVGetFileFieldId( const char * pszFilename, const char * pszFieldName ){ CSVTable *psTable; int i; /* -------------------------------------------------------------------- *//* Get access to the table. *//* -------------------------------------------------------------------- */ CPLAssert( pszFilename != NULL ); psTable = CSVAccess( pszFilename ); if( psTable == NULL ) return -1;/* -------------------------------------------------------------------- *//* Find the requested field. *//* -------------------------------------------------------------------- */ for( i = 0; psTable->papszFieldNames != NULL && psTable->papszFieldNames[i] != NULL; i++ ) { if( EQUAL(psTable->papszFieldNames[i],pszFieldName) ) { return i; } } return -1;}/************************************************************************//* CSVScanFileByName() *//* *//* Same as CSVScanFile(), but using a field name instead of a *//* field number. *//************************************************************************/char **CSVScanFileByName( const char * pszFilename, const char * pszKeyFieldName, const char * pszValue, CSVCompareCriteria eCriteria ){ int iKeyField; iKeyField = CSVGetFileFieldId( pszFilename, pszKeyFieldName ); if( iKeyField == -1 ) return NULL; return( CSVScanFile( pszFilename, iKeyField, pszValue, eCriteria ) );}/************************************************************************//* CSVGetField() *//* *//* The all-in-one function to fetch a particular field value *//* from a CSV file. Note this function will return an empty *//* string, rather than NULL if it fails to find the desired *//* value for some reason. The caller can't establish that the *//* fetch failed. *//************************************************************************/const char *CSVGetField( const char * pszFilename, const char * pszKeyFieldName, const char * pszKeyFieldValue, CSVCompareCriteria eCriteria, const char * pszTargetField ){ CSVTable *psTable; char **papszRecord; int iTargetField; /* -------------------------------------------------------------------- *//* Find the table. *//* -------------------------------------------------------------------- */ psTable = CSVAccess( pszFilename ); if( psTable == NULL ) return "";/* -------------------------------------------------------------------- *//* Find the correct record. *//* -------------------------------------------------------------------- */ papszRecord = CSVScanFileByName( pszFilename, pszKeyFieldName, pszKeyFieldValue, eCriteria ); if( papszRecord == NULL ) return "";/* -------------------------------------------------------------------- *//* Figure out which field we want out of this. *//* -------------------------------------------------------------------- */ iTargetField = CSVGetFileFieldId( pszFilename, pszTargetField ); if( iTargetField < 0 ) return ""; if( iTargetField >= CSLCount( papszRecord ) ) return ""; return( papszRecord[iTargetField] );}/************************************************************************//* CSVFilename() *//* *//* Return the full path to a particular CSV file. This will *//* eventually be something the application can override. *//************************************************************************/static const char *(*pfnCSVFilenameHook)(const char *) = NULL;const char * CSVFilename( const char *pszBasename ){ static char szPath[512]; if( pfnCSVFilenameHook == NULL ) { FILE *fp = NULL; const char *pszResult; static int bFinderInitialized = FALSE; pszResult = CPLFindFile( "epsg_csv", pszBasename ); if( pszResult != NULL ) return pszResult; if( !bFinderInitialized ) { bFinderInitialized = TRUE; if( CPLGetConfigOption("GEOTIFF_CSV",NULL) != NULL ) CPLPushFinderLocation( CPLGetConfigOption("GEOTIFF_CSV",NULL)); if( CPLGetConfigOption("GDAL_DATA",NULL) != NULL ) CPLPushFinderLocation( CPLGetConfigOption("GDAL_DATA",NULL) ); pszResult = CPLFindFile( "epsg_csv", pszBasename ); if( pszResult != NULL ) return pszResult; } if( (fp = fopen( "csv/horiz_cs.csv", "rt" )) != NULL ) { sprintf( szPath, "csv/%s", pszBasename ); } else { sprintf( szPath, "/usr/local/share/epsg_csv/%s", pszBasename ); if( (fp = fopen( szPath, "rt" )) == NULL ) strcpy( szPath, pszBasename ); } if( fp != NULL ) fclose( fp ); return( szPath ); } else return( pfnCSVFilenameHook( pszBasename ) );}/************************************************************************//* SetCSVFilenameHook() *//* *//* Applications can use this to set a function that will *//* massage CSV filenames. *//************************************************************************//** * Override CSV file search method. * * @param CSVFileOverride The pointer to a function which will return the * full path for a given filename. *This function allows an application to override how the GTIFGetDefn() and related function find the CSV (Comma SeparatedValue) values required. The pfnHook argument should be a pointer to a function that will take in a CSV filename and return afull path to the file. The returned string should be to an internal static buffer so that the caller doesn't have to free the result.<b>Example:</b><br>The listgeo utility uses the following override function if the userspecified a CSV file directory with the -t commandline switch (argumentput into CSVDirName). <p><pre> ... SetCSVFilenameHook( CSVFileOverride ); ...static const char *CSVFileOverride( const char * pszInput ){ static char szPath[1024];#ifdef WIN32 sprintf( szPath, "%s\\%s", CSVDirName, pszInput );#else sprintf( szPath, "%s/%s", CSVDirName, pszInput );#endif return( szPath );}</pre>*/void SetCSVFilenameHook( const char *(*pfnNewHook)( const char * ) ){ pfnCSVFilenameHook = pfnNewHook;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -