Пример #1
0
OGRErr OGRSpatialReference::importFromPanorama( long iProjSys, long iDatum,
                                                long iEllips,
                                                double *padfPrjParams )

{
    Clear();

/* -------------------------------------------------------------------- */
/*      Use safe defaults if projection parameters are not supplied.    */
/* -------------------------------------------------------------------- */
    int     bProjAllocated = FALSE;

    if( padfPrjParams == NULL )
    {
        int     i;

        padfPrjParams = (double *)CPLMalloc( 7 * sizeof(double) );
        if ( !padfPrjParams )
            return OGRERR_NOT_ENOUGH_MEMORY;
        for ( i = 0; i < 7; i++ )
            padfPrjParams[i] = 0.0;
        bProjAllocated = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Operate on the basis of the projection code.                    */
/* -------------------------------------------------------------------- */
    switch ( iProjSys )
    {
        case PAN_PROJ_NONE:
            break;

        case PAN_PROJ_UTM:
            {
                long nZone = (long)TO_ZONE(padfPrjParams[3]);

                // XXX: no way to determine south hemisphere. Always assume
                // nothern hemisphere.
                SetUTM( nZone, TRUE );
            }
            break;

        case PAN_PROJ_WAG1:
            SetWagner( 1, 0.0,
                       padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_MERCAT:
            SetMercator( TO_DEGREES * padfPrjParams[0],
                         TO_DEGREES * padfPrjParams[3],
                         padfPrjParams[4],
                         padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_PS:
            SetPS( TO_DEGREES * padfPrjParams[2],
                   TO_DEGREES * padfPrjParams[3],
                   padfPrjParams[4],
                   padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_POLYC:
            SetPolyconic( TO_DEGREES * padfPrjParams[2],
                          TO_DEGREES * padfPrjParams[3],
                          padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_EC:
            SetEC( TO_DEGREES * padfPrjParams[0],
                   TO_DEGREES * padfPrjParams[1],
                   TO_DEGREES * padfPrjParams[2],
                   TO_DEGREES * padfPrjParams[3],
                   padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_LCC:
            SetLCC( TO_DEGREES * padfPrjParams[0],
                    TO_DEGREES * padfPrjParams[1],
                    TO_DEGREES * padfPrjParams[2],
                    TO_DEGREES * padfPrjParams[3],
                    padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_TM:
            {
                // XXX: we need zone number to compute false easting
                // parameter, because usually it is not contained in the
                // "Panorama" projection definition.
                // FIXME: what to do with negative values?
                long nZone = (long)TO_ZONE(padfPrjParams[3]);

                padfPrjParams[5] = nZone * 1000000.0 + 500000.0;
                padfPrjParams[4] = 1.0;
                SetTM( TO_DEGREES * padfPrjParams[2],
                       TO_DEGREES * padfPrjParams[3],
                       padfPrjParams[4],
                       padfPrjParams[5], padfPrjParams[6] );
            }
            break;

        case PAN_PROJ_STEREO:
            SetStereographic( TO_DEGREES * padfPrjParams[2],
                              TO_DEGREES * padfPrjParams[3],
                              padfPrjParams[4],
                              padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_AE:
            SetAE( TO_DEGREES * padfPrjParams[0],
                   TO_DEGREES * padfPrjParams[3],
                   padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_GNOMON:
            SetGnomonic( TO_DEGREES * padfPrjParams[2],
                         TO_DEGREES * padfPrjParams[3],
                         padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_MOLL:
            SetMollweide( TO_DEGREES * padfPrjParams[3],
                          padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_LAEA:
            SetLAEA( TO_DEGREES * padfPrjParams[0],
                     TO_DEGREES * padfPrjParams[3],
                     padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_EQC:
            SetEquirectangular( TO_DEGREES * padfPrjParams[0],
                                TO_DEGREES * padfPrjParams[3],
                                padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_CEA:
            SetCEA( TO_DEGREES * padfPrjParams[0],
                    TO_DEGREES * padfPrjParams[3],
                    padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_IMWP:
            SetIWMPolyconic( TO_DEGREES * padfPrjParams[0],
                             TO_DEGREES * padfPrjParams[1],
                             TO_DEGREES * padfPrjParams[3],
                             padfPrjParams[5], padfPrjParams[6] );
            break;

        default:
            CPLDebug( "OSR_Panorama", "Unsupported projection: %ld", iProjSys );
            SetLocalCS( CPLString().Printf("\"Panorama\" projection number %ld",
                                   iProjSys) );
            break;
            
    }

/* -------------------------------------------------------------------- */
/*      Try to translate the datum/spheroid.                            */
/* -------------------------------------------------------------------- */

    if ( !IsLocal() )
    {
        if ( iDatum > 0 && iDatum < NUMBER_OF_DATUMS && aoDatums[iDatum] )
        {
            OGRSpatialReference oGCS;
            oGCS.importFromEPSG( aoDatums[iDatum] );
            CopyGeogCSFrom( &oGCS );
        }

        else if ( iEllips > 0
                  && iEllips < (long)NUMBER_OF_ELLIPSOIDS
                  && aoEllips[iEllips] )
        {
            char    *pszName = NULL;
            double  dfSemiMajor, dfInvFlattening;

            if( PanoramaGetEllipsoidInfo( aoEllips[iEllips],
                                          &pszName,
                                          &dfSemiMajor, &dfInvFlattening ) )
            {
                SetGeogCS( CPLString().Printf("Unknown datum based upon the %s ellipsoid",
                                      pszName ),
                           CPLString().Printf( "Not specified (based on %s spheroid)",
                                       pszName ),
                           pszName, dfSemiMajor, dfInvFlattening,
                           NULL, 0.0, NULL, 0.0 );
                SetAuthority( "SPHEROID", "EPSG", aoEllips[iEllips] );
            }
            else
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "Failed to lookup ellipsoid code %d, likely due to"
                          " missing GDAL gcs.csv\n"
                          " file.  Falling back to use WGS84.", (int) iEllips );
                SetWellKnownGeogCS( "WGS84" );
            }

            if ( pszName )
                CPLFree( pszName );
        }
        
        else
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Wrong datum code %d. Supported datums are 1--%ld only.\n"
                      "Setting WGS84 as a fallback.",
                      (int) iDatum, NUMBER_OF_DATUMS - 1 );
            SetWellKnownGeogCS( "WGS84" );
        }
    }

/* -------------------------------------------------------------------- */
/*      Grid units translation                                          */
/* -------------------------------------------------------------------- */
    if( IsLocal() || IsProjected() )
        SetLinearUnits( SRS_UL_METER, 1.0 );

    FixupOrdering();

    if ( bProjAllocated && padfPrjParams )
        CPLFree( padfPrjParams );

    return OGRERR_NONE;
}
Пример #2
0
OGRErr OGRSpatialReference::importFromUSGS( long iProjSys, long iZone,
                                            double *padfPrjParams,
                                            long iDatum, 
                                            int nUSGSAngleFormat  )

{
    if( !padfPrjParams )
        return OGRERR_CORRUPT_DATA;

    double (*pfnUnpackAnglesFn)(double) = NULL;

    if (nUSGSAngleFormat == USGS_ANGLE_DECIMALDEGREES )
        pfnUnpackAnglesFn = OGRSpatialReferenceUSGSUnpackNoOp;
    else if (nUSGSAngleFormat == USGS_ANGLE_RADIANS )
        pfnUnpackAnglesFn = OGRSpatialReferenceUSGSUnpackRadian;
    else
        pfnUnpackAnglesFn = CPLPackedDMSToDec;

/* -------------------------------------------------------------------- */
/*      Operate on the basis of the projection code.                    */
/* -------------------------------------------------------------------- */
    switch ( iProjSys )
    {
        case GEO:
            break;

        case UTM:
            {
                int bNorth = TRUE;

                if ( !iZone )
                {
                    if ( padfPrjParams[2] != 0.0 )
                        iZone = (long) padfPrjParams[2];
                    else if (padfPrjParams[0] != 0.0 && padfPrjParams[1] != 0.0)
                    {
                        iZone = (long)(((pfnUnpackAnglesFn(padfPrjParams[0])
                                         + 180.0) / 6.0) + 1.0);
                        if ( pfnUnpackAnglesFn(padfPrjParams[0]) < 0 )
                            bNorth = FALSE;
                    }
                }

                if ( iZone < 0 )
                {
                    iZone = -iZone;
                    bNorth = FALSE;
                }
                SetUTM( iZone, bNorth );
            }
            break;

        case SPCS:
            {
                int bNAD83 = TRUE;

                if ( iDatum == 0 )
                    bNAD83 = FALSE;
                else if ( iDatum != 8 )
                    CPLError( CE_Warning, CPLE_AppDefined,
                              "Wrong datum for State Plane projection %d. "
                              "Should be 0 or 8.", (int) iDatum );
                
                SetStatePlane( iZone, bNAD83 );
            }
            break;

        case ALBERS:
            SetACEA( pfnUnpackAnglesFn(padfPrjParams[2]),
                     pfnUnpackAnglesFn(padfPrjParams[3]),
                     pfnUnpackAnglesFn(padfPrjParams[5]),
                     pfnUnpackAnglesFn(padfPrjParams[4]),
                     padfPrjParams[6], padfPrjParams[7] );
            break;

        case LAMCC:
            SetLCC( pfnUnpackAnglesFn(padfPrjParams[2]),
                    pfnUnpackAnglesFn(padfPrjParams[3]),
                    pfnUnpackAnglesFn(padfPrjParams[5]),
                    pfnUnpackAnglesFn(padfPrjParams[4]),
                    padfPrjParams[6], padfPrjParams[7] );
            break;

        case MERCAT:
            SetMercator( pfnUnpackAnglesFn(padfPrjParams[5]),
                         pfnUnpackAnglesFn(padfPrjParams[4]),
                         1.0,
                         padfPrjParams[6], padfPrjParams[7] );
            break;

        case PS:
            SetPS( pfnUnpackAnglesFn(padfPrjParams[5]),
                   pfnUnpackAnglesFn(padfPrjParams[4]),
                   1.0,
                   padfPrjParams[6], padfPrjParams[7] );

            break;

        case POLYC:
            SetPolyconic( pfnUnpackAnglesFn(padfPrjParams[5]),
                          pfnUnpackAnglesFn(padfPrjParams[4]),
                          padfPrjParams[6], padfPrjParams[7] );
            break;

        case EQUIDC:
            if ( padfPrjParams[8] )
            {
                SetEC( pfnUnpackAnglesFn(padfPrjParams[2]),
                       pfnUnpackAnglesFn(padfPrjParams[3]),
                       pfnUnpackAnglesFn(padfPrjParams[5]),
                       pfnUnpackAnglesFn(padfPrjParams[4]),
                       padfPrjParams[6], padfPrjParams[7] );
            }
            else
            {
                SetEC( pfnUnpackAnglesFn(padfPrjParams[2]),
                       pfnUnpackAnglesFn(padfPrjParams[2]),
                       pfnUnpackAnglesFn(padfPrjParams[5]),
                       pfnUnpackAnglesFn(padfPrjParams[4]),
                       padfPrjParams[6], padfPrjParams[7] );
            }
            break;

        case TM:
            SetTM( pfnUnpackAnglesFn(padfPrjParams[5]),
                   pfnUnpackAnglesFn(padfPrjParams[4]),
                   padfPrjParams[2],
                   padfPrjParams[6], padfPrjParams[7] );
            break;

        case STEREO:
            SetStereographic( pfnUnpackAnglesFn(padfPrjParams[5]),
                              pfnUnpackAnglesFn(padfPrjParams[4]),
                              1.0,
                              padfPrjParams[6], padfPrjParams[7] );
            break;

        case LAMAZ:
            SetLAEA( pfnUnpackAnglesFn(padfPrjParams[5]),
                     pfnUnpackAnglesFn(padfPrjParams[4]),
                     padfPrjParams[6], padfPrjParams[7] );
            break;

        case AZMEQD:
            SetAE( pfnUnpackAnglesFn(padfPrjParams[5]),
                   pfnUnpackAnglesFn(padfPrjParams[4]),
                   padfPrjParams[6], padfPrjParams[7] );
            break;

        case GNOMON:
            SetGnomonic( pfnUnpackAnglesFn(padfPrjParams[5]),
                         pfnUnpackAnglesFn(padfPrjParams[4]),
                         padfPrjParams[6], padfPrjParams[7] );
            break;

        case ORTHO:
            SetOrthographic( pfnUnpackAnglesFn(padfPrjParams[5]),
                             pfnUnpackAnglesFn(padfPrjParams[4]),
                             padfPrjParams[6], padfPrjParams[7] );
            break;

        // FIXME: GVNSP --- General Vertical Near-Side Perspective skipped

        case SNSOID:
            SetSinusoidal( pfnUnpackAnglesFn(padfPrjParams[4]),
                           padfPrjParams[6], padfPrjParams[7] );
            break;

        case EQRECT:
            SetEquirectangular2( 0.0,
                                 pfnUnpackAnglesFn(padfPrjParams[4]),
                                 pfnUnpackAnglesFn(padfPrjParams[5]),
                                 padfPrjParams[6], padfPrjParams[7] );
            break;

        case MILLER:
            SetMC( pfnUnpackAnglesFn(padfPrjParams[5]),
                   pfnUnpackAnglesFn(padfPrjParams[4]),
                   padfPrjParams[6], padfPrjParams[7] );
            break;

        case VGRINT:
            SetVDG( pfnUnpackAnglesFn(padfPrjParams[4]),
                    padfPrjParams[6], padfPrjParams[7] );
            break;

        case HOM:
            if ( padfPrjParams[12] )
            {
                SetHOM( pfnUnpackAnglesFn(padfPrjParams[5]),
                        pfnUnpackAnglesFn(padfPrjParams[4]),
                        pfnUnpackAnglesFn(padfPrjParams[3]),
                        0.0, padfPrjParams[2],
                        padfPrjParams[6],  padfPrjParams[7] );
            }
            else
            {
                SetHOM2PNO( pfnUnpackAnglesFn(padfPrjParams[5]),
                            pfnUnpackAnglesFn(padfPrjParams[9]),
                            pfnUnpackAnglesFn(padfPrjParams[8]),
                            pfnUnpackAnglesFn(padfPrjParams[11]),
                            pfnUnpackAnglesFn(padfPrjParams[10]),
                            padfPrjParams[2],
                            padfPrjParams[6],  padfPrjParams[7] );
            }
            break;

        case ROBIN:
            SetRobinson( pfnUnpackAnglesFn(padfPrjParams[4]),
                         padfPrjParams[6], padfPrjParams[7] );
            break;

        // FIXME: SOM --- Space Oblique Mercator skipped

        // FIXME: ALASKA --- Alaska Conformal skipped

        // FIXME: GOODE --- Interrupted Goode skipped

        case MOLL:
            SetMollweide( pfnUnpackAnglesFn(padfPrjParams[4]),
                          padfPrjParams[6], padfPrjParams[7] );
            break;

        // FIXME: IMOLL --- Interrupted Mollweide skipped

        // FIXME: HAMMER --- Hammer skipped

        case WAGIV:
            SetWagner( 4, 0.0, padfPrjParams[6], padfPrjParams[7] );
            break;

        case WAGVII:
            SetWagner( 7, 0.0, padfPrjParams[6], padfPrjParams[7] );
            break;

        // FIXME: OBEQA --- Oblated Equal Area skipped

        // FIXME: ISINUS1 --- Integerized Sinusoidal Grid (the same as 99) skipped
        
        // FIXME: CEA --- Cylindrical Equal Area skipped (Grid corners set in meters for EASE grid)

        // FIXME: BCEA --- Cylindrical Equal Area skipped (Grid corners set in DMS degs for EASE grid)

        // FIXME: ISINUS --- Integrized Sinusoidal skipped

        default:
            CPLDebug( "OSR_USGS", "Unsupported projection: %ld", iProjSys );
            SetLocalCS( CPLString().Printf("GCTP projection number %ld", iProjSys) );
            break;
            
    }

/* -------------------------------------------------------------------- */
/*      Try to translate the datum/spheroid.                            */
/* -------------------------------------------------------------------- */

    if ( !IsLocal() )
    {
        char    *pszName = NULL;
        double  dfSemiMajor, dfInvFlattening;

        if ( iDatum < 0  ) // Use specified ellipsoid parameters
        {
            if ( padfPrjParams[0] > 0.0 )
            {
                if ( padfPrjParams[1] > 1.0 )
                {
                    if( ABS(padfPrjParams[0] - padfPrjParams[1]) < 0.01 )
                        dfInvFlattening = 0.0;
                    else
                    {
                        dfInvFlattening = padfPrjParams[0]
                            / ( padfPrjParams[0] - padfPrjParams[1] );
                    }
                }
                else if ( padfPrjParams[1] > 0.0 )
                {
                    dfInvFlattening =
                        1.0 / ( 1.0 - sqrt(1.0 - padfPrjParams[1]) );
                }
                else
                    dfInvFlattening = 0.0;

                SetGeogCS( "Unknown datum based upon the custom spheroid",
                           "Not specified (based on custom spheroid)",
                           "Custom spheroid", padfPrjParams[0], dfInvFlattening,
                           NULL, 0, NULL, 0 );
            }
            else if ( padfPrjParams[1] > 0.0 )  // Clarke 1866
            {
                if ( OSRGetEllipsoidInfo( 7008, &pszName, &dfSemiMajor,
                                          &dfInvFlattening ) == OGRERR_NONE )
                {
                    SetGeogCS( CPLString().Printf(
                                    "Unknown datum based upon the %s ellipsoid",
                                    pszName ),
                               CPLString().Printf( 
                                    "Not specified (based on %s spheroid)",
                                    pszName ),
                               pszName, dfSemiMajor, dfInvFlattening,
                               NULL, 0.0, NULL, 0.0 );
                    SetAuthority( "SPHEROID", "EPSG", 7008 );
                }
            }
            else                              // Sphere, rad 6370997 m
            {
                if ( OSRGetEllipsoidInfo( 7047, &pszName, &dfSemiMajor,
                                     &dfInvFlattening ) == OGRERR_NONE )
                {
                    SetGeogCS( CPLString().Printf(
                                    "Unknown datum based upon the %s ellipsoid",
                                    pszName ),
                               CPLString().Printf(
                                    "Not specified (based on %s spheroid)",
                                    pszName ),
                               pszName, dfSemiMajor, dfInvFlattening,
                               NULL, 0.0, NULL, 0.0 );
                    SetAuthority( "SPHEROID", "EPSG", 7047 );
                }
            }

        }
        else if ( iDatum < NUMBER_OF_ELLIPSOIDS && aoEllips[iDatum] )
        {
            if( OSRGetEllipsoidInfo( aoEllips[iDatum], &pszName,
                                     &dfSemiMajor, &dfInvFlattening ) == OGRERR_NONE )
            {
                SetGeogCS( CPLString().Printf("Unknown datum based upon the %s ellipsoid",
                                              pszName ),
                           CPLString().Printf( "Not specified (based on %s spheroid)",
                                               pszName ),
                           pszName, dfSemiMajor, dfInvFlattening,
                           NULL, 0.0, NULL, 0.0 );
                SetAuthority( "SPHEROID", "EPSG", aoEllips[iDatum] );
            }
            else
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "Failed to lookup datum code %d, likely due to missing GDAL gcs.csv\n"
                          " file.  Falling back to use WGS84.", 
                          (int) iDatum );
                SetWellKnownGeogCS("WGS84" );
            }
        }
        else
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Wrong datum code %d. Supported datums 0--%d only.\n"
                      "Setting WGS84 as a fallback.",
                      (int) iDatum, NUMBER_OF_ELLIPSOIDS );
            SetWellKnownGeogCS( "WGS84" );
        }

        if ( pszName )
            CPLFree( pszName );
    }

/* -------------------------------------------------------------------- */
/*      Grid units translation                                          */
/* -------------------------------------------------------------------- */
    if( IsLocal() || IsProjected() )
        SetLinearUnits( SRS_UL_METER, 1.0 );

    FixupOrdering();

    return OGRERR_NONE;
}