ogr_fromepsg.cpp

来自「用于读取TAB、MIF、SHP文件的类」· C++ 代码 · 共 1,725 行 · 第 1/5 页

CPP
1,725
字号
/* -------------------------------------------------------------------- */    if( pszUOMName != NULL )    {        double dfFactorB, dfFactorC;                dfFactorB =             atof(CSVGetField( pszFilename,                              "UOM_CODE", szSearchKey, CC_Integer,                              "FACTOR_B" ));                dfFactorC =             atof(CSVGetField( pszFilename,                              "UOM_CODE", szSearchKey, CC_Integer,                              "FACTOR_C" ));        if( dfFactorC != 0.0 )            dfInDegrees = (dfFactorB / dfFactorC) * (180.0 / PI);        /* We do a special override of some of the DMS formats name */        if( nUOMAngleCode == 9102 || nUOMAngleCode == 9107            || nUOMAngleCode == 9108 || nUOMAngleCode == 9110             || nUOMAngleCode == 9122 )            pszUOMName = "degree";        // For some reason, (FactorB) is not very precise in EPSG, use        // a more exact form for grads.        if( nUOMAngleCode == 9105 )            dfInDegrees = 180.0 / 200.0;    }/* -------------------------------------------------------------------- *//*      Otherwise handle a few well known units directly.               *//* -------------------------------------------------------------------- */    else    {        switch( nUOMAngleCode )        {          case 9101:            pszUOMName = "radian";            dfInDegrees = 180.0 / PI;            break;                  case 9102:          case 9107:          case 9108:          case 9110:          case 9122:            pszUOMName = "degree";            dfInDegrees = 1.0;            break;          case 9103:            pszUOMName = "arc-minute";            dfInDegrees = 1 / 60.0;            break;          case 9104:            pszUOMName = "arc-second";            dfInDegrees = 1 / 3600.0;            break;                  case 9105:            pszUOMName = "grad";            dfInDegrees = 180.0 / 200.0;            break;          case 9106:            pszUOMName = "gon";            dfInDegrees = 180.0 / 200.0;            break;                  case 9109:            pszUOMName = "microradian";            dfInDegrees = 180.0 / (3.14159265358979 * 1000000.0);            break;          default:            return FALSE;        }    }/* -------------------------------------------------------------------- *//*      Return to caller.                                               *//* -------------------------------------------------------------------- */    if( ppszUOMName != NULL )    {        if( pszUOMName != NULL )            *ppszUOMName = CPLStrdup( pszUOMName );        else            *ppszUOMName = NULL;    }    if( pdfInDegrees != NULL )        *pdfInDegrees = dfInDegrees;    return( TRUE );}/************************************************************************//*                        EPSGGetUOMLengthInfo()                        *//*                                                                      *//*      Note: This function should eventually also know how to          *//*      lookup length aliases in the UOM_LE_ALIAS table.                *//************************************************************************/static int EPSGGetUOMLengthInfo( int nUOMLengthCode,                      char **ppszUOMName,                      double * pdfInMeters ){    char        **papszUnitsRecord;    char        szSearchKey[24];    int         iNameField;#define UOM_FILENAME CSVFilename( "unit_of_measure.csv" )/* -------------------------------------------------------------------- *//*      We short cut meter to save work in the most common case.        *//* -------------------------------------------------------------------- */    if( nUOMLengthCode == 9001 )    {        if( ppszUOMName != NULL )            *ppszUOMName = CPLStrdup( "metre" );        if( pdfInMeters != NULL )            *pdfInMeters = 1.0;        return TRUE;    }/* -------------------------------------------------------------------- *//*      Search the units database for this unit.  If we don't find      *//*      it return failure.                                              *//* -------------------------------------------------------------------- */    sprintf( szSearchKey, "%d", nUOMLengthCode );    papszUnitsRecord =        CSVScanFileByName( UOM_FILENAME, "UOM_CODE", szSearchKey, CC_Integer );    if( papszUnitsRecord == NULL )        return FALSE;/* -------------------------------------------------------------------- *//*      Get the name, if requested.                                     *//* -------------------------------------------------------------------- */    if( ppszUOMName != NULL )    {        iNameField = CSVGetFileFieldId( UOM_FILENAME, "UNIT_OF_MEAS_NAME" );        *ppszUOMName = CPLStrdup( CSLGetField(papszUnitsRecord, iNameField) );    }    /* -------------------------------------------------------------------- *//*      Get the A and B factor fields, and create the multiplicative    *//*      factor.                                                         *//* -------------------------------------------------------------------- */    if( pdfInMeters != NULL )    {        int     iBFactorField, iCFactorField;                iBFactorField = CSVGetFileFieldId( UOM_FILENAME, "FACTOR_B" );        iCFactorField = CSVGetFileFieldId( UOM_FILENAME, "FACTOR_C" );        if( atof(CSLGetField(papszUnitsRecord, iCFactorField)) > 0.0 )            *pdfInMeters = atof(CSLGetField(papszUnitsRecord, iBFactorField))                / atof(CSLGetField(papszUnitsRecord, iCFactorField));        else            *pdfInMeters = 0.0;    }        return( TRUE );}/************************************************************************//*                       EPSGGetWGS84Transform()                        *//*                                                                      *//*      The following code attempts to find a bursa-wolf                *//*      transformation from this GeogCS to WGS84 (4326).                *//*                                                                      *//*      Faults:                                                         *//*       o I think there are codes other than 9603 and 9607 that        *//*         return compatible, or easily transformed parameters.         *//*       o Only the first path from the given GeogCS is checked due     *//*         to limitations in the CSV API.                               *//************************************************************************/int EPSGGetWGS84Transform( int nGeogCS, double *padfTransform ){    int         nMethodCode, iDXField, iField;    char        szCode[32];    const char *pszFilename = CSVFilename("gcs.csv");/* -------------------------------------------------------------------- *//*      Fetch the line from the GCS table.                              *//* -------------------------------------------------------------------- */    char **papszLine;    sprintf( szCode, "%d", nGeogCS );    papszLine = CSVScanFileByName( pszFilename,                                   "COORD_REF_SYS_CODE",                                    szCode, CC_Integer );    if( papszLine == NULL )        return FALSE;/* -------------------------------------------------------------------- *//*      Verify that the method code is one of our accepted ones.        *//* -------------------------------------------------------------------- */    nMethodCode =         atoi(CSLGetField( papszLine,                          CSVGetFileFieldId(pszFilename,                                            "COORD_OP_METHOD_CODE")));    if( nMethodCode != 9603 && nMethodCode != 9607 && nMethodCode != 9606 )        return FALSE;/* -------------------------------------------------------------------- *//*      Fetch the transformation parameters.                            *//* -------------------------------------------------------------------- */    iDXField = CSVGetFileFieldId(pszFilename, "DX");    for( iField = 0; iField < 7; iField++ )        padfTransform[iField] = atof(papszLine[iDXField+iField]);/* -------------------------------------------------------------------- *//*      9607 - coordinate frame rotation has reverse signs on the       *//*      rotational coefficients.  Fix up now since we internal          *//*      operate according to method 9606 (position vector 7-parameter). *//* -------------------------------------------------------------------- */    if( nMethodCode == 9607 )    {        padfTransform[3] *= -1;        padfTransform[4] *= -1;        padfTransform[5] *= -1;    }            return TRUE;}/************************************************************************//*                           EPSGGetPMInfo()                            *//*                                                                      *//*      Get the offset between a given prime meridian and Greenwich     *//*      in degrees.                                                     *//************************************************************************/static int EPSGGetPMInfo( int nPMCode, char ** ppszName, double *pdfOffset ){    char        szSearchKey[24];    int         nUOMAngle;#define PM_FILENAME CSVFilename("prime_meridian.csv")/* -------------------------------------------------------------------- *//*      Use a special short cut for Greenwich, since it is so common.   *//* -------------------------------------------------------------------- */    if( nPMCode == 7022 /* PM_Greenwich */ )    {        if( pdfOffset != NULL )            *pdfOffset = 0.0;        if( ppszName != NULL )            *ppszName = CPLStrdup( "Greenwich" );        return TRUE;    }/* -------------------------------------------------------------------- *//*      Search the database for the corresponding datum code.           *//* -------------------------------------------------------------------- */    sprintf( szSearchKey, "%d", nPMCode );    nUOMAngle =        atoi(CSVGetField( PM_FILENAME,                          "PRIME_MERIDIAN_CODE", szSearchKey, CC_Integer,                          "UOM_CODE" ) );    if( nUOMAngle < 1 )        return FALSE;/* -------------------------------------------------------------------- *//*      Get the PM offset.                                              *//* -------------------------------------------------------------------- */    if( pdfOffset != NULL )    {        *pdfOffset =            EPSGAngleStringToDD(                CSVGetField( PM_FILENAME,                             "PRIME_MERIDIAN_CODE", szSearchKey, CC_Integer,                             "GREENWICH_LONGITUDE" ),                nUOMAngle );    }    /* -------------------------------------------------------------------- *//*      Get the name, if requested.                                     *//* -------------------------------------------------------------------- */    if( ppszName != NULL )        *ppszName =            CPLStrdup(                CSVGetField( PM_FILENAME,                              "PRIME_MERIDIAN_CODE", szSearchKey, CC_Integer,                             "PRIME_MERIDIAN_NAME" ));        return( TRUE );}/************************************************************************//*                           EPSGGetGCSInfo()                           *//*                                                                      *//*      Fetch the datum, and prime meridian related to a particular     *//*      GCS.                                                            *//************************************************************************/static intEPSGGetGCSInfo( int nGCSCode, char ** ppszName,                int * pnDatum, char **ppszDatumName,                int * pnPM, int *pnEllipsoid, int *pnUOMAngle ){    char        szSearchKey[24];    int         nDatum, nPM, nUOMAngle, nEllipsoid;    const char  *pszFilename = CSVFilename("gcs.csv");/* -------------------------------------------------------------------- *//*      Search the database for the corresponding datum code.           *//* -------------------------------------------------------------------- */    sprintf( szSearchKey, "%d", nGCSCode );    nDatum = atoi(CSVGetField( pszFilename, "COORD_REF_SYS_CODE",                                szSearchKey, CC_Integer,                               "DATUM_CODE" ) );    if( nDatum < 1 )        return FALSE;    if( pnDatum != NULL )        *pnDatum = nDatum;    /* -------------------------------------------------------------------- *//*      Get the PM.                                                     *//* -------------------------------------------------------------------- */    nPM = atoi(CSVGetField( pszFilename, "COORD_REF_SYS_CODE",                             szSearchKey, CC_Integer,                            "PRIME_MERIDIAN_CODE" ) );    if( nPM < 1 )        return FALSE;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?