📄 cpl_conv.cpp
字号:
else return VSIStat( pszPath, psStatBuf );}/************************************************************************//* proj_strtod() *//************************************************************************/static doubleproj_strtod(char *nptr, char **endptr) { char c, *cp = nptr; double result; /* * Scan for characters which cause problems with VC++ strtod() */ while ((c = *cp) != '\0') { if (c == 'd' || c == 'D') { /* * Found one, so NUL it out, call strtod(), * then restore it and return */ *cp = '\0'; result = strtod(nptr, endptr); *cp = c; return result; } ++cp; } /* no offending characters, just handle normally */ return strtod(nptr, endptr);}/************************************************************************//* CPLDMSToDec() *//************************************************************************/static const char*sym = "NnEeSsWw";static const double vm[] = { 1.0, 0.0166666666667, 0.00027777778 };double CPLDMSToDec( const char *is ){ int sign, n, nl; char *p, *s, work[64]; double v, tv; /* copy sting into work space */ while (isspace(sign = *is)) ++is; for (n = sizeof(work), s = work, p = (char *)is; isgraph(*p) && --n ; ) *s++ = *p++; *s = '\0'; /* it is possible that a really odd input (like lots of leading zeros) could be truncated in copying into work. But ... */ sign = *(s = work); if (sign == '+' || sign == '-') s++; else sign = '+'; for (v = 0., nl = 0 ; nl < 3 ; nl = n + 1 ) { if (!(isdigit(*s) || *s == '.')) break; if ((tv = proj_strtod(s, &s)) == HUGE_VAL) return tv; switch (*s) { case 'D': case 'd': n = 0; break; case '\'': n = 1; break; case '"': n = 2; break; case 'r': case 'R': if (nl) { return 0.0; } ++s; v = tv; goto skip; default: v += tv * vm[nl]; skip: n = 4; continue; } if (n < nl) { return 0.0; } v += tv * vm[n]; ++s; } /* postfix sign */ if (*s && (p = (char *) strchr(sym, *s))) { sign = (p - sym) >= 4 ? '-' : '+'; ++s; } if (sign == '-') v = -v; return v;}/************************************************************************//* CPLDecToDMS() *//* *//* Translate a decimal degrees value to a DMS string with *//* hemisphere. *//************************************************************************/const char *CPLDecToDMS( double dfAngle, const char * pszAxis, int nPrecision ){ int nDegrees, nMinutes; double dfSeconds, dfABSAngle, dfEpsilon; char szFormat[30]; static CPL_THREADLOCAL char szBuffer[50]; const char *pszHemisphere; dfEpsilon = (0.5/3600.0) * pow(0.1,nPrecision); dfABSAngle = ABS(dfAngle) + dfEpsilon; nDegrees = (int) dfABSAngle; nMinutes = (int) ((dfABSAngle - nDegrees) * 60); dfSeconds = dfABSAngle * 3600 - nDegrees*3600 - nMinutes*60; if( dfSeconds > dfEpsilon * 3600.0 ) dfSeconds -= dfEpsilon * 3600.0; if( EQUAL(pszAxis,"Long") && dfAngle < 0.0 ) pszHemisphere = "W"; else if( EQUAL(pszAxis,"Long") ) pszHemisphere = "E"; else if( dfAngle < 0.0 ) pszHemisphere = "S"; else pszHemisphere = "N"; sprintf( szFormat, "%%3dd%%2d\'%%.%df\"%s", nPrecision, pszHemisphere ); sprintf( szBuffer, szFormat, nDegrees, nMinutes, dfSeconds ); return( szBuffer );}/************************************************************************//* CPLPackedDMSToDec() *//************************************************************************//** * Convert a packed DMS value (DDDMMMSSS.SS) into decimal degrees. * * This function converts a packed DMS angle to seconds. The standard * packed DMS format is: * * degrees * 1000000 + minutes * 1000 + seconds * * Example: ang = 120025045.25 yields * deg = 120 * min = 25 * sec = 45.25 * * The algorithm used for the conversion is as follows: * * 1. The absolute value of the angle is used. * * 2. The degrees are separated out: * deg = ang/1000000 (fractional portion truncated) * * 3. The minutes are separated out: * min = (ang - deg * 1000000) / 1000 (fractional portion truncated) * * 4. The seconds are then computed: * sec = ang - deg * 1000000 - min * 1000 * * 5. The total angle in seconds is computed: * sec = deg * 3600.0 + min * 60.0 + sec * * 6. The sign of sec is set to that of the input angle. * * Packed DMS values used by the USGS GCTP package and probably by other * software. * * NOTE: This code does not validate input value. If you give the wrong * value, you will get the wrong result. * * @param dfPacked Angle in packed DMS format. * * @return Angle in decimal degrees. * */double CPLPackedDMSToDec( double dfPacked ){ double dfDegrees, dfMinutes, dfSeconds, dfSign; dfSign = ( dfPacked < 0.0 )? -1 : 1; dfSeconds = ABS( dfPacked ); dfDegrees = floor(dfSeconds / 1000000.0); dfSeconds = dfSeconds - dfDegrees * 1000000.0; dfMinutes = floor(dfSeconds / 1000.0); dfSeconds = dfSeconds - dfMinutes * 1000.0; dfSeconds = dfSign * ( dfDegrees * 3600.0 + dfMinutes * 60.0 + dfSeconds); dfDegrees = dfSeconds / 3600.0; return dfDegrees;}/************************************************************************//* CPLDecToPackedDMS() *//************************************************************************//** * Convert decimal degrees into packed DMS value (DDDMMMSSS.SS). * * This function converts a value, specified in decimal degrees into * packed DMS angle. The standard packed DMS format is: * * degrees * 1000000 + minutes * 1000 + seconds * * See also CPLPackedDMSToDec(). * * @param dfDec Angle in decimal degrees. * * @return Angle in packed DMS format. * */double CPLDecToPackedDMS( double dfDec ){ double dfDegrees, dfMinutes, dfSeconds, dfSign; dfSign = ( dfDec < 0.0 )? -1 : 1; dfDec = ABS( dfDec ); dfDegrees = floor( dfDec ); dfMinutes = floor( ( dfDec - dfDegrees ) * 60.0 ); dfSeconds = ( dfDec - dfDegrees ) * 3600.0 - dfMinutes * 60.0; return dfSign * (dfDegrees * 1000000.0 + dfMinutes * 1000.0 + dfSeconds);}/************************************************************************//* CPLStringToComplex() *//************************************************************************/void CPL_DLL CPLStringToComplex( const char *pszString, double *pdfReal, double *pdfImag ){ int i; int iPlus = -1, iImagEnd = -1; while( *pszString == ' ' ) pszString++; *pdfReal = atof(pszString); *pdfImag = 0.0; for( i = 0; pszString[i] != '\0' && pszString[i] != ' ' && i < 100; i++ ) { if( pszString[i] == '+' && i > 0 ) iPlus = i; if( pszString[i] == '-' && i > 0 ) iPlus = i; if( pszString[i] == 'i' ) iImagEnd = i; } if( iPlus > -1 && iImagEnd > -1 && iPlus < iImagEnd ) { *pdfImag = atof(pszString + iPlus); } return;}/************************************************************************//* CPLOpenShared() *//************************************************************************//** * Open a shared file handle. * * Some operating systems have limits on the number of file handles that can * be open at one time. This function attempts to maintain a registry of * already open file handles, and reuse existing ones if the same file * is requested by another part of the application. * * Note that access is only shared for access types "r", "rb", "r+" and * "rb+". All others will just result in direct VSIOpen() calls. Keep in * mind that a file is only reused if the file name is exactly the same. * Different names referring to the same file will result in different * handles. * * The VSIFOpen() or VSIFOpenL() function is used to actually open the file, * when an existing file handle can't be shared. * * @param pszFilename the name of the file to open. * @param pszAccess the normal fopen()/VSIFOpen() style access string. * @param bLarge If TRUE VSIFOpenL() (for large files) will be used instead of * VSIFOpen(). * * @return a file handle or NULL if opening fails. */FILE *CPLOpenShared( const char *pszFilename, const char *pszAccess, int bLarge ){ int i; int bReuse; CPLMutexHolderD( &hSharedFileMutex );/* -------------------------------------------------------------------- *//* Is there an existing file we can use? *//* -------------------------------------------------------------------- */ bReuse = EQUAL(pszAccess,"rb") || EQUAL(pszAccess, "rb+"); for( i = 0; bReuse && i < nSharedFileCount; i++ ) { if( strcmp(pasSharedFileList[i].pszFilename,pszFilename) == 0 && !bLarge == !pasSharedFileList[i].bLarge && EQUAL(pasSharedFileList[i].pszAccess,pszAccess) ) { pasSharedFileList[i].nRefCount++; return pasSharedFileList[i].fp; } }/* -------------------------------------------------------------------- *//* Open the file. *//* -------------------------------------------------------------------- */ FILE *fp; if( bLarge ) fp = VSIFOpenL( pszFilename, pszAccess ); else fp = VSIFOpen( pszFilename, pszAccess ); if( fp == NULL ) return NULL;/* -------------------------------------------------------------------- *//* Add an entry to the list. *//* -------------------------------------------------------------------- */ nSharedFileCount++; pasSharedFileList = (CPLSharedFileInfo *) CPLRealloc( (void *) pasSharedFileList, sizeof(CPLSharedFileInfo) * nSharedFileCount ); pasSharedFileList[nSharedFileCount-1].fp = fp; pasSharedFileList[nSharedFileCount-1].nRefCount = 1; pasSharedFileList[nSharedFileCount-1].bLarge = bLarge; pasSharedFileList[nSharedFileCount-1].pszFilename =CPLStrdup(pszFilename); pasSharedFileList[nSharedFileCount-1].pszAccess = CPLStrdup(pszAccess); return fp;}/************************************************************************//* CPLCloseShared() *//************************************************************************//** * Close shared file. * * Dereferences the indicated file handle, and closes it if the reference * count has dropped to zero. A CPLError() is issued if the file is not * in the shared file list. * * @param fp file handle from CPLOpenShared() to deaccess. */void CPLCloseShared( FILE * fp ){ CPLMutexHolderD( &hSharedFileMutex ); int i;/* -------------------------------------------------------------------- *//* Search for matching information. *//* -------------------------------------------------------------------- */ for( i = 0; i < nSharedFileCount && fp != pasSharedFileList[i].fp; i++ ){} if( i == nSharedFileCount ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find file handle %p i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -