/****************************************************************************** * $Id: imggeotiff.c,v 1.6 2006/04/04 03:31:13 fwarmerdam Exp $ * * Project: Erdas Imagine (.img) Translator * Purpose: Mapping Imagine georeferencing to GeoTIFF georeferencing. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Intergraph Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: imggeotiff.c,v $ * Revision 1.6 2006/04/04 03:31:13 fwarmerdam * Fixed contact info. * * Revision 1.5 2001/07/18 04:51:57 warmerda * added CPL_CVSID * * Revision 1.4 1999/06/01 12:29:51 warmerda * Ensure ImagineToGeoTIFFProjection() has C linkaged even if compiled with c++. * * Revision 1.3 1999/03/02 14:18:09 warmerda * Don't write geotiff info if no mapinfo * * Revision 1.2 1999/01/28 16:21:24 warmerda * defined PI if needed * * Revision 1.1 1999/01/22 17:40:43 warmerda * New * */ #include "hfa.h" #include "cpl_conv.h" #include "geotiff.h" #include "geo_tiffp.h" #include "geo_keyp.h" #include "geovalues.h" CPL_CVSID("$Id: imggeotiff.c,v 1.6 2006/04/04 03:31:13 fwarmerdam Exp $"); #ifndef PI # define PI 3.14159265358979323846 #endif #define RAD_TO_DEG (180/PI) #define MapSys_State_Plane -9003 int GTIFMapSysToPCS( int MapSys, int Datum, int nZone ); CPL_C_START CPLErr ImagineToGeoTIFFProjection( HFAHandle hHFA, TIFF * hTIFF ); CPL_C_END /* ==================================================================== */ /* Table relating USGS and ESRI state plane zones. */ /* ==================================================================== */ int anUsgsEsriZones[] = { 101, 3101, 102, 3126, 201, 3151, 202, 3176, 203, 3201, 301, 3226, 302, 3251, 401, 3276, 402, 3301, 403, 3326, 404, 3351, 405, 3376, 406, 3401, 407, 3426, 501, 3451, 502, 3476, 503, 3501, 600, 3526, 700, 3551, 901, 3601, 902, 3626, 903, 3576, 1001, 3651, 1002, 3676, 1101, 3701, 1102, 3726, 1103, 3751, 1201, 3776, 1202, 3801, 1301, 3826, 1302, 3851, 1401, 3876, 1402, 3901, 1501, 3926, 1502, 3951, 1601, 3976, 1602, 4001, 1701, 4026, 1702, 4051, 1703, 6426, 1801, 4076, 1802, 4101, 1900, 4126, 2001, 4151, 2002, 4176, 2101, 4201, 2102, 4226, 2103, 4251, 2111, 6351, 2112, 6376, 2113, 6401, 2201, 4276, 2202, 4301, 2203, 4326, 2301, 4351, 2302, 4376, 2401, 4401, 2402, 4426, 2403, 4451, 2500, 0, 2501, 4476, 2502, 4501, 2503, 4526, 2600, 0, 2601, 4551, 2602, 4576, 2701, 4601, 2702, 4626, 2703, 4651, 2800, 4676, 2900, 4701, 3001, 4726, 3002, 4751, 3003, 4776, 3101, 4801, 3102, 4826, 3103, 4851, 3104, 4876, 3200, 4901, 3301, 4926, 3302, 4951, 3401, 4976, 3402, 5001, 3501, 5026, 3502, 5051, 3601, 5076, 3602, 5101, 3701, 5126, 3702, 5151, 3800, 5176, 3900, 0, 3901, 5201, 3902, 5226, 4001, 5251, 4002, 5276, 4100, 5301, 4201, 5326, 4202, 5351, 4203, 5376, 4204, 5401, 4205, 5426, 4301, 5451, 4302, 5476, 4303, 5501, 4400, 5526, 4501, 5551, 4502, 5576, 4601, 5601, 4602, 5626, 4701, 5651, 4702, 5676, 4801, 5701, 4802, 5726, 4803, 5751, 4901, 5776, 4902, 5801, 4903, 5826, 4904, 5851, 5001, 6101, 5002, 6126, 5003, 6151, 5004, 6176, 5005, 6201, 5006, 6226, 5007, 6251, 5008, 6276, 5009, 6301, 5010, 6326, 5101, 5876, 5102, 5901, 5103, 5926, 5104, 5951, 5105, 5976, 5201, 6001, 5200, 6026, 5200, 6076, 5201, 6051, 5202, 6051, 5300, 0, 5400, 0 }; /************************************************************************/ /* ESRIToUSGSZone() */ /* */ /* Convert ESRI style state plane zones to USGS style state */ /* plane zones. */ /************************************************************************/ static int ESRIToUSGSZone( int nESRIZone ) { int nPairs = sizeof(anUsgsEsriZones) / (2*sizeof(int)); int i; for( i = 0; i < nPairs; i++ ) { if( anUsgsEsriZones[i*2+1] == nESRIZone ) return anUsgsEsriZones[i*2]; } return 0; } /************************************************************************/ /* ImagineToGeoTIFFProjection() */ /* */ /* Apply ``Geo'' information to the GeoTIFF file based on the */ /* source Imagine file. */ /************************************************************************/ CPLErr ImagineToGeoTIFFProjection( HFAHandle hHFA, TIFF * hTIFF ) { GTIF *hGTiff; const Eprj_Datum *psDatum; const Eprj_ProParameters *psProParameters; const Eprj_MapInfo *psMapInfo; int16 nPCS = KvUserDefined; /* -------------------------------------------------------------------- */ /* Get info on Imagine file projection. */ /* -------------------------------------------------------------------- */ psMapInfo = HFAGetMapInfo( hHFA ); psProParameters = HFAGetProParameters( hHFA ); psDatum = HFAGetDatum( hHFA ); if( psMapInfo == NULL ) return CE_None; hGTiff = GTIFNew( hTIFF ); /* -------------------------------------------------------------------- */ /* Write out the pixelisarea marker. */ /* -------------------------------------------------------------------- */ GTIFKeySet(hGTiff, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea ); /* -------------------------------------------------------------------- */ /* Write out the corner coordinates. */ /* -------------------------------------------------------------------- */ if( psMapInfo != NULL ) { double adfPixelScale[3], adfTiePoints[6]; adfPixelScale[0] = psMapInfo->pixelSize.width; adfPixelScale[1] = psMapInfo->pixelSize.height; adfPixelScale[2] = 0.0; TIFFSetField( hTIFF, TIFFTAG_GEOPIXELSCALE, 3, adfPixelScale ); adfTiePoints[0] = 0.5; adfTiePoints[1] = 0.5; adfTiePoints[2] = 0.0; adfTiePoints[3] = psMapInfo->upperLeftCenter.x; adfTiePoints[4] = psMapInfo->upperLeftCenter.y; adfTiePoints[5] = 0.0; TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 6, adfTiePoints ); } /* -------------------------------------------------------------------- */ /* Try to write out units information. */ /* -------------------------------------------------------------------- */ if( psMapInfo != NULL ) { if( EQUAL(psMapInfo->units,"meters") ) { GTIFKeySet(hGTiff, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Meter ); } else if( EQUAL(psMapInfo->units,"feet") ) { GTIFKeySet(hGTiff, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Foot_US_Survey); } else if( EQUAL(psMapInfo->units,"dd") ) { GTIFKeySet(hGTiff, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, Angular_Degree); } } /* -------------------------------------------------------------------- */ /* If this is not geographic, write out the model type as */ /* projected. Note that this will get written even if we end */ /* up not translating the projection which may be unwise. */ /* -------------------------------------------------------------------- */ if( psProParameters != NULL ) { if( psProParameters->proNumber == 0 ) GTIFKeySet(hGTiff, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelTypeGeographic ); else GTIFKeySet(hGTiff, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelTypeProjected ); } /* -------------------------------------------------------------------- */ /* Do we have a ``nice'' UTM PCS situation? */ /* -------------------------------------------------------------------- */ if( psProParameters != NULL && psProParameters->proNumber == 1 /* UTM */ && psProParameters->proParams[3] >= 0.0 /* north */ && psDatum != NULL && EQUAL(psDatum->datumname,"NAD27") ) { nPCS = 26700 + psProParameters->proZone; } if( psProParameters != NULL && psProParameters->proNumber == 1 /* UTM */ && psProParameters->proParams[3] >= 0.0 /* north */ && psDatum != NULL && EQUAL(psDatum->datumname,"NAD83") ) { nPCS = 26800 + psProParameters->proZone; } if( psProParameters != NULL && psProParameters->proNumber == 1 /* UTM */ && psProParameters->proParams[3] >= 0.0 /* north */ && psDatum != NULL && EQUAL(psDatum->datumname,"WGS 84") ) { /* I don't know if the above datum names really work ... just a guess*/ nPCS = 32600 + psProParameters->proZone; } if( psProParameters != NULL && psProParameters->proNumber == 1 /* UTM */ && psProParameters->proParams[3] < 0.0 /* south */ && psDatum != NULL && EQUAL(psDatum->datumname,"WGS 84") ) { /* I don't know if the above datum names really work ... just a guess*/ nPCS = 32700 + psProParameters->proZone; } /* -------------------------------------------------------------------- */ /* Do we have a nice State Plane situation? */ /* */ /* For this we have to translate the Erdas (ESRI) zone number */ /* to a USGS zone number. This we pass to GTIFMapSysToPCS() */ /* which turns it into a Proj_ code, and then it does a lookup */ /* to map this to a PCS_ number. Oiii! */ /* -------------------------------------------------------------------- */ if( psProParameters != NULL && psProParameters->proNumber == 2 ) { if( psProParameters->proParams[0] == 0.0 ) /* NAD27 */ { nPCS = GTIFMapSysToPCS( MapSys_State_Plane, GCS_NAD27, ESRIToUSGSZone(psProParameters->proZone)); } else { nPCS = GTIFMapSysToPCS( MapSys_State_Plane, GCS_NAD83, ESRIToUSGSZone(psProParameters->proZone)); } } /* -------------------------------------------------------------------- */ /* Write with a PCS if we have one. */ /* -------------------------------------------------------------------- */ if( nPCS != KvUserDefined ) { GTIFKeySet(hGTiff, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, nPCS ); } else if( psProParameters != NULL && psProParameters->proNumber != 0 ) { GTIFKeySet(hGTiff, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, KvUserDefined ); GTIFKeySet(hGTiff, ProjectionGeoKey, TYPE_SHORT, 1, KvUserDefined ); } /* ==================================================================== */ /* Handle various non-PCS situations */ /* ==================================================================== */ if( nPCS != KvUserDefined ) { /* already handled */ } else if( psProParameters == NULL ) { /* do nothing */ } /* -------------------------------------------------------------------- */ /* Lat/long. */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 0 ) { /* GTModelType and GeogLinearUnits already written */ } /* -------------------------------------------------------------------- */ /* UTM */ /* */ /* If we didn't match to a particular PCS we are just going to */ /* fallback to the TM definition of this zone. */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 1 ) { /* notdef: if( psProParameters->proParams[3] < 0.0 / * south * / ... */ } /* -------------------------------------------------------------------- */ /* State Plane */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 2 ) { /* notdef: this is complicated by the translation of ESRI state plane numbers to USGS (GeoTIFF) numbering */ } /* -------------------------------------------------------------------- */ /* Albers Conic Equal Area */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 3 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_AlbersEqualArea ); GTIFKeySet( hGTiff, ProjStdParallelGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[2] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[3] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Lambert Conformal Conic */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 4 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_LambertConfConic_2SP ); GTIFKeySet( hGTiff, ProjStdParallelGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[2] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[3] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseOriginLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Mercator */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 5 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Mercator ); GTIFKeySet( hGTiff, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Polar Stereographic */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 6 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_PolarStereographic ); GTIFKeySet( hGTiff, ProjStraightVertPoleLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Polyconic */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 7 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Polyconic ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Equidistant Conic */ /* */ /* Note that Imagine files have two cases (keyed off param 8 */ /* being zero or one) indicating whether a second standard */ /* parallel is present. */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 8 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_EquidistantConic ); GTIFKeySet( hGTiff, ProjStdParallelGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[2] * RAD_TO_DEG ); if( psProParameters->proParams[8] != 0.0 ) GTIFKeySet( hGTiff, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[3] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Transverse Mercator */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 9 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_TransverseMercator ); GTIFKeySet( hGTiff, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[2] ); GTIFKeySet( hGTiff, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Stereographic */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 10 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Stereographic ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Lambert Azimuthal Equal-Area */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 11 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_LambertAzimEqualArea ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Azimuthal Equidistant */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 12 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_AzimuthalEquidistant ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Gnomonic */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 13 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Gnomonic ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Orthographic */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 14 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Orthographic ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* General Vertical Near-Side Perspective */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 15 ) { /* no mapping! */ } /* -------------------------------------------------------------------- */ /* Sinusoidal */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 16 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Sinusoidal ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Equirectangular */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 17 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_Equirectangular ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Miller Cylindrical */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 18 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_MillerCylindrical ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Van der Grinten I */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 19 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_VanDerGrinten ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Oblique Mercator (Hotine) - Case 0 */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 20 && psProParameters->proParams[12] == 0.0 ) { #ifdef notdef /* This does not appear to be a supported formulation for GeoTIFF, but I will write out the parameters and hope */ GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_ObliqueMercator ); GTIFKeySet( hGTiff, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[2] ); /* proParams[8-11] also existing in this case */ GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); #endif } /* -------------------------------------------------------------------- */ /* Oblique Mercator (Hotine) - Case 1 */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 20 && psProParameters->proParams[12] > 0.0 ) { GTIFKeySet( hGTiff, ProjCoordTransGeoKey, TYPE_SHORT, 1, CT_ObliqueMercator ); GTIFKeySet( hGTiff, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[2] ); GTIFKeySet( hGTiff, ProjAzimuthAngleGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[3] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[4] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[5] * RAD_TO_DEG ); GTIFKeySet( hGTiff, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[6] ); GTIFKeySet( hGTiff, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, psProParameters->proParams[7] ); } /* -------------------------------------------------------------------- */ /* Space Oblique Mercator */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 21 ) { /* not supported by GeoTIFF */ } /* -------------------------------------------------------------------- */ /* Modified Transverse Mercator (MTM) */ /* -------------------------------------------------------------------- */ else if( psProParameters->proNumber == 22 ) { /* not supported by GeoTIFF */ } /* -------------------------------------------------------------------- */ /* Ellipsoid */ /* -------------------------------------------------------------------- */ if( psProParameters != NULL ) { int nEllipsoid = KvUserDefined; if( EQUAL(psProParameters->proSpheroid.sphereName,"WGS 84") ) nEllipsoid = Ellipse_WGS_84; else if( EQUAL(psProParameters->proSpheroid.sphereName,"GRS 80") ) nEllipsoid = Ellipse_GRS_1980; else if( EQUAL(psProParameters->proSpheroid.sphereName,"Clarke 1866") ) nEllipsoid = Ellipse_Clarke_1866; else if( EQUAL(psProParameters->proSpheroid.sphereName,"Clarke 1880") ) nEllipsoid = Ellipse_Clarke_1880; GTIFKeySet( hGTiff, GeogEllipsoidGeoKey, TYPE_SHORT, 1, nEllipsoid ); GTIFKeySet( hGTiff, GeogCitationGeoKey, TYPE_ASCII, 0, psProParameters->proSpheroid.sphereName ); GTIFKeySet( hGTiff, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, psProParameters->proSpheroid.a ); GTIFKeySet( hGTiff, GeogSemiMinorAxisGeoKey, TYPE_DOUBLE, 1, psProParameters->proSpheroid.b ); } /* -------------------------------------------------------------------- */ /* Datum (GCS) - We always assume Greenwich */ /* */ /* If we used the parameter information available through the */ /* EPSG tables we could likely find an appropriate name for */ /* this datum if it has a seven term (or three term) Molondosky */ /* transform. */ /* -------------------------------------------------------------------- */ if( psDatum != NULL ) { int nGCS = KvUserDefined; if( EQUAL(psDatum->datumname,"NAD27") ) nGCS = GCS_NAD27; else if( EQUAL(psDatum->datumname,"NAD83") ) nGCS = GCS_NAD83; else if( EQUAL(psDatum->datumname,"WGS 84") ) nGCS = GCS_WGS_84; else if( EQUAL(psDatum->datumname,"WGS 72") ) nGCS = GCS_WGS_72; GTIFKeySet( hGTiff, GeographicTypeGeoKey, TYPE_SHORT, 1, nGCS ); } /* -------------------------------------------------------------------- */ /* Write information to header and clean up. */ /* -------------------------------------------------------------------- */ GTIFWriteKeys( hGTiff ); GTIFFree( hGTiff ); return CE_None; }