1 : /******************************************************************************
2 : * $Id: gt_wkt_srs.cpp 18584 2010-01-19 04:24:54Z warmerdam $
3 : *
4 : * Project: GeoTIFF Driver
5 : * Purpose: Implements translation between GeoTIFF normalized projection
6 : * definitions and OpenGIS WKT SRS format. This code is
7 : * deliberately GDAL free, and it is intended to be moved into
8 : * libgeotiff someday if possible.
9 : * Author: Frank Warmerdam, warmerdam@pobox.com
10 : *
11 : ******************************************************************************
12 : * Copyright (c) 1999, Frank Warmerdam
13 : *
14 : * Permission is hereby granted, free of charge, to any person obtaining a
15 : * copy of this software and associated documentation files (the "Software"),
16 : * to deal in the Software without restriction, including without limitation
17 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 : * and/or sell copies of the Software, and to permit persons to whom the
19 : * Software is furnished to do so, subject to the following conditions:
20 : *
21 : * The above copyright notice and this permission notice shall be included
22 : * in all copies or substantial portions of the Software.
23 : *
24 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 : * DEALINGS IN THE SOFTWARE.
31 : ****************************************************************************/
32 :
33 : #include "cpl_port.h"
34 : #include "cpl_serv.h"
35 : #include "geo_tiffp.h"
36 : #define CPL_ERROR_H_INCLUDED
37 :
38 : #include "geo_normalize.h"
39 : #include "geovalues.h"
40 : #include "ogr_spatialref.h"
41 : #include "gdal.h"
42 : #include "xtiffio.h"
43 : #include "cpl_multiproc.h"
44 :
45 : CPL_CVSID("$Id: gt_wkt_srs.cpp 18584 2010-01-19 04:24:54Z warmerdam $")
46 :
47 : CPL_C_START
48 : void GTiffOneTimeInit();
49 : int CPL_DLL VSIFCloseL( FILE * );
50 : int CPL_DLL VSIUnlink( const char * );
51 : FILE CPL_DLL *VSIFileFromMemBuffer( const char *pszFilename,
52 : GByte *pabyData,
53 : GUIntBig nDataLength,
54 : int bTakeOwnership );
55 : GByte CPL_DLL *VSIGetMemFileBuffer( const char *pszFilename,
56 : GUIntBig *pnDataLength,
57 : int bUnlinkAndSeize );
58 :
59 : char CPL_DLL * GTIFGetOGISDefn( GTIF *, GTIFDefn * );
60 : int CPL_DLL GTIFSetFromOGISDefn( GTIF *, const char * );
61 :
62 : CPLErr CPL_DLL GTIFMemBufFromWkt( const char *pszWKT,
63 : const double *padfGeoTransform,
64 : int nGCPCount, const GDAL_GCP *pasGCPList,
65 : int *pnSize, unsigned char **ppabyBuffer );
66 : CPLErr CPL_DLL GTIFWktFromMemBuf( int nSize, unsigned char *pabyBuffer,
67 : char **ppszWKT, double *padfGeoTransform,
68 : int *pnGCPCount, GDAL_GCP **ppasGCPList );
69 : CPL_C_END
70 :
71 : TIFF* VSI_TIFFOpen(const char* name, const char* mode);
72 :
73 : static const char *papszDatumEquiv[] =
74 : {
75 : "Militar_Geographische_Institut",
76 : "Militar_Geographische_Institute",
77 : "World_Geodetic_System_1984",
78 : "WGS_1984",
79 : "WGS_72_Transit_Broadcast_Ephemeris",
80 : "WGS_1972_Transit_Broadcast_Ephemeris",
81 : "World_Geodetic_System_1972",
82 : "WGS_1972",
83 : "European_Terrestrial_Reference_System_89",
84 : "European_Reference_System_1989",
85 : NULL
86 : };
87 :
88 : // older libgeotiff's won't list this.
89 : #ifndef CT_CylindricalEqualArea
90 : # define CT_CylindricalEqualArea 28
91 : #endif
92 :
93 : void SetLinearUnitCitation(GTIF* psGTIF, char* pszLinearUOMName);
94 : void SetGeogCSCitation(GTIF * psGTIF, OGRSpatialReference *poSRS, char* angUnitName, int nDatum, short nSpheroid);
95 : OGRBoolean SetCitationToSRS(GTIF* hGTIF, char* szCTString, int nCTStringLen,
96 : geokey_t geoKey, OGRSpatialReference* poSRS, OGRBoolean* linearUnitIsSet);
97 : void GetGeogCSFromCitation(char* szGCSName, int nGCSName,
98 : geokey_t geoKey,
99 : char **ppszGeogName,
100 : char **ppszDatumName,
101 : char **ppszPMName,
102 : char **ppszSpheroidName,
103 : char **ppszAngularUnits);
104 :
105 : /************************************************************************/
106 : /* WKTMassageDatum() */
107 : /* */
108 : /* Massage an EPSG datum name into WMT format. Also transform */
109 : /* specific exception cases into WKT versions. */
110 : /************************************************************************/
111 :
112 5057 : static void WKTMassageDatum( char ** ppszDatum )
113 :
114 : {
115 : int i, j;
116 : char *pszDatum;
117 :
118 : /* -------------------------------------------------------------------- */
119 : /* First copy string and allocate with our CPLStrdup() to so we */
120 : /* know when we are done this function we will have a CPL */
121 : /* string, not a GTIF one. */
122 : /* -------------------------------------------------------------------- */
123 5057 : pszDatum = CPLStrdup(*ppszDatum);
124 5057 : GTIFFreeMemory( *ppszDatum );
125 5057 : *ppszDatum = pszDatum;
126 5057 : if (pszDatum[0] == '\0')
127 0 : return;
128 :
129 : /* -------------------------------------------------------------------- */
130 : /* Translate non-alphanumeric values to underscores. */
131 : /* -------------------------------------------------------------------- */
132 112846 : for( i = 0; pszDatum[i] != '\0'; i++ )
133 : {
134 107789 : if( pszDatum[i] != '+'
135 : && !(pszDatum[i] >= 'A' && pszDatum[i] <= 'Z')
136 : && !(pszDatum[i] >= 'a' && pszDatum[i] <= 'z')
137 : && !(pszDatum[i] >= '0' && pszDatum[i] <= '9') )
138 : {
139 12992 : pszDatum[i] = '_';
140 : }
141 : }
142 :
143 : /* -------------------------------------------------------------------- */
144 : /* Remove repeated and trailing underscores. */
145 : /* -------------------------------------------------------------------- */
146 107789 : for( i = 1, j = 0; pszDatum[i] != '\0'; i++ )
147 : {
148 102732 : if( pszDatum[j] == '_' && pszDatum[i] == '_' )
149 806 : continue;
150 :
151 101926 : pszDatum[++j] = pszDatum[i];
152 : }
153 5057 : if( pszDatum[j] == '_' )
154 582 : pszDatum[j] = '\0';
155 : else
156 4475 : pszDatum[j+1] = '\0';
157 :
158 : /* -------------------------------------------------------------------- */
159 : /* Search for datum equivelences. Specific massaged names get */
160 : /* mapped to OpenGIS specified names. */
161 : /* -------------------------------------------------------------------- */
162 27656 : for( i = 0; papszDatumEquiv[i] != NULL; i += 2 )
163 : {
164 23275 : if( EQUAL(*ppszDatum,papszDatumEquiv[i]) )
165 : {
166 676 : CPLFree( *ppszDatum );
167 676 : *ppszDatum = CPLStrdup( papszDatumEquiv[i+1] );
168 676 : return;
169 : }
170 : }
171 : }
172 :
173 : /************************************************************************/
174 : /* GTIFCleanupImageineNames() */
175 : /* */
176 : /* Erdas Imagine sometimes emits big copyright messages, and */
177 : /* other stuff into citations. These can be pretty messy when */
178 : /* turned into WKT, so we try to trim and clean the strings */
179 : /* somewhat. */
180 : /************************************************************************/
181 :
182 : /* For example:
183 : GTCitationGeoKey (Ascii,215): "IMAGINE GeoTIFF Support\nCopyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile$ $Revision: 18584 $ $Date: 2010-01-19 05:24:54 +0100 (mar 19 jan 2010) $\nProjection Name = UTM\nUnits = meters\nGeoTIFF Units = meters"
184 :
185 : GeogCitationGeoKey (Ascii,267): "IMAGINE GeoTIFF Support\nCopyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile$ $Revision: 18584 $ $Date: 2010-01-19 05:24:54 +0100 (mar 19 jan 2010) $\nUnable to match Ellipsoid (Datum) to a GeographicTypeGeoKey value\nEllipsoid = Clarke 1866\nDatum = NAD27 (CONUS)"
186 :
187 : PCSCitationGeoKey (Ascii,214): "IMAGINE GeoTIFF Support\nCopyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile$ $Revision: 18584 $ $Date: 2010-01-19 05:24:54 +0100 (mar 19 jan 2010) $\nUTM Zone 10N\nEllipsoid = Clarke 1866\nDatum = NAD27 (CONUS)"
188 :
189 : */
190 :
191 8 : static void GTIFCleanupImagineNames( char *pszCitation )
192 :
193 : {
194 8 : if( strstr(pszCitation,"IMAGINE GeoTIFF") == NULL )
195 8 : return;
196 :
197 : /* -------------------------------------------------------------------- */
198 : /* First, we skip past all the copyright, and RCS stuff. We */
199 : /* assume that this will have a "$" at the end of it all. */
200 : /* -------------------------------------------------------------------- */
201 : char *pszSkip;
202 :
203 0 : for( pszSkip = pszCitation + strlen(pszCitation) - 1;
204 : pszSkip != pszCitation && *pszSkip != '$';
205 : pszSkip-- ) {}
206 :
207 0 : if( *pszSkip == '$' )
208 0 : pszSkip++;
209 :
210 0 : memmove( pszCitation, pszSkip, strlen(pszSkip)+1 );
211 :
212 : /* -------------------------------------------------------------------- */
213 : /* Convert any newlines into spaces, they really gum up the */
214 : /* WKT. */
215 : /* -------------------------------------------------------------------- */
216 : int i;
217 :
218 0 : for( i = 0; pszCitation[i] != '\0'; i++ )
219 : {
220 0 : if( pszCitation[i] == '\n' )
221 0 : pszCitation[i] = ' ';
222 : }
223 : }
224 :
225 : /************************************************************************/
226 : /* GTIFGetOGISDefn() */
227 : /************************************************************************/
228 :
229 998 : char *GTIFGetOGISDefn( GTIF *hGTIF, GTIFDefn * psDefn )
230 :
231 : {
232 998 : OGRSpatialReference oSRS;
233 :
234 : /* -------------------------------------------------------------------- */
235 : /* Handle non-standard coordinate systems where GTModelTypeGeoKey */
236 : /* is not defined, but ProjectedCSTypeGeoKey is defined (ticket #3019) */
237 : /* -------------------------------------------------------------------- */
238 998 : if( psDefn->Model == KvUserDefined && psDefn->PCS != KvUserDefined)
239 : {
240 1 : psDefn->Model = ModelTypeProjected;
241 : }
242 :
243 : /* -------------------------------------------------------------------- */
244 : /* Handle non-standard coordinate systems as LOCAL_CS. */
245 : /* -------------------------------------------------------------------- */
246 998 : if( psDefn->Model != ModelTypeProjected
247 : && psDefn->Model != ModelTypeGeographic )
248 : {
249 : char *pszWKT;
250 : char szPeStr[2400];
251 :
252 : /** check if there is a pe string citation key **/
253 8 : if( GTIFKeyGet( hGTIF, PCSCitationGeoKey, szPeStr, 0, sizeof(szPeStr) ) &&
254 : strstr(szPeStr, "ESRI PE String = " ) )
255 : {
256 0 : pszWKT = CPLStrdup( szPeStr + strlen("ESRI PE String = ") );
257 0 : return pszWKT;
258 : }
259 : else
260 : {
261 8 : char *pszUnitsName = NULL;
262 : char szPCSName[300];
263 8 : int nKeyCount = 0;
264 : int anVersion[3];
265 :
266 8 : if( hGTIF != NULL )
267 8 : GTIFDirectoryInfo( hGTIF, anVersion, &nKeyCount );
268 :
269 8 : if( nKeyCount > 0 ) // Use LOCAL_CS if we have any geokeys at all.
270 : {
271 : // Handle citation.
272 8 : strcpy( szPCSName, "unnamed" );
273 8 : if( !GTIFKeyGet( hGTIF, GTCitationGeoKey, szPCSName,
274 : 0, sizeof(szPCSName) ) )
275 : GTIFKeyGet( hGTIF, GeogCitationGeoKey, szPCSName,
276 0 : 0, sizeof(szPCSName) );
277 :
278 8 : GTIFCleanupImagineNames( szPCSName );
279 8 : oSRS.SetLocalCS( szPCSName );
280 :
281 : // Handle units
282 8 : GTIFGetUOMLengthInfo( psDefn->UOMLength, &pszUnitsName, NULL );
283 :
284 8 : if( pszUnitsName != NULL && psDefn->UOMLength != KvUserDefined )
285 : {
286 0 : oSRS.SetLinearUnits( pszUnitsName, psDefn->UOMLengthInMeters );
287 0 : oSRS.SetAuthority( "LOCAL_CS|UNIT", "EPSG", psDefn->UOMLength);
288 : }
289 : else
290 8 : oSRS.SetLinearUnits( "unknown", psDefn->UOMLengthInMeters );
291 :
292 8 : GTIFFreeMemory( pszUnitsName );
293 : }
294 8 : oSRS.exportToWkt( &pszWKT );
295 :
296 8 : return pszWKT;
297 : }
298 : }
299 :
300 : /* -------------------------------------------------------------------- */
301 : /* If this is a projected SRS we set the PROJCS keyword first */
302 : /* to ensure that the GEOGCS will be a child. */
303 : /* -------------------------------------------------------------------- */
304 990 : OGRBoolean linearUnitIsSet = FALSE;
305 990 : if( psDefn->Model == ModelTypeProjected )
306 : {
307 : char szCTString[512];
308 375 : strcpy( szCTString, "unnamed" );
309 375 : if( psDefn->PCS != KvUserDefined )
310 : {
311 371 : char *pszPCSName = NULL;
312 :
313 371 : GTIFGetPCSInfo( psDefn->PCS, &pszPCSName, NULL, NULL, NULL );
314 :
315 371 : oSRS.SetNode( "PROJCS", pszPCSName ? pszPCSName : "unnamed" );
316 371 : if ( pszPCSName )
317 371 : GTIFFreeMemory( pszPCSName );
318 :
319 371 : oSRS.SetAuthority( "PROJCS", "EPSG", psDefn->PCS );
320 : }
321 4 : else if(hGTIF && GTIFKeyGet( hGTIF, PCSCitationGeoKey, szCTString, 0,
322 : sizeof(szCTString)) )
323 : {
324 0 : if (!SetCitationToSRS(hGTIF, szCTString, sizeof(szCTString),
325 : PCSCitationGeoKey, &oSRS, &linearUnitIsSet))
326 0 : oSRS.SetNode("PROJCS",szCTString);
327 : }
328 : else
329 : {
330 4 : if( hGTIF )
331 : {
332 4 : GTIFKeyGet( hGTIF, GTCitationGeoKey, szCTString, 0, sizeof(szCTString) );
333 4 : if(!SetCitationToSRS(hGTIF, szCTString, sizeof(szCTString),
334 : GTCitationGeoKey, &oSRS, &linearUnitIsSet))
335 4 : oSRS.SetNode( "PROJCS", szCTString );
336 : }
337 : else
338 0 : oSRS.SetNode( "PROJCS", szCTString );
339 : }
340 : }
341 :
342 : /* ==================================================================== */
343 : /* Setup the GeogCS */
344 : /* ==================================================================== */
345 990 : char *pszGeogName = NULL;
346 990 : char *pszDatumName = NULL;
347 990 : char *pszPMName = NULL;
348 990 : char *pszSpheroidName = NULL;
349 990 : char *pszAngularUnits = NULL;
350 990 : double dfInvFlattening=0.0, dfSemiMajor=0.0;
351 : char szGCSName[512];
352 990 : OGRBoolean aUnitGot = FALSE;
353 :
354 990 : if( !GTIFGetGCSInfo( psDefn->GCS, &pszGeogName, NULL, NULL, NULL )
355 : && hGTIF != NULL
356 : && GTIFKeyGet( hGTIF, GeogCitationGeoKey, szGCSName, 0,
357 : sizeof(szGCSName)) )
358 : GetGeogCSFromCitation(szGCSName, sizeof(szGCSName),
359 : GeogCitationGeoKey,
360 : &pszGeogName, &pszDatumName,
361 : &pszPMName, &pszSpheroidName,
362 7 : &pszAngularUnits);
363 :
364 990 : if( !pszDatumName )
365 985 : GTIFGetDatumInfo( psDefn->Datum, &pszDatumName, NULL );
366 990 : if( !pszSpheroidName )
367 985 : GTIFGetEllipsoidInfo( psDefn->Ellipsoid, &pszSpheroidName, NULL, NULL );
368 : else
369 : {
370 5 : GTIFKeyGet(hGTIF, GeogSemiMajorAxisGeoKey, &(psDefn->SemiMajor), 0, 1 );
371 5 : GTIFKeyGet(hGTIF, GeogInvFlatteningGeoKey, &dfInvFlattening, 0, 1 );
372 : }
373 990 : if( !pszPMName )
374 985 : GTIFGetPMInfo( psDefn->PM, &pszPMName, NULL );
375 : else
376 5 : GTIFKeyGet(hGTIF, GeogPrimeMeridianLongGeoKey, &(psDefn->PMLongToGreenwich), 0, 1 );
377 :
378 990 : if( !pszAngularUnits )
379 : {
380 990 : GTIFGetUOMAngleInfo( psDefn->UOMAngle, &pszAngularUnits, NULL );
381 990 : if( pszAngularUnits == NULL )
382 0 : pszAngularUnits = CPLStrdup("unknown");
383 : }
384 : else
385 : {
386 0 : GTIFKeyGet(hGTIF, GeogAngularUnitSizeGeoKey, &(psDefn->UOMAngleInDegrees), 0, 1 );
387 0 : aUnitGot = TRUE;
388 : }
389 :
390 990 : if( pszDatumName != NULL ) /* was a GTIFFreeMemory'able string */
391 990 : WKTMassageDatum( &pszDatumName ); /* now a CPLFree'able string */
392 :
393 990 : dfSemiMajor = psDefn->SemiMajor;
394 990 : if( dfSemiMajor == 0.0 )
395 : {
396 0 : pszSpheroidName = CPLStrdup("unretrievable - using WGS84");
397 0 : dfSemiMajor = SRS_WGS84_SEMIMAJOR;
398 0 : dfInvFlattening = SRS_WGS84_INVFLATTENING;
399 : }
400 990 : else if( dfInvFlattening == 0.0 && ((psDefn->SemiMinor / psDefn->SemiMajor) < 0.99999999999999999
401 : || (psDefn->SemiMinor / psDefn->SemiMajor) > 1.00000000000000001 ) )
402 : {
403 985 : dfInvFlattening = -1.0 / (psDefn->SemiMinor/psDefn->SemiMajor - 1.0);
404 :
405 : /* Take official inverse flattening definition in the WGS84 case */
406 985 : if (dfSemiMajor == SRS_WGS84_SEMIMAJOR &&
407 : fabs(dfInvFlattening - SRS_WGS84_INVFLATTENING) < 1e-10)
408 646 : dfInvFlattening = SRS_WGS84_INVFLATTENING;
409 : }
410 990 : if(!pszGeogName || strlen(pszGeogName) == 0)
411 : {
412 2 : GTIFFreeMemory(pszGeogName); /* was a GTIFFreeMemory'able string */
413 2 : pszGeogName = CPLStrdup( pszDatumName ); /* now a CPLFree'able string */
414 : }
415 990 : if(aUnitGot)
416 : oSRS.SetGeogCS( pszGeogName, pszDatumName,
417 : pszSpheroidName, dfSemiMajor, dfInvFlattening,
418 : pszPMName,
419 : psDefn->PMLongToGreenwich / psDefn->UOMAngleInDegrees,
420 : pszAngularUnits,
421 0 : psDefn->UOMAngleInDegrees );
422 : else
423 : oSRS.SetGeogCS( pszGeogName, pszDatumName,
424 : pszSpheroidName, dfSemiMajor, dfInvFlattening,
425 : pszPMName,
426 : psDefn->PMLongToGreenwich / psDefn->UOMAngleInDegrees,
427 : pszAngularUnits,
428 990 : psDefn->UOMAngleInDegrees * 0.0174532925199433 );
429 :
430 990 : if( psDefn->GCS != KvUserDefined && psDefn->GCS > 0 )
431 983 : oSRS.SetAuthority( "GEOGCS", "EPSG", psDefn->GCS );
432 :
433 990 : if( psDefn->Datum != KvUserDefined )
434 985 : oSRS.SetAuthority( "DATUM", "EPSG", psDefn->Datum );
435 :
436 990 : if( psDefn->Ellipsoid != KvUserDefined )
437 985 : oSRS.SetAuthority( "SPHEROID", "EPSG", psDefn->Ellipsoid );
438 :
439 990 : CPLFree( pszGeogName );
440 990 : CPLFree( pszDatumName );
441 990 : GTIFFreeMemory( pszPMName );
442 990 : GTIFFreeMemory( pszSpheroidName );
443 990 : GTIFFreeMemory( pszAngularUnits );
444 :
445 : /* ==================================================================== */
446 : /* Handle projection parameters. */
447 : /* ==================================================================== */
448 990 : if( psDefn->Model == ModelTypeProjected )
449 : {
450 : /* -------------------------------------------------------------------- */
451 : /* Make a local copy of parms, and convert back into the */
452 : /* angular units of the GEOGCS and the linear units of the */
453 : /* projection. */
454 : /* -------------------------------------------------------------------- */
455 : double adfParm[10];
456 : int i;
457 :
458 3000 : for( i = 0; i < MIN(10,psDefn->nParms); i++ )
459 2625 : adfParm[i] = psDefn->ProjParm[i];
460 :
461 1500 : for( ; i < 10; i++ )
462 1125 : adfParm[i] = 0.0;
463 :
464 375 : if(!aUnitGot)
465 : {
466 375 : adfParm[0] *= psDefn->UOMAngleInDegrees;
467 375 : adfParm[1] *= psDefn->UOMAngleInDegrees;
468 375 : adfParm[2] *= psDefn->UOMAngleInDegrees;
469 375 : adfParm[3] *= psDefn->UOMAngleInDegrees;
470 : }
471 375 : int unitCode = 0;
472 375 : GTIFKeyGet(hGTIF, ProjLinearUnitsGeoKey, &unitCode, 0, 1 );
473 375 : if(unitCode != KvUserDefined)
474 : {
475 375 : adfParm[5] /= psDefn->UOMLengthInMeters;
476 375 : adfParm[6] /= psDefn->UOMLengthInMeters;
477 : }
478 :
479 : /* -------------------------------------------------------------------- */
480 : /* Translation the fundamental projection. */
481 : /* -------------------------------------------------------------------- */
482 375 : switch( psDefn->CTProjection )
483 : {
484 : case CT_TransverseMercator:
485 : oSRS.SetTM( adfParm[0], adfParm[1],
486 : adfParm[4],
487 372 : adfParm[5], adfParm[6] );
488 372 : break;
489 :
490 : case CT_TransvMercator_SouthOriented:
491 : oSRS.SetTMSO( adfParm[0], adfParm[1],
492 : adfParm[4],
493 0 : adfParm[5], adfParm[6] );
494 0 : break;
495 :
496 : case CT_Mercator:
497 : oSRS.SetMercator( adfParm[0], adfParm[1],
498 : adfParm[4],
499 0 : adfParm[5], adfParm[6] );
500 :
501 0 : if (psDefn->Projection == 1024 || psDefn->Projection == 9841) // override hack for google mercator.
502 : {
503 : oSRS.SetExtension( "PROJCS", "PROJ4",
504 0 : "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" );
505 : }
506 0 : break;
507 :
508 : case CT_ObliqueStereographic:
509 : oSRS.SetOS( adfParm[0], adfParm[1],
510 : adfParm[4],
511 0 : adfParm[5], adfParm[6] );
512 0 : break;
513 :
514 : case CT_Stereographic:
515 : oSRS.SetOS( adfParm[0], adfParm[1],
516 : adfParm[4],
517 0 : adfParm[5], adfParm[6] );
518 0 : break;
519 :
520 : case CT_ObliqueMercator: /* hotine */
521 : oSRS.SetHOM( adfParm[0], adfParm[1],
522 : adfParm[2], adfParm[3],
523 : adfParm[4],
524 0 : adfParm[5], adfParm[6] );
525 0 : break;
526 :
527 : case CT_EquidistantConic:
528 : oSRS.SetEC( adfParm[0], adfParm[1],
529 : adfParm[2], adfParm[3],
530 0 : adfParm[5], adfParm[6] );
531 0 : break;
532 :
533 : case CT_CassiniSoldner:
534 : oSRS.SetCS( adfParm[0], adfParm[1],
535 0 : adfParm[5], adfParm[6] );
536 0 : break;
537 :
538 : case CT_Polyconic:
539 : oSRS.SetPolyconic( adfParm[0], adfParm[1],
540 0 : adfParm[5], adfParm[6] );
541 0 : break;
542 :
543 : case CT_AzimuthalEquidistant:
544 : oSRS.SetAE( adfParm[0], adfParm[1],
545 0 : adfParm[5], adfParm[6] );
546 0 : break;
547 :
548 : case CT_MillerCylindrical:
549 : oSRS.SetMC( adfParm[0], adfParm[1],
550 0 : adfParm[5], adfParm[6] );
551 0 : break;
552 :
553 : case CT_Equirectangular:
554 : oSRS.SetEquirectangular2( adfParm[0], adfParm[1],
555 : adfParm[2],
556 1 : adfParm[5], adfParm[6] );
557 1 : break;
558 :
559 : case CT_Gnomonic:
560 : oSRS.SetGnomonic( adfParm[0], adfParm[1],
561 0 : adfParm[5], adfParm[6] );
562 0 : break;
563 :
564 : case CT_LambertAzimEqualArea:
565 : oSRS.SetLAEA( adfParm[0], adfParm[1],
566 0 : adfParm[5], adfParm[6] );
567 0 : break;
568 :
569 : case CT_Orthographic:
570 : oSRS.SetOrthographic( adfParm[0], adfParm[1],
571 0 : adfParm[5], adfParm[6] );
572 0 : break;
573 :
574 : case CT_Robinson:
575 : oSRS.SetRobinson( adfParm[1],
576 0 : adfParm[5], adfParm[6] );
577 0 : break;
578 :
579 : case CT_Sinusoidal:
580 : oSRS.SetSinusoidal( adfParm[1],
581 0 : adfParm[5], adfParm[6] );
582 0 : break;
583 :
584 : case CT_VanDerGrinten:
585 : oSRS.SetVDG( adfParm[1],
586 0 : adfParm[5], adfParm[6] );
587 0 : break;
588 :
589 : case CT_PolarStereographic:
590 : oSRS.SetPS( adfParm[0], adfParm[1],
591 : adfParm[4],
592 0 : adfParm[5], adfParm[6] );
593 0 : break;
594 :
595 : case CT_LambertConfConic_2SP:
596 : oSRS.SetLCC( adfParm[2], adfParm[3],
597 : adfParm[0], adfParm[1],
598 1 : adfParm[5], adfParm[6] );
599 1 : break;
600 :
601 : case CT_LambertConfConic_1SP:
602 : oSRS.SetLCC1SP( adfParm[0], adfParm[1],
603 : adfParm[4],
604 1 : adfParm[5], adfParm[6] );
605 1 : break;
606 :
607 : case CT_AlbersEqualArea:
608 : oSRS.SetACEA( adfParm[0], adfParm[1],
609 : adfParm[2], adfParm[3],
610 0 : adfParm[5], adfParm[6] );
611 0 : break;
612 :
613 : case CT_NewZealandMapGrid:
614 : oSRS.SetNZMG( adfParm[0], adfParm[1],
615 0 : adfParm[5], adfParm[6] );
616 0 : break;
617 :
618 : case CT_CylindricalEqualArea:
619 : oSRS.SetCEA( adfParm[0], adfParm[1],
620 0 : adfParm[5], adfParm[6] );
621 : break;
622 : }
623 :
624 : /* -------------------------------------------------------------------- */
625 : /* Set projection units. */
626 : /* -------------------------------------------------------------------- */
627 375 : if(!linearUnitIsSet)
628 : {
629 375 : char *pszUnitsName = NULL;
630 :
631 375 : GTIFGetUOMLengthInfo( psDefn->UOMLength, &pszUnitsName, NULL );
632 :
633 750 : if( pszUnitsName != NULL && psDefn->UOMLength != KvUserDefined )
634 : {
635 375 : oSRS.SetLinearUnits( pszUnitsName, psDefn->UOMLengthInMeters );
636 375 : oSRS.SetAuthority( "PROJCS|UNIT", "EPSG", psDefn->UOMLength );
637 : }
638 : else
639 0 : oSRS.SetLinearUnits( "unknown", psDefn->UOMLengthInMeters );
640 :
641 375 : GTIFFreeMemory( pszUnitsName );
642 : }
643 : }
644 :
645 : /* ==================================================================== */
646 : /* Handle vertical coordinate system information if we have it. */
647 : /* ==================================================================== */
648 990 : short verticalCSType = -1;
649 990 : short verticalDatum = -1;
650 990 : short verticalUnits = -1;
651 990 : const char *pszFilename = NULL;
652 : const char *pszValue;
653 : char szSearchKey[128];
654 :
655 : // Don't do anything if there is no apparent vertical information.
656 990 : GTIFKeyGet( hGTIF, VerticalCSTypeGeoKey, &verticalCSType, 0, 1 );
657 990 : GTIFKeyGet( hGTIF, VerticalDatumGeoKey, &verticalDatum, 0, 1 );
658 990 : GTIFKeyGet( hGTIF, VerticalUnitsGeoKey, &verticalUnits, 0, 1 );
659 :
660 990 : if( (verticalCSType != -1 || verticalDatum != -1 || verticalUnits != -1)
661 : && (oSRS.IsGeographic() || oSRS.IsProjected() || oSRS.IsLocal()) )
662 : {
663 : char citation[2048];
664 :
665 0 : if( !GTIFKeyGet( hGTIF, VerticalCitationGeoKey, &citation,
666 : 0, sizeof(citation) ) )
667 0 : strcpy( citation, "unknown" );
668 :
669 : /* -------------------------------------------------------------------- */
670 : /* The original geotiff specification appears to have */
671 : /* misconstrued the EPSG codes 5101 to 5106 to be vertical */
672 : /* coordinate system codes, when in fact they are vertical */
673 : /* datum codes. So if these are found in the */
674 : /* VerticalCSTypeGeoKey move them to the VerticalDatumGeoKey */
675 : /* and insert the "normal" corresponding VerticalCSTypeGeoKey */
676 : /* value. */
677 : /* -------------------------------------------------------------------- */
678 0 : if( (verticalCSType >= 5101 && verticalCSType <= 5112)
679 : && verticalDatum == -1 )
680 : {
681 0 : verticalDatum = verticalCSType;
682 0 : verticalCSType = verticalDatum + 600;
683 : }
684 :
685 : /* -------------------------------------------------------------------- */
686 : /* Somewhat similarly, codes 5001 to 5033 were treated as */
687 : /* vertical coordinate systems based on ellipsoidal heights. */
688 : /* We use the corresponding 2d geodetic datum as the vertical */
689 : /* datum and clear the vertical coordinate system code since */
690 : /* there isn't one in epsg. */
691 : /* -------------------------------------------------------------------- */
692 0 : if( (verticalCSType >= 5001 && verticalCSType <= 5033)
693 : && verticalDatum == -1 )
694 : {
695 0 : verticalDatum = verticalCSType+1000;
696 0 : verticalCSType = -1;
697 : }
698 :
699 : /* -------------------------------------------------------------------- */
700 : /* Promote to being a compound coordinate system. */
701 : /* -------------------------------------------------------------------- */
702 0 : OGR_SRSNode *poOldRoot = oSRS.GetRoot()->Clone();
703 :
704 0 : oSRS.Clear();
705 0 : oSRS.SetNode( "COMPD_CS", "unknown" );
706 0 : oSRS.GetRoot()->AddChild( poOldRoot );
707 :
708 : /* -------------------------------------------------------------------- */
709 : /* Collect some information from the VerticalCS if not provided */
710 : /* via geokeys. */
711 : /* -------------------------------------------------------------------- */
712 0 : if( verticalCSType > 0 && verticalCSType != KvUserDefined )
713 : {
714 0 : pszFilename = CSVFilename( "coordinate_reference_system.csv" );
715 0 : sprintf( szSearchKey, "%d", verticalCSType );
716 :
717 0 : if( verticalDatum < 1 || verticalDatum == KvUserDefined )
718 : {
719 : pszValue = CSVGetField( pszFilename,
720 : "coord_ref_sys_code",
721 : szSearchKey, CC_Integer,
722 0 : "datum_code" );
723 0 : if( pszValue != NULL )
724 0 : verticalDatum = atoi(pszValue);
725 : }
726 :
727 0 : if( EQUAL(citation,"unknown") )
728 : {
729 : pszValue = CSVGetField( pszFilename,
730 : "coord_ref_sys_code",
731 : szSearchKey, CC_Integer,
732 0 : "coord_ref_sys_name" );
733 0 : if( pszValue != NULL && *pszValue != '\0' )
734 0 : strncpy( citation, pszValue, sizeof(citation) );
735 : }
736 :
737 0 : if( verticalUnits < 1 || verticalUnits == KvUserDefined )
738 : {
739 : pszValue = CSVGetField( pszFilename,
740 : "coord_ref_sys_code",
741 : szSearchKey, CC_Integer,
742 0 : "coord_sys_code" );
743 0 : if( pszValue != NULL )
744 : {
745 0 : pszFilename = CSVFilename( "coordinate_axis.csv" );
746 : pszValue = CSVGetField( pszFilename,
747 : "coord_sys_code",
748 : pszValue, CC_Integer,
749 0 : "uom_code" );
750 0 : if( pszValue != NULL )
751 0 : verticalUnits = atoi(pszValue);
752 : }
753 : }
754 : }
755 :
756 : /* -------------------------------------------------------------------- */
757 : /* Setup VERT_CS with citation if present. */
758 : /* -------------------------------------------------------------------- */
759 0 : oSRS.SetNode( "COMPD_CS|VERT_CS", citation );
760 :
761 : /* -------------------------------------------------------------------- */
762 : /* Setup the vertical datum. */
763 : /* -------------------------------------------------------------------- */
764 0 : const char *pszVDatumName = "unknown";
765 0 : const char *pszVDatumType = "2005"; // CS_VD_GeoidModelDerived
766 :
767 0 : if( verticalDatum > 0 && verticalDatum != KvUserDefined )
768 : {
769 0 : pszFilename = CSVFilename( "datum.csv" );
770 0 : if( EQUAL(pszFilename,"datum.csv") )
771 0 : pszFilename = CSVFilename( "gdal_datum.csv" );
772 :
773 0 : sprintf( szSearchKey, "%d", verticalDatum );
774 :
775 : pszValue = CSVGetField( pszFilename,
776 : "DATUM_CODE", szSearchKey, CC_Integer,
777 0 : "DATUM_NAME" );
778 0 : if( pszValue != NULL && *pszValue != '\0' )
779 0 : pszVDatumName = pszValue;
780 :
781 : pszValue = CSVGetField( pszFilename,
782 : "DATUM_CODE", szSearchKey, CC_Integer,
783 0 : "DATUM_TYPE" );
784 0 : if( pszValue != NULL && EQUALN(pszValue,"geodetic",8) )
785 0 : pszVDatumType = "2002"; // CS_VD_Ellipsoidal
786 :
787 : // We unfortunately don't know how to identify other
788 : // vertical datum types, particularly orthometric (2001).
789 : }
790 :
791 0 : oSRS.SetNode( "COMPD_CS|VERT_CS|VERT_DATUM", pszVDatumName );
792 : oSRS.GetAttrNode( "COMPD_CS|VERT_CS|VERT_DATUM" )
793 0 : ->AddChild( new OGR_SRSNode( pszVDatumType ) );
794 0 : if( verticalDatum > 0 && verticalDatum != KvUserDefined )
795 : oSRS.SetAuthority( "COMPD_CS|VERT_CS|VERT_DATUM", "EPSG",
796 0 : verticalDatum );
797 :
798 : /* -------------------------------------------------------------------- */
799 : /* Set the vertical units. */
800 : /* -------------------------------------------------------------------- */
801 0 : if( verticalUnits > 0 && verticalUnits != KvUserDefined
802 : && verticalUnits != 9001 )
803 : {
804 : char szInMeters[128];
805 :
806 0 : pszFilename = CSVFilename("unit_of_measure.csv");
807 :
808 : // Name
809 0 : sprintf( szSearchKey, "%d", verticalUnits );
810 : pszValue = CSVGetField( pszFilename,
811 : "uom_code", szSearchKey, CC_Integer,
812 0 : "unit_of_meas_name" );
813 0 : if( pszValue == NULL )
814 0 : pszValue = "unknown";
815 :
816 0 : oSRS.SetNode( "COMPD_CS|VERT_CS|UNIT", pszValue );
817 :
818 : // Value
819 : double dfFactorB, dfFactorC;
820 : dfFactorB = atof(CSVGetField( pszFilename,
821 : "uom_code", szSearchKey, CC_Integer,
822 0 : "factor_b" ));
823 : dfFactorC = atof(CSVGetField( pszFilename,
824 : "uom_code", szSearchKey, CC_Integer,
825 0 : "factor_b" ));
826 0 : if( dfFactorB != 0.0 && dfFactorC != 0.0 )
827 0 : sprintf( szInMeters, "%.16g", dfFactorB / dfFactorC );
828 : else
829 0 : strcpy( szInMeters, "1" );
830 :
831 :
832 : oSRS.GetAttrNode( "COMPD_CS|VERT_CS|UNIT" )
833 0 : ->AddChild( new OGR_SRSNode( szInMeters ) );
834 :
835 0 : oSRS.SetAuthority( "COMPD_CS|VERT_CS|UNIT", "EPSG", verticalUnits);
836 : }
837 : else
838 : {
839 0 : oSRS.SetNode( "COMPD_CS|VERT_CS|UNIT", "metre" );
840 : oSRS.GetAttrNode( "COMPD_CS|VERT_CS|UNIT" )
841 0 : ->AddChild( new OGR_SRSNode( "1.0" ) );
842 0 : oSRS.SetAuthority( "COMPD_CS|VERT_CS|UNIT", "EPSG", 9001 );
843 : }
844 :
845 : /* -------------------------------------------------------------------- */
846 : /* Set the axis and VERT_CS authority. */
847 : /* -------------------------------------------------------------------- */
848 0 : oSRS.SetNode( "COMPD_CS|VERT_CS|AXIS", "Up" );
849 : oSRS.GetAttrNode( "COMPD_CS|VERT_CS|AXIS" )
850 0 : ->AddChild( new OGR_SRSNode( "UP" ) );
851 :
852 0 : if( verticalCSType > 0 && verticalCSType != KvUserDefined )
853 0 : oSRS.SetAuthority( "COMPD_CS|VERT_CS", "EPSG", verticalCSType );
854 : }
855 :
856 : /* ==================================================================== */
857 : /* Return the WKT serialization of the object. */
858 : /* ==================================================================== */
859 : char *pszWKT;
860 :
861 990 : oSRS.FixupOrdering();
862 :
863 990 : if( oSRS.exportToWkt( &pszWKT ) == OGRERR_NONE )
864 990 : return pszWKT;
865 : else
866 0 : return NULL;
867 : }
868 :
869 : /************************************************************************/
870 : /* OGCDatumName2EPSGDatumCode() */
871 : /************************************************************************/
872 :
873 283 : static int OGCDatumName2EPSGDatumCode( const char * pszOGCName )
874 :
875 : {
876 : FILE *fp;
877 : char **papszTokens;
878 283 : int nReturn = KvUserDefined;
879 :
880 : /* -------------------------------------------------------------------- */
881 : /* Do we know it as a built in? */
882 : /* -------------------------------------------------------------------- */
883 283 : if( EQUAL(pszOGCName,"NAD27")
884 : || EQUAL(pszOGCName,"North_American_Datum_1927") )
885 0 : return Datum_North_American_Datum_1927;
886 283 : else if( EQUAL(pszOGCName,"NAD83")
887 : || EQUAL(pszOGCName,"North_American_Datum_1983") )
888 0 : return Datum_North_American_Datum_1983;
889 283 : else if( EQUAL(pszOGCName,"WGS84") || EQUAL(pszOGCName,"WGS_1984")
890 : || EQUAL(pszOGCName,"WGS 84"))
891 274 : return Datum_WGS84;
892 9 : else if( EQUAL(pszOGCName,"WGS72") || EQUAL(pszOGCName,"WGS_1972") )
893 2 : return Datum_WGS72;
894 :
895 : /* -------------------------------------------------------------------- */
896 : /* Open the table if possible. */
897 : /* -------------------------------------------------------------------- */
898 7 : fp = VSIFOpen( CSVFilename("gdal_datum.csv"), "r" );
899 7 : if( fp == NULL )
900 0 : fp = VSIFOpen( CSVFilename("datum.csv"), "r" );
901 :
902 7 : if( fp == NULL )
903 0 : return nReturn;
904 :
905 : /* -------------------------------------------------------------------- */
906 : /* Discard the first line with field names. */
907 : /* -------------------------------------------------------------------- */
908 7 : CSLDestroy( CSVReadParseLine( fp ) );
909 :
910 : /* -------------------------------------------------------------------- */
911 : /* Read lines looking for our datum. */
912 : /* -------------------------------------------------------------------- */
913 4074 : for( papszTokens = CSVReadParseLine( fp );
914 : CSLCount(papszTokens) > 2 && nReturn == KvUserDefined;
915 : papszTokens = CSVReadParseLine( fp ) )
916 : {
917 4067 : WKTMassageDatum( papszTokens + 1 );
918 :
919 4067 : if( EQUAL(papszTokens[1], pszOGCName) )
920 0 : nReturn = atoi(papszTokens[0]);
921 :
922 4067 : CSLDestroy( papszTokens );
923 : }
924 :
925 7 : CSLDestroy( papszTokens );
926 7 : VSIFClose( fp );
927 :
928 7 : return nReturn;
929 : }
930 :
931 : /************************************************************************/
932 : /* GTIFSetFromOGISDefn() */
933 : /* */
934 : /* Write GeoTIFF projection tags from an OGC WKT definition. */
935 : /************************************************************************/
936 :
937 701 : int GTIFSetFromOGISDefn( GTIF * psGTIF, const char *pszOGCWKT )
938 :
939 : {
940 : OGRSpatialReference *poSRS;
941 701 : int nPCS = KvUserDefined;
942 : OGRErr eErr;
943 701 : OGRBoolean peStrStored = FALSE;
944 :
945 : GTIFKeySet(psGTIF, GTRasterTypeGeoKey, TYPE_SHORT, 1,
946 701 : RasterPixelIsArea);
947 :
948 : /* -------------------------------------------------------------------- */
949 : /* Create an OGRSpatialReference object corresponding to the */
950 : /* string. */
951 : /* -------------------------------------------------------------------- */
952 701 : poSRS = new OGRSpatialReference();
953 701 : if( poSRS->importFromWkt((char **) &pszOGCWKT) != OGRERR_NONE )
954 : {
955 0 : delete poSRS;
956 0 : return FALSE;
957 : }
958 :
959 : /* -------------------------------------------------------------------- */
960 : /* Get the ellipsoid definition. */
961 : /* -------------------------------------------------------------------- */
962 701 : short nSpheroid = KvUserDefined;
963 : double dfSemiMajor, dfInvFlattening;
964 :
965 701 : if( poSRS->GetAuthorityName("PROJCS|GEOGCS|DATUM|SPHEROID") != NULL
966 : && EQUAL(poSRS->GetAuthorityName("PROJCS|GEOGCS|DATUM|SPHEROID"),
967 : "EPSG"))
968 : {
969 : nSpheroid = (short)
970 129 : atoi(poSRS->GetAuthorityCode("PROJCS|GEOGCS|DATUM|SPHEROID"));
971 : }
972 572 : else if( poSRS->GetAuthorityName("GEOGCS|DATUM|SPHEROID") != NULL
973 : && EQUAL(poSRS->GetAuthorityName("GEOGCS|DATUM|SPHEROID"),"EPSG"))
974 : {
975 : nSpheroid = (short)
976 289 : atoi(poSRS->GetAuthorityCode("GEOGCS|DATUM|SPHEROID"));
977 : }
978 :
979 701 : dfSemiMajor = poSRS->GetSemiMajor( &eErr );
980 701 : dfInvFlattening = poSRS->GetInvFlattening( &eErr );
981 701 : if( eErr != OGRERR_NONE )
982 : {
983 2 : dfSemiMajor = 0.0;
984 2 : dfInvFlattening = 0.0;
985 : }
986 :
987 : /* -------------------------------------------------------------------- */
988 : /* Get the Datum so we can special case a few PCS codes. */
989 : /* -------------------------------------------------------------------- */
990 701 : int nDatum = KvUserDefined;
991 :
992 701 : if( poSRS->GetAuthorityName("PROJCS|GEOGCS|DATUM") != NULL
993 : && EQUAL(poSRS->GetAuthorityName("PROJCS|GEOGCS|DATUM"),"EPSG") )
994 129 : nDatum = atoi(poSRS->GetAuthorityCode("PROJCS|GEOGCS|DATUM"));
995 572 : else if( poSRS->GetAuthorityName("GEOGCS|DATUM") != NULL
996 : && EQUAL(poSRS->GetAuthorityName("GEOGCS|DATUM"),"EPSG") )
997 289 : nDatum = atoi(poSRS->GetAuthorityCode("GEOGCS|DATUM"));
998 283 : else if( poSRS->GetAttrValue("DATUM") != NULL )
999 283 : nDatum = OGCDatumName2EPSGDatumCode( poSRS->GetAttrValue("DATUM") );
1000 :
1001 : /* -------------------------------------------------------------------- */
1002 : /* Get the GCS if possible. */
1003 : /* -------------------------------------------------------------------- */
1004 701 : int nGCS = KvUserDefined;
1005 :
1006 701 : if( poSRS->GetAuthorityName("PROJCS|GEOGCS") != NULL
1007 : && EQUAL(poSRS->GetAuthorityName("PROJCS|GEOGCS"),"EPSG") )
1008 129 : nGCS = atoi(poSRS->GetAuthorityCode("PROJCS|GEOGCS"));
1009 572 : else if( poSRS->GetAuthorityName("GEOGCS") != NULL
1010 : && EQUAL(poSRS->GetAuthorityName("GEOGCS"),"EPSG") )
1011 298 : nGCS = atoi(poSRS->GetAuthorityCode("GEOGCS"));
1012 :
1013 701 : if( nGCS > 32767 )
1014 0 : nGCS = KvUserDefined;
1015 :
1016 : /* -------------------------------------------------------------------- */
1017 : /* Get the linear units. */
1018 : /* -------------------------------------------------------------------- */
1019 701 : char *pszLinearUOMName = NULL;
1020 701 : double dfLinearUOM = poSRS->GetLinearUnits( &pszLinearUOMName );
1021 701 : int nUOMLengthCode = 9001; /* meters */
1022 :
1023 701 : if( (pszLinearUOMName != NULL
1024 : && EQUAL(pszLinearUOMName,SRS_UL_FOOT))
1025 : || dfLinearUOM == atof(SRS_UL_FOOT_CONV) )
1026 0 : nUOMLengthCode = 9002; /* international foot */
1027 702 : else if( (pszLinearUOMName != NULL
1028 : && EQUAL(pszLinearUOMName,SRS_UL_US_FOOT))
1029 : || ABS(dfLinearUOM-atof(SRS_UL_US_FOOT_CONV)) < 0.0000001 )
1030 1 : nUOMLengthCode = 9003; /* us survey foot */
1031 700 : else if( dfLinearUOM != 1.0 )
1032 0 : nUOMLengthCode = KvUserDefined;
1033 :
1034 : /* -------------------------------------------------------------------- */
1035 : /* Get some authority values. */
1036 : /* -------------------------------------------------------------------- */
1037 701 : if( poSRS->GetAuthorityName("PROJCS") != NULL
1038 : && EQUAL(poSRS->GetAuthorityName("PROJCS"),"EPSG") )
1039 : {
1040 128 : nPCS = atoi(poSRS->GetAuthorityCode("PROJCS"));
1041 128 : if( nPCS > 32767 )
1042 0 : nPCS = KvUserDefined;
1043 : }
1044 :
1045 : /* -------------------------------------------------------------------- */
1046 : /* Handle the projection transformation. */
1047 : /* -------------------------------------------------------------------- */
1048 701 : const char *pszProjection = poSRS->GetAttrValue( "PROJECTION" );
1049 :
1050 701 : if( nPCS != KvUserDefined )
1051 : {
1052 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1053 128 : ModelTypeProjected);
1054 128 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, nPCS );
1055 : }
1056 573 : else if( pszProjection == NULL )
1057 : {
1058 566 : if( poSRS->IsGeographic() )
1059 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1060 566 : ModelTypeGeographic);
1061 : // otherwise, presumably something like LOCAL_CS.
1062 : }
1063 7 : else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
1064 : {
1065 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1066 0 : ModelTypeProjected);
1067 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1068 0 : KvUserDefined );
1069 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1070 0 : KvUserDefined );
1071 :
1072 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1073 0 : CT_AlbersEqualArea );
1074 :
1075 : GTIFKeySet(psGTIF, ProjStdParallelGeoKey, TYPE_DOUBLE, 1,
1076 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1077 :
1078 : GTIFKeySet(psGTIF, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1,
1079 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
1080 :
1081 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1082 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1083 :
1084 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1085 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1086 :
1087 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1088 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1089 :
1090 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1091 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1092 : }
1093 :
1094 7 : else if( poSRS->GetUTMZone() != 0 )
1095 : {
1096 : int bNorth, nZone, nProjection;
1097 :
1098 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1099 1 : ModelTypeProjected);
1100 :
1101 1 : nZone = poSRS->GetUTMZone( &bNorth );
1102 :
1103 1 : if( nDatum == Datum_North_American_Datum_1983 && nZone >= 3
1104 : && nZone <= 22 && bNorth && nUOMLengthCode == 9001 )
1105 : {
1106 0 : nPCS = 26900 + nZone;
1107 :
1108 0 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, nPCS );
1109 : }
1110 1 : else if( nDatum == Datum_North_American_Datum_1927 && nZone >= 3
1111 : && nZone <= 22 && bNorth && nUOMLengthCode == 9001 )
1112 : {
1113 0 : nPCS = 26700 + nZone;
1114 :
1115 0 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, nPCS );
1116 : }
1117 1 : else if( nDatum == Datum_WGS84 && nUOMLengthCode == 9001 )
1118 : {
1119 0 : if( bNorth )
1120 0 : nPCS = 32600 + nZone;
1121 : else
1122 0 : nPCS = 32700 + nZone;
1123 :
1124 0 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, nPCS );
1125 : }
1126 : else
1127 : {
1128 1 : if( bNorth )
1129 1 : nProjection = 16000 + nZone;
1130 : else
1131 0 : nProjection = 16100 + nZone;
1132 :
1133 :
1134 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1135 1 : KvUserDefined );
1136 :
1137 1 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1, nProjection );
1138 : }
1139 : }
1140 :
1141 6 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
1142 : {
1143 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1144 0 : ModelTypeProjected);
1145 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1146 0 : KvUserDefined );
1147 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1148 0 : KvUserDefined );
1149 :
1150 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1151 0 : CT_TransverseMercator );
1152 :
1153 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1154 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1155 :
1156 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1157 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1158 :
1159 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1160 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1161 :
1162 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1163 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1164 :
1165 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1166 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1167 : }
1168 :
1169 6 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED) )
1170 : {
1171 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1172 0 : ModelTypeProjected);
1173 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1174 0 : KvUserDefined );
1175 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1176 0 : KvUserDefined );
1177 :
1178 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1179 0 : CT_TransvMercator_SouthOriented );
1180 :
1181 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1182 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1183 :
1184 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1185 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1186 :
1187 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1188 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1189 :
1190 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1191 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1192 :
1193 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1194 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1195 : }
1196 :
1197 6 : else if( EQUAL(pszProjection,SRS_PT_MERCATOR_2SP)
1198 : || EQUAL(pszProjection,SRS_PT_MERCATOR_1SP) )
1199 :
1200 : {
1201 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1202 0 : ModelTypeProjected);
1203 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1204 0 : KvUserDefined );
1205 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1206 0 : KvUserDefined );
1207 :
1208 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1209 0 : CT_Mercator );
1210 :
1211 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1212 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1213 :
1214 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1215 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1216 :
1217 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1218 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1219 :
1220 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1221 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1222 :
1223 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1224 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1225 : }
1226 :
1227 6 : else if( EQUAL(pszProjection,SRS_PT_OBLIQUE_STEREOGRAPHIC) )
1228 : {
1229 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1230 0 : ModelTypeProjected);
1231 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1232 0 : KvUserDefined );
1233 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1234 0 : KvUserDefined );
1235 :
1236 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1237 0 : CT_ObliqueStereographic );
1238 :
1239 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1240 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1241 :
1242 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1243 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1244 :
1245 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1246 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1247 :
1248 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1249 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1250 :
1251 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1252 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1253 : }
1254 :
1255 6 : else if( EQUAL(pszProjection,SRS_PT_STEREOGRAPHIC) )
1256 : {
1257 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1258 0 : ModelTypeProjected);
1259 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1260 0 : KvUserDefined );
1261 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1262 0 : KvUserDefined );
1263 :
1264 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1265 0 : CT_Stereographic );
1266 :
1267 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1268 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1269 :
1270 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1271 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1272 :
1273 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1274 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1275 :
1276 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1277 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1278 :
1279 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1280 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1281 : }
1282 :
1283 6 : else if( EQUAL(pszProjection,SRS_PT_POLAR_STEREOGRAPHIC) )
1284 : {
1285 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1286 0 : ModelTypeProjected);
1287 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1288 0 : KvUserDefined );
1289 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1290 0 : KvUserDefined );
1291 :
1292 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1293 0 : CT_PolarStereographic );
1294 :
1295 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1296 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1297 :
1298 : GTIFKeySet(psGTIF, ProjStraightVertPoleLongGeoKey, TYPE_DOUBLE, 1,
1299 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1300 :
1301 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1302 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1303 :
1304 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1305 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1306 :
1307 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1308 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1309 : }
1310 :
1311 6 : else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
1312 : {
1313 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1314 0 : ModelTypeProjected);
1315 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1316 0 : KvUserDefined );
1317 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1318 0 : KvUserDefined );
1319 :
1320 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1321 0 : CT_ObliqueMercator );
1322 :
1323 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1324 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1325 :
1326 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1327 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1328 :
1329 : GTIFKeySet(psGTIF, ProjAzimuthAngleGeoKey, TYPE_DOUBLE, 1,
1330 0 : poSRS->GetNormProjParm( SRS_PP_AZIMUTH, 0.0 ) );
1331 :
1332 : GTIFKeySet(psGTIF, ProjRectifiedGridAngleGeoKey, TYPE_DOUBLE, 1,
1333 0 : poSRS->GetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, 0.0 ) );
1334 :
1335 : GTIFKeySet(psGTIF, ProjScaleAtCenterGeoKey, TYPE_DOUBLE, 1,
1336 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1337 :
1338 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1339 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1340 :
1341 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1342 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1343 : }
1344 :
1345 6 : else if( EQUAL(pszProjection,SRS_PT_CASSINI_SOLDNER) )
1346 : {
1347 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1348 0 : ModelTypeProjected);
1349 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1350 0 : KvUserDefined );
1351 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1352 0 : KvUserDefined );
1353 :
1354 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1355 0 : CT_CassiniSoldner );
1356 :
1357 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1358 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1359 :
1360 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1361 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1362 :
1363 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1364 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1365 :
1366 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1367 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1368 : }
1369 :
1370 6 : else if( EQUAL(pszProjection,SRS_PT_EQUIDISTANT_CONIC) )
1371 : {
1372 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1373 0 : ModelTypeProjected);
1374 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1375 0 : KvUserDefined );
1376 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1377 0 : KvUserDefined );
1378 :
1379 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1380 0 : CT_EquidistantConic );
1381 :
1382 : GTIFKeySet(psGTIF, ProjStdParallel1GeoKey, TYPE_DOUBLE, 1,
1383 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1384 :
1385 : GTIFKeySet(psGTIF, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1,
1386 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
1387 :
1388 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1389 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1390 :
1391 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1392 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1393 :
1394 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1395 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1396 :
1397 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1398 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1399 : }
1400 :
1401 6 : else if( EQUAL(pszProjection,SRS_PT_POLYCONIC) )
1402 : {
1403 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1404 0 : ModelTypeProjected);
1405 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1406 0 : KvUserDefined );
1407 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1408 0 : KvUserDefined );
1409 :
1410 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1411 0 : CT_Polyconic );
1412 :
1413 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1414 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1415 :
1416 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1417 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1418 :
1419 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1420 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1421 :
1422 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1423 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1424 :
1425 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1426 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1427 : }
1428 :
1429 6 : else if( EQUAL(pszProjection,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
1430 : {
1431 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1432 1 : ModelTypeProjected);
1433 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1434 1 : KvUserDefined );
1435 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1436 1 : KvUserDefined );
1437 :
1438 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1439 1 : CT_AzimuthalEquidistant );
1440 :
1441 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1442 1 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1443 :
1444 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1445 1 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1446 :
1447 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1448 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1449 :
1450 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1451 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1452 : }
1453 :
1454 5 : else if( EQUAL(pszProjection,SRS_PT_MILLER_CYLINDRICAL) )
1455 : {
1456 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1457 0 : ModelTypeProjected);
1458 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1459 0 : KvUserDefined );
1460 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1461 0 : KvUserDefined );
1462 :
1463 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1464 0 : CT_MillerCylindrical );
1465 :
1466 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1467 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1468 :
1469 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1470 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1471 :
1472 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1473 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1474 :
1475 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1476 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1477 : }
1478 :
1479 5 : else if( EQUAL(pszProjection,SRS_PT_EQUIRECTANGULAR) )
1480 : {
1481 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1482 1 : ModelTypeProjected);
1483 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1484 1 : KvUserDefined );
1485 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1486 1 : KvUserDefined );
1487 :
1488 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1489 1 : CT_Equirectangular );
1490 :
1491 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1492 1 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1493 :
1494 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1495 1 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1496 :
1497 : GTIFKeySet(psGTIF, ProjStdParallel1GeoKey, TYPE_DOUBLE, 1,
1498 1 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1499 :
1500 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1501 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1502 :
1503 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1504 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1505 : }
1506 :
1507 4 : else if( EQUAL(pszProjection,SRS_PT_GNOMONIC) )
1508 : {
1509 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1510 0 : ModelTypeProjected);
1511 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1512 0 : KvUserDefined );
1513 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1514 0 : KvUserDefined );
1515 :
1516 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1517 0 : CT_Gnomonic );
1518 :
1519 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1520 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1521 :
1522 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1523 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1524 :
1525 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1526 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1527 :
1528 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1529 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1530 : }
1531 :
1532 4 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
1533 : {
1534 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1535 0 : ModelTypeProjected);
1536 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1537 0 : KvUserDefined );
1538 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1539 0 : KvUserDefined );
1540 :
1541 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1542 0 : CT_LambertAzimEqualArea );
1543 :
1544 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1545 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1546 :
1547 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1548 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1549 :
1550 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1551 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1552 :
1553 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1554 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1555 : }
1556 :
1557 4 : else if( EQUAL(pszProjection,SRS_PT_ORTHOGRAPHIC) )
1558 : {
1559 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1560 0 : ModelTypeProjected);
1561 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1562 0 : KvUserDefined );
1563 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1564 0 : KvUserDefined );
1565 :
1566 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1567 0 : CT_Orthographic );
1568 :
1569 : GTIFKeySet(psGTIF, ProjCenterLatGeoKey, TYPE_DOUBLE, 1,
1570 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1571 :
1572 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1573 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1574 :
1575 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1576 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1577 :
1578 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1579 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1580 : }
1581 :
1582 4 : else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
1583 : {
1584 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1585 0 : ModelTypeProjected);
1586 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1587 0 : KvUserDefined );
1588 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1589 0 : KvUserDefined );
1590 :
1591 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1592 0 : CT_NewZealandMapGrid );
1593 :
1594 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1595 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1596 :
1597 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1598 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1599 :
1600 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1601 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1602 :
1603 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1604 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1605 : }
1606 :
1607 4 : else if( EQUAL(pszProjection,SRS_PT_ROBINSON) )
1608 : {
1609 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1610 0 : ModelTypeProjected);
1611 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1612 0 : KvUserDefined );
1613 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1614 0 : KvUserDefined );
1615 :
1616 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1617 0 : CT_Robinson );
1618 :
1619 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1620 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1621 :
1622 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1623 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1624 :
1625 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1626 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1627 : }
1628 :
1629 4 : else if( EQUAL(pszProjection,SRS_PT_SINUSOIDAL) )
1630 : {
1631 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1632 1 : ModelTypeProjected);
1633 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1634 1 : KvUserDefined );
1635 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1636 1 : KvUserDefined );
1637 :
1638 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1639 1 : CT_Sinusoidal );
1640 :
1641 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1642 1 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1643 :
1644 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1645 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1646 :
1647 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1648 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1649 : }
1650 :
1651 3 : else if( EQUAL(pszProjection,SRS_PT_VANDERGRINTEN) )
1652 : {
1653 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1654 1 : ModelTypeProjected);
1655 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1656 1 : KvUserDefined );
1657 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1658 1 : KvUserDefined );
1659 :
1660 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1661 1 : CT_VanDerGrinten );
1662 :
1663 : GTIFKeySet(psGTIF, ProjCenterLongGeoKey, TYPE_DOUBLE, 1,
1664 1 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1665 :
1666 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1667 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1668 :
1669 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1670 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1671 : }
1672 :
1673 2 : else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
1674 : {
1675 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1676 0 : ModelTypeProjected);
1677 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1678 0 : KvUserDefined );
1679 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1680 0 : KvUserDefined );
1681 :
1682 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1683 0 : CT_AlbersEqualArea );
1684 :
1685 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1686 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1687 :
1688 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1689 0 : poSRS->GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1690 :
1691 : GTIFKeySet(psGTIF, ProjStdParallel1GeoKey, TYPE_DOUBLE, 1,
1692 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1693 :
1694 : GTIFKeySet(psGTIF, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1,
1695 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
1696 :
1697 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1698 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1699 :
1700 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1701 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1702 : }
1703 :
1704 2 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
1705 : {
1706 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1707 1 : ModelTypeProjected);
1708 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1709 1 : KvUserDefined );
1710 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1711 1 : KvUserDefined );
1712 :
1713 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1714 1 : CT_LambertConfConic_2SP );
1715 :
1716 : GTIFKeySet(psGTIF, ProjFalseOriginLatGeoKey, TYPE_DOUBLE, 1,
1717 1 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1718 :
1719 : GTIFKeySet(psGTIF, ProjFalseOriginLongGeoKey, TYPE_DOUBLE, 1,
1720 1 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1721 :
1722 : GTIFKeySet(psGTIF, ProjStdParallel1GeoKey, TYPE_DOUBLE, 1,
1723 1 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1724 :
1725 : GTIFKeySet(psGTIF, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1,
1726 1 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
1727 :
1728 : GTIFKeySet(psGTIF, ProjFalseOriginEastingGeoKey, TYPE_DOUBLE, 1,
1729 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1730 :
1731 : GTIFKeySet(psGTIF, ProjFalseOriginNorthingGeoKey, TYPE_DOUBLE, 1,
1732 1 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1733 : }
1734 :
1735 1 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP) )
1736 : {
1737 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1738 0 : ModelTypeProjected);
1739 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1740 0 : KvUserDefined );
1741 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1742 0 : KvUserDefined );
1743 :
1744 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1745 0 : CT_LambertConfConic_1SP );
1746 :
1747 : GTIFKeySet(psGTIF, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
1748 0 : poSRS->GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1749 :
1750 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1751 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1752 :
1753 : GTIFKeySet(psGTIF, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
1754 0 : poSRS->GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) );
1755 :
1756 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1757 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1758 :
1759 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1760 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1761 : }
1762 :
1763 1 : else if( EQUAL(pszProjection,SRS_PT_CYLINDRICAL_EQUAL_AREA) )
1764 : {
1765 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1766 0 : ModelTypeProjected);
1767 : GTIFKeySet(psGTIF, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
1768 0 : KvUserDefined );
1769 : GTIFKeySet(psGTIF, ProjectionGeoKey, TYPE_SHORT, 1,
1770 0 : KvUserDefined );
1771 :
1772 : GTIFKeySet(psGTIF, ProjCoordTransGeoKey, TYPE_SHORT, 1,
1773 0 : CT_CylindricalEqualArea );
1774 :
1775 : GTIFKeySet(psGTIF, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
1776 0 : poSRS->GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1777 :
1778 : GTIFKeySet(psGTIF, ProjStdParallel1GeoKey, TYPE_DOUBLE, 1,
1779 0 : poSRS->GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1780 :
1781 : GTIFKeySet(psGTIF, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
1782 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 ) );
1783 :
1784 : GTIFKeySet(psGTIF, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
1785 0 : poSRS->GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 ) );
1786 : }
1787 :
1788 : else
1789 : {
1790 : /* Anyhing we can't map, we store as an ESRI PE string with a citation key */
1791 1 : char *pszPEString = NULL;
1792 1 : poSRS->morphToESRI();
1793 1 : poSRS->exportToWkt( &pszPEString );
1794 1 : int peStrLen = strlen(pszPEString);
1795 1 : if(peStrLen > 0)
1796 : {
1797 1 : char *outPeStr = new char[peStrLen + strlen("ESRI PE String = ")+1];
1798 1 : strcpy(outPeStr, "ESRI PE String = ");
1799 1 : strcat(outPeStr, pszPEString);
1800 1 : GTIFKeySet( psGTIF, PCSCitationGeoKey, TYPE_ASCII, 0, outPeStr );
1801 1 : peStrStored = TRUE;
1802 1 : delete[] outPeStr;
1803 : }
1804 1 : if(pszPEString)
1805 1 : CPLFree( pszPEString );
1806 : GTIFKeySet(psGTIF, GTModelTypeGeoKey, TYPE_SHORT, 1,
1807 1 : KvUserDefined );
1808 : }
1809 :
1810 : /* -------------------------------------------------------------------- */
1811 : /* Write linear units information. */
1812 : /* -------------------------------------------------------------------- */
1813 701 : if( !poSRS->IsGeographic() )
1814 : {
1815 : GTIFKeySet(psGTIF, ProjLinearUnitsGeoKey, TYPE_SHORT, 1,
1816 135 : nUOMLengthCode );
1817 135 : if( nUOMLengthCode == KvUserDefined )
1818 : GTIFKeySet( psGTIF, ProjLinearUnitSizeGeoKey, TYPE_DOUBLE, 1,
1819 0 : dfLinearUOM);
1820 :
1821 : /* if linear units name is available and user defined, store it as citation */
1822 135 : if(!peStrStored && nUOMLengthCode == KvUserDefined && pszLinearUOMName && strlen(pszLinearUOMName)>0)
1823 0 : SetLinearUnitCitation(psGTIF, pszLinearUOMName);
1824 : }
1825 :
1826 : /* -------------------------------------------------------------------- */
1827 : /* Write angular units. Always Degrees for now. */
1828 : /* Changed to support different angular units */
1829 : /* -------------------------------------------------------------------- */
1830 :
1831 701 : char* angUnitName = NULL;
1832 701 : double angUnitValue = poSRS->GetAngularUnits(&angUnitName);
1833 701 : if(EQUAL(angUnitName, "Degree"))
1834 : GTIFKeySet(psGTIF, GeogAngularUnitsGeoKey, TYPE_SHORT, 1,
1835 701 : Angular_Degree );
1836 0 : else if(angUnitName)
1837 : {
1838 : GTIFKeySet(psGTIF, GeogCitationGeoKey, TYPE_ASCII, 0,
1839 0 : angUnitName ); // it may be rewritten if the gcs is userdefined
1840 : GTIFKeySet(psGTIF, GeogAngularUnitSizeGeoKey, TYPE_DOUBLE, 1,
1841 0 : angUnitValue );
1842 : }
1843 :
1844 : /* -------------------------------------------------------------------- */
1845 : /* Try to write a citation from the main coordinate system */
1846 : /* name. */
1847 : /* -------------------------------------------------------------------- */
1848 701 : if( poSRS->GetRoot() != NULL
1849 : && poSRS->GetRoot()->GetChild(0) != NULL
1850 : && (poSRS->IsProjected() || poSRS->IsLocal()) )
1851 : {
1852 : GTIFKeySet( psGTIF, GTCitationGeoKey, TYPE_ASCII, 0,
1853 135 : poSRS->GetRoot()->GetChild(0)->GetValue() );
1854 : }
1855 :
1856 : /* -------------------------------------------------------------------- */
1857 : /* Try to write a GCS citation. */
1858 : /* -------------------------------------------------------------------- */
1859 701 : OGR_SRSNode *poGCS = poSRS->GetAttrNode( "GEOGCS" );
1860 :
1861 701 : if( poGCS != NULL && poGCS->GetChild(0) != NULL )
1862 : {
1863 : GTIFKeySet( psGTIF, GeogCitationGeoKey, TYPE_ASCII, 0,
1864 701 : poGCS->GetChild(0)->GetValue() );
1865 : }
1866 :
1867 : /* -------------------------------------------------------------------- */
1868 : /* Try to identify the GCS/datum, scanning the EPSG datum file for */
1869 : /* a match. */
1870 : /* -------------------------------------------------------------------- */
1871 701 : if( nPCS == KvUserDefined )
1872 : {
1873 573 : if( nGCS == KvUserDefined )
1874 : {
1875 274 : if( nDatum == Datum_North_American_Datum_1927 )
1876 0 : nGCS = GCS_NAD27;
1877 274 : else if( nDatum == Datum_North_American_Datum_1983 )
1878 0 : nGCS = GCS_NAD83;
1879 274 : else if( nDatum == Datum_WGS84 || nDatum == DatumE_WGS84 )
1880 265 : nGCS = GCS_WGS_84;
1881 : }
1882 :
1883 573 : if( nGCS != KvUserDefined )
1884 : {
1885 : GTIFKeySet( psGTIF, GeographicTypeGeoKey, TYPE_SHORT,
1886 564 : 1, nGCS );
1887 : }
1888 9 : else if( nDatum != KvUserDefined )
1889 : {
1890 : GTIFKeySet( psGTIF, GeographicTypeGeoKey, TYPE_SHORT, 1,
1891 2 : KvUserDefined );
1892 : GTIFKeySet( psGTIF, GeogGeodeticDatumGeoKey, TYPE_SHORT,
1893 2 : 1, nDatum );
1894 : }
1895 7 : else if( nSpheroid != KvUserDefined )
1896 : {
1897 : GTIFKeySet( psGTIF, GeographicTypeGeoKey, TYPE_SHORT, 1,
1898 0 : KvUserDefined );
1899 : GTIFKeySet( psGTIF, GeogGeodeticDatumGeoKey, TYPE_SHORT,
1900 0 : 1, KvUserDefined );
1901 : GTIFKeySet( psGTIF, GeogEllipsoidGeoKey, TYPE_SHORT, 1,
1902 0 : nSpheroid );
1903 : }
1904 7 : else if( dfSemiMajor != 0.0 )
1905 : {
1906 : GTIFKeySet( psGTIF, GeographicTypeGeoKey, TYPE_SHORT, 1,
1907 7 : KvUserDefined );
1908 : GTIFKeySet( psGTIF, GeogGeodeticDatumGeoKey, TYPE_SHORT,
1909 7 : 1, KvUserDefined );
1910 : GTIFKeySet( psGTIF, GeogEllipsoidGeoKey, TYPE_SHORT, 1,
1911 7 : KvUserDefined );
1912 : GTIFKeySet( psGTIF, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1,
1913 7 : dfSemiMajor );
1914 7 : if( dfInvFlattening == 0.0 )
1915 : GTIFKeySet( psGTIF, GeogSemiMinorAxisGeoKey, TYPE_DOUBLE, 1,
1916 1 : dfSemiMajor );
1917 : else
1918 : GTIFKeySet( psGTIF, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1,
1919 6 : dfInvFlattening );
1920 : }
1921 0 : else if( poSRS->GetAttrValue("DATUM") != NULL
1922 : && strstr(poSRS->GetAttrValue("DATUM"),"unknown") == NULL
1923 : && strstr(poSRS->GetAttrValue("DATUM"),"unnamed") == NULL )
1924 :
1925 : {
1926 : CPLError( CE_Warning, CPLE_AppDefined,
1927 : "Couldn't translate `%s' to a GeoTIFF datum.\n",
1928 0 : poSRS->GetAttrValue("DATUM") );
1929 : }
1930 :
1931 : /* Always set InvFlattening if it is avaliable. */
1932 : /* So that it doesn'tneed to calculate from SemiMinor */
1933 573 : if( dfInvFlattening != 0.0 )
1934 : GTIFKeySet( psGTIF, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1,
1935 570 : dfInvFlattening );
1936 : /* Always set SemiMajor to keep the precision and in case of editing */
1937 573 : if( dfSemiMajor != 0.0 )
1938 : GTIFKeySet( psGTIF, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1,
1939 571 : dfSemiMajor );
1940 :
1941 573 : if( nGCS == KvUserDefined )
1942 9 : SetGeogCSCitation(psGTIF, poSRS, angUnitName, nDatum, nSpheroid);
1943 : }
1944 :
1945 : /* -------------------------------------------------------------------- */
1946 : /* Do we have vertical datum information to set? */
1947 : /* -------------------------------------------------------------------- */
1948 701 : if( poSRS->GetAttrValue( "COMPD_CS|VERT_CS" ) != NULL )
1949 : {
1950 : const char *pszValue;
1951 :
1952 : GTIFKeySet( psGTIF, VerticalCitationGeoKey, TYPE_ASCII, 0,
1953 0 : poSRS->GetAttrValue( "COMPD_CS|VERT_CS" ) );
1954 :
1955 0 : pszValue = poSRS->GetAuthorityCode( "COMPD_CS|VERT_CS" );
1956 0 : if( pszValue && atoi(pszValue) )
1957 : GTIFKeySet( psGTIF, VerticalCSTypeGeoKey, TYPE_SHORT, 1,
1958 0 : atoi(pszValue) );
1959 :
1960 0 : pszValue = poSRS->GetAuthorityCode( "COMPD_CS|VERT_CS|VERT_DATUM" );
1961 0 : if( pszValue && atoi(pszValue) )
1962 : GTIFKeySet( psGTIF, VerticalDatumGeoKey, TYPE_SHORT, 1,
1963 0 : atoi(pszValue) );
1964 :
1965 0 : pszValue = poSRS->GetAuthorityCode( "COMPD_CS|VERT_CS|UNIT" );
1966 0 : if( pszValue && atoi(pszValue) )
1967 : GTIFKeySet( psGTIF, VerticalUnitsGeoKey, TYPE_SHORT, 1,
1968 0 : atoi(pszValue) );
1969 : }
1970 :
1971 : /* -------------------------------------------------------------------- */
1972 : /* Cleanup */
1973 : /* -------------------------------------------------------------------- */
1974 701 : delete poSRS;
1975 701 : return TRUE;
1976 : }
1977 :
1978 : /************************************************************************/
1979 : /* GTIFWktFromMemBuf() */
1980 : /************************************************************************/
1981 :
1982 : CPLErr GTIFWktFromMemBuf( int nSize, unsigned char *pabyBuffer,
1983 : char **ppszWKT, double *padfGeoTransform,
1984 15 : int *pnGCPCount, GDAL_GCP **ppasGCPList )
1985 :
1986 : {
1987 : TIFF *hTIFF;
1988 : GTIF *hGTIF;
1989 : GTIFDefn sGTIFDefn;
1990 : char szFilename[100];
1991 :
1992 : sprintf( szFilename, "/vsimem/wkt_from_mem_buf_%ld.tif",
1993 15 : (long) CPLGetPID() );
1994 :
1995 : /* -------------------------------------------------------------------- */
1996 : /* Create a memory file from the buffer. */
1997 : /* -------------------------------------------------------------------- */
1998 15 : FILE *fp = VSIFileFromMemBuffer( szFilename, pabyBuffer, nSize, FALSE );
1999 15 : if( fp == NULL )
2000 0 : return CE_Failure;
2001 15 : VSIFCloseL( fp );
2002 :
2003 : /* -------------------------------------------------------------------- */
2004 : /* Initialize access to the memory geotiff structure. */
2005 : /* -------------------------------------------------------------------- */
2006 15 : hTIFF = VSI_TIFFOpen( szFilename, "r" );
2007 :
2008 15 : if( hTIFF == NULL )
2009 : {
2010 : CPLError( CE_Failure, CPLE_AppDefined,
2011 0 : "TIFF/GeoTIFF structure is corrupt." );
2012 0 : VSIUnlink( szFilename );
2013 0 : return CE_Failure;
2014 : }
2015 :
2016 : /* -------------------------------------------------------------------- */
2017 : /* Get the projection definition. */
2018 : /* -------------------------------------------------------------------- */
2019 15 : hGTIF = GTIFNew(hTIFF);
2020 :
2021 15 : if( hGTIF != NULL && GTIFGetDefn( hGTIF, &sGTIFDefn ) )
2022 15 : *ppszWKT = GTIFGetOGISDefn( hGTIF, &sGTIFDefn );
2023 : else
2024 0 : *ppszWKT = NULL;
2025 :
2026 15 : if( hGTIF )
2027 15 : GTIFFree( hGTIF );
2028 :
2029 : /* -------------------------------------------------------------------- */
2030 : /* Get geotransform or tiepoints. */
2031 : /* -------------------------------------------------------------------- */
2032 : double *padfTiePoints, *padfScale, *padfMatrix;
2033 : int16 nCount;
2034 :
2035 15 : padfGeoTransform[0] = 0.0;
2036 15 : padfGeoTransform[1] = 1.0;
2037 15 : padfGeoTransform[2] = 0.0;
2038 15 : padfGeoTransform[3] = 0.0;
2039 15 : padfGeoTransform[4] = 0.0;
2040 15 : padfGeoTransform[5] = 1.0;
2041 :
2042 15 : *pnGCPCount = 0;
2043 15 : *ppasGCPList = NULL;
2044 :
2045 15 : if( TIFFGetField(hTIFF,TIFFTAG_GEOPIXELSCALE,&nCount,&padfScale )
2046 : && nCount >= 2 )
2047 : {
2048 11 : padfGeoTransform[1] = padfScale[0];
2049 11 : padfGeoTransform[5] = - ABS(padfScale[1]);
2050 :
2051 11 : if( TIFFGetField(hTIFF,TIFFTAG_GEOTIEPOINTS,&nCount,&padfTiePoints )
2052 : && nCount >= 6 )
2053 : {
2054 : padfGeoTransform[0] =
2055 11 : padfTiePoints[3] - padfTiePoints[0] * padfGeoTransform[1];
2056 : padfGeoTransform[3] =
2057 11 : padfTiePoints[4] - padfTiePoints[1] * padfGeoTransform[5];
2058 : }
2059 : }
2060 :
2061 4 : else if( TIFFGetField(hTIFF,TIFFTAG_GEOTIEPOINTS,&nCount,&padfTiePoints )
2062 : && nCount >= 6 )
2063 : {
2064 4 : *pnGCPCount = nCount / 6;
2065 4 : *ppasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),*pnGCPCount);
2066 :
2067 64 : for( int iGCP = 0; iGCP < *pnGCPCount; iGCP++ )
2068 : {
2069 : char szID[32];
2070 60 : GDAL_GCP *psGCP = *ppasGCPList + iGCP;
2071 :
2072 60 : sprintf( szID, "%d", iGCP+1 );
2073 60 : psGCP->pszId = CPLStrdup( szID );
2074 60 : psGCP->pszInfo = CPLStrdup("");
2075 60 : psGCP->dfGCPPixel = padfTiePoints[iGCP*6+0];
2076 60 : psGCP->dfGCPLine = padfTiePoints[iGCP*6+1];
2077 60 : psGCP->dfGCPX = padfTiePoints[iGCP*6+3];
2078 60 : psGCP->dfGCPY = padfTiePoints[iGCP*6+4];
2079 60 : psGCP->dfGCPZ = padfTiePoints[iGCP*6+5];
2080 : }
2081 : }
2082 :
2083 0 : else if( TIFFGetField(hTIFF,TIFFTAG_GEOTRANSMATRIX,&nCount,&padfMatrix )
2084 : && nCount == 16 )
2085 : {
2086 0 : padfGeoTransform[0] = padfMatrix[3];
2087 0 : padfGeoTransform[1] = padfMatrix[0];
2088 0 : padfGeoTransform[2] = padfMatrix[1];
2089 0 : padfGeoTransform[3] = padfMatrix[7];
2090 0 : padfGeoTransform[4] = padfMatrix[4];
2091 0 : padfGeoTransform[5] = padfMatrix[5];
2092 : }
2093 :
2094 : /* -------------------------------------------------------------------- */
2095 : /* Cleanup. */
2096 : /* -------------------------------------------------------------------- */
2097 15 : XTIFFClose( hTIFF );
2098 :
2099 15 : VSIUnlink( szFilename );
2100 :
2101 15 : if( *ppszWKT == NULL )
2102 0 : return CE_Failure;
2103 : else
2104 15 : return CE_None;
2105 : }
2106 :
2107 : /************************************************************************/
2108 : /* GTIFMemBufFromWkt() */
2109 : /************************************************************************/
2110 :
2111 : CPLErr GTIFMemBufFromWkt( const char *pszWKT, const double *padfGeoTransform,
2112 : int nGCPCount, const GDAL_GCP *pasGCPList,
2113 0 : int *pnSize, unsigned char **ppabyBuffer )
2114 :
2115 : {
2116 : TIFF *hTIFF;
2117 : GTIF *hGTIF;
2118 : char szFilename[100];
2119 :
2120 : sprintf( szFilename, "/vsimem/wkt_from_mem_buf_%ld.tif",
2121 0 : (long) CPLGetPID() );
2122 :
2123 : /* -------------------------------------------------------------------- */
2124 : /* Initialize access to the memory geotiff structure. */
2125 : /* -------------------------------------------------------------------- */
2126 0 : hTIFF = VSI_TIFFOpen( szFilename, "w" );
2127 :
2128 0 : if( hTIFF == NULL )
2129 : {
2130 : CPLError( CE_Failure, CPLE_AppDefined,
2131 0 : "TIFF/GeoTIFF structure is corrupt." );
2132 0 : return CE_Failure;
2133 : }
2134 :
2135 : /* -------------------------------------------------------------------- */
2136 : /* Write some minimal set of image parameters. */
2137 : /* -------------------------------------------------------------------- */
2138 0 : TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, 1 );
2139 0 : TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, 1 );
2140 0 : TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, 8 );
2141 0 : TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, 1 );
2142 0 : TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, 1 );
2143 0 : TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
2144 0 : TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
2145 :
2146 : /* -------------------------------------------------------------------- */
2147 : /* Get the projection definition. */
2148 : /* -------------------------------------------------------------------- */
2149 :
2150 0 : if( pszWKT != NULL )
2151 : {
2152 0 : hGTIF = GTIFNew(hTIFF);
2153 0 : GTIFSetFromOGISDefn( hGTIF, pszWKT );
2154 0 : GTIFWriteKeys( hGTIF );
2155 0 : GTIFFree( hGTIF );
2156 : }
2157 :
2158 : /* -------------------------------------------------------------------- */
2159 : /* Set the geotransform, or GCPs. */
2160 : /* -------------------------------------------------------------------- */
2161 0 : if( padfGeoTransform[0] != 0.0 || padfGeoTransform[1] != 1.0
2162 : || padfGeoTransform[2] != 0.0 || padfGeoTransform[3] != 0.0
2163 : || padfGeoTransform[4] != 0.0 || ABS(padfGeoTransform[5]) != 1.0 )
2164 : {
2165 :
2166 0 : if( padfGeoTransform[2] == 0.0 && padfGeoTransform[4] == 0.0 )
2167 : {
2168 : double adfPixelScale[3], adfTiePoints[6];
2169 :
2170 0 : adfPixelScale[0] = padfGeoTransform[1];
2171 0 : adfPixelScale[1] = fabs(padfGeoTransform[5]);
2172 0 : adfPixelScale[2] = 0.0;
2173 :
2174 0 : TIFFSetField( hTIFF, TIFFTAG_GEOPIXELSCALE, 3, adfPixelScale );
2175 :
2176 0 : adfTiePoints[0] = 0.0;
2177 0 : adfTiePoints[1] = 0.0;
2178 0 : adfTiePoints[2] = 0.0;
2179 0 : adfTiePoints[3] = padfGeoTransform[0];
2180 0 : adfTiePoints[4] = padfGeoTransform[3];
2181 0 : adfTiePoints[5] = 0.0;
2182 :
2183 0 : TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 6, adfTiePoints );
2184 : }
2185 : else
2186 : {
2187 : double adfMatrix[16];
2188 :
2189 0 : memset(adfMatrix,0,sizeof(double) * 16);
2190 :
2191 0 : adfMatrix[0] = padfGeoTransform[1];
2192 0 : adfMatrix[1] = padfGeoTransform[2];
2193 0 : adfMatrix[3] = padfGeoTransform[0];
2194 0 : adfMatrix[4] = padfGeoTransform[4];
2195 0 : adfMatrix[5] = padfGeoTransform[5];
2196 0 : adfMatrix[7] = padfGeoTransform[3];
2197 0 : adfMatrix[15] = 1.0;
2198 :
2199 0 : TIFFSetField( hTIFF, TIFFTAG_GEOTRANSMATRIX, 16, adfMatrix );
2200 : }
2201 : }
2202 :
2203 : /* -------------------------------------------------------------------- */
2204 : /* Otherwise write tiepoints if they are available. */
2205 : /* -------------------------------------------------------------------- */
2206 0 : else if( nGCPCount > 0 )
2207 : {
2208 : double *padfTiePoints;
2209 :
2210 0 : padfTiePoints = (double *) CPLMalloc(6*sizeof(double)*nGCPCount);
2211 :
2212 0 : for( int iGCP = 0; iGCP < nGCPCount; iGCP++ )
2213 : {
2214 :
2215 0 : padfTiePoints[iGCP*6+0] = pasGCPList[iGCP].dfGCPPixel;
2216 0 : padfTiePoints[iGCP*6+1] = pasGCPList[iGCP].dfGCPLine;
2217 0 : padfTiePoints[iGCP*6+2] = 0;
2218 0 : padfTiePoints[iGCP*6+3] = pasGCPList[iGCP].dfGCPX;
2219 0 : padfTiePoints[iGCP*6+4] = pasGCPList[iGCP].dfGCPY;
2220 0 : padfTiePoints[iGCP*6+5] = pasGCPList[iGCP].dfGCPZ;
2221 : }
2222 :
2223 0 : TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 6*nGCPCount, padfTiePoints);
2224 0 : CPLFree( padfTiePoints );
2225 : }
2226 :
2227 : /* -------------------------------------------------------------------- */
2228 : /* Cleanup and return the created memory buffer. */
2229 : /* -------------------------------------------------------------------- */
2230 0 : GByte bySmallImage = 0;
2231 :
2232 0 : TIFFWriteEncodedStrip( hTIFF, 0, (char *) &bySmallImage, 1 );
2233 0 : TIFFWriteCheck( hTIFF, TIFFIsTiled(hTIFF), "GTIFMemBufFromWkt");
2234 0 : TIFFWriteDirectory( hTIFF );
2235 :
2236 0 : XTIFFClose( hTIFF );
2237 :
2238 : /* -------------------------------------------------------------------- */
2239 : /* Read back from the memory buffer. It would be preferrable */
2240 : /* to be able to "steal" the memory buffer, but there isn't */
2241 : /* currently any support for this. */
2242 : /* -------------------------------------------------------------------- */
2243 : GUIntBig nBigLength;
2244 :
2245 0 : *ppabyBuffer = VSIGetMemFileBuffer( szFilename, &nBigLength, TRUE );
2246 0 : *pnSize = (int) nBigLength;
2247 :
2248 0 : return CE_None;
2249 : }
2250 :
|