OGRErr OGRSpatialReference::importFromOzi( const char *pszDatum, const char *pszProj, const char *pszProjParms ) { Clear(); /* -------------------------------------------------------------------- */ /* Operate on the basis of the projection name. */ /* -------------------------------------------------------------------- */ char **papszProj = CSLTokenizeStringComplex( pszProj, ",", TRUE, TRUE ); char **papszProjParms = CSLTokenizeStringComplex( pszProjParms, ",", TRUE, TRUE ); char **papszDatum = NULL; if (CSLCount(papszProj) < 2) { goto not_enough_data; } if ( EQUALN(papszProj[1], "Latitude/Longitude", 18) ) { } else if ( EQUALN(papszProj[1], "Mercator", 8) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; double dfScale = CPLAtof(papszProjParms[3]); if (papszProjParms[3][0] == 0) dfScale = 1; /* if unset, default to scale = 1 */ SetMercator( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), dfScale, CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Transverse Mercator", 19) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetTM( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[3]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Lambert Conformal Conic", 23) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetLCC( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Sinusoidal", 10) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetSinusoidal( CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Albers Equal Area", 17) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetACEA( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else { CPLDebug( "OSR_Ozi", "Unsupported projection: \"%s\"", papszProj[1] ); SetLocalCS( CPLString().Printf("\"Ozi\" projection \"%s\"", papszProj[1]) ); } /* -------------------------------------------------------------------- */ /* Try to translate the datum/spheroid. */ /* -------------------------------------------------------------------- */ papszDatum = CSLTokenizeString2( pszDatum, ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( papszDatum == NULL) goto not_enough_data; if ( !IsLocal() ) { /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the datums */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_datum.csv" ), "EPSG_DATUM_CODE", "4326", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_datum.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Search for matching datum */ /* -------------------------------------------------------------------- */ const char *pszOziDatum = CSVFilename( "ozi_datum.csv" ); CPLString osDName = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "NAME" ); if( strlen(osDName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find datum %s in ozi_datum.csv.", papszDatum[0] ); goto other_error; } int nDatumCode = atoi( CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "EPSG_DATUM_CODE" ) ); if ( nDatumCode > 0 ) // There is a matching EPSG code { OGRSpatialReference oGCS; oGCS.importFromEPSG( nDatumCode ); CopyGeogCSFrom( &oGCS ); } else // We use the parameters from the CSV files { CPLString osEllipseCode = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "ELLIPSOID_CODE" ); double dfDeltaX = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAX" ) ); double dfDeltaY = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAY" ) ); double dfDeltaZ = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAZ" ) ); /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the ellipsoids */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_ellips.csv" ), "ELLIPSOID_CODE", "20", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_ellips.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Lookup the ellipse code. */ /* -------------------------------------------------------------------- */ const char *pszOziEllipse = CSVFilename( "ozi_ellips.csv" ); CPLString osEName = CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "NAME" ); if( strlen(osEName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find ellipsoid %s in ozi_ellips.csv.", osEllipseCode.c_str() ); goto other_error; } double dfA = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "A" )); double dfInvF = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "INVF" )); /* -------------------------------------------------------------------- */ /* Create geographic coordinate system. */ /* -------------------------------------------------------------------- */ SetGeogCS( osDName, osDName, osEName, dfA, dfInvF ); SetTOWGS84( dfDeltaX, dfDeltaY, dfDeltaZ ); } } /* -------------------------------------------------------------------- */ /* Grid units translation */ /* -------------------------------------------------------------------- */ if( IsLocal() || IsProjected() ) SetLinearUnits( SRS_UL_METER, 1.0 ); FixupOrdering(); CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NONE; not_enough_data: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NOT_ENOUGH_DATA; other_error: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_FAILURE; }
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 ( OSRGetEllipsoidInfo( aoEllips[iEllips], &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[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; }
OGRErr OGRSpatialReference::importFromUSGS( long iProjSys, long iZone, double *padfPrjParams, long iDatum, int bAnglesInPackedDMSFormat ) { if( !padfPrjParams ) return OGRERR_CORRUPT_DATA; double (*pfnUnpackAnglesFn)(double); if (bAnglesInPackedDMSFormat) pfnUnpackAnglesFn = CPLPackedDMSToDec; else pfnUnpackAnglesFn = OGRSpatialReferenceUSGSUnpackNoOp; /* -------------------------------------------------------------------- */ /* 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; }
OGRErr OGRSpatialReference::importFromOzi( const char * const* papszLines ) { int iLine; const char *pszDatum, *pszProj = NULL, *pszProjParms = NULL; Clear(); int nLines = CSLCount((char**)papszLines); if( nLines < 5 ) return OGRERR_NOT_ENOUGH_DATA; pszDatum = papszLines[4]; for ( iLine = 5; iLine < nLines; iLine++ ) { if ( EQUALN(papszLines[iLine], "Map Projection", 14) ) { pszProj = papszLines[iLine]; } else if ( EQUALN(papszLines[iLine], "Projection Setup", 16) ) { pszProjParms = papszLines[iLine]; } } if ( ! ( pszDatum && pszProj && pszProjParms ) ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Operate on the basis of the projection name. */ /* -------------------------------------------------------------------- */ char **papszProj = CSLTokenizeStringComplex( pszProj, ",", TRUE, TRUE ); char **papszProjParms = CSLTokenizeStringComplex( pszProjParms, ",", TRUE, TRUE ); char **papszDatum = NULL; if (CSLCount(papszProj) < 2) { goto not_enough_data; } if ( EQUALN(papszProj[1], "Latitude/Longitude", 18) ) { } else if ( EQUALN(papszProj[1], "Mercator", 8) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; double dfScale = CPLAtof(papszProjParms[3]); if (papszProjParms[3][0] == 0) dfScale = 1; /* if unset, default to scale = 1 */ SetMercator( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), dfScale, CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Transverse Mercator", 19) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetTM( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[3]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Lambert Conformal Conic", 23) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetLCC( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Sinusoidal", 10) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetSinusoidal( CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Albers Equal Area", 17) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetACEA( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "(UTM) Universal Transverse Mercator", 35) && nLines > 5 ) { /* Look for the UTM zone in the calibration point data */ for ( iLine = 5; iLine < nLines; iLine++ ) { if ( EQUALN(papszLines[iLine], "Point", 5) ) { char **papszTok = NULL; papszTok = CSLTokenizeString2( papszLines[iLine], ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( CSLCount(papszTok) < 17 || EQUAL(papszTok[2], "") || EQUAL(papszTok[13], "") || EQUAL(papszTok[14], "") || EQUAL(papszTok[15], "") || EQUAL(papszTok[16], "") ) { CSLDestroy(papszTok); continue; } SetUTM( CPLAtofM(papszTok[13]), EQUAL(papszTok[16], "N") ); CSLDestroy(papszTok); break; } } if ( iLine == nLines ) /* Try to guess the UTM zone */ { float fMinLongitude = INT_MAX; float fMaxLongitude = INT_MIN; float fMinLatitude = INT_MAX; float fMaxLatitude = INT_MIN; int bFoundMMPLL = FALSE; for ( iLine = 5; iLine < nLines; iLine++ ) { if ( EQUALN(papszLines[iLine], "MMPLL", 5) ) { char **papszTok = NULL; papszTok = CSLTokenizeString2( papszLines[iLine], ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( CSLCount(papszTok) < 4 ) { CSLDestroy(papszTok); continue; } float fLongitude = CPLAtofM(papszTok[2]); float fLatitude = CPLAtofM(papszTok[3]); CSLDestroy(papszTok); bFoundMMPLL = TRUE; if ( fMinLongitude > fLongitude ) fMinLongitude = fLongitude; if ( fMaxLongitude < fLongitude ) fMaxLongitude = fLongitude; if ( fMinLatitude > fLatitude ) fMinLatitude = fLatitude; if ( fMaxLatitude < fLatitude ) fMaxLatitude = fLatitude; } } float fMedianLatitude = ( fMinLatitude + fMaxLatitude ) / 2; float fMedianLongitude = ( fMinLongitude + fMaxLongitude ) / 2; if ( bFoundMMPLL && fMaxLatitude <= 90 ) { int nUtmZone; if ( fMedianLatitude >= 56 && fMedianLatitude <= 64 && fMedianLongitude >= 3 && fMedianLongitude <= 12 ) nUtmZone = 32; /* Norway exception */ else if ( fMedianLatitude >= 72 && fMedianLatitude <= 84 && fMedianLongitude >= 0 && fMedianLongitude <= 42 ) nUtmZone = (int) ((fMedianLongitude + 3 ) / 12) * 2 + 31; /* Svalbard exception */ else nUtmZone = (int) ((fMedianLongitude + 180 ) / 6) + 1; SetUTM( nUtmZone, fMedianLatitude >= 0 ); } else CPLDebug( "OSR_Ozi", "UTM Zone not found"); } } else if ( EQUALN(papszProj[1], "(I) France Zone I", 17) ) { SetLCC1SP( 49.5, 2.337229167, 0.99987734, 600000, 1200000 ); } else if ( EQUALN(papszProj[1], "(II) France Zone II", 19) ) { SetLCC1SP( 46.8, 2.337229167, 0.99987742, 600000, 2200000 ); } else if ( EQUALN(papszProj[1], "(III) France Zone III", 21) ) { SetLCC1SP( 44.1, 2.337229167, 0.99987750, 600000, 3200000 ); } else if ( EQUALN(papszProj[1], "(IV) France Zone IV", 19) ) { SetLCC1SP( 42.165, 2.337229167, 0.99994471, 234.358, 4185861.369 ); } /* * Note : The following projections have not been implemented yet * */ /* else if ( EQUALN(papszProj[1], "(BNG) British National Grid", 27) ) { } else if ( EQUALN(papszProj[1], "(IG) Irish Grid", 15) ) { } else if ( EQUALN(papszProj[1], "(NZG) New Zealand Grid", 22) ) { } else if ( EQUALN(papszProj[1], "(NZTM2) New Zealand TM 2000", 27) ) { } else if ( EQUALN(papszProj[1], "(SG) Swedish Grid", 27) ) { } else if ( EQUALN(papszProj[1], "(SUI) Swiss Grid", 26) ) { } else if ( EQUALN(papszProj[1], "(A)Lambert Azimuthual Equal Area", 32) ) { } else if ( EQUALN(papszProj[1], "(EQC) Equidistant Conic", 23) ) { } else if ( EQUALN(papszProj[1], "Polyconic (American)", 20) ) { } else if ( EQUALN(papszProj[1], "Van Der Grinten", 15) ) { } else if ( EQUALN(papszProj[1], "Vertical Near-Sided Perspective", 31) ) { } else if ( EQUALN(papszProj[1], "(WIV) Wagner IV", 15) ) { } else if ( EQUALN(papszProj[1], "Bonne", 5) ) { } else if ( EQUALN(papszProj[1], "(MT0) Montana State Plane Zone 2500", 35) ) { } else if ( EQUALN(papszProj[1], "ITA1) Italy Grid Zone 1", 23) ) { } else if ( EQUALN(papszProj[1], "ITA2) Italy Grid Zone 2", 23) ) { } else if ( EQUALN(papszProj[1], "(VICMAP-TM) Victoria Aust.(pseudo AMG)", 38) ) { } else if ( EQUALN(papszProj[1], "VICGRID) Victoria Australia", 27) ) { } else if ( EQUALN(papszProj[1], "(VG94) VICGRID94 Victoria Australia", 35) ) { } else if ( EQUALN(papszProj[1], "Gnomonic", 8) ) { } */ else { CPLDebug( "OSR_Ozi", "Unsupported projection: \"%s\"", papszProj[1] ); SetLocalCS( CPLString().Printf("\"Ozi\" projection \"%s\"", papszProj[1]) ); } /* -------------------------------------------------------------------- */ /* Try to translate the datum/spheroid. */ /* -------------------------------------------------------------------- */ papszDatum = CSLTokenizeString2( pszDatum, ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( papszDatum == NULL) goto not_enough_data; if ( !IsLocal() ) { /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the datums */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_datum.csv" ), "EPSG_DATUM_CODE", "4326", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_datum.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Search for matching datum */ /* -------------------------------------------------------------------- */ const char *pszOziDatum = CSVFilename( "ozi_datum.csv" ); CPLString osDName = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "NAME" ); if( strlen(osDName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find datum %s in ozi_datum.csv.", papszDatum[0] ); goto other_error; } int nDatumCode = atoi( CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "EPSG_DATUM_CODE" ) ); if ( nDatumCode > 0 ) // There is a matching EPSG code { OGRSpatialReference oGCS; oGCS.importFromEPSG( nDatumCode ); CopyGeogCSFrom( &oGCS ); } else // We use the parameters from the CSV files { CPLString osEllipseCode = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "ELLIPSOID_CODE" ); double dfDeltaX = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAX" ) ); double dfDeltaY = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAY" ) ); double dfDeltaZ = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAZ" ) ); /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the ellipsoids */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_ellips.csv" ), "ELLIPSOID_CODE", "20", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_ellips.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Lookup the ellipse code. */ /* -------------------------------------------------------------------- */ const char *pszOziEllipse = CSVFilename( "ozi_ellips.csv" ); CPLString osEName = CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "NAME" ); if( strlen(osEName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find ellipsoid %s in ozi_ellips.csv.", osEllipseCode.c_str() ); goto other_error; } double dfA = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "A" )); double dfInvF = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "INVF" )); /* -------------------------------------------------------------------- */ /* Create geographic coordinate system. */ /* -------------------------------------------------------------------- */ SetGeogCS( osDName, osDName, osEName, dfA, dfInvF ); SetTOWGS84( dfDeltaX, dfDeltaY, dfDeltaZ ); } } /* -------------------------------------------------------------------- */ /* Grid units translation */ /* -------------------------------------------------------------------- */ if( IsLocal() || IsProjected() ) SetLinearUnits( SRS_UL_METER, 1.0 ); FixupOrdering(); CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NONE; not_enough_data: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NOT_ENOUGH_DATA; other_error: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_FAILURE; }