1 : /******************************************************************************
2 : * $Id: hfadataset.cpp 24323 2012-04-27 05:45:18Z warmerdam $
3 : *
4 : * Name: hfadataset.cpp
5 : * Project: Erdas Imagine Driver
6 : * Purpose: Main driver for Erdas Imagine format.
7 : * Author: Frank Warmerdam, warmerdam@pobox.com
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 1999, Frank Warmerdam
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "gdal_pam.h"
32 : #include "gdal_rat.h"
33 : #include "hfa_p.h"
34 : #include "ogr_spatialref.h"
35 :
36 : CPL_CVSID("$Id: hfadataset.cpp 24323 2012-04-27 05:45:18Z warmerdam $");
37 :
38 : CPL_C_START
39 : void GDALRegister_HFA(void);
40 : CPL_C_END
41 :
42 : #ifndef PI
43 : # define PI 3.14159265358979323846
44 : #endif
45 :
46 : #ifndef R2D
47 : # define R2D (180/PI)
48 : #endif
49 : #ifndef D2R
50 : # define D2R (PI/180)
51 : #endif
52 :
53 : int WritePeStringIfNeeded(OGRSpatialReference* poSRS, HFAHandle hHFA);
54 : void ClearSR(HFAHandle hHFA);
55 :
56 : static const char *apszDatumMap[] = {
57 : /* Imagine name, WKT name */
58 : "NAD27", "North_American_Datum_1927",
59 : "NAD83", "North_American_Datum_1983",
60 : "WGS 84", "WGS_1984",
61 : "WGS 1972", "WGS_1972",
62 : "GDA94", "Geocentric_Datum_of_Australia_1994",
63 : NULL, NULL
64 : };
65 :
66 : static const char *apszUnitMap[] = {
67 : "meters", "1.0",
68 : "meter", "1.0",
69 : "m", "1.0",
70 : "centimeters", "0.01",
71 : "centimeter", "0.01",
72 : "cm", "0.01",
73 : "millimeters", "0.001",
74 : "millimeter", "0.001",
75 : "mm", "0.001",
76 : "kilometers", "1000.0",
77 : "kilometer", "1000.0",
78 : "km", "1000.0",
79 : "us_survey_feet", "0.3048006096012192",
80 : "us_survey_foot", "0.3048006096012192",
81 : "feet", "0.3048006096012192",
82 : "foot", "0.3048006096012192",
83 : "ft", "0.3048006096012192",
84 : "international_feet", "0.3048",
85 : "international_foot", "0.3048",
86 : "inches", "0.0254000508001",
87 : "inch", "0.0254000508001",
88 : "in", "0.0254000508001",
89 : "yards", "0.9144",
90 : "yard", "0.9144",
91 : "yd", "0.9144",
92 : "miles", "1304.544",
93 : "mile", "1304.544",
94 : "mi", "1304.544",
95 : "modified_american_feet", "0.3048122530",
96 : "modified_american_foot", "0.3048122530",
97 : "clarke_feet", "0.3047972651",
98 : "clarke_foot", "0.3047972651",
99 : "indian_feet", "0.3047995142",
100 : "indian_foot", "0.3047995142",
101 : NULL, NULL
102 : };
103 :
104 :
105 : /* ==================================================================== */
106 : /* Table relating USGS and ESRI state plane zones. */
107 : /* ==================================================================== */
108 : static const int anUsgsEsriZones[] =
109 : {
110 : 101, 3101,
111 : 102, 3126,
112 : 201, 3151,
113 : 202, 3176,
114 : 203, 3201,
115 : 301, 3226,
116 : 302, 3251,
117 : 401, 3276,
118 : 402, 3301,
119 : 403, 3326,
120 : 404, 3351,
121 : 405, 3376,
122 : 406, 3401,
123 : 407, 3426,
124 : 501, 3451,
125 : 502, 3476,
126 : 503, 3501,
127 : 600, 3526,
128 : 700, 3551,
129 : 901, 3601,
130 : 902, 3626,
131 : 903, 3576,
132 : 1001, 3651,
133 : 1002, 3676,
134 : 1101, 3701,
135 : 1102, 3726,
136 : 1103, 3751,
137 : 1201, 3776,
138 : 1202, 3801,
139 : 1301, 3826,
140 : 1302, 3851,
141 : 1401, 3876,
142 : 1402, 3901,
143 : 1501, 3926,
144 : 1502, 3951,
145 : 1601, 3976,
146 : 1602, 4001,
147 : 1701, 4026,
148 : 1702, 4051,
149 : 1703, 6426,
150 : 1801, 4076,
151 : 1802, 4101,
152 : 1900, 4126,
153 : 2001, 4151,
154 : 2002, 4176,
155 : 2101, 4201,
156 : 2102, 4226,
157 : 2103, 4251,
158 : 2111, 6351,
159 : 2112, 6376,
160 : 2113, 6401,
161 : 2201, 4276,
162 : 2202, 4301,
163 : 2203, 4326,
164 : 2301, 4351,
165 : 2302, 4376,
166 : 2401, 4401,
167 : 2402, 4426,
168 : 2403, 4451,
169 : 2500, 0,
170 : 2501, 4476,
171 : 2502, 4501,
172 : 2503, 4526,
173 : 2600, 0,
174 : 2601, 4551,
175 : 2602, 4576,
176 : 2701, 4601,
177 : 2702, 4626,
178 : 2703, 4651,
179 : 2800, 4676,
180 : 2900, 4701,
181 : 3001, 4726,
182 : 3002, 4751,
183 : 3003, 4776,
184 : 3101, 4801,
185 : 3102, 4826,
186 : 3103, 4851,
187 : 3104, 4876,
188 : 3200, 4901,
189 : 3301, 4926,
190 : 3302, 4951,
191 : 3401, 4976,
192 : 3402, 5001,
193 : 3501, 5026,
194 : 3502, 5051,
195 : 3601, 5076,
196 : 3602, 5101,
197 : 3701, 5126,
198 : 3702, 5151,
199 : 3800, 5176,
200 : 3900, 0,
201 : 3901, 5201,
202 : 3902, 5226,
203 : 4001, 5251,
204 : 4002, 5276,
205 : 4100, 5301,
206 : 4201, 5326,
207 : 4202, 5351,
208 : 4203, 5376,
209 : 4204, 5401,
210 : 4205, 5426,
211 : 4301, 5451,
212 : 4302, 5476,
213 : 4303, 5501,
214 : 4400, 5526,
215 : 4501, 5551,
216 : 4502, 5576,
217 : 4601, 5601,
218 : 4602, 5626,
219 : 4701, 5651,
220 : 4702, 5676,
221 : 4801, 5701,
222 : 4802, 5726,
223 : 4803, 5751,
224 : 4901, 5776,
225 : 4902, 5801,
226 : 4903, 5826,
227 : 4904, 5851,
228 : 5001, 6101,
229 : 5002, 6126,
230 : 5003, 6151,
231 : 5004, 6176,
232 : 5005, 6201,
233 : 5006, 6226,
234 : 5007, 6251,
235 : 5008, 6276,
236 : 5009, 6301,
237 : 5010, 6326,
238 : 5101, 5876,
239 : 5102, 5901,
240 : 5103, 5926,
241 : 5104, 5951,
242 : 5105, 5976,
243 : 5201, 6001,
244 : 5200, 6026,
245 : 5200, 6076,
246 : 5201, 6051,
247 : 5202, 6051,
248 : 5300, 0,
249 : 5400, 0
250 : };
251 :
252 :
253 : /************************************************************************/
254 : /* ==================================================================== */
255 : /* HFADataset */
256 : /* ==================================================================== */
257 : /************************************************************************/
258 :
259 : class HFARasterBand;
260 :
261 : class CPL_DLL HFADataset : public GDALPamDataset
262 : {
263 : friend class HFARasterBand;
264 :
265 : HFAHandle hHFA;
266 :
267 : int bMetadataDirty;
268 :
269 : int bGeoDirty;
270 : double adfGeoTransform[6];
271 : char *pszProjection;
272 :
273 : int bIgnoreUTM;
274 :
275 : CPLErr ReadProjection();
276 : CPLErr WriteProjection();
277 : int bForceToPEString;
278 :
279 : int nGCPCount;
280 : GDAL_GCP asGCPList[36];
281 :
282 : void UseXFormStack( int nStepCount,
283 : Efga_Polynomial *pasPolyListForward,
284 : Efga_Polynomial *pasPolyListReverse );
285 :
286 : protected:
287 : virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
288 : void *, int, int, GDALDataType,
289 : int, int *, int, int, int );
290 :
291 : public:
292 : HFADataset();
293 : ~HFADataset();
294 :
295 : static int Identify( GDALOpenInfo * );
296 : static CPLErr Rename( const char *pszNewName, const char *pszOldName);
297 : static CPLErr CopyFiles( const char *pszNewName, const char *pszOldName);
298 : static GDALDataset *Open( GDALOpenInfo * );
299 : static GDALDataset *Create( const char * pszFilename,
300 : int nXSize, int nYSize, int nBands,
301 : GDALDataType eType, char ** papszParmList );
302 : static GDALDataset *CreateCopy( const char * pszFilename,
303 : GDALDataset *poSrcDS,
304 : int bStrict, char ** papszOptions,
305 : GDALProgressFunc pfnProgress,
306 : void * pProgressData );
307 : static CPLErr Delete( const char *pszFilename );
308 :
309 : virtual char **GetFileList(void);
310 :
311 : virtual const char *GetProjectionRef(void);
312 : virtual CPLErr SetProjection( const char * );
313 :
314 : virtual CPLErr GetGeoTransform( double * );
315 : virtual CPLErr SetGeoTransform( double * );
316 :
317 : virtual int GetGCPCount();
318 : virtual const char *GetGCPProjection();
319 : virtual const GDAL_GCP *GetGCPs();
320 :
321 : virtual CPLErr SetMetadata( char **, const char * = "" );
322 : virtual CPLErr SetMetadataItem( const char *, const char *, const char * = "" );
323 :
324 : virtual void FlushCache( void );
325 : virtual CPLErr IBuildOverviews( const char *pszResampling,
326 : int nOverviews, int *panOverviewList,
327 : int nListBands, int *panBandList,
328 : GDALProgressFunc pfnProgress,
329 : void * pProgressData );
330 : };
331 :
332 : /************************************************************************/
333 : /* ==================================================================== */
334 : /* HFARasterBand */
335 : /* ==================================================================== */
336 : /************************************************************************/
337 :
338 : class HFARasterBand : public GDALPamRasterBand
339 : {
340 : friend class HFADataset;
341 :
342 : GDALColorTable *poCT;
343 :
344 : int nHFADataType;
345 :
346 : int nOverviews;
347 : int nThisOverview;
348 : HFARasterBand **papoOverviewBands;
349 :
350 : CPLErr CleanOverviews();
351 :
352 : HFAHandle hHFA;
353 :
354 : int bMetadataDirty;
355 :
356 : GDALRasterAttributeTable *poDefaultRAT;
357 :
358 : void ReadAuxMetadata();
359 : void ReadHistogramMetadata();
360 : void EstablishOverviews();
361 : CPLErr WriteNamedRAT( const char *pszName, const GDALRasterAttributeTable *poRAT );
362 :
363 :
364 : GDALRasterAttributeTable* ReadNamedRAT( const char *pszName );
365 :
366 : public:
367 :
368 : HFARasterBand( HFADataset *, int, int );
369 : virtual ~HFARasterBand();
370 :
371 : virtual CPLErr IReadBlock( int, int, void * );
372 : virtual CPLErr IWriteBlock( int, int, void * );
373 :
374 : virtual const char *GetDescription() const;
375 : virtual void SetDescription( const char * );
376 :
377 : virtual GDALColorInterp GetColorInterpretation();
378 : virtual GDALColorTable *GetColorTable();
379 : virtual CPLErr SetColorTable( GDALColorTable * );
380 : virtual int GetOverviewCount();
381 : virtual GDALRasterBand *GetOverview( int );
382 :
383 : virtual double GetMinimum( int *pbSuccess = NULL );
384 : virtual double GetMaximum(int *pbSuccess = NULL );
385 : virtual double GetNoDataValue( int *pbSuccess = NULL );
386 : virtual CPLErr SetNoDataValue( double dfValue );
387 :
388 : virtual CPLErr SetMetadata( char **, const char * = "" );
389 : virtual CPLErr SetMetadataItem( const char *, const char *, const char * = "" );
390 : virtual CPLErr BuildOverviews( const char *, int, int *,
391 : GDALProgressFunc, void * );
392 :
393 : virtual CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
394 : int *pnBuckets, int ** ppanHistogram,
395 : int bForce,
396 : GDALProgressFunc, void *pProgressData);
397 :
398 : virtual const GDALRasterAttributeTable *GetDefaultRAT();
399 : virtual CPLErr SetDefaultRAT( const GDALRasterAttributeTable * );
400 : };
401 :
402 : /************************************************************************/
403 : /* HFARasterBand() */
404 : /************************************************************************/
405 :
406 974 : HFARasterBand::HFARasterBand( HFADataset *poDS, int nBand, int iOverview )
407 :
408 : {
409 : int nCompression;
410 :
411 974 : if( iOverview == -1 )
412 904 : this->poDS = poDS;
413 : else
414 70 : this->poDS = NULL;
415 :
416 974 : this->hHFA = poDS->hHFA;
417 974 : this->nBand = nBand;
418 974 : this->poCT = NULL;
419 974 : this->nThisOverview = iOverview;
420 974 : this->papoOverviewBands = NULL;
421 974 : this->bMetadataDirty = FALSE;
422 974 : this->poDefaultRAT = NULL;
423 974 : this->nOverviews = -1;
424 :
425 : HFAGetBandInfo( hHFA, nBand, &nHFADataType,
426 974 : &nBlockXSize, &nBlockYSize, &nCompression );
427 :
428 : /* -------------------------------------------------------------------- */
429 : /* If this is an overview, we need to fetch the actual size, */
430 : /* and block size. */
431 : /* -------------------------------------------------------------------- */
432 974 : if( iOverview > -1 )
433 : {
434 : int nHFADataTypeO;
435 :
436 70 : nOverviews = 0;
437 70 : if (HFAGetOverviewInfo( hHFA, nBand, iOverview,
438 : &nRasterXSize, &nRasterYSize,
439 : &nBlockXSize, &nBlockYSize, &nHFADataTypeO ) != CE_None)
440 : {
441 0 : nRasterXSize = nRasterYSize = 0;
442 0 : return;
443 : }
444 :
445 : /* -------------------------------------------------------------------- */
446 : /* If we are an 8bit overview of a 1bit layer, we need to mark */
447 : /* ourselves as being "resample: average_bit2grayscale". */
448 : /* -------------------------------------------------------------------- */
449 70 : if( nHFADataType == EPT_u1 && nHFADataTypeO == EPT_u8 )
450 : {
451 : GDALMajorObject::SetMetadataItem( "RESAMPLING",
452 10 : "AVERAGE_BIT2GRAYSCALE" );
453 10 : GDALMajorObject::SetMetadataItem( "NBITS", "8" );
454 10 : nHFADataType = nHFADataTypeO;
455 : }
456 : }
457 :
458 : /* -------------------------------------------------------------------- */
459 : /* Set some other information. */
460 : /* -------------------------------------------------------------------- */
461 974 : if( nCompression != 0 )
462 : GDALMajorObject::SetMetadataItem( "COMPRESSION", "RLE",
463 126 : "IMAGE_STRUCTURE" );
464 :
465 974 : switch( nHFADataType )
466 : {
467 : case EPT_u1:
468 : case EPT_u2:
469 : case EPT_u4:
470 : case EPT_u8:
471 : case EPT_s8:
472 544 : eDataType = GDT_Byte;
473 544 : break;
474 :
475 : case EPT_u16:
476 66 : eDataType = GDT_UInt16;
477 66 : break;
478 :
479 : case EPT_s16:
480 44 : eDataType = GDT_Int16;
481 44 : break;
482 :
483 : case EPT_u32:
484 44 : eDataType = GDT_UInt32;
485 44 : break;
486 :
487 : case EPT_s32:
488 70 : eDataType = GDT_Int32;
489 70 : break;
490 :
491 : case EPT_f32:
492 60 : eDataType = GDT_Float32;
493 60 : break;
494 :
495 : case EPT_f64:
496 62 : eDataType = GDT_Float64;
497 62 : break;
498 :
499 : case EPT_c64:
500 42 : eDataType = GDT_CFloat32;
501 42 : break;
502 :
503 : case EPT_c128:
504 42 : eDataType = GDT_CFloat64;
505 42 : break;
506 :
507 : default:
508 0 : eDataType = GDT_Byte;
509 : /* notdef: this should really report an error, but this isn't
510 : so easy from within constructors. */
511 : CPLDebug( "GDAL", "Unsupported pixel type in HFARasterBand: %d.",
512 0 : (int) nHFADataType );
513 : break;
514 : }
515 :
516 974 : if( HFAGetDataTypeBits( nHFADataType ) < 8 )
517 : {
518 : GDALMajorObject::SetMetadataItem(
519 : "NBITS",
520 20 : CPLString().Printf( "%d", HFAGetDataTypeBits( nHFADataType ) ), "IMAGE_STRUCTURE" );
521 : }
522 :
523 974 : if( nHFADataType == EPT_s8 )
524 : {
525 : GDALMajorObject::SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE",
526 4 : "IMAGE_STRUCTURE" );
527 : }
528 :
529 : /* -------------------------------------------------------------------- */
530 : /* Collect color table if present. */
531 : /* -------------------------------------------------------------------- */
532 : double *padfRed, *padfGreen, *padfBlue, *padfAlpha, *padfBins;
533 : int nColors;
534 :
535 974 : if( iOverview == -1
536 : && HFAGetPCT( hHFA, nBand, &nColors,
537 : &padfRed, &padfGreen, &padfBlue, &padfAlpha,
538 : &padfBins ) == CE_None
539 : && nColors > 0 )
540 : {
541 14 : poCT = new GDALColorTable();
542 1426 : for( int iColor = 0; iColor < nColors; iColor++ )
543 : {
544 : GDALColorEntry sEntry;
545 :
546 : // The following mapping assigns "equal sized" section of
547 : // the [0...1] range to each possible output value and avoid
548 : // rounding issues for the "normal" values generated using n/255.
549 : // See bug #1732 for some discussion.
550 1412 : sEntry.c1 = MIN(255,(short) (padfRed[iColor] * 256));
551 1412 : sEntry.c2 = MIN(255,(short) (padfGreen[iColor] * 256));
552 1412 : sEntry.c3 = MIN(255,(short) (padfBlue[iColor] * 256));
553 1412 : sEntry.c4 = MIN(255,(short) (padfAlpha[iColor] * 256));
554 :
555 1412 : if( padfBins != NULL )
556 600 : poCT->SetColorEntry( (int) padfBins[iColor], &sEntry );
557 : else
558 812 : poCT->SetColorEntry( iColor, &sEntry );
559 : }
560 : }
561 :
562 974 : poDefaultRAT = ReadNamedRAT( "Descriptor_Table" );
563 0 : }
564 :
565 : /************************************************************************/
566 : /* ~HFARasterBand() */
567 : /************************************************************************/
568 :
569 974 : HFARasterBand::~HFARasterBand()
570 :
571 : {
572 974 : FlushCache();
573 :
574 1042 : for( int iOvIndex = 0; iOvIndex < nOverviews; iOvIndex++ )
575 : {
576 68 : delete papoOverviewBands[iOvIndex];
577 : }
578 974 : CPLFree( papoOverviewBands );
579 :
580 974 : if( poCT != NULL )
581 12 : delete poCT;
582 :
583 974 : if( poDefaultRAT )
584 108 : delete poDefaultRAT;
585 974 : }
586 :
587 : /************************************************************************/
588 : /* ReadAuxMetadata() */
589 : /************************************************************************/
590 :
591 904 : void HFARasterBand::ReadAuxMetadata()
592 :
593 : {
594 : int i;
595 904 : HFABand *poBand = hHFA->papoBand[nBand-1];
596 :
597 : // only load metadata for full resolution layer.
598 904 : if( nThisOverview != -1 )
599 0 : return;
600 :
601 904 : const char ** pszAuxMetaData = GetHFAAuxMetaDataList();
602 12656 : for( i = 0; pszAuxMetaData[i] != NULL; i += 4 )
603 : {
604 : HFAEntry *poEntry;
605 :
606 11752 : if( strlen(pszAuxMetaData[i]) > 0 )
607 10848 : poEntry = poBand->poNode->GetNamedChild( pszAuxMetaData[i] );
608 : else
609 904 : poEntry = poBand->poNode;
610 :
611 11752 : const char *pszFieldName = pszAuxMetaData[i+1] + 1;
612 11752 : CPLErr eErr = CE_None;
613 :
614 11752 : if( poEntry == NULL )
615 9768 : continue;
616 :
617 1984 : switch( pszAuxMetaData[i+1][0] )
618 : {
619 : case 'd':
620 : {
621 : int nCount, iValue;
622 : double dfValue;
623 812 : CPLString osValueList;
624 :
625 812 : nCount = poEntry->GetFieldCount( pszFieldName, &eErr );
626 812 : for( iValue = 0; eErr == CE_None && iValue < nCount; iValue++ )
627 : {
628 778 : CPLString osSubFieldName;
629 778 : osSubFieldName.Printf( "%s[%d]", pszFieldName, iValue );
630 778 : dfValue = poEntry->GetDoubleField( osSubFieldName, &eErr );
631 778 : if( eErr != CE_None )
632 : break;
633 :
634 : char szValueAsString[100];
635 738 : sprintf( szValueAsString, "%.14g", dfValue );
636 :
637 738 : if( iValue > 0 )
638 4 : osValueList += ",";
639 738 : osValueList += szValueAsString;
640 : }
641 812 : if( eErr == CE_None )
642 772 : SetMetadataItem( pszAuxMetaData[i+2], osValueList );
643 : }
644 812 : break;
645 : case 'i':
646 : case 'l':
647 : {
648 : int nValue, nCount, iValue;
649 268 : CPLString osValueList;
650 :
651 268 : nCount = poEntry->GetFieldCount( pszFieldName, &eErr );
652 268 : for( iValue = 0; eErr == CE_None && iValue < nCount; iValue++ )
653 : {
654 268 : CPLString osSubFieldName;
655 268 : osSubFieldName.Printf( "%s[%d]", pszFieldName, iValue );
656 268 : nValue = poEntry->GetIntField( osSubFieldName, &eErr );
657 268 : if( eErr != CE_None )
658 : break;
659 :
660 : char szValueAsString[100];
661 248 : sprintf( szValueAsString, "%d", nValue );
662 :
663 248 : if( iValue > 0 )
664 0 : osValueList += ",";
665 248 : osValueList += szValueAsString;
666 : }
667 268 : if( eErr == CE_None )
668 248 : SetMetadataItem( pszAuxMetaData[i+2], osValueList );
669 : }
670 268 : break;
671 : case 's':
672 : case 'e':
673 : {
674 : const char *pszValue;
675 904 : pszValue = poEntry->GetStringField( pszFieldName, &eErr );
676 904 : if( eErr == CE_None )
677 904 : SetMetadataItem( pszAuxMetaData[i+2], pszValue );
678 : }
679 904 : break;
680 : default:
681 0 : CPLAssert( FALSE );
682 : }
683 : }
684 : }
685 :
686 : /************************************************************************/
687 : /* ReadHistogramMetadata() */
688 : /************************************************************************/
689 :
690 904 : void HFARasterBand::ReadHistogramMetadata()
691 :
692 : {
693 : int i;
694 904 : HFABand *poBand = hHFA->papoBand[nBand-1];
695 :
696 : // only load metadata for full resolution layer.
697 904 : if( nThisOverview != -1 )
698 0 : return;
699 :
700 : HFAEntry *poEntry =
701 904 : poBand->poNode->GetNamedChild( "Descriptor_Table.Histogram" );
702 904 : if ( poEntry == NULL )
703 812 : return;
704 :
705 92 : int nNumBins = poEntry->GetIntField( "numRows" );
706 92 : if (nNumBins < 0)
707 0 : return;
708 :
709 : /* -------------------------------------------------------------------- */
710 : /* Fetch the histogram values. */
711 : /* -------------------------------------------------------------------- */
712 :
713 92 : int nOffset = poEntry->GetIntField( "columnDataPtr" );
714 92 : const char * pszType = poEntry->GetStringField( "dataType" );
715 92 : int nBinSize = 4;
716 :
717 92 : if( pszType != NULL && EQUALN( "real", pszType, 4 ) )
718 72 : nBinSize = 8;
719 :
720 92 : int *panHistValues = (int *) VSIMalloc2(sizeof(int), nNumBins);
721 92 : GByte *pabyWorkBuf = (GByte *) VSIMalloc2(nBinSize, nNumBins);
722 :
723 92 : if (panHistValues == NULL || pabyWorkBuf == NULL)
724 : {
725 0 : CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate memory");
726 0 : VSIFree(panHistValues);
727 0 : VSIFree(pabyWorkBuf);
728 0 : return;
729 : }
730 :
731 92 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
732 :
733 92 : if( (int)VSIFReadL( pabyWorkBuf, nBinSize, nNumBins, hHFA->fp ) != nNumBins)
734 : {
735 : CPLError( CE_Failure, CPLE_FileIO,
736 0 : "Cannot read histogram values." );
737 0 : CPLFree( panHistValues );
738 0 : CPLFree( pabyWorkBuf );
739 0 : return;
740 : }
741 :
742 : // Swap into local order.
743 92 : for( i = 0; i < nNumBins; i++ )
744 : HFAStandard( nBinSize, pabyWorkBuf + i*nBinSize );
745 :
746 92 : if( nBinSize == 8 ) // source is doubles
747 : {
748 13488 : for( i = 0; i < nNumBins; i++ )
749 13416 : panHistValues[i] = (int) ((double *) pabyWorkBuf)[i];
750 : }
751 : else // source is 32bit integers
752 : {
753 20 : memcpy( panHistValues, pabyWorkBuf, 4 * nNumBins );
754 : }
755 :
756 92 : CPLFree( pabyWorkBuf );
757 92 : pabyWorkBuf = NULL;
758 :
759 : /* -------------------------------------------------------------------- */
760 : /* Do we have unique values for the bins? */
761 : /* -------------------------------------------------------------------- */
762 92 : double *padfBinValues = NULL;
763 92 : HFAEntry *poBinEntry = poBand->poNode->GetNamedChild( "Descriptor_Table.#Bin_Function840#" );
764 :
765 92 : if( poBinEntry != NULL
766 : && EQUAL(poBinEntry->GetType(),"Edsc_BinFunction840")
767 : && EQUAL(poBinEntry->GetStringField( "binFunction.type.string" ),
768 : "BFUnique") )
769 20 : padfBinValues = HFAReadBFUniqueBins( poBinEntry, nNumBins );
770 :
771 92 : if( padfBinValues )
772 : {
773 20 : int nMaxValue = 0;
774 20 : int nMinValue = 1000000;
775 20 : int bAllInteger = TRUE;
776 :
777 1830 : for( i = 0; i < nNumBins; i++ )
778 : {
779 1810 : if( padfBinValues[i] != floor(padfBinValues[i]) )
780 0 : bAllInteger = FALSE;
781 :
782 1810 : nMaxValue = MAX(nMaxValue,(int)padfBinValues[i]);
783 1810 : nMinValue = MIN(nMinValue,(int)padfBinValues[i]);
784 : }
785 :
786 20 : if( nMinValue < 0 || nMaxValue > 1000 || !bAllInteger )
787 : {
788 0 : CPLFree( padfBinValues );
789 0 : CPLFree( panHistValues );
790 0 : CPLDebug( "HFA", "Unable to offer histogram because unique values list is not convenient to reform as HISTOBINVALUES." );
791 0 : return;
792 : }
793 :
794 20 : int nNewBins = nMaxValue + 1;
795 20 : int *panNewHistValues = (int *) CPLCalloc(sizeof(int),nNewBins);
796 :
797 1830 : for( i = 0; i < nNumBins; i++ )
798 1810 : panNewHistValues[(int) padfBinValues[i]] = panHistValues[i];
799 :
800 20 : CPLFree( panHistValues );
801 20 : panHistValues = panNewHistValues;
802 20 : nNumBins = nNewBins;
803 :
804 20 : SetMetadataItem( "STATISTICS_HISTOMIN", "0" );
805 : SetMetadataItem( "STATISTICS_HISTOMAX",
806 20 : CPLString().Printf("%d", nMaxValue ) );
807 : SetMetadataItem( "STATISTICS_HISTONUMBINS",
808 40 : CPLString().Printf("%d", nMaxValue+1 ) );
809 :
810 20 : CPLFree(padfBinValues);
811 20 : padfBinValues = NULL;
812 : }
813 :
814 : /* -------------------------------------------------------------------- */
815 : /* Format into HISTOBINVALUES text format. */
816 : /* -------------------------------------------------------------------- */
817 92 : unsigned int nBufSize = 1024;
818 92 : char * pszBinValues = (char *)CPLMalloc( nBufSize );
819 92 : int nBinValuesLen = 0;
820 92 : pszBinValues[0] = 0;
821 :
822 21282 : for ( int nBin = 0; nBin < nNumBins; ++nBin )
823 : {
824 : char szBuf[32];
825 21190 : snprintf( szBuf, 31, "%d", panHistValues[nBin] );
826 21190 : if ( ( nBinValuesLen + strlen( szBuf ) + 2 ) > nBufSize )
827 : {
828 6 : nBufSize *= 2;
829 6 : char* pszNewBinValues = (char *)VSIRealloc( pszBinValues, nBufSize );
830 6 : if (pszNewBinValues == NULL)
831 : {
832 0 : CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate memory");
833 0 : break;
834 : }
835 6 : pszBinValues = pszNewBinValues;
836 : }
837 21190 : strcat( pszBinValues+nBinValuesLen, szBuf );
838 21190 : strcat( pszBinValues+nBinValuesLen, "|" );
839 21190 : nBinValuesLen += strlen(pszBinValues+nBinValuesLen);
840 : }
841 :
842 92 : SetMetadataItem( "STATISTICS_HISTOBINVALUES", pszBinValues );
843 92 : CPLFree( panHistValues );
844 92 : CPLFree( pszBinValues );
845 : }
846 :
847 : /************************************************************************/
848 : /* GetNoDataValue() */
849 : /************************************************************************/
850 :
851 200 : double HFARasterBand::GetNoDataValue( int *pbSuccess )
852 :
853 : {
854 : double dfNoData;
855 :
856 200 : if( HFAGetBandNoData( hHFA, nBand, &dfNoData ) )
857 : {
858 32 : if( pbSuccess )
859 28 : *pbSuccess = TRUE;
860 32 : return dfNoData;
861 : }
862 : else
863 168 : return GDALPamRasterBand::GetNoDataValue( pbSuccess );
864 : }
865 :
866 : /************************************************************************/
867 : /* SetNoDataValue() */
868 : /************************************************************************/
869 :
870 14 : CPLErr HFARasterBand::SetNoDataValue( double dfValue )
871 : {
872 14 : return HFASetBandNoData( hHFA, nBand, dfValue );
873 : }
874 :
875 : /************************************************************************/
876 : /* GetMinimum() */
877 : /************************************************************************/
878 :
879 4 : double HFARasterBand::GetMinimum( int *pbSuccess )
880 :
881 : {
882 4 : const char *pszValue = GetMetadataItem( "STATISTICS_MINIMUM" );
883 :
884 4 : if( pszValue != NULL )
885 : {
886 4 : if( pbSuccess )
887 4 : *pbSuccess = TRUE;
888 4 : return CPLAtofM(pszValue);
889 : }
890 : else
891 : {
892 0 : return GDALRasterBand::GetMinimum( pbSuccess );
893 : }
894 : }
895 :
896 : /************************************************************************/
897 : /* GetMaximum() */
898 : /************************************************************************/
899 :
900 4 : double HFARasterBand::GetMaximum( int *pbSuccess )
901 :
902 : {
903 4 : const char *pszValue = GetMetadataItem( "STATISTICS_MAXIMUM" );
904 :
905 4 : if( pszValue != NULL )
906 : {
907 4 : if( pbSuccess )
908 4 : *pbSuccess = TRUE;
909 4 : return CPLAtofM(pszValue);
910 : }
911 : else
912 : {
913 0 : return GDALRasterBand::GetMaximum( pbSuccess );
914 : }
915 : }
916 :
917 : /************************************************************************/
918 : /* EstablishOverviews() */
919 : /* */
920 : /* Delayed population of overview information. */
921 : /************************************************************************/
922 :
923 282 : void HFARasterBand::EstablishOverviews()
924 :
925 : {
926 282 : if( nOverviews != -1 )
927 80 : return;
928 :
929 202 : nOverviews = HFAGetOverviewCount( hHFA, nBand );
930 202 : if( nOverviews > 0 )
931 : {
932 : papoOverviewBands = (HFARasterBand **)
933 42 : CPLMalloc(sizeof(void*)*nOverviews);
934 :
935 98 : for( int iOvIndex = 0; iOvIndex < nOverviews; iOvIndex++ )
936 : {
937 56 : papoOverviewBands[iOvIndex] =
938 112 : new HFARasterBand( (HFADataset *) poDS, nBand, iOvIndex );
939 56 : if (papoOverviewBands[iOvIndex]->GetXSize() == 0)
940 : {
941 0 : delete papoOverviewBands[iOvIndex];
942 0 : papoOverviewBands[iOvIndex] = NULL;
943 : }
944 : }
945 : }
946 : }
947 :
948 : /************************************************************************/
949 : /* GetOverviewCount() */
950 : /************************************************************************/
951 :
952 208 : int HFARasterBand::GetOverviewCount()
953 :
954 : {
955 208 : EstablishOverviews();
956 :
957 208 : if( nOverviews == 0 )
958 154 : return GDALRasterBand::GetOverviewCount();
959 : else
960 54 : return nOverviews;
961 : }
962 :
963 : /************************************************************************/
964 : /* GetOverview() */
965 : /************************************************************************/
966 :
967 58 : GDALRasterBand *HFARasterBand::GetOverview( int i )
968 :
969 : {
970 58 : EstablishOverviews();
971 :
972 58 : if( nOverviews == 0 )
973 0 : return GDALRasterBand::GetOverview( i );
974 58 : else if( i < 0 || i >= nOverviews )
975 0 : return NULL;
976 : else
977 58 : return papoOverviewBands[i];
978 : }
979 :
980 : /************************************************************************/
981 : /* IReadBlock() */
982 : /************************************************************************/
983 :
984 742 : CPLErr HFARasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
985 : void * pImage )
986 :
987 : {
988 : CPLErr eErr;
989 :
990 742 : if( nThisOverview == -1 )
991 : eErr = HFAGetRasterBlockEx( hHFA, nBand, nBlockXOff, nBlockYOff,
992 : pImage,
993 674 : nBlockXSize * nBlockYSize * (GDALGetDataTypeSize(eDataType) / 8) );
994 : else
995 : {
996 : eErr = HFAGetOverviewRasterBlockEx( hHFA, nBand, nThisOverview,
997 : nBlockXOff, nBlockYOff,
998 : pImage,
999 68 : nBlockXSize * nBlockYSize * (GDALGetDataTypeSize(eDataType) / 8));
1000 : }
1001 :
1002 742 : if( eErr == CE_None && nHFADataType == EPT_u4 )
1003 : {
1004 0 : GByte *pabyData = (GByte *) pImage;
1005 :
1006 0 : for( int ii = nBlockXSize * nBlockYSize - 2; ii >= 0; ii -= 2 )
1007 : {
1008 0 : int k = ii>>1;
1009 0 : pabyData[ii+1] = (pabyData[k]>>4) & 0xf;
1010 0 : pabyData[ii] = (pabyData[k]) & 0xf;
1011 : }
1012 : }
1013 742 : if( eErr == CE_None && nHFADataType == EPT_u2 )
1014 : {
1015 8 : GByte *pabyData = (GByte *) pImage;
1016 :
1017 8200 : for( int ii = nBlockXSize * nBlockYSize - 4; ii >= 0; ii -= 4 )
1018 : {
1019 8192 : int k = ii>>2;
1020 8192 : pabyData[ii+3] = (pabyData[k]>>6) & 0x3;
1021 8192 : pabyData[ii+2] = (pabyData[k]>>4) & 0x3;
1022 8192 : pabyData[ii+1] = (pabyData[k]>>2) & 0x3;
1023 8192 : pabyData[ii] = (pabyData[k]) & 0x3;
1024 : }
1025 : }
1026 742 : if( eErr == CE_None && nHFADataType == EPT_u1)
1027 : {
1028 58 : GByte *pabyData = (GByte *) pImage;
1029 :
1030 237626 : for( int ii = nBlockXSize * nBlockYSize - 1; ii >= 0; ii-- )
1031 : {
1032 237568 : if( (pabyData[ii>>3] & (1 << (ii & 0x7))) )
1033 161194 : pabyData[ii] = 1;
1034 : else
1035 76374 : pabyData[ii] = 0;
1036 : }
1037 : }
1038 :
1039 742 : return eErr;
1040 : }
1041 :
1042 : /************************************************************************/
1043 : /* IWriteBlock() */
1044 : /************************************************************************/
1045 :
1046 216 : CPLErr HFARasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
1047 : void * pImage )
1048 :
1049 : {
1050 216 : GByte *pabyOutBuf = (GByte *) pImage;
1051 :
1052 : /* -------------------------------------------------------------------- */
1053 : /* Do we need to pack 1/2/4 bit data? */
1054 : /* -------------------------------------------------------------------- */
1055 216 : if( nHFADataType == EPT_u1
1056 : || nHFADataType == EPT_u2
1057 : || nHFADataType == EPT_u4 )
1058 : {
1059 4 : int nPixCount = nBlockXSize * nBlockYSize;
1060 4 : pabyOutBuf = (GByte *) VSIMalloc2(nBlockXSize, nBlockYSize);
1061 4 : if (pabyOutBuf == NULL)
1062 0 : return CE_Failure;
1063 :
1064 4 : if( nHFADataType == EPT_u1 )
1065 : {
1066 2052 : for( int ii = 0; ii < nPixCount - 7; ii += 8 )
1067 : {
1068 2048 : int k = ii>>3;
1069 2048 : pabyOutBuf[k] =
1070 2048 : (((GByte *) pImage)[ii] & 0x1)
1071 2048 : | ((((GByte *) pImage)[ii+1]&0x1) << 1)
1072 2048 : | ((((GByte *) pImage)[ii+2]&0x1) << 2)
1073 2048 : | ((((GByte *) pImage)[ii+3]&0x1) << 3)
1074 2048 : | ((((GByte *) pImage)[ii+4]&0x1) << 4)
1075 2048 : | ((((GByte *) pImage)[ii+5]&0x1) << 5)
1076 2048 : | ((((GByte *) pImage)[ii+6]&0x1) << 6)
1077 14336 : | ((((GByte *) pImage)[ii+7]&0x1) << 7);
1078 : }
1079 : }
1080 0 : else if( nHFADataType == EPT_u2 )
1081 : {
1082 0 : for( int ii = 0; ii < nPixCount - 3; ii += 4 )
1083 : {
1084 0 : int k = ii>>2;
1085 0 : pabyOutBuf[k] =
1086 0 : (((GByte *) pImage)[ii] & 0x3)
1087 0 : | ((((GByte *) pImage)[ii+1]&0x3) << 2)
1088 0 : | ((((GByte *) pImage)[ii+2]&0x3) << 4)
1089 0 : | ((((GByte *) pImage)[ii+3]&0x3) << 6);
1090 : }
1091 : }
1092 0 : else if( nHFADataType == EPT_u4 )
1093 : {
1094 0 : for( int ii = 0; ii < nPixCount - 1; ii += 2 )
1095 : {
1096 0 : int k = ii>>1;
1097 0 : pabyOutBuf[k] =
1098 0 : (((GByte *) pImage)[ii] & 0xf)
1099 0 : | ((((GByte *) pImage)[ii+1]&0xf) << 4);
1100 : }
1101 : }
1102 : }
1103 :
1104 : /* -------------------------------------------------------------------- */
1105 : /* Actually write out. */
1106 : /* -------------------------------------------------------------------- */
1107 : CPLErr nRetCode;
1108 :
1109 216 : if( nThisOverview == -1 )
1110 : nRetCode = HFASetRasterBlock( hHFA, nBand, nBlockXOff, nBlockYOff,
1111 180 : pabyOutBuf );
1112 : else
1113 : nRetCode = HFASetOverviewRasterBlock( hHFA, nBand, nThisOverview,
1114 : nBlockXOff, nBlockYOff,
1115 36 : pabyOutBuf );
1116 :
1117 216 : if( pabyOutBuf != pImage )
1118 4 : CPLFree( pabyOutBuf );
1119 :
1120 216 : return nRetCode;
1121 : }
1122 :
1123 : /************************************************************************/
1124 : /* GetDescription() */
1125 : /************************************************************************/
1126 :
1127 312 : const char * HFARasterBand::GetDescription() const
1128 : {
1129 312 : const char *pszName = HFAGetBandName( hHFA, nBand );
1130 :
1131 312 : if( pszName == NULL )
1132 0 : return GDALPamRasterBand::GetDescription();
1133 : else
1134 312 : return pszName;
1135 : }
1136 :
1137 : /************************************************************************/
1138 : /* SetDescription() */
1139 : /************************************************************************/
1140 10 : void HFARasterBand::SetDescription( const char *pszName )
1141 : {
1142 10 : if( strlen(pszName) > 0 )
1143 10 : HFASetBandName( hHFA, nBand, pszName );
1144 10 : }
1145 :
1146 : /************************************************************************/
1147 : /* GetColorInterpretation() */
1148 : /************************************************************************/
1149 :
1150 100 : GDALColorInterp HFARasterBand::GetColorInterpretation()
1151 :
1152 : {
1153 100 : if( poCT != NULL )
1154 2 : return GCI_PaletteIndex;
1155 : else
1156 98 : return GCI_Undefined;
1157 : }
1158 :
1159 : /************************************************************************/
1160 : /* GetColorTable() */
1161 : /************************************************************************/
1162 :
1163 30 : GDALColorTable *HFARasterBand::GetColorTable()
1164 :
1165 : {
1166 30 : return poCT;
1167 : }
1168 :
1169 : /************************************************************************/
1170 : /* SetColorTable() */
1171 : /************************************************************************/
1172 :
1173 6 : CPLErr HFARasterBand::SetColorTable( GDALColorTable * poCTable )
1174 :
1175 : {
1176 6 : if( GetAccess() == GA_ReadOnly )
1177 : {
1178 : CPLError( CE_Failure, CPLE_NoWriteAccess,
1179 0 : "Unable to set color table on read-only file." );
1180 0 : return CE_Failure;
1181 : }
1182 :
1183 : /* -------------------------------------------------------------------- */
1184 : /* Special case if we are clearing the color table. */
1185 : /* -------------------------------------------------------------------- */
1186 6 : if( poCTable == NULL )
1187 : {
1188 4 : delete poCT;
1189 4 : poCT = NULL;
1190 :
1191 4 : HFASetPCT( hHFA, nBand, 0, NULL, NULL, NULL, NULL );
1192 :
1193 4 : return CE_None;
1194 : }
1195 :
1196 : /* -------------------------------------------------------------------- */
1197 : /* Write out the colortable, and update the configuration. */
1198 : /* -------------------------------------------------------------------- */
1199 2 : int nColors = poCTable->GetColorEntryCount();
1200 :
1201 : double *padfRed, *padfGreen, *padfBlue, *padfAlpha;
1202 :
1203 2 : padfRed = (double *) CPLMalloc(sizeof(double) * nColors);
1204 2 : padfGreen = (double *) CPLMalloc(sizeof(double) * nColors);
1205 2 : padfBlue = (double *) CPLMalloc(sizeof(double) * nColors);
1206 2 : padfAlpha = (double *) CPLMalloc(sizeof(double) * nColors);
1207 :
1208 514 : for( int iColor = 0; iColor < nColors; iColor++ )
1209 : {
1210 : GDALColorEntry sRGB;
1211 :
1212 512 : poCTable->GetColorEntryAsRGB( iColor, &sRGB );
1213 :
1214 512 : padfRed[iColor] = sRGB.c1 / 255.0;
1215 512 : padfGreen[iColor] = sRGB.c2 / 255.0;
1216 512 : padfBlue[iColor] = sRGB.c3 / 255.0;
1217 512 : padfAlpha[iColor] = sRGB.c4 / 255.0;
1218 : }
1219 :
1220 : HFASetPCT( hHFA, nBand, nColors,
1221 2 : padfRed, padfGreen, padfBlue, padfAlpha);
1222 :
1223 2 : CPLFree( padfRed );
1224 2 : CPLFree( padfGreen );
1225 2 : CPLFree( padfBlue );
1226 2 : CPLFree( padfAlpha );
1227 :
1228 2 : if( poCT )
1229 0 : delete poCT;
1230 :
1231 2 : poCT = poCTable->Clone();
1232 :
1233 2 : return CE_None;
1234 : }
1235 :
1236 : /************************************************************************/
1237 : /* SetMetadata() */
1238 : /************************************************************************/
1239 :
1240 28 : CPLErr HFARasterBand::SetMetadata( char **papszMDIn, const char *pszDomain )
1241 :
1242 : {
1243 28 : bMetadataDirty = TRUE;
1244 :
1245 28 : return GDALPamRasterBand::SetMetadata( papszMDIn, pszDomain );
1246 : }
1247 :
1248 : /************************************************************************/
1249 : /* SetMetadata() */
1250 : /************************************************************************/
1251 :
1252 2100 : CPLErr HFARasterBand::SetMetadataItem( const char *pszTag, const char *pszValue,
1253 : const char *pszDomain )
1254 :
1255 : {
1256 2100 : bMetadataDirty = TRUE;
1257 :
1258 2100 : return GDALPamRasterBand::SetMetadataItem( pszTag, pszValue, pszDomain );
1259 : }
1260 :
1261 : /************************************************************************/
1262 : /* CleanOverviews() */
1263 : /************************************************************************/
1264 :
1265 2 : CPLErr HFARasterBand::CleanOverviews()
1266 :
1267 : {
1268 2 : if( nOverviews == 0 )
1269 0 : return CE_None;
1270 :
1271 : /* -------------------------------------------------------------------- */
1272 : /* Clear our reference to overviews as bands. */
1273 : /* -------------------------------------------------------------------- */
1274 : int iOverview;
1275 :
1276 4 : for( iOverview = 0; iOverview < nOverviews; iOverview++ )
1277 2 : delete papoOverviewBands[iOverview];
1278 :
1279 2 : CPLFree( papoOverviewBands );
1280 2 : papoOverviewBands = NULL;
1281 2 : nOverviews = 0;
1282 :
1283 : /* -------------------------------------------------------------------- */
1284 : /* Search for any RRDNamesList and destroy it. */
1285 : /* -------------------------------------------------------------------- */
1286 2 : HFABand *poBand = hHFA->papoBand[nBand-1];
1287 2 : HFAEntry *poEntry = poBand->poNode->GetNamedChild( "RRDNamesList" );
1288 2 : if( poEntry != NULL )
1289 : {
1290 2 : poEntry->RemoveAndDestroy();
1291 : }
1292 :
1293 : /* -------------------------------------------------------------------- */
1294 : /* Destroy and subsample layers under our band. */
1295 : /* -------------------------------------------------------------------- */
1296 : HFAEntry *poChild;
1297 12 : for( poChild = poBand->poNode->GetChild();
1298 : poChild != NULL; )
1299 : {
1300 8 : HFAEntry *poNext = poChild->GetNext();
1301 :
1302 8 : if( EQUAL(poChild->GetType(),"Eimg_Layer_SubSample") )
1303 0 : poChild->RemoveAndDestroy();
1304 :
1305 8 : poChild = poNext;
1306 : }
1307 :
1308 : /* -------------------------------------------------------------------- */
1309 : /* Clean up dependent file if we are the last band under the */
1310 : /* assumption there will be nothing else referencing it after */
1311 : /* this. */
1312 : /* -------------------------------------------------------------------- */
1313 2 : if( hHFA->psDependent != hHFA && hHFA->psDependent != NULL )
1314 : {
1315 : CPLString osFilename =
1316 : CPLFormFilename( hHFA->psDependent->pszPath,
1317 2 : hHFA->psDependent->pszFilename, NULL );
1318 :
1319 2 : HFAClose( hHFA->psDependent );
1320 2 : hHFA->psDependent = NULL;
1321 :
1322 2 : CPLDebug( "HFA", "Unlink(%s)", osFilename.c_str() );
1323 2 : VSIUnlink( osFilename );
1324 : }
1325 :
1326 2 : return CE_None;
1327 : }
1328 :
1329 : /************************************************************************/
1330 : /* BuildOverviews() */
1331 : /************************************************************************/
1332 :
1333 16 : CPLErr HFARasterBand::BuildOverviews( const char *pszResampling,
1334 : int nReqOverviews, int *panOverviewList,
1335 : GDALProgressFunc pfnProgress,
1336 : void *pProgressData )
1337 :
1338 : {
1339 : int iOverview;
1340 : GDALRasterBand **papoOvBands;
1341 16 : int bNoRegen = FALSE;
1342 :
1343 16 : EstablishOverviews();
1344 :
1345 16 : if( nThisOverview != -1 )
1346 : {
1347 : CPLError( CE_Failure, CPLE_AppDefined,
1348 0 : "Attempt to build overviews on an overview layer." );
1349 :
1350 0 : return CE_Failure;
1351 : }
1352 :
1353 16 : if( nReqOverviews == 0 )
1354 2 : return CleanOverviews();
1355 :
1356 14 : papoOvBands = (GDALRasterBand **) CPLCalloc(sizeof(void*),nReqOverviews);
1357 :
1358 14 : if( EQUALN(pszResampling,"NO_REGEN:",9) )
1359 : {
1360 4 : pszResampling += 9;
1361 4 : bNoRegen = TRUE;
1362 : }
1363 :
1364 : /* -------------------------------------------------------------------- */
1365 : /* Loop over overview levels requested. */
1366 : /* -------------------------------------------------------------------- */
1367 30 : for( iOverview = 0; iOverview < nReqOverviews; iOverview++ )
1368 : {
1369 : /* -------------------------------------------------------------------- */
1370 : /* Find this overview level. */
1371 : /* -------------------------------------------------------------------- */
1372 16 : int i, iResult = -1, nReqOvLevel;
1373 :
1374 : nReqOvLevel =
1375 16 : GDALOvLevelAdjust(panOverviewList[iOverview],nRasterXSize);
1376 :
1377 26 : for( i = 0; i < nOverviews && papoOvBands[iOverview] == NULL; i++ )
1378 : {
1379 : int nThisOvLevel;
1380 :
1381 : nThisOvLevel = (int) (0.5 + GetXSize()
1382 10 : / (double) papoOverviewBands[i]->GetXSize());
1383 :
1384 10 : if( nReqOvLevel == nThisOvLevel )
1385 2 : papoOvBands[iOverview] = papoOverviewBands[i];
1386 : }
1387 :
1388 : /* -------------------------------------------------------------------- */
1389 : /* If this overview level does not yet exist, create it now. */
1390 : /* -------------------------------------------------------------------- */
1391 16 : if( papoOvBands[iOverview] == NULL )
1392 : {
1393 : iResult = HFACreateOverview( hHFA, nBand,
1394 : panOverviewList[iOverview],
1395 14 : pszResampling );
1396 14 : if( iResult < 0 )
1397 0 : return CE_Failure;
1398 :
1399 14 : nOverviews = iResult + 1;
1400 : papoOverviewBands = (HFARasterBand **)
1401 14 : CPLRealloc( papoOverviewBands, sizeof(void*) * nOverviews);
1402 14 : papoOverviewBands[iResult] = new HFARasterBand(
1403 28 : (HFADataset *) poDS, nBand, iResult );
1404 :
1405 14 : papoOvBands[iOverview] = papoOverviewBands[iResult];
1406 : }
1407 :
1408 : }
1409 :
1410 : /* -------------------------------------------------------------------- */
1411 : /* Regenerate the overviews. */
1412 : /* -------------------------------------------------------------------- */
1413 14 : CPLErr eErr = CE_None;
1414 :
1415 14 : if( !bNoRegen )
1416 : eErr = GDALRegenerateOverviews( (GDALRasterBandH) this,
1417 : nReqOverviews,
1418 : (GDALRasterBandH *) papoOvBands,
1419 : pszResampling,
1420 10 : pfnProgress, pProgressData );
1421 :
1422 14 : CPLFree( papoOvBands );
1423 :
1424 14 : return eErr;
1425 : }
1426 :
1427 : /************************************************************************/
1428 : /* GetDefaultHistogram() */
1429 : /************************************************************************/
1430 :
1431 : CPLErr
1432 6 : HFARasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax,
1433 : int *pnBuckets, int ** ppanHistogram,
1434 : int bForce,
1435 : GDALProgressFunc pfnProgress,
1436 : void *pProgressData)
1437 :
1438 : {
1439 10 : if( GetMetadataItem( "STATISTICS_HISTOBINVALUES" ) != NULL
1440 2 : && GetMetadataItem( "STATISTICS_HISTOMIN" ) != NULL
1441 2 : && GetMetadataItem( "STATISTICS_HISTOMAX" ) != NULL )
1442 : {
1443 : int i;
1444 : const char *pszNextBin;
1445 : const char *pszBinValues =
1446 2 : GetMetadataItem( "STATISTICS_HISTOBINVALUES" );
1447 :
1448 2 : *pdfMin = atof(GetMetadataItem("STATISTICS_HISTOMIN"));
1449 2 : *pdfMax = atof(GetMetadataItem("STATISTICS_HISTOMAX"));
1450 :
1451 2 : *pnBuckets = 0;
1452 1146 : for( i = 0; pszBinValues[i] != '\0'; i++ )
1453 : {
1454 1144 : if( pszBinValues[i] == '|' )
1455 440 : (*pnBuckets)++;
1456 : }
1457 :
1458 2 : *ppanHistogram = (int *) CPLCalloc(sizeof(int),*pnBuckets);
1459 :
1460 2 : pszNextBin = pszBinValues;
1461 442 : for( i = 0; i < *pnBuckets; i++ )
1462 : {
1463 440 : (*ppanHistogram)[i] = atoi(pszNextBin);
1464 :
1465 1584 : while( *pszNextBin != '|' && *pszNextBin != '\0' )
1466 704 : pszNextBin++;
1467 440 : if( *pszNextBin == '|' )
1468 440 : pszNextBin++;
1469 : }
1470 :
1471 : // Adjust min/max to reflect outer edges of buckets.
1472 2 : double dfBucketWidth = (*pdfMax - *pdfMin) / (*pnBuckets-1);
1473 2 : *pdfMax += 0.5 * dfBucketWidth;
1474 2 : *pdfMin -= 0.5 * dfBucketWidth;
1475 :
1476 2 : return CE_None;
1477 : }
1478 : else
1479 : return GDALPamRasterBand::GetDefaultHistogram( pdfMin, pdfMax,
1480 : pnBuckets,ppanHistogram,
1481 : bForce,
1482 : pfnProgress,
1483 4 : pProgressData );
1484 : }
1485 :
1486 : /************************************************************************/
1487 : /* SetDefaultRAT() */
1488 : /************************************************************************/
1489 :
1490 2 : CPLErr HFARasterBand::SetDefaultRAT( const GDALRasterAttributeTable * poRAT )
1491 :
1492 : {
1493 2 : return WriteNamedRAT( "Descriptor_Table", poRAT );
1494 : }
1495 :
1496 : /************************************************************************/
1497 : /* GetDefaultRAT() */
1498 : /************************************************************************/
1499 :
1500 32 : const GDALRasterAttributeTable *HFARasterBand::GetDefaultRAT()
1501 :
1502 : {
1503 32 : return poDefaultRAT;
1504 : }
1505 :
1506 : /************************************************************************/
1507 : /* ReadNamedRAT() */
1508 : /************************************************************************/
1509 :
1510 974 : GDALRasterAttributeTable *HFARasterBand::ReadNamedRAT( const char *pszName )
1511 :
1512 : {
1513 : /* -------------------------------------------------------------------- */
1514 : /* Find the requested table. */
1515 : /* -------------------------------------------------------------------- */
1516 974 : HFAEntry *poDT = hHFA->papoBand[nBand-1]->poNode->GetNamedChild(pszName);
1517 :
1518 974 : if( poDT == NULL )
1519 866 : return NULL;
1520 :
1521 : /* -------------------------------------------------------------------- */
1522 : /* Create a corresponding RAT. */
1523 : /* -------------------------------------------------------------------- */
1524 108 : GDALRasterAttributeTable *poRAT = NULL;
1525 108 : int nRowCount = poDT->GetIntField( "numRows" );
1526 :
1527 108 : poRAT = new GDALRasterAttributeTable();
1528 :
1529 : /* -------------------------------------------------------------------- */
1530 : /* Scan under table for columns. */
1531 : /* -------------------------------------------------------------------- */
1532 : HFAEntry *poDTChild;
1533 :
1534 362 : for( poDTChild = poDT->GetChild();
1535 : poDTChild != NULL;
1536 : poDTChild = poDTChild->GetNext() )
1537 : {
1538 : int i;
1539 :
1540 254 : if( EQUAL(poDTChild->GetType(),"Edsc_BinFunction") )
1541 : {
1542 74 : double dfMax = poDTChild->GetDoubleField( "maxLimit" );
1543 74 : double dfMin = poDTChild->GetDoubleField( "minLimit" );
1544 74 : int nBinCount = poDTChild->GetIntField( "numBins" );
1545 :
1546 74 : if( nBinCount == nRowCount
1547 : && dfMax != dfMin && nBinCount != 0 )
1548 : poRAT->SetLinearBinning( dfMin,
1549 74 : (dfMax-dfMin) / (nBinCount-1) );
1550 : }
1551 :
1552 254 : if( EQUAL(poDTChild->GetType(),"Edsc_BinFunction840")
1553 : && EQUAL(poDTChild->GetStringField( "binFunction.type.string" ),
1554 : "BFUnique") )
1555 : {
1556 20 : double *padfBinValues = HFAReadBFUniqueBins( poDTChild, nRowCount );
1557 :
1558 20 : if( padfBinValues != NULL )
1559 : {
1560 20 : poRAT->CreateColumn( "BinValues", GFT_Real, GFU_MinMax );
1561 1830 : for( i = 0; i < nRowCount; i++ )
1562 : poRAT->SetValue( i, poRAT->GetColumnCount()-1,
1563 1810 : padfBinValues[i] );
1564 :
1565 20 : CPLFree( padfBinValues );
1566 : }
1567 : }
1568 :
1569 254 : if( !EQUAL(poDTChild->GetType(),"Edsc_Column") )
1570 94 : continue;
1571 :
1572 160 : int nOffset = poDTChild->GetIntField( "columnDataPtr" );
1573 160 : const char * pszType = poDTChild->GetStringField( "dataType" );
1574 160 : GDALRATFieldUsage eType = GFU_Generic;
1575 :
1576 160 : if( pszType == NULL || nOffset == 0 )
1577 0 : continue;
1578 :
1579 160 : if( EQUAL(poDTChild->GetName(),"Histogram") )
1580 96 : eType = GFU_Generic;
1581 64 : else if( EQUAL(poDTChild->GetName(),"Red") )
1582 14 : eType = GFU_Red;
1583 50 : else if( EQUAL(poDTChild->GetName(),"Green") )
1584 14 : eType = GFU_Green;
1585 36 : else if( EQUAL(poDTChild->GetName(),"Blue") )
1586 14 : eType = GFU_Blue;
1587 22 : else if( EQUAL(poDTChild->GetName(),"Alpha") )
1588 0 : eType = GFU_Alpha;
1589 22 : else if( EQUAL(poDTChild->GetName(),"Class_Names") )
1590 0 : eType = GFU_Name;
1591 :
1592 160 : if( EQUAL(pszType,"real") )
1593 : {
1594 136 : double *padfColData = (double*)VSIMalloc2(nRowCount, sizeof(double));
1595 136 : if (nRowCount != 0 && padfColData == NULL)
1596 : {
1597 : CPLError( CE_Failure, CPLE_OutOfMemory,
1598 0 : "HFARasterBand::ReadNamedRAT : Out of memory");
1599 0 : delete poRAT;
1600 0 : return NULL;
1601 : }
1602 :
1603 136 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
1604 136 : if ((int)VSIFReadL( padfColData, sizeof(double), nRowCount, hHFA->fp ) != nRowCount)
1605 : {
1606 : CPLError( CE_Failure, CPLE_AppDefined,
1607 0 : "HFARasterBand::ReadNamedRAT : Cannot read values");
1608 0 : CPLFree(padfColData);
1609 0 : delete poRAT;
1610 0 : return NULL;
1611 : }
1612 : #ifdef CPL_MSB
1613 : GDALSwapWords( padfColData, 8, nRowCount, 8 );
1614 : #endif
1615 136 : poRAT->CreateColumn( poDTChild->GetName(), GFT_Real, eType );
1616 20368 : for( i = 0; i < nRowCount; i++ )
1617 20232 : poRAT->SetValue( i, poRAT->GetColumnCount()-1, padfColData[i]);
1618 :
1619 136 : CPLFree( padfColData );
1620 : }
1621 24 : else if( EQUAL(pszType,"string") )
1622 : {
1623 2 : int nMaxNumChars = poDTChild->GetIntField( "maxNumChars" );
1624 2 : char *pachColData = (char*)VSICalloc(nRowCount+1,nMaxNumChars);
1625 2 : if (pachColData == NULL)
1626 : {
1627 : CPLError( CE_Failure, CPLE_OutOfMemory,
1628 0 : "HFARasterBand::ReadNamedRAT : Out of memory");
1629 0 : delete poRAT;
1630 0 : return NULL;
1631 : }
1632 :
1633 2 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
1634 2 : if ((int)VSIFReadL( pachColData, nMaxNumChars, nRowCount, hHFA->fp ) != nRowCount)
1635 : {
1636 : CPLError( CE_Failure, CPLE_AppDefined,
1637 0 : "HFARasterBand::ReadNamedRAT : Cannot read values");
1638 0 : CPLFree(pachColData);
1639 0 : delete poRAT;
1640 0 : return NULL;
1641 : }
1642 :
1643 2 : poRAT->CreateColumn(poDTChild->GetName(),GFT_String,eType);
1644 438 : for( i = 0; i < nRowCount; i++ )
1645 : {
1646 436 : CPLString oRowVal;
1647 :
1648 436 : oRowVal.assign( pachColData+nMaxNumChars*i, nMaxNumChars );
1649 : poRAT->SetValue( i, poRAT->GetColumnCount()-1,
1650 436 : oRowVal.c_str() );
1651 : }
1652 :
1653 2 : CPLFree( pachColData );
1654 : }
1655 22 : else if( EQUALN(pszType,"int",3) )
1656 : {
1657 22 : GInt32 *panColData = (GInt32*)VSIMalloc2(nRowCount, sizeof(GInt32));
1658 22 : if (nRowCount != 0 && panColData == NULL)
1659 : {
1660 : CPLError( CE_Failure, CPLE_OutOfMemory,
1661 0 : "HFARasterBand::ReadNamedRAT : Out of memory");
1662 0 : delete poRAT;
1663 0 : return NULL;
1664 : }
1665 :
1666 22 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
1667 22 : if ((int)VSIFReadL( panColData, sizeof(GInt32), nRowCount, hHFA->fp ) != nRowCount)
1668 : {
1669 : CPLError( CE_Failure, CPLE_AppDefined,
1670 0 : "HFARasterBand::ReadNamedRAT : Cannot read values");
1671 0 : CPLFree(panColData);
1672 0 : delete poRAT;
1673 0 : return NULL;
1674 : }
1675 : #ifdef CPL_MSB
1676 : GDALSwapWords( panColData, 4, nRowCount, 4 );
1677 : #endif
1678 22 : poRAT->CreateColumn(poDTChild->GetName(),GFT_Integer,eType);
1679 5534 : for( i = 0; i < nRowCount; i++ )
1680 5512 : poRAT->SetValue( i, poRAT->GetColumnCount()-1, panColData[i] );
1681 :
1682 22 : CPLFree( panColData );
1683 : }
1684 : }
1685 :
1686 108 : return poRAT;
1687 : }
1688 :
1689 : /************************************************************************/
1690 : /* WriteNamedRAT() */
1691 : /************************************************************************/
1692 :
1693 2 : CPLErr HFARasterBand::WriteNamedRAT( const char *pszName, const GDALRasterAttributeTable *poRAT )
1694 : {
1695 : /* -------------------------------------------------------------------- */
1696 : /* Find the requested table. */
1697 : /* -------------------------------------------------------------------- */
1698 2 : HFAEntry * poDT = hHFA->papoBand[nBand-1]->poNode->GetNamedChild( "Descriptor_Table" );
1699 2 : if( poDT == NULL || !EQUAL(poDT->GetType(),"Edsc_Table") )
1700 2 : poDT = new HFAEntry( hHFA->papoBand[nBand-1]->psInfo,
1701 : "Descriptor_Table", "Edsc_Table",
1702 4 : hHFA->papoBand[nBand-1]->poNode );
1703 :
1704 :
1705 2 : int nRowCount = poRAT->GetRowCount();
1706 :
1707 2 : poDT->SetIntField( "numrows", nRowCount );
1708 : /* Check if binning is set on this RAT */
1709 : double dfBinSize, dfRow0Min;
1710 2 : if(poRAT->GetLinearBinning( &dfRow0Min, &dfBinSize))
1711 : {
1712 : /* then it should have an Edsc_BinFunction */
1713 0 : HFAEntry *poBinFunction = poDT->GetNamedChild( "#Bin_Function#" );
1714 0 : if( poBinFunction == NULL || !EQUAL(poBinFunction->GetType(),"Edsc_BinFunction") )
1715 0 : poBinFunction = new HFAEntry( hHFA->papoBand[nBand-1]->psInfo,
1716 : "#Bin_Function#", "Edsc_BinFunction",
1717 0 : poDT );
1718 :
1719 0 : poBinFunction->SetStringField("binFunction", "direct");
1720 0 : poBinFunction->SetDoubleField("minLimit",dfRow0Min);
1721 0 : poBinFunction->SetDoubleField("maxLimit",(nRowCount -1)*dfBinSize+dfRow0Min);
1722 0 : poBinFunction->SetIntField("numBins",nRowCount);
1723 : }
1724 :
1725 : /* -------------------------------------------------------------------- */
1726 : /* Loop through each column in the RAT */
1727 : /* -------------------------------------------------------------------- */
1728 14 : for(int col = 0; col < poRAT->GetColumnCount(); col++)
1729 : {
1730 12 : const char *pszName = NULL;
1731 :
1732 12 : if( poRAT->GetUsageOfCol(col) == GFU_Red )
1733 : {
1734 2 : pszName = "Red";
1735 : }
1736 10 : else if( poRAT->GetUsageOfCol(col) == GFU_Green )
1737 : {
1738 2 : pszName = "Green";
1739 : }
1740 8 : else if( poRAT->GetUsageOfCol(col) == GFU_Blue )
1741 : {
1742 2 : pszName = "Blue";
1743 : }
1744 6 : else if( poRAT->GetUsageOfCol(col) == GFU_Alpha )
1745 : {
1746 0 : pszName = "Alpha";
1747 : }
1748 6 : else if( poRAT->GetUsageOfCol(col) == GFU_PixelCount )
1749 : {
1750 0 : pszName = "Histogram";
1751 : }
1752 6 : else if( poRAT->GetUsageOfCol(col) == GFU_Name )
1753 : {
1754 0 : pszName = "Class_Names";
1755 : }
1756 : else
1757 : {
1758 6 : pszName = poRAT->GetNameOfCol(col);
1759 : }
1760 :
1761 : /* -------------------------------------------------------------------- */
1762 : /* Check to see if a column with pszName exists and create if */
1763 : /* if necessary. */
1764 : /* -------------------------------------------------------------------- */
1765 :
1766 : HFAEntry *poColumn;
1767 12 : poColumn = poDT->GetNamedChild(pszName);
1768 :
1769 12 : if(poColumn == NULL || !EQUAL(poColumn->GetType(),"Edsc_Column"))
1770 12 : poColumn = new HFAEntry( hHFA->papoBand[nBand-1]->psInfo,
1771 : pszName, "Edsc_Column",
1772 24 : poDT );
1773 :
1774 :
1775 12 : poColumn->SetIntField( "numRows", nRowCount );
1776 :
1777 12 : if( poRAT->GetTypeOfCol(col) == GFT_Real )
1778 : {
1779 12 : int nOffset = HFAAllocateSpace( hHFA->papoBand[nBand-1]->psInfo,
1780 24 : nRowCount * sizeof(double) );
1781 12 : poColumn->SetIntField( "columnDataPtr", nOffset );
1782 12 : poColumn->SetStringField( "dataType", "real" );
1783 :
1784 12 : double *padfColData = (double*)CPLCalloc( nRowCount, sizeof(double) );
1785 912 : for( int i = 0; i < nRowCount; i++)
1786 : {
1787 900 : padfColData[i] = poRAT->GetValueAsDouble(i,col);
1788 : }
1789 : #ifdef CPL_MSB
1790 : GDALSwapWords( padfColData, 8, nRowCount, 8 );
1791 : #endif
1792 12 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
1793 12 : VSIFWriteL( padfColData, nRowCount, sizeof(double), hHFA->fp );
1794 12 : CPLFree( padfColData );
1795 : }
1796 0 : else if( poRAT->GetTypeOfCol(col) == GFT_String )
1797 : {
1798 0 : unsigned int nMaxNumChars = 0;
1799 : /* find the length of the longest string */
1800 0 : for( int i = 0; i < nRowCount; i++)
1801 : {
1802 0 : if(nMaxNumChars < strlen(poRAT->GetValueAsString(i,col)))
1803 : {
1804 0 : nMaxNumChars = strlen(poRAT->GetValueAsString(i,col));
1805 : }
1806 : }
1807 :
1808 0 : int nOffset = HFAAllocateSpace( hHFA->papoBand[nBand-1]->psInfo,
1809 0 : (nRowCount+1) * nMaxNumChars );
1810 0 : poColumn->SetIntField( "columnDataPtr", nOffset );
1811 0 : poColumn->SetStringField( "dataType", "string" );
1812 0 : poColumn->SetIntField( "maxNumChars", nMaxNumChars );
1813 :
1814 0 : char *pachColData = (char*)CPLCalloc(nRowCount+1,nMaxNumChars);
1815 0 : for( int i = 0; i < nRowCount; i++)
1816 : {
1817 0 : strcpy(&pachColData[nMaxNumChars*i],poRAT->GetValueAsString(i,col));
1818 : }
1819 0 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
1820 0 : VSIFWriteL( pachColData, nRowCount, nMaxNumChars, hHFA->fp );
1821 0 : CPLFree( pachColData );
1822 : }
1823 0 : else if (poRAT->GetTypeOfCol(col) == GFT_Integer)
1824 : {
1825 0 : int nOffset = HFAAllocateSpace( hHFA->papoBand[nBand-1]->psInfo,
1826 0 : nRowCount * sizeof(GInt32) );
1827 0 : poColumn->SetIntField( "columnDataPtr", nOffset );
1828 0 : poColumn->SetStringField( "dataType", "integer" );
1829 :
1830 0 : GInt32 *panColData = (GInt32*)CPLCalloc(nRowCount, sizeof(GInt32));
1831 0 : for( int i = 0; i < nRowCount; i++)
1832 : {
1833 0 : panColData[i] = poRAT->GetValueAsInt(i,col);
1834 : }
1835 : #ifdef CPL_MSB
1836 : GDALSwapWords( panColData, 4, nRowCount, 4 );
1837 : #endif
1838 0 : VSIFSeekL( hHFA->fp, nOffset, SEEK_SET );
1839 0 : VSIFWriteL( panColData, nRowCount, sizeof(GInt32), hHFA->fp );
1840 0 : CPLFree( panColData );
1841 : }
1842 : else
1843 : {
1844 : /* can't deal with any of the others yet */
1845 : CPLError( CE_Failure, CPLE_NotSupported,
1846 0 : "Writing this data type in a column is not supported for this Raster Attribute Table.");
1847 : }
1848 : }
1849 :
1850 2 : return CE_None;
1851 : }
1852 :
1853 :
1854 : /************************************************************************/
1855 : /* ==================================================================== */
1856 : /* HFADataset */
1857 : /* ==================================================================== */
1858 : /************************************************************************/
1859 :
1860 : /************************************************************************/
1861 : /* HFADataset() */
1862 : /************************************************************************/
1863 :
1864 762 : HFADataset::HFADataset()
1865 :
1866 : {
1867 762 : hHFA = NULL;
1868 762 : bGeoDirty = FALSE;
1869 762 : pszProjection = CPLStrdup("");
1870 762 : bMetadataDirty = FALSE;
1871 762 : bIgnoreUTM = FALSE;
1872 762 : bForceToPEString = FALSE;
1873 :
1874 762 : nGCPCount = 0;
1875 762 : }
1876 :
1877 : /************************************************************************/
1878 : /* ~HFADataset() */
1879 : /************************************************************************/
1880 :
1881 762 : HFADataset::~HFADataset()
1882 :
1883 : {
1884 762 : FlushCache();
1885 :
1886 : /* -------------------------------------------------------------------- */
1887 : /* Destroy the raster bands if they exist. We forcably clean */
1888 : /* them up now to avoid any effort to write to them after the */
1889 : /* file is closed. */
1890 : /* -------------------------------------------------------------------- */
1891 : int i;
1892 :
1893 1666 : for( i = 0; i < nBands && papoBands != NULL; i++ )
1894 : {
1895 904 : if( papoBands[i] != NULL )
1896 904 : delete papoBands[i];
1897 : }
1898 :
1899 762 : CPLFree( papoBands );
1900 762 : papoBands = NULL;
1901 :
1902 : /* -------------------------------------------------------------------- */
1903 : /* Close the file */
1904 : /* -------------------------------------------------------------------- */
1905 762 : if( hHFA != NULL )
1906 : {
1907 762 : HFAClose( hHFA );
1908 762 : hHFA = NULL;
1909 : }
1910 :
1911 : /* -------------------------------------------------------------------- */
1912 : /* Cleanup */
1913 : /* -------------------------------------------------------------------- */
1914 762 : CPLFree( pszProjection );
1915 762 : if( nGCPCount > 0 )
1916 2 : GDALDeinitGCPs( 36, asGCPList );
1917 762 : }
1918 :
1919 : /************************************************************************/
1920 : /* FlushCache() */
1921 : /************************************************************************/
1922 :
1923 772 : void HFADataset::FlushCache()
1924 :
1925 : {
1926 772 : GDALPamDataset::FlushCache();
1927 :
1928 772 : if( eAccess != GA_Update )
1929 492 : return;
1930 :
1931 280 : if( bGeoDirty )
1932 184 : WriteProjection();
1933 :
1934 280 : if( bMetadataDirty && GetMetadata() != NULL )
1935 : {
1936 86 : HFASetMetadata( hHFA, 0, GetMetadata() );
1937 86 : bMetadataDirty = FALSE;
1938 : }
1939 :
1940 628 : for( int iBand = 0; iBand < nBands; iBand++ )
1941 : {
1942 348 : HFARasterBand *poBand = (HFARasterBand *) GetRasterBand(iBand+1);
1943 348 : if( poBand->bMetadataDirty && poBand->GetMetadata() != NULL )
1944 : {
1945 16 : HFASetMetadata( hHFA, iBand+1, poBand->GetMetadata() );
1946 16 : poBand->bMetadataDirty = FALSE;
1947 : }
1948 : }
1949 :
1950 280 : if( nGCPCount > 0 )
1951 : {
1952 0 : GDALDeinitGCPs( nGCPCount, asGCPList );
1953 : }
1954 : }
1955 :
1956 : /************************************************************************/
1957 : /* WriteProjection() */
1958 : /************************************************************************/
1959 :
1960 184 : CPLErr HFADataset::WriteProjection()
1961 :
1962 : {
1963 : Eprj_Datum sDatum;
1964 : Eprj_ProParameters sPro;
1965 : Eprj_MapInfo sMapInfo;
1966 184 : OGRSpatialReference oSRS;
1967 184 : OGRSpatialReference *poGeogSRS = NULL;
1968 : int bHaveSRS;
1969 184 : char *pszP = pszProjection;
1970 184 : int bPEStringStored = FALSE;
1971 :
1972 184 : bGeoDirty = FALSE;
1973 :
1974 184 : if( pszProjection != NULL && strlen(pszProjection) > 0
1975 : && oSRS.importFromWkt( &pszP ) == OGRERR_NONE )
1976 160 : bHaveSRS = TRUE;
1977 : else
1978 24 : bHaveSRS = FALSE;
1979 :
1980 : /* -------------------------------------------------------------------- */
1981 : /* Initialize projection and datum. */
1982 : /* -------------------------------------------------------------------- */
1983 184 : memset( &sPro, 0, sizeof(sPro) );
1984 184 : memset( &sDatum, 0, sizeof(sDatum) );
1985 184 : memset( &sMapInfo, 0, sizeof(sMapInfo) );
1986 :
1987 : /* -------------------------------------------------------------------- */
1988 : /* Collect datum information. */
1989 : /* -------------------------------------------------------------------- */
1990 184 : if( bHaveSRS )
1991 : {
1992 160 : poGeogSRS = oSRS.CloneGeogCS();
1993 : }
1994 :
1995 184 : if( poGeogSRS )
1996 : {
1997 : int i;
1998 :
1999 160 : sDatum.datumname = (char *) poGeogSRS->GetAttrValue( "GEOGCS|DATUM" );
2000 :
2001 : /* WKT to Imagine translation */
2002 470 : for( i = 0; apszDatumMap[i] != NULL; i += 2 )
2003 : {
2004 440 : if( EQUAL(sDatum.datumname,apszDatumMap[i+1]) )
2005 : {
2006 130 : sDatum.datumname = (char *) apszDatumMap[i];
2007 130 : break;
2008 : }
2009 : }
2010 :
2011 : /* Map some EPSG datum codes directly to Imagine names */
2012 160 : int nGCS = poGeogSRS->GetEPSGGeogCS();
2013 :
2014 160 : if( nGCS == 4326 )
2015 78 : sDatum.datumname = (char*) "WGS 84";
2016 160 : if( nGCS == 4322 )
2017 0 : sDatum.datumname = (char*) "WGS 1972";
2018 160 : if( nGCS == 4267 )
2019 48 : sDatum.datumname = (char*) "NAD27";
2020 160 : if( nGCS == 4269 )
2021 4 : sDatum.datumname = (char*) "NAD83";
2022 160 : if( nGCS == 4283 )
2023 0 : sDatum.datumname = (char*) "GDA94";
2024 :
2025 160 : if( poGeogSRS->GetTOWGS84( sDatum.params ) == OGRERR_NONE )
2026 22 : sDatum.type = EPRJ_DATUM_PARAMETRIC;
2027 138 : else if( EQUAL(sDatum.datumname,"NAD27") )
2028 : {
2029 48 : sDatum.type = EPRJ_DATUM_GRID;
2030 48 : sDatum.gridname = (char*) "nadcon.dat";
2031 : }
2032 : else
2033 : {
2034 : /* we will default to this (effectively WGS84) for now */
2035 90 : sDatum.type = EPRJ_DATUM_PARAMETRIC;
2036 : }
2037 :
2038 : /* Verify if we need to write a ESRI PE string */
2039 160 : bPEStringStored = WritePeStringIfNeeded(&oSRS, hHFA);
2040 :
2041 : sPro.proSpheroid.sphereName = (char *)
2042 160 : poGeogSRS->GetAttrValue( "GEOGCS|DATUM|SPHEROID" );
2043 160 : sPro.proSpheroid.a = poGeogSRS->GetSemiMajor();
2044 160 : sPro.proSpheroid.b = poGeogSRS->GetSemiMinor();
2045 160 : sPro.proSpheroid.radius = sPro.proSpheroid.a;
2046 :
2047 160 : double a2 = sPro.proSpheroid.a*sPro.proSpheroid.a;
2048 160 : double b2 = sPro.proSpheroid.b*sPro.proSpheroid.b;
2049 :
2050 160 : sPro.proSpheroid.eSquared = (a2-b2)/a2;
2051 : }
2052 :
2053 : /* -------------------------------------------------------------------- */
2054 : /* Recognise various projections. */
2055 : /* -------------------------------------------------------------------- */
2056 184 : const char * pszProjName = NULL;
2057 :
2058 184 : if( bHaveSRS )
2059 160 : pszProjName = oSRS.GetAttrValue( "PROJCS|PROJECTION" );
2060 :
2061 184 : if( bForceToPEString && !bPEStringStored )
2062 : {
2063 0 : char *pszPEString = NULL;
2064 0 : oSRS.morphToESRI();
2065 0 : oSRS.exportToWkt( &pszPEString );
2066 : // need to transform this into ESRI format.
2067 0 : HFASetPEString( hHFA, pszPEString );
2068 0 : CPLFree( pszPEString );
2069 :
2070 0 : bPEStringStored = TRUE;
2071 : }
2072 184 : else if( pszProjName == NULL )
2073 : {
2074 94 : if( bHaveSRS && oSRS.IsGeographic() )
2075 : {
2076 70 : sPro.proNumber = EPRJ_LATLONG;
2077 70 : sPro.proName = (char*) "Geographic (Lat/Lon)";
2078 : }
2079 : }
2080 :
2081 : /* FIXME/NOTDEF/TODO: Add State Plane */
2082 90 : else if( !bIgnoreUTM && oSRS.GetUTMZone( NULL ) != 0 )
2083 : {
2084 : int bNorth, nZone;
2085 :
2086 48 : nZone = oSRS.GetUTMZone( &bNorth );
2087 48 : sPro.proNumber = EPRJ_UTM;
2088 48 : sPro.proName = (char*) "UTM";
2089 48 : sPro.proZone = nZone;
2090 48 : if( bNorth )
2091 48 : sPro.proParams[3] = 1.0;
2092 : else
2093 0 : sPro.proParams[3] = -1.0;
2094 : }
2095 :
2096 42 : else if( EQUAL(pszProjName,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
2097 : {
2098 0 : sPro.proNumber = EPRJ_ALBERS_CONIC_EQUAL_AREA;
2099 0 : sPro.proName = (char*) "Albers Conical Equal Area";
2100 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2101 0 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_2)*D2R;
2102 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2103 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2104 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2105 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2106 : }
2107 42 : else if( EQUAL(pszProjName,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
2108 : {
2109 0 : sPro.proNumber = EPRJ_LAMBERT_CONFORMAL_CONIC;
2110 0 : sPro.proName = (char*) "Lambert Conformal Conic";
2111 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2112 0 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_2)*D2R;
2113 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2114 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2115 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2116 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2117 : }
2118 42 : else if( EQUAL(pszProjName,SRS_PT_MERCATOR_1SP)
2119 : && oSRS.GetProjParm(SRS_PP_SCALE_FACTOR) == 1.0 )
2120 : {
2121 0 : sPro.proNumber = EPRJ_MERCATOR;
2122 0 : sPro.proName = (char*) "Mercator";
2123 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2124 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2125 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2126 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2127 : }
2128 42 : else if( EQUAL(pszProjName,SRS_PT_MERCATOR_1SP) )
2129 : {
2130 0 : sPro.proNumber = EPRJ_MERCATOR_VARIANT_A;
2131 0 : sPro.proName = (char*) "Mercator (Variant A)";
2132 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2133 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2134 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR);
2135 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2136 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2137 : }
2138 42 : else if( EQUAL(pszProjName,SRS_PT_KROVAK) )
2139 : {
2140 2 : sPro.proNumber = EPRJ_KROVAK;
2141 2 : sPro.proName = (char*) "Krovak";
2142 2 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR);
2143 2 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_AZIMUTH)*D2R;
2144 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2145 2 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2146 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2147 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2148 2 : sPro.proParams[9] = oSRS.GetProjParm(SRS_PP_PSEUDO_STD_PARALLEL_1);
2149 :
2150 : // XY plane rotation
2151 2 : sPro.proParams[8] = 0.0;
2152 : // X scale
2153 2 : sPro.proParams[10] = 1.0;
2154 : // Y scale
2155 2 : sPro.proParams[11] = 1.0;
2156 : }
2157 40 : else if( EQUAL(pszProjName,SRS_PT_POLAR_STEREOGRAPHIC) )
2158 : {
2159 0 : sPro.proNumber = EPRJ_POLAR_STEREOGRAPHIC;
2160 0 : sPro.proName = (char*) "Polar Stereographic";
2161 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2162 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2163 : /* hopefully the scale factor is 1.0! */
2164 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2165 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2166 : }
2167 40 : else if( EQUAL(pszProjName,SRS_PT_POLYCONIC) )
2168 : {
2169 2 : sPro.proNumber = EPRJ_POLYCONIC;
2170 2 : sPro.proName = (char*) "Polyconic";
2171 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2172 2 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2173 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2174 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2175 : }
2176 38 : else if( EQUAL(pszProjName,SRS_PT_EQUIDISTANT_CONIC) )
2177 : {
2178 0 : sPro.proNumber = EPRJ_EQUIDISTANT_CONIC;
2179 0 : sPro.proName = (char*) "Equidistant Conic";
2180 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2181 0 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_2)*D2R;
2182 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2183 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2184 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2185 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2186 0 : sPro.proParams[8] = 1.0;
2187 : }
2188 38 : else if( EQUAL(pszProjName,SRS_PT_TRANSVERSE_MERCATOR) )
2189 : {
2190 2 : sPro.proNumber = EPRJ_TRANSVERSE_MERCATOR;
2191 2 : sPro.proName = (char*) "Transverse Mercator";
2192 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2193 2 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2194 2 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
2195 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2196 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2197 : }
2198 36 : else if( EQUAL(pszProjName,SRS_PT_STEREOGRAPHIC) )
2199 : {
2200 0 : sPro.proNumber = EPRJ_STEREOGRAPHIC_EXTENDED;
2201 0 : sPro.proName = (char*) "Stereographic (Extended)";
2202 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
2203 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2204 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2205 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2206 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2207 : }
2208 36 : else if( EQUAL(pszProjName,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
2209 : {
2210 2 : sPro.proNumber = EPRJ_LAMBERT_AZIMUTHAL_EQUAL_AREA;
2211 2 : sPro.proName = (char*) "Lambert Azimuthal Equal-area";
2212 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2213 2 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2214 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2215 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2216 : }
2217 34 : else if( EQUAL(pszProjName,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
2218 : {
2219 0 : sPro.proNumber = EPRJ_AZIMUTHAL_EQUIDISTANT;
2220 0 : sPro.proName = (char*) "Azimuthal Equidistant";
2221 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2222 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2223 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2224 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2225 : }
2226 34 : else if( EQUAL(pszProjName,SRS_PT_GNOMONIC) )
2227 : {
2228 0 : sPro.proNumber = EPRJ_GNOMONIC;
2229 0 : sPro.proName = (char*) "Gnomonic";
2230 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2231 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2232 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2233 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2234 : }
2235 34 : else if( EQUAL(pszProjName,SRS_PT_ORTHOGRAPHIC) )
2236 : {
2237 0 : sPro.proNumber = EPRJ_ORTHOGRAPHIC;
2238 0 : sPro.proName = (char*) "Orthographic";
2239 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2240 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2241 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2242 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2243 : }
2244 34 : else if( EQUAL(pszProjName,SRS_PT_SINUSOIDAL) )
2245 : {
2246 0 : sPro.proNumber = EPRJ_SINUSOIDAL;
2247 0 : sPro.proName = (char*) "Sinusoidal";
2248 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2249 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2250 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2251 : }
2252 34 : else if( EQUAL(pszProjName,SRS_PT_EQUIRECTANGULAR) )
2253 : {
2254 0 : sPro.proNumber = EPRJ_EQUIRECTANGULAR;
2255 0 : sPro.proName = (char*) "Equirectangular";
2256 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2257 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2258 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2259 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2260 : }
2261 34 : else if( EQUAL(pszProjName,SRS_PT_MILLER_CYLINDRICAL) )
2262 : {
2263 0 : sPro.proNumber = EPRJ_MILLER_CYLINDRICAL;
2264 0 : sPro.proName = (char*) "Miller Cylindrical";
2265 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2266 : /* hopefully the latitude is zero! */
2267 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2268 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2269 : }
2270 34 : else if( EQUAL(pszProjName,SRS_PT_VANDERGRINTEN) )
2271 : {
2272 0 : sPro.proNumber = EPRJ_VANDERGRINTEN;
2273 0 : sPro.proName = (char*) "Van der Grinten";
2274 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2275 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2276 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2277 : }
2278 34 : else if( EQUAL(pszProjName,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
2279 : {
2280 0 : sPro.proNumber = EPRJ_HOTINE_OBLIQUE_MERCATOR;
2281 0 : sPro.proName = (char*) "Oblique Mercator (Hotine)";
2282 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
2283 0 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_AZIMUTH)*D2R;
2284 : /* hopefully the rectified grid angle is zero */
2285 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2286 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2287 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2288 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2289 0 : sPro.proParams[12] = 1.0;
2290 : }
2291 34 : else if( EQUAL(pszProjName,SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER) )
2292 : {
2293 4 : sPro.proNumber = EPRJ_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER;
2294 4 : sPro.proName = (char*) "Hotine Oblique Mercator Azimuth Center";
2295 4 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
2296 4 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_AZIMUTH)*D2R;
2297 4 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2298 4 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2299 4 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2300 4 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2301 4 : sPro.proParams[12] = 1.0;
2302 : }
2303 30 : else if( EQUAL(pszProjName,SRS_PT_ROBINSON) )
2304 : {
2305 0 : sPro.proNumber = EPRJ_ROBINSON;
2306 0 : sPro.proName = (char*) "Robinson";
2307 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2308 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2309 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2310 : }
2311 30 : else if( EQUAL(pszProjName,SRS_PT_MOLLWEIDE) )
2312 : {
2313 0 : sPro.proNumber = EPRJ_MOLLWEIDE;
2314 0 : sPro.proName = (char*) "Mollweide";
2315 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2316 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2317 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2318 : }
2319 30 : else if( EQUAL(pszProjName,SRS_PT_ECKERT_I) )
2320 : {
2321 0 : sPro.proNumber = EPRJ_ECKERT_I;
2322 0 : sPro.proName = (char*) "Eckert I";
2323 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2324 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2325 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2326 : }
2327 30 : else if( EQUAL(pszProjName,SRS_PT_ECKERT_II) )
2328 : {
2329 0 : sPro.proNumber = EPRJ_ECKERT_II;
2330 0 : sPro.proName = (char*) "Eckert II";
2331 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2332 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2333 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2334 : }
2335 30 : else if( EQUAL(pszProjName,SRS_PT_ECKERT_III) )
2336 : {
2337 0 : sPro.proNumber = EPRJ_ECKERT_III;
2338 0 : sPro.proName = (char*) "Eckert III";
2339 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2340 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2341 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2342 : }
2343 30 : else if( EQUAL(pszProjName,SRS_PT_ECKERT_IV) )
2344 : {
2345 0 : sPro.proNumber = EPRJ_ECKERT_IV;
2346 0 : sPro.proName = (char*) "Eckert IV";
2347 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2348 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2349 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2350 : }
2351 30 : else if( EQUAL(pszProjName,SRS_PT_ECKERT_V) )
2352 : {
2353 0 : sPro.proNumber = EPRJ_ECKERT_V;
2354 0 : sPro.proName = (char*) "Eckert V";
2355 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2356 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2357 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2358 : }
2359 30 : else if( EQUAL(pszProjName,SRS_PT_ECKERT_VI) )
2360 : {
2361 0 : sPro.proNumber = EPRJ_ECKERT_VI;
2362 0 : sPro.proName = (char*) "Eckert VI";
2363 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2364 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2365 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2366 : }
2367 30 : else if( EQUAL(pszProjName,SRS_PT_GALL_STEREOGRAPHIC) )
2368 : {
2369 0 : sPro.proNumber = EPRJ_GALL_STEREOGRAPHIC;
2370 0 : sPro.proName = (char*) "Gall Stereographic";
2371 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2372 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2373 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2374 : }
2375 30 : else if( EQUAL(pszProjName,SRS_PT_CASSINI_SOLDNER) )
2376 : {
2377 0 : sPro.proNumber = EPRJ_CASSINI;
2378 0 : sPro.proName = (char*) "Cassini";
2379 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2380 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2381 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2382 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2383 : }
2384 30 : else if( EQUAL(pszProjName,SRS_PT_TWO_POINT_EQUIDISTANT) )
2385 : {
2386 0 : sPro.proNumber = EPRJ_TWO_POINT_EQUIDISTANT;
2387 0 : sPro.proName = (char*) "Two_Point_Equidistant";
2388 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2389 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2390 0 : sPro.proParams[8] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_POINT_1, 0.0)*D2R;
2391 0 : sPro.proParams[9] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_POINT_1, 0.0)*D2R;
2392 0 : sPro.proParams[10] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_POINT_2, 60.0)*D2R;
2393 0 : sPro.proParams[11] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_POINT_2, 60.0)*D2R;
2394 : }
2395 30 : else if( EQUAL(pszProjName,SRS_PT_BONNE) )
2396 : {
2397 0 : sPro.proNumber = EPRJ_BONNE;
2398 0 : sPro.proName = (char*) "Bonne";
2399 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2400 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2401 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2402 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2403 : }
2404 30 : else if( EQUAL(pszProjName,"Loximuthal") )
2405 : {
2406 0 : sPro.proNumber = EPRJ_LOXIMUTHAL;
2407 0 : sPro.proName = (char*) "Loximuthal";
2408 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2409 0 : sPro.proParams[5] = oSRS.GetProjParm("central_parallel")*D2R;
2410 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2411 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2412 : }
2413 30 : else if( EQUAL(pszProjName,"Quartic_Authalic") )
2414 : {
2415 0 : sPro.proNumber = EPRJ_QUARTIC_AUTHALIC;
2416 0 : sPro.proName = (char*) "Quartic Authalic";
2417 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2418 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2419 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2420 : }
2421 30 : else if( EQUAL(pszProjName,"Winkel_I") )
2422 : {
2423 0 : sPro.proNumber = EPRJ_WINKEL_I;
2424 0 : sPro.proName = (char*) "Winkel I";
2425 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2426 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2427 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2428 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2429 : }
2430 30 : else if( EQUAL(pszProjName,"Winkel_II") )
2431 : {
2432 0 : sPro.proNumber = EPRJ_WINKEL_II;
2433 0 : sPro.proName = (char*) "Winkel II";
2434 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2435 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2436 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2437 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2438 : }
2439 30 : else if( EQUAL(pszProjName,"Behrmann") )
2440 : {
2441 0 : sPro.proNumber = EPRJ_BEHRMANN;
2442 0 : sPro.proName = (char*) "Behrmann";
2443 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2444 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2445 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2446 : }
2447 30 : else if( EQUAL(pszProjName,"Equidistant_Cylindrical") )
2448 : {
2449 2 : sPro.proNumber = EPRJ_EQUIDISTANT_CYLINDRICAL;
2450 2 : sPro.proName = (char*) "Equidistant_Cylindrical";
2451 2 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2452 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2453 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2454 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2455 : }
2456 28 : else if( EQUAL(pszProjName, SRS_PT_KROVAK) )
2457 : {
2458 0 : sPro.proNumber = EPRJ_KROVAK;
2459 0 : sPro.proName = (char*) "Krovak";
2460 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR, 1.0);
2461 0 : sPro.proParams[3] = oSRS.GetProjParm(SRS_PP_AZIMUTH)*D2R;
2462 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER)*D2R;
2463 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER)*D2R;
2464 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2465 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2466 0 : sPro.proParams[8] = oSRS.GetProjParm("XY_Plane_Rotation", 0.0)*D2R;
2467 0 : sPro.proParams[9] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2468 0 : sPro.proParams[10] = oSRS.GetProjParm("X_Scale", 1.0);
2469 0 : sPro.proParams[11] = oSRS.GetProjParm("Y_Scale", 1.0);
2470 : }
2471 28 : else if( EQUAL(pszProjName, "Double_Stereographic") )
2472 : {
2473 2 : sPro.proNumber = EPRJ_DOUBLE_STEREOGRAPHIC;
2474 2 : sPro.proName = (char*) "Double_Stereographic";
2475 2 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR, 1.0);
2476 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2477 2 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN)*D2R;
2478 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2479 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2480 : }
2481 26 : else if( EQUAL(pszProjName, "Aitoff") )
2482 : {
2483 0 : sPro.proNumber = EPRJ_AITOFF;
2484 0 : sPro.proName = (char*) "Aitoff";
2485 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2486 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2487 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2488 : }
2489 26 : else if( EQUAL(pszProjName, "Craster_Parabolic") )
2490 : {
2491 0 : sPro.proNumber = EPRJ_CRASTER_PARABOLIC;
2492 0 : sPro.proName = (char*) "Craster_Parabolic";
2493 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2494 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2495 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2496 : }
2497 26 : else if( EQUAL(pszProjName, SRS_PT_CYLINDRICAL_EQUAL_AREA) )
2498 : {
2499 2 : sPro.proNumber = EPRJ_CYLINDRICAL_EQUAL_AREA;
2500 2 : sPro.proName = (char*) "Cylindrical_Equal_Area";
2501 2 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2502 2 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2503 2 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2504 2 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2505 : }
2506 24 : else if( EQUAL(pszProjName, "Flat_Polar_Quartic") )
2507 : {
2508 0 : sPro.proNumber = EPRJ_FLAT_POLAR_QUARTIC;
2509 0 : sPro.proName = (char*) "Flat_Polar_Quartic";
2510 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2511 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2512 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2513 : }
2514 24 : else if( EQUAL(pszProjName, "Times") )
2515 : {
2516 0 : sPro.proNumber = EPRJ_TIMES;
2517 0 : sPro.proName = (char*) "Times";
2518 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2519 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2520 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2521 : }
2522 24 : else if( EQUAL(pszProjName, "Winkel_Tripel") )
2523 : {
2524 0 : sPro.proNumber = EPRJ_WINKEL_TRIPEL;
2525 0 : sPro.proName = (char*) "Winkel_Tripel";
2526 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_STANDARD_PARALLEL_1)*D2R;
2527 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2528 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2529 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2530 : }
2531 24 : else if( EQUAL(pszProjName, "Hammer_Aitoff") )
2532 : {
2533 0 : sPro.proNumber = EPRJ_HAMMER_AITOFF;
2534 0 : sPro.proName = (char*) "Hammer_Aitoff";
2535 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_CENTRAL_MERIDIAN)*D2R;
2536 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2537 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2538 : }
2539 24 : else if( EQUAL(pszProjName, "Vertical_Near_Side_Perspective") )
2540 : {
2541 0 : sPro.proNumber = EPRJ_VERTICAL_NEAR_SIDE_PERSPECTIVE;
2542 0 : sPro.proName = (char*) "Vertical_Near_Side_Perspective";
2543 0 : sPro.proParams[2] = oSRS.GetProjParm("Height");
2544 0 : sPro.proParams[4] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_CENTER, 75.0)*D2R;
2545 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER, 40.0)*D2R;
2546 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2547 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2548 : }
2549 24 : else if( EQUAL(pszProjName, "Hotine_Oblique_Mercator_Two_Point_Center") )
2550 : {
2551 0 : sPro.proNumber = EPRJ_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_CENTER;
2552 0 : sPro.proName = (char*) "Hotine_Oblique_Mercator_Two_Point_Center";
2553 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR, 1.0);
2554 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER, 40.0)*D2R;
2555 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2556 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2557 0 : sPro.proParams[8] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_POINT_1, 0.0)*D2R;
2558 0 : sPro.proParams[9] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_POINT_1, 0.0)*D2R;
2559 0 : sPro.proParams[10] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_POINT_2, 60.0)*D2R;
2560 0 : sPro.proParams[11] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_POINT_2, 60.0)*D2R;
2561 : }
2562 24 : else if( EQUAL(pszProjName, SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN) )
2563 : {
2564 0 : sPro.proNumber = EPRJ_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN;
2565 0 : sPro.proName = (char*) "Hotine_Oblique_Mercator_Two_Point_Natural_Origin";
2566 0 : sPro.proParams[2] = oSRS.GetProjParm(SRS_PP_SCALE_FACTOR, 1.0);
2567 0 : sPro.proParams[5] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_CENTER, 40.0)*D2R;
2568 0 : sPro.proParams[6] = oSRS.GetProjParm(SRS_PP_FALSE_EASTING);
2569 0 : sPro.proParams[7] = oSRS.GetProjParm(SRS_PP_FALSE_NORTHING);
2570 0 : sPro.proParams[8] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_POINT_1, 0.0)*D2R;
2571 0 : sPro.proParams[9] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_POINT_1, 0.0)*D2R;
2572 0 : sPro.proParams[10] = oSRS.GetProjParm(SRS_PP_LONGITUDE_OF_POINT_2, 60.0)*D2R;
2573 0 : sPro.proParams[11] = oSRS.GetProjParm(SRS_PP_LATITUDE_OF_POINT_2, 60.0)*D2R;
2574 : }
2575 24 : else if( EQUAL(pszProjName,"New_Zealand_Map_Grid") )
2576 : {
2577 2 : sPro.proType = EPRJ_EXTERNAL;
2578 2 : sPro.proNumber = 0;
2579 2 : sPro.proExeName = (char*) EPRJ_EXTERNAL_NZMG;
2580 2 : sPro.proName = (char*) "New Zealand Map Grid";
2581 2 : sPro.proZone = 0;
2582 2 : sPro.proParams[0] = 0; // false easting etc not stored in .img it seems
2583 2 : sPro.proParams[1] = 0; // always fixed by definition.
2584 2 : sPro.proParams[2] = 0;
2585 2 : sPro.proParams[3] = 0;
2586 2 : sPro.proParams[4] = 0;
2587 2 : sPro.proParams[5] = 0;
2588 2 : sPro.proParams[6] = 0;
2589 2 : sPro.proParams[7] = 0;
2590 : }
2591 : // Anything we can't map, we store as an ESRI PE_STRING
2592 22 : else if( oSRS.IsProjected() || oSRS.IsGeographic() )
2593 : {
2594 22 : if(!bPEStringStored)
2595 : {
2596 0 : char *pszPEString = NULL;
2597 0 : oSRS.morphToESRI();
2598 0 : oSRS.exportToWkt( &pszPEString );
2599 : // need to transform this into ESRI format.
2600 0 : HFASetPEString( hHFA, pszPEString );
2601 0 : CPLFree( pszPEString );
2602 0 : bPEStringStored = TRUE;
2603 : }
2604 : }
2605 : else
2606 : {
2607 : CPLError( CE_Warning, CPLE_NotSupported,
2608 : "Projection %s not supported for translation to Imagine.",
2609 0 : pszProjName );
2610 : }
2611 :
2612 : /* -------------------------------------------------------------------- */
2613 : /* MapInfo */
2614 : /* -------------------------------------------------------------------- */
2615 184 : const char *pszPROJCS = oSRS.GetAttrValue( "PROJCS" );
2616 :
2617 184 : if( pszPROJCS )
2618 90 : sMapInfo.proName = (char *) pszPROJCS;
2619 164 : else if( bHaveSRS && sPro.proName != NULL )
2620 70 : sMapInfo.proName = sPro.proName;
2621 : else
2622 24 : sMapInfo.proName = (char*) "Unknown";
2623 :
2624 : sMapInfo.upperLeftCenter.x =
2625 184 : adfGeoTransform[0] + adfGeoTransform[1]*0.5;
2626 : sMapInfo.upperLeftCenter.y =
2627 184 : adfGeoTransform[3] + adfGeoTransform[5]*0.5;
2628 :
2629 : sMapInfo.lowerRightCenter.x =
2630 184 : adfGeoTransform[0] + adfGeoTransform[1] * (GetRasterXSize()-0.5);
2631 : sMapInfo.lowerRightCenter.y =
2632 184 : adfGeoTransform[3] + adfGeoTransform[5] * (GetRasterYSize()-0.5);
2633 :
2634 184 : sMapInfo.pixelSize.width = ABS(adfGeoTransform[1]);
2635 184 : sMapInfo.pixelSize.height = ABS(adfGeoTransform[5]);
2636 :
2637 : /* -------------------------------------------------------------------- */
2638 : /* Handle units. Try to match up with a known name. */
2639 : /* -------------------------------------------------------------------- */
2640 184 : sMapInfo.units = (char*) "meters";
2641 :
2642 184 : if( bHaveSRS && oSRS.IsGeographic() )
2643 70 : sMapInfo.units = (char*) "dd";
2644 114 : else if( bHaveSRS && oSRS.GetLinearUnits() != 1.0 )
2645 : {
2646 8 : double dfClosestDiff = 100.0;
2647 8 : int iClosest=-1, iUnit;
2648 8 : char *pszUnitName = NULL;
2649 8 : double dfActualSize = oSRS.GetLinearUnits( &pszUnitName );
2650 :
2651 280 : for( iUnit = 0; apszUnitMap[iUnit] != NULL; iUnit += 2 )
2652 : {
2653 272 : if( fabs(atof(apszUnitMap[iUnit+1]) - dfActualSize) < dfClosestDiff )
2654 : {
2655 28 : iClosest = iUnit;
2656 28 : dfClosestDiff = fabs(atof(apszUnitMap[iUnit+1])-dfActualSize);
2657 : }
2658 : }
2659 :
2660 10 : if( iClosest == -1 || fabs(dfClosestDiff/dfActualSize) > 0.0001 )
2661 : {
2662 : CPLError( CE_Warning, CPLE_NotSupported,
2663 : "Unable to identify Erdas units matching %s/%gm,\n"
2664 : "output units will be wrong.",
2665 2 : pszUnitName, dfActualSize );
2666 : }
2667 : else
2668 6 : sMapInfo.units = (char *) apszUnitMap[iClosest];
2669 :
2670 : /* We need to convert false easting and northing to meters. */
2671 8 : sPro.proParams[6] *= dfActualSize;
2672 8 : sPro.proParams[7] *= dfActualSize;
2673 : }
2674 :
2675 : /* -------------------------------------------------------------------- */
2676 : /* Write out definitions. */
2677 : /* -------------------------------------------------------------------- */
2678 366 : if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 )
2679 : {
2680 182 : HFASetMapInfo( hHFA, &sMapInfo );
2681 : }
2682 : else
2683 : {
2684 : HFASetGeoTransform( hHFA,
2685 : sMapInfo.proName, sMapInfo.units,
2686 2 : adfGeoTransform );
2687 : }
2688 :
2689 322 : if( bHaveSRS && sPro.proName != NULL)
2690 : {
2691 138 : HFASetProParameters( hHFA, &sPro );
2692 138 : HFASetDatum( hHFA, &sDatum );
2693 :
2694 138 : if( !bPEStringStored )
2695 0 : HFASetPEString( hHFA, "" );
2696 : }
2697 46 : else if( !bPEStringStored )
2698 24 : ClearSR(hHFA);
2699 :
2700 : /* -------------------------------------------------------------------- */
2701 : /* Cleanup */
2702 : /* -------------------------------------------------------------------- */
2703 184 : if( poGeogSRS != NULL )
2704 160 : delete poGeogSRS;
2705 :
2706 184 : return CE_None;
2707 : }
2708 :
2709 : /************************************************************************/
2710 : /* WritePeStringIfNeeded() */
2711 : /************************************************************************/
2712 160 : int WritePeStringIfNeeded(OGRSpatialReference* poSRS, HFAHandle hHFA)
2713 : {
2714 160 : OGRBoolean ret = FALSE;
2715 160 : if(!poSRS || !hHFA)
2716 0 : return ret;
2717 :
2718 160 : const char *pszGEOGCS = poSRS->GetAttrValue( "GEOGCS" );
2719 160 : const char *pszDatum = poSRS->GetAttrValue( "DATUM" );
2720 160 : int gcsNameOffset = 0;
2721 160 : int datumNameOffset = 0;
2722 160 : if(strstr(pszGEOGCS, "GCS_"))
2723 6 : gcsNameOffset = strlen("GCS_");
2724 160 : if(strstr(pszDatum, "D_"))
2725 0 : datumNameOffset = strlen("D_");
2726 :
2727 160 : if(!EQUAL(pszGEOGCS+gcsNameOffset, pszDatum+datumNameOffset))
2728 152 : ret = TRUE;
2729 : else
2730 : {
2731 8 : const char* name = poSRS->GetAttrValue("PRIMEM");
2732 8 : if(name && !EQUAL(name,"Greenwich"))
2733 0 : ret = TRUE;
2734 8 : if(!ret)
2735 : {
2736 8 : OGR_SRSNode * poAUnits = poSRS->GetAttrNode( "GEOGCS|UNIT" );
2737 8 : name = poAUnits->GetChild(0)->GetValue();
2738 8 : if(name && !EQUAL(name,"Degree"))
2739 0 : ret = TRUE;
2740 : }
2741 8 : if(!ret)
2742 : {
2743 8 : name = poSRS->GetAttrValue("UNIT");
2744 8 : if(name)
2745 : {
2746 8 : ret = TRUE;
2747 280 : for(int i=0; apszUnitMap[i] != NULL; i+=2)
2748 272 : if(EQUAL(name, apszUnitMap[i]))
2749 2 : ret = FALSE;
2750 : }
2751 : }
2752 8 : if(!ret)
2753 : {
2754 2 : int nGCS = poSRS->GetEPSGGeogCS();
2755 2 : switch(nGCS)
2756 : {
2757 : case 4326:
2758 2 : if(!EQUAL(pszDatum+datumNameOffset, "WGS_84"))
2759 2 : ret = TRUE;
2760 2 : break;
2761 : case 4322:
2762 0 : if(!EQUAL(pszDatum+datumNameOffset, "WGS_72"))
2763 0 : ret = TRUE;
2764 0 : break;
2765 : case 4267:
2766 0 : if(!EQUAL(pszDatum+datumNameOffset, "North_America_1927"))
2767 0 : ret = TRUE;
2768 0 : break;
2769 : case 4269:
2770 0 : if(!EQUAL(pszDatum+datumNameOffset, "North_America_1983"))
2771 0 : ret = TRUE;
2772 : break;
2773 : }
2774 : }
2775 : }
2776 160 : if(ret)
2777 : {
2778 160 : char *pszPEString = NULL;
2779 160 : poSRS->morphToESRI();
2780 160 : poSRS->exportToWkt( &pszPEString );
2781 160 : HFASetPEString( hHFA, pszPEString );
2782 160 : CPLFree( pszPEString );
2783 : }
2784 :
2785 160 : return ret;
2786 : }
2787 :
2788 : /************************************************************************/
2789 : /* ClearSR() */
2790 : /************************************************************************/
2791 24 : void ClearSR(HFAHandle hHFA)
2792 : {
2793 48 : for( int iBand = 0; iBand < hHFA->nBands; iBand++ )
2794 : {
2795 : HFAEntry *poMIEntry;
2796 24 : if( hHFA->papoBand[iBand]->poNode && (poMIEntry = hHFA->papoBand[iBand]->poNode->GetNamedChild("Projection")) != NULL )
2797 : {
2798 0 : poMIEntry->MarkDirty();
2799 0 : poMIEntry->SetIntField( "proType", 0 );
2800 0 : poMIEntry->SetIntField( "proNumber", 0 );
2801 0 : poMIEntry->SetStringField( "proExeName", "");
2802 0 : poMIEntry->SetStringField( "proName", "");
2803 0 : poMIEntry->SetIntField( "proZone", 0 );
2804 0 : poMIEntry->SetDoubleField( "proParams[0]", 0.0 );
2805 0 : poMIEntry->SetDoubleField( "proParams[1]", 0.0 );
2806 0 : poMIEntry->SetDoubleField( "proParams[2]", 0.0 );
2807 0 : poMIEntry->SetDoubleField( "proParams[3]", 0.0 );
2808 0 : poMIEntry->SetDoubleField( "proParams[4]", 0.0 );
2809 0 : poMIEntry->SetDoubleField( "proParams[5]", 0.0 );
2810 0 : poMIEntry->SetDoubleField( "proParams[6]", 0.0 );
2811 0 : poMIEntry->SetDoubleField( "proParams[7]", 0.0 );
2812 0 : poMIEntry->SetDoubleField( "proParams[8]", 0.0 );
2813 0 : poMIEntry->SetDoubleField( "proParams[9]", 0.0 );
2814 0 : poMIEntry->SetDoubleField( "proParams[10]", 0.0 );
2815 0 : poMIEntry->SetDoubleField( "proParams[11]", 0.0 );
2816 0 : poMIEntry->SetDoubleField( "proParams[12]", 0.0 );
2817 0 : poMIEntry->SetDoubleField( "proParams[13]", 0.0 );
2818 0 : poMIEntry->SetDoubleField( "proParams[14]", 0.0 );
2819 0 : poMIEntry->SetStringField( "proSpheroid.sphereName", "" );
2820 0 : poMIEntry->SetDoubleField( "proSpheroid.a", 0.0 );
2821 0 : poMIEntry->SetDoubleField( "proSpheroid.b", 0.0 );
2822 0 : poMIEntry->SetDoubleField( "proSpheroid.eSquared", 0.0 );
2823 0 : poMIEntry->SetDoubleField( "proSpheroid.radius", 0.0 );
2824 0 : HFAEntry* poDatumEntry = poMIEntry->GetNamedChild("Datum");
2825 0 : if( poDatumEntry != NULL )
2826 : {
2827 0 : poDatumEntry->MarkDirty();
2828 0 : poDatumEntry->SetStringField( "datumname", "" );
2829 0 : poDatumEntry->SetIntField( "type", 0 );
2830 0 : poDatumEntry->SetDoubleField( "params[0]", 0.0 );
2831 0 : poDatumEntry->SetDoubleField( "params[1]", 0.0 );
2832 0 : poDatumEntry->SetDoubleField( "params[2]", 0.0 );
2833 0 : poDatumEntry->SetDoubleField( "params[3]", 0.0 );
2834 0 : poDatumEntry->SetDoubleField( "params[4]", 0.0 );
2835 0 : poDatumEntry->SetDoubleField( "params[5]", 0.0 );
2836 0 : poDatumEntry->SetDoubleField( "params[6]", 0.0 );
2837 0 : poDatumEntry->SetStringField( "gridname", "" );
2838 : }
2839 0 : poMIEntry->FlushToDisk();
2840 0 : char* peStr = HFAGetPEString( hHFA );
2841 0 : if( peStr != NULL && strlen(peStr) > 0 )
2842 0 : HFASetPEString( hHFA, "" );
2843 : }
2844 : }
2845 : return;
2846 : }
2847 :
2848 : /************************************************************************/
2849 : /* ESRIToUSGSZone() */
2850 : /* */
2851 : /* Convert ESRI style state plane zones to USGS style state */
2852 : /* plane zones. */
2853 : /************************************************************************/
2854 :
2855 6 : static int ESRIToUSGSZone( int nESRIZone )
2856 :
2857 : {
2858 6 : int nPairs = sizeof(anUsgsEsriZones) / (2*sizeof(int));
2859 : int i;
2860 :
2861 6 : if( nESRIZone < 0 )
2862 2 : return ABS(nESRIZone);
2863 :
2864 424 : for( i = 0; i < nPairs; i++ )
2865 : {
2866 424 : if( anUsgsEsriZones[i*2+1] == nESRIZone )
2867 4 : return anUsgsEsriZones[i*2];
2868 : }
2869 :
2870 0 : return 0;
2871 : }
2872 :
2873 : /************************************************************************/
2874 : /* PCSStructToWKT() */
2875 : /* */
2876 : /* Convert the datum, proparameters and mapinfo structures into */
2877 : /* WKT format. */
2878 : /************************************************************************/
2879 :
2880 : char *
2881 78 : HFAPCSStructToWKT( const Eprj_Datum *psDatum,
2882 : const Eprj_ProParameters *psPro,
2883 : const Eprj_MapInfo *psMapInfo,
2884 : HFAEntry *poMapInformation )
2885 :
2886 : {
2887 78 : OGRSpatialReference oSRS;
2888 78 : char *pszNewProj = NULL;
2889 :
2890 : /* -------------------------------------------------------------------- */
2891 : /* General case for Erdas style projections. */
2892 : /* */
2893 : /* We make a particular effort to adapt the mapinfo->proname as */
2894 : /* the PROJCS[] name per #2422. */
2895 : /* -------------------------------------------------------------------- */
2896 :
2897 78 : if( psPro == NULL && psMapInfo != NULL )
2898 : {
2899 0 : oSRS.SetLocalCS( psMapInfo->proName );
2900 : }
2901 :
2902 78 : else if( psPro == NULL )
2903 : {
2904 0 : return NULL;
2905 : }
2906 :
2907 78 : else if( psPro->proType == EPRJ_EXTERNAL )
2908 : {
2909 0 : if( EQUALN(psPro->proExeName,EPRJ_EXTERNAL_NZMG,4) )
2910 : {
2911 : /* -------------------------------------------------------------------- */
2912 : /* handle NZMG which is an external projection see */
2913 : /* http://www.linz.govt.nz/core/surveysystem/geodeticinfo\ */
2914 : /* /datums-projections/projections/nzmg/index.html */
2915 : /* -------------------------------------------------------------------- */
2916 : /* Is there a better way that doesn't require hardcoding of these numbers? */
2917 0 : oSRS.SetNZMG(-41.0,173.0,2510000,6023150);
2918 : }
2919 : else
2920 : {
2921 0 : oSRS.SetLocalCS( psPro->proName );
2922 : }
2923 : }
2924 :
2925 146 : else if( psPro->proNumber != EPRJ_LATLONG
2926 : && psMapInfo != NULL )
2927 : {
2928 68 : oSRS.SetProjCS( psMapInfo->proName );
2929 : }
2930 10 : else if( psPro->proNumber != EPRJ_LATLONG )
2931 : {
2932 10 : oSRS.SetProjCS( psPro->proName );
2933 : }
2934 :
2935 : /* -------------------------------------------------------------------- */
2936 : /* Handle units. It is important to deal with this first so */
2937 : /* that the projection Set methods will automatically do */
2938 : /* translation of linear values (like false easting) to PROJCS */
2939 : /* units from meters. Erdas linear projection values are */
2940 : /* always in meters. */
2941 : /* -------------------------------------------------------------------- */
2942 78 : int iUnitIndex = 0;
2943 :
2944 78 : if( oSRS.IsProjected() || oSRS.IsLocal() )
2945 : {
2946 78 : const char *pszUnits = NULL;
2947 :
2948 78 : if( psMapInfo )
2949 68 : pszUnits = psMapInfo->units;
2950 10 : else if( poMapInformation != NULL )
2951 8 : pszUnits = poMapInformation->GetStringField( "units.string" );
2952 :
2953 78 : if( pszUnits != NULL )
2954 : {
2955 296 : for( iUnitIndex = 0;
2956 148 : apszUnitMap[iUnitIndex] != NULL;
2957 : iUnitIndex += 2 )
2958 : {
2959 148 : if( EQUAL(apszUnitMap[iUnitIndex], pszUnits ) )
2960 76 : break;
2961 : }
2962 :
2963 76 : if( apszUnitMap[iUnitIndex] == NULL )
2964 0 : iUnitIndex = 0;
2965 :
2966 : oSRS.SetLinearUnits( pszUnits,
2967 76 : atof(apszUnitMap[iUnitIndex+1]) );
2968 : }
2969 : else
2970 2 : oSRS.SetLinearUnits( SRS_UL_METER, 1.0 );
2971 : }
2972 :
2973 78 : if( psPro == NULL )
2974 : {
2975 0 : if( oSRS.IsLocal() )
2976 : {
2977 0 : if( oSRS.exportToWkt( &pszNewProj ) == OGRERR_NONE )
2978 0 : return pszNewProj;
2979 : else
2980 : {
2981 0 : pszNewProj = NULL;
2982 0 : return NULL;
2983 : }
2984 : }
2985 : else
2986 0 : return NULL;
2987 : }
2988 :
2989 : /* -------------------------------------------------------------------- */
2990 : /* Try to work out ellipsoid and datum information. */
2991 : /* -------------------------------------------------------------------- */
2992 78 : const char *pszDatumName = psPro->proSpheroid.sphereName;
2993 78 : const char *pszEllipsoidName = psPro->proSpheroid.sphereName;
2994 : double dfInvFlattening;
2995 :
2996 78 : if( psDatum != NULL )
2997 : {
2998 : int i;
2999 :
3000 78 : pszDatumName = psDatum->datumname;
3001 :
3002 : /* Imagine to WKT translation */
3003 192 : for( i = 0; pszDatumName != NULL && apszDatumMap[i] != NULL; i += 2 )
3004 : {
3005 188 : if( EQUAL(pszDatumName,apszDatumMap[i]) )
3006 : {
3007 74 : pszDatumName = apszDatumMap[i+1];
3008 74 : break;
3009 : }
3010 : }
3011 : }
3012 :
3013 78 : if( psPro->proSpheroid.a == 0.0 )
3014 0 : ((Eprj_ProParameters *) psPro)->proSpheroid.a = 6378137.0;
3015 78 : if( psPro->proSpheroid.b == 0.0 )
3016 0 : ((Eprj_ProParameters *) psPro)->proSpheroid.b = 6356752.3;
3017 :
3018 78 : if( fabs(psPro->proSpheroid.b - psPro->proSpheroid.a) < 0.001 )
3019 0 : dfInvFlattening = 0.0; /* special value for sphere. */
3020 : else
3021 78 : dfInvFlattening = 1.0/(1.0-psPro->proSpheroid.b/psPro->proSpheroid.a);
3022 :
3023 : /* -------------------------------------------------------------------- */
3024 : /* Handle different projection methods. */
3025 : /* -------------------------------------------------------------------- */
3026 78 : switch( psPro->proNumber )
3027 : {
3028 : case EPRJ_LATLONG:
3029 0 : break;
3030 :
3031 : case EPRJ_UTM:
3032 : // We change this to unnamed so that SetUTM will set the long
3033 : // UTM description.
3034 50 : oSRS.SetProjCS( "unnamed" );
3035 50 : oSRS.SetUTM( psPro->proZone, psPro->proParams[3] >= 0.0 );
3036 :
3037 : // The PCS name from the above function may be different with the input name.
3038 : // If there is a PCS name in psMapInfo that is different with
3039 : // the one in psPro, just use it as the PCS name. This case happens
3040 : // if the dataset's SR was written by the new GDAL.
3041 50 : if( psMapInfo && strlen(psMapInfo->proName) > 0
3042 : && strlen(psPro->proName) > 0
3043 : && !EQUAL(psMapInfo->proName, psPro->proName) )
3044 14 : oSRS.SetProjCS( psMapInfo->proName );
3045 50 : break;
3046 :
3047 : case EPRJ_STATE_PLANE:
3048 : {
3049 6 : char *pszUnitsName = NULL;
3050 6 : double dfLinearUnits = oSRS.GetLinearUnits( &pszUnitsName );
3051 :
3052 6 : pszUnitsName = CPLStrdup( pszUnitsName );
3053 :
3054 : /* Historically, hfa used esri state plane zone code. Try esri pe string first. */
3055 6 : int zoneCode = ESRIToUSGSZone(psPro->proZone);
3056 : char nad[32];
3057 6 : strcpy(nad, "HARN");
3058 6 : if(psDatum)
3059 6 : strcpy(nad, psDatum->datumname);
3060 : char units[32];
3061 6 : strcpy(units, "meters");
3062 6 : if(psMapInfo)
3063 0 : strcpy(units, psMapInfo->units);
3064 6 : else if(pszUnitsName && strlen(pszUnitsName) > 0)
3065 6 : strcpy(units, pszUnitsName);
3066 6 : int proNu = 0;
3067 6 : if(psPro)
3068 6 : proNu = psPro->proNumber;
3069 6 : if(oSRS.ImportFromESRIStatePlaneWKT(zoneCode, nad, units, proNu) == OGRERR_NONE)
3070 : {
3071 6 : CPLFree( pszUnitsName );
3072 6 : oSRS.morphFromESRI();
3073 6 : oSRS.AutoIdentifyEPSG();
3074 6 : oSRS.Fixup();
3075 6 : if( oSRS.exportToWkt( &pszNewProj ) == OGRERR_NONE )
3076 6 : return pszNewProj;
3077 : else
3078 0 : return NULL;
3079 : }
3080 :
3081 : /* Set state plane zone. Set NAD83/27 on basis of spheroid */
3082 : oSRS.SetStatePlane( ESRIToUSGSZone(psPro->proZone),
3083 : fabs(psPro->proSpheroid.a - 6378137.0)< 1.0,
3084 0 : pszUnitsName, dfLinearUnits );
3085 :
3086 0 : CPLFree( pszUnitsName );
3087 :
3088 : // Same as the UTM, The following is needed.
3089 0 : if( psMapInfo && strlen(psMapInfo->proName) > 0
3090 : && strlen(psPro->proName) > 0
3091 : && !EQUAL(psMapInfo->proName, psPro->proName) )
3092 0 : oSRS.SetProjCS( psMapInfo->proName );
3093 : }
3094 0 : break;
3095 :
3096 : case EPRJ_ALBERS_CONIC_EQUAL_AREA:
3097 0 : oSRS.SetACEA( psPro->proParams[2]*R2D, psPro->proParams[3]*R2D,
3098 0 : psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3099 0 : psPro->proParams[6], psPro->proParams[7] );
3100 0 : break;
3101 :
3102 : case EPRJ_LAMBERT_CONFORMAL_CONIC:
3103 : // check the possible Wisconsin first
3104 0 : if(psDatum && psMapInfo && EQUAL(psDatum->datumname, "HARN"))
3105 : {
3106 0 : if(oSRS.ImportFromESRIWisconsinWKT("Lambert_Conformal_Conic", psPro->proParams[4]*R2D, psPro->proParams[5]*R2D, psMapInfo->units) == OGRERR_NONE)
3107 : {
3108 0 : oSRS.morphFromESRI();
3109 0 : oSRS.AutoIdentifyEPSG();
3110 0 : oSRS.Fixup();
3111 0 : if( oSRS.exportToWkt( &pszNewProj ) == OGRERR_NONE )
3112 0 : return pszNewProj;
3113 : }
3114 : }
3115 0 : oSRS.SetLCC( psPro->proParams[2]*R2D, psPro->proParams[3]*R2D,
3116 0 : psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3117 0 : psPro->proParams[6], psPro->proParams[7] );
3118 0 : break;
3119 :
3120 : case EPRJ_MERCATOR:
3121 0 : oSRS.SetMercator( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3122 : 1.0,
3123 0 : psPro->proParams[6], psPro->proParams[7] );
3124 0 : break;
3125 :
3126 : case EPRJ_POLAR_STEREOGRAPHIC:
3127 0 : oSRS.SetPS( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3128 : 1.0,
3129 0 : psPro->proParams[6], psPro->proParams[7] );
3130 0 : break;
3131 :
3132 : case EPRJ_POLYCONIC:
3133 0 : oSRS.SetPolyconic( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3134 0 : psPro->proParams[6], psPro->proParams[7] );
3135 0 : break;
3136 :
3137 : case EPRJ_EQUIDISTANT_CONIC:
3138 : double dfStdParallel2;
3139 :
3140 0 : if( psPro->proParams[8] != 0.0 )
3141 0 : dfStdParallel2 = psPro->proParams[3]*R2D;
3142 : else
3143 0 : dfStdParallel2 = psPro->proParams[2]*R2D;
3144 0 : oSRS.SetEC( psPro->proParams[2]*R2D, dfStdParallel2,
3145 0 : psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3146 0 : psPro->proParams[6], psPro->proParams[7] );
3147 0 : break;
3148 :
3149 : case EPRJ_TRANSVERSE_MERCATOR:
3150 : case EPRJ_GAUSS_KRUGER:
3151 : // check the possible Wisconsin first
3152 22 : if(psDatum && psMapInfo && EQUAL(psDatum->datumname, "HARN"))
3153 : {
3154 0 : if(oSRS.ImportFromESRIWisconsinWKT("Transverse_Mercator", psPro->proParams[4]*R2D, psPro->proParams[5]*R2D, psMapInfo->units) == OGRERR_NONE)
3155 : {
3156 0 : oSRS.morphFromESRI();
3157 0 : oSRS.AutoIdentifyEPSG();
3158 0 : oSRS.Fixup();
3159 0 : if( oSRS.exportToWkt( &pszNewProj ) == OGRERR_NONE )
3160 0 : return pszNewProj;
3161 : }
3162 : }
3163 44 : oSRS.SetTM( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3164 : psPro->proParams[2],
3165 66 : psPro->proParams[6], psPro->proParams[7] );
3166 22 : break;
3167 :
3168 : case EPRJ_STEREOGRAPHIC:
3169 0 : oSRS.SetStereographic( psPro->proParams[5]*R2D,psPro->proParams[4]*R2D,
3170 : 1.0,
3171 0 : psPro->proParams[6], psPro->proParams[7] );
3172 0 : break;
3173 :
3174 : case EPRJ_LAMBERT_AZIMUTHAL_EQUAL_AREA:
3175 0 : oSRS.SetLAEA( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3176 0 : psPro->proParams[6], psPro->proParams[7] );
3177 0 : break;
3178 :
3179 : case EPRJ_AZIMUTHAL_EQUIDISTANT:
3180 0 : oSRS.SetAE( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3181 0 : psPro->proParams[6], psPro->proParams[7] );
3182 0 : break;
3183 :
3184 : case EPRJ_GNOMONIC:
3185 0 : oSRS.SetGnomonic( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3186 0 : psPro->proParams[6], psPro->proParams[7] );
3187 0 : break;
3188 :
3189 : case EPRJ_ORTHOGRAPHIC:
3190 0 : oSRS.SetOrthographic( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3191 0 : psPro->proParams[6], psPro->proParams[7] );
3192 0 : break;
3193 :
3194 : case EPRJ_SINUSOIDAL:
3195 0 : oSRS.SetSinusoidal( psPro->proParams[4]*R2D,
3196 0 : psPro->proParams[6], psPro->proParams[7] );
3197 0 : break;
3198 :
3199 : case EPRJ_PLATE_CARREE:
3200 : case EPRJ_EQUIRECTANGULAR:
3201 : oSRS.SetEquirectangular2( 0.0,
3202 0 : psPro->proParams[4]*R2D,
3203 0 : psPro->proParams[5]*R2D,
3204 0 : psPro->proParams[6], psPro->proParams[7] );
3205 0 : break;
3206 :
3207 : case EPRJ_EQUIDISTANT_CYLINDRICAL:
3208 : oSRS.SetEquirectangular2( 0.0,
3209 0 : psPro->proParams[4]*R2D,
3210 0 : psPro->proParams[2]*R2D,
3211 0 : psPro->proParams[6], psPro->proParams[7] );
3212 0 : break;
3213 :
3214 : case EPRJ_MILLER_CYLINDRICAL:
3215 0 : oSRS.SetMC( 0.0, psPro->proParams[4]*R2D,
3216 0 : psPro->proParams[6], psPro->proParams[7] );
3217 0 : break;
3218 :
3219 : case EPRJ_VANDERGRINTEN:
3220 0 : oSRS.SetVDG( psPro->proParams[4]*R2D,
3221 0 : psPro->proParams[6], psPro->proParams[7] );
3222 0 : break;
3223 :
3224 : case EPRJ_HOTINE_OBLIQUE_MERCATOR:
3225 0 : if( psPro->proParams[12] > 0.0 )
3226 0 : oSRS.SetHOM( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3227 0 : psPro->proParams[3]*R2D, 0.0,
3228 : psPro->proParams[2],
3229 0 : psPro->proParams[6], psPro->proParams[7] );
3230 0 : break;
3231 :
3232 : case EPRJ_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER:
3233 0 : if( psPro->proParams[12] > 0.0 )
3234 0 : oSRS.SetHOMAC( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3235 0 : psPro->proParams[3]*R2D, 0.0,
3236 : psPro->proParams[2],
3237 0 : psPro->proParams[6], psPro->proParams[7] );
3238 0 : break;
3239 :
3240 : case EPRJ_ROBINSON:
3241 0 : oSRS.SetRobinson( psPro->proParams[4]*R2D,
3242 0 : psPro->proParams[6], psPro->proParams[7] );
3243 0 : break;
3244 :
3245 : case EPRJ_MOLLWEIDE:
3246 0 : oSRS.SetMollweide( psPro->proParams[4]*R2D,
3247 0 : psPro->proParams[6], psPro->proParams[7] );
3248 0 : break;
3249 :
3250 : case EPRJ_GALL_STEREOGRAPHIC:
3251 0 : oSRS.SetGS( psPro->proParams[4]*R2D,
3252 0 : psPro->proParams[6], psPro->proParams[7] );
3253 0 : break;
3254 :
3255 : case EPRJ_ECKERT_I:
3256 0 : oSRS.SetEckert( 1, psPro->proParams[4]*R2D,
3257 0 : psPro->proParams[6], psPro->proParams[7] );
3258 0 : break;
3259 :
3260 : case EPRJ_ECKERT_II:
3261 0 : oSRS.SetEckert( 2, psPro->proParams[4]*R2D,
3262 0 : psPro->proParams[6], psPro->proParams[7] );
3263 0 : break;
3264 :
3265 : case EPRJ_ECKERT_III:
3266 0 : oSRS.SetEckert( 3, psPro->proParams[4]*R2D,
3267 0 : psPro->proParams[6], psPro->proParams[7] );
3268 0 : break;
3269 :
3270 : case EPRJ_ECKERT_IV:
3271 0 : oSRS.SetEckert( 4, psPro->proParams[4]*R2D,
3272 0 : psPro->proParams[6], psPro->proParams[7] );
3273 0 : break;
3274 :
3275 : case EPRJ_ECKERT_V:
3276 0 : oSRS.SetEckert( 5, psPro->proParams[4]*R2D,
3277 0 : psPro->proParams[6], psPro->proParams[7] );
3278 0 : break;
3279 :
3280 : case EPRJ_ECKERT_VI:
3281 0 : oSRS.SetEckert( 6, psPro->proParams[4]*R2D,
3282 0 : psPro->proParams[6], psPro->proParams[7] );
3283 0 : break;
3284 :
3285 : case EPRJ_CASSINI:
3286 0 : oSRS.SetCS( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3287 0 : psPro->proParams[6], psPro->proParams[7] );
3288 0 : break;
3289 :
3290 : case EPRJ_TWO_POINT_EQUIDISTANT:
3291 0 : oSRS.SetTPED( psPro->proParams[9] * R2D,
3292 0 : psPro->proParams[8] * R2D,
3293 0 : psPro->proParams[11] * R2D,
3294 0 : psPro->proParams[10] * R2D,
3295 0 : psPro->proParams[6], psPro->proParams[7] );
3296 0 : break;
3297 :
3298 : case EPRJ_STEREOGRAPHIC_EXTENDED:
3299 0 : oSRS.SetStereographic( psPro->proParams[5]*R2D,psPro->proParams[4]*R2D,
3300 : psPro->proParams[2],
3301 0 : psPro->proParams[6], psPro->proParams[7] );
3302 0 : break;
3303 :
3304 : case EPRJ_BONNE:
3305 0 : oSRS.SetBonne( psPro->proParams[2]*R2D, psPro->proParams[4]*R2D,
3306 0 : psPro->proParams[6], psPro->proParams[7] );
3307 0 : break;
3308 :
3309 : case EPRJ_LOXIMUTHAL:
3310 : {
3311 0 : oSRS.SetProjection( "Loximuthal" );
3312 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3313 0 : psPro->proParams[4] * R2D );
3314 : oSRS.SetNormProjParm( "central_parallel",
3315 0 : psPro->proParams[5] * R2D );
3316 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3317 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3318 : }
3319 0 : break;
3320 :
3321 : case EPRJ_QUARTIC_AUTHALIC:
3322 : {
3323 0 : oSRS.SetProjection( "Quartic_Authalic" );
3324 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3325 0 : psPro->proParams[4] * R2D );
3326 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3327 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3328 : }
3329 0 : break;
3330 :
3331 : case EPRJ_WINKEL_I:
3332 : {
3333 0 : oSRS.SetProjection( "Winkel_I" );
3334 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3335 0 : psPro->proParams[4] * R2D );
3336 : oSRS.SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1,
3337 0 : psPro->proParams[2] * R2D );
3338 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3339 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3340 : }
3341 0 : break;
3342 :
3343 : case EPRJ_WINKEL_II:
3344 : {
3345 0 : oSRS.SetProjection( "Winkel_II" );
3346 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3347 0 : psPro->proParams[4] * R2D );
3348 : oSRS.SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1,
3349 0 : psPro->proParams[2] * R2D );
3350 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3351 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3352 : }
3353 0 : break;
3354 :
3355 : case EPRJ_BEHRMANN:
3356 : {
3357 0 : oSRS.SetProjection( "Behrmann" );
3358 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3359 0 : psPro->proParams[4] * R2D );
3360 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3361 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3362 : }
3363 0 : break;
3364 :
3365 : case EPRJ_KROVAK:
3366 0 : oSRS.SetKrovak( psPro->proParams[4]*R2D, psPro->proParams[5]*R2D,
3367 0 : psPro->proParams[3]*R2D, psPro->proParams[9]*R2D,
3368 : psPro->proParams[2],
3369 0 : psPro->proParams[6], psPro->proParams[7] );
3370 0 : break;
3371 :
3372 : case EPRJ_DOUBLE_STEREOGRAPHIC:
3373 : {
3374 0 : oSRS.SetProjection( "Double_Stereographic" );
3375 : oSRS.SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN,
3376 0 : psPro->proParams[5] * R2D );
3377 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3378 0 : psPro->proParams[4] * R2D );
3379 0 : oSRS.SetNormProjParm( SRS_PP_SCALE_FACTOR, psPro->proParams[2] );
3380 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3381 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3382 : }
3383 0 : break;
3384 :
3385 : case EPRJ_AITOFF:
3386 : {
3387 0 : oSRS.SetProjection( "Aitoff" );
3388 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3389 0 : psPro->proParams[4] * R2D );
3390 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3391 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3392 : }
3393 0 : break;
3394 :
3395 : case EPRJ_CRASTER_PARABOLIC:
3396 : {
3397 0 : oSRS.SetProjection( "Craster_Parabolic" );
3398 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3399 0 : psPro->proParams[4] * R2D );
3400 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3401 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3402 : }
3403 0 : break;
3404 :
3405 : case EPRJ_CYLINDRICAL_EQUAL_AREA:
3406 0 : oSRS.SetCEA(psPro->proParams[2] * R2D, psPro->proParams[4] * R2D,
3407 0 : psPro->proParams[6], psPro->proParams[7]);
3408 0 : break;
3409 :
3410 : case EPRJ_FLAT_POLAR_QUARTIC:
3411 : {
3412 0 : oSRS.SetProjection( "Flat_Polar_Quartic" );
3413 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3414 0 : psPro->proParams[4] * R2D );
3415 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3416 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3417 : }
3418 0 : break;
3419 :
3420 : case EPRJ_TIMES:
3421 : {
3422 0 : oSRS.SetProjection( "Times" );
3423 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3424 0 : psPro->proParams[4] * R2D );
3425 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3426 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3427 : }
3428 0 : break;
3429 :
3430 : case EPRJ_WINKEL_TRIPEL:
3431 : {
3432 0 : oSRS.SetProjection( "Winkel_Tripel" );
3433 : oSRS.SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1,
3434 0 : psPro->proParams[2] * R2D );
3435 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3436 0 : psPro->proParams[4] * R2D );
3437 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3438 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3439 : }
3440 0 : break;
3441 :
3442 : case EPRJ_HAMMER_AITOFF:
3443 : {
3444 0 : oSRS.SetProjection( "Hammer_Aitoff" );
3445 : oSRS.SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
3446 0 : psPro->proParams[4] * R2D );
3447 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3448 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3449 : }
3450 0 : break;
3451 :
3452 : case EPRJ_VERTICAL_NEAR_SIDE_PERSPECTIVE:
3453 : {
3454 0 : oSRS.SetProjection( "Vertical_Near_Side_Perspective" );
3455 : oSRS.SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER,
3456 0 : psPro->proParams[5] * R2D );
3457 : oSRS.SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER,
3458 0 : psPro->proParams[4] * R2D );
3459 : oSRS.SetNormProjParm( "height",
3460 0 : psPro->proParams[2] );
3461 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3462 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3463 : }
3464 0 : break;
3465 :
3466 : case EPRJ_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_CENTER:
3467 : {
3468 0 : oSRS.SetProjection( "Hotine_Oblique_Mercator_Twp_Point_Center" );
3469 : oSRS.SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER,
3470 0 : psPro->proParams[5] * R2D );
3471 : oSRS.SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT,
3472 0 : psPro->proParams[9] * R2D );
3473 : oSRS.SetNormProjParm( SRS_PP_LONGITUDE_OF_1ST_POINT,
3474 0 : psPro->proParams[8] * R2D );
3475 : oSRS.SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT,
3476 0 : psPro->proParams[11] * R2D );
3477 : oSRS.SetNormProjParm( SRS_PP_LONGITUDE_OF_2ND_POINT,
3478 0 : psPro->proParams[10] * R2D );
3479 : oSRS.SetNormProjParm( SRS_PP_SCALE_FACTOR,
3480 0 : psPro->proParams[2] );
3481 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_EASTING, psPro->proParams[6] );
3482 0 : oSRS.SetNormProjParm( SRS_PP_FALSE_NORTHING, psPro->proParams[7] );
3483 : }
3484 0 : break;
3485 :
3486 : case EPRJ_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN:
3487 0 : oSRS.SetHOM2PNO( psPro->proParams[5] * R2D,
3488 0 : psPro->proParams[8] * R2D,
3489 0 : psPro->proParams[9] * R2D,
3490 0 : psPro->proParams[10] * R2D,
3491 0 : psPro->proParams[11] * R2D,
3492 : psPro->proParams[2],
3493 0 : psPro->proParams[6], psPro->proParams[7] );
3494 0 : break;
3495 :
3496 : case EPRJ_LAMBERT_CONFORMAL_CONIC_1SP:
3497 0 : oSRS.SetLCC1SP( psPro->proParams[3]*R2D, psPro->proParams[2]*R2D,
3498 : psPro->proParams[4],
3499 0 : psPro->proParams[5], psPro->proParams[6] );
3500 0 : break;
3501 :
3502 : case EPRJ_MERCATOR_VARIANT_A:
3503 0 : oSRS.SetMercator( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3504 : psPro->proParams[2],
3505 0 : psPro->proParams[6], psPro->proParams[7] );
3506 0 : break;
3507 :
3508 : case EPRJ_PSEUDO_MERCATOR: // likely this is google mercator?
3509 0 : oSRS.SetMercator( psPro->proParams[5]*R2D, psPro->proParams[4]*R2D,
3510 : 1.0,
3511 0 : psPro->proParams[6], psPro->proParams[7] );
3512 0 : break;
3513 :
3514 : default:
3515 0 : if( oSRS.IsProjected() )
3516 0 : oSRS.GetRoot()->SetValue( "LOCAL_CS" );
3517 : else
3518 0 : oSRS.SetLocalCS( psPro->proName );
3519 : break;
3520 : }
3521 :
3522 : /* -------------------------------------------------------------------- */
3523 : /* Try and set the GeogCS information. */
3524 : /* -------------------------------------------------------------------- */
3525 72 : if( oSRS.GetAttrNode("GEOGCS") == NULL
3526 : && oSRS.GetAttrNode("LOCAL_CS") == NULL )
3527 : {
3528 72 : if( pszDatumName == NULL)
3529 : oSRS.SetGeogCS( pszDatumName, pszDatumName, pszEllipsoidName,
3530 0 : psPro->proSpheroid.a, dfInvFlattening );
3531 72 : else if( EQUAL(pszDatumName,"WGS 84")
3532 : || EQUAL(pszDatumName,"WGS_1984") )
3533 0 : oSRS.SetWellKnownGeogCS( "WGS84" );
3534 122 : else if( strstr(pszDatumName,"NAD27") != NULL
3535 : || EQUAL(pszDatumName,"North_American_Datum_1927") )
3536 50 : oSRS.SetWellKnownGeogCS( "NAD27" );
3537 22 : else if( strstr(pszDatumName,"NAD83") != NULL
3538 : || EQUAL(pszDatumName,"North_American_Datum_1983"))
3539 0 : oSRS.SetWellKnownGeogCS( "NAD83" );
3540 : else
3541 : oSRS.SetGeogCS( pszDatumName, pszDatumName, pszEllipsoidName,
3542 22 : psPro->proSpheroid.a, dfInvFlattening );
3543 :
3544 72 : if( psDatum != NULL && psDatum->type == EPRJ_DATUM_PARAMETRIC )
3545 : {
3546 : oSRS.SetTOWGS84( psDatum->params[0],
3547 : psDatum->params[1],
3548 : psDatum->params[2],
3549 : psDatum->params[3],
3550 : psDatum->params[4],
3551 : psDatum->params[5],
3552 26 : psDatum->params[6] );
3553 : }
3554 : }
3555 :
3556 : /* -------------------------------------------------------------------- */
3557 : /* Try to insert authority information if possible. Fixup any */
3558 : /* ordering oddities. */
3559 : /* -------------------------------------------------------------------- */
3560 72 : oSRS.AutoIdentifyEPSG();
3561 72 : oSRS.Fixup();
3562 :
3563 : /* -------------------------------------------------------------------- */
3564 : /* Get the WKT representation of the coordinate system. */
3565 : /* -------------------------------------------------------------------- */
3566 72 : if( oSRS.exportToWkt( &pszNewProj ) == OGRERR_NONE )
3567 72 : return pszNewProj;
3568 : else
3569 : {
3570 0 : return NULL;
3571 0 : }
3572 : }
3573 :
3574 : /************************************************************************/
3575 : /* ReadProjection() */
3576 : /************************************************************************/
3577 :
3578 756 : CPLErr HFADataset::ReadProjection()
3579 :
3580 : {
3581 : const Eprj_Datum *psDatum;
3582 : const Eprj_ProParameters *psPro;
3583 : const Eprj_MapInfo *psMapInfo;
3584 756 : OGRSpatialReference oSRS;
3585 : char *pszPE_COORDSYS;
3586 :
3587 : /* -------------------------------------------------------------------- */
3588 : /* Special logic for PE string in ProjectionX node. */
3589 : /* -------------------------------------------------------------------- */
3590 756 : pszPE_COORDSYS = HFAGetPEString( hHFA );
3591 756 : if( pszPE_COORDSYS != NULL
3592 : && strlen(pszPE_COORDSYS) > 0
3593 : && oSRS.SetFromUserInput( pszPE_COORDSYS ) == OGRERR_NONE )
3594 : {
3595 200 : CPLFree( pszPE_COORDSYS );
3596 :
3597 200 : oSRS.morphFromESRI();
3598 200 : oSRS.Fixup();
3599 :
3600 200 : CPLFree( pszProjection );
3601 200 : pszProjection = NULL;
3602 200 : oSRS.exportToWkt( &pszProjection );
3603 :
3604 200 : return CE_None;
3605 : }
3606 :
3607 556 : CPLFree( pszPE_COORDSYS );
3608 :
3609 : /* -------------------------------------------------------------------- */
3610 : /* General case for Erdas style projections. */
3611 : /* */
3612 : /* We make a particular effort to adapt the mapinfo->proname as */
3613 : /* the PROJCS[] name per #2422. */
3614 : /* -------------------------------------------------------------------- */
3615 556 : psDatum = HFAGetDatum( hHFA );
3616 556 : psPro = HFAGetProParameters( hHFA );
3617 556 : psMapInfo = HFAGetMapInfo( hHFA );
3618 :
3619 556 : HFAEntry *poMapInformation = NULL;
3620 556 : if( psMapInfo == NULL )
3621 : {
3622 432 : HFABand *poBand = hHFA->papoBand[0];
3623 432 : poMapInformation = poBand->poNode->GetNamedChild("MapInformation");
3624 : }
3625 :
3626 556 : CPLFree( pszProjection );
3627 :
3628 556 : if( !psDatum || !psPro ||
3629 : (psMapInfo == NULL && poMapInformation == NULL) ||
3630 : ((strlen(psDatum->datumname) == 0 || EQUAL(psDatum->datumname, "Unknown")) &&
3631 : (strlen(psPro->proName) == 0 || EQUAL(psPro->proName, "Unknown")) &&
3632 : (psMapInfo && (strlen(psMapInfo->proName) == 0 || EQUAL(psMapInfo->proName, "Unknown"))) &&
3633 : psPro->proZone == 0) )
3634 : {
3635 480 : pszProjection = CPLStrdup("");
3636 480 : return CE_None;
3637 : }
3638 :
3639 : pszProjection = HFAPCSStructToWKT( psDatum, psPro, psMapInfo,
3640 76 : poMapInformation );
3641 :
3642 76 : if( pszProjection != NULL )
3643 76 : return CE_None;
3644 : else
3645 : {
3646 0 : pszProjection = CPLStrdup("");
3647 0 : return CE_Failure;
3648 0 : }
3649 : }
3650 :
3651 : /************************************************************************/
3652 : /* IBuildOverviews() */
3653 : /************************************************************************/
3654 :
3655 16 : CPLErr HFADataset::IBuildOverviews( const char *pszResampling,
3656 : int nOverviews, int *panOverviewList,
3657 : int nListBands, int *panBandList,
3658 : GDALProgressFunc pfnProgress,
3659 : void * pProgressData )
3660 :
3661 : {
3662 : int i;
3663 :
3664 16 : if( GetAccess() == GA_ReadOnly )
3665 : {
3666 0 : for( i = 0; i < nListBands; i++ )
3667 : {
3668 0 : if (HFAGetOverviewCount(hHFA, panBandList[i]) > 0)
3669 : {
3670 : CPLError(CE_Failure, CPLE_NotSupported,
3671 0 : "Cannot add external overviews when there are already internal overviews");
3672 0 : return CE_Failure;
3673 : }
3674 : }
3675 :
3676 : return GDALDataset::IBuildOverviews( pszResampling,
3677 : nOverviews, panOverviewList,
3678 : nListBands, panBandList,
3679 0 : pfnProgress, pProgressData );
3680 : }
3681 :
3682 32 : for( i = 0; i < nListBands; i++ )
3683 : {
3684 : CPLErr eErr;
3685 : GDALRasterBand *poBand;
3686 :
3687 : void* pScaledProgressData = GDALCreateScaledProgress(
3688 : i * 1.0 / nListBands, (i + 1) * 1.0 / nListBands,
3689 16 : pfnProgress, pProgressData);
3690 :
3691 16 : poBand = GetRasterBand( panBandList[i] );
3692 : eErr =
3693 : poBand->BuildOverviews( pszResampling, nOverviews, panOverviewList,
3694 16 : GDALScaledProgress, pScaledProgressData );
3695 :
3696 16 : GDALDestroyScaledProgress(pScaledProgressData);
3697 :
3698 16 : if( eErr != CE_None )
3699 0 : return eErr;
3700 : }
3701 :
3702 16 : return CE_None;
3703 : }
3704 :
3705 : /************************************************************************/
3706 : /* Identify() */
3707 : /************************************************************************/
3708 :
3709 27644 : int HFADataset::Identify( GDALOpenInfo * poOpenInfo )
3710 :
3711 : {
3712 : /* -------------------------------------------------------------------- */
3713 : /* Verify that this is a HFA file. */
3714 : /* -------------------------------------------------------------------- */
3715 27644 : if( poOpenInfo->nHeaderBytes < 15
3716 : || !EQUALN((char *) poOpenInfo->pabyHeader,"EHFA_HEADER_TAG",15) )
3717 26880 : return FALSE;
3718 : else
3719 764 : return TRUE;
3720 : }
3721 :
3722 : /************************************************************************/
3723 : /* Open() */
3724 : /************************************************************************/
3725 :
3726 8618 : GDALDataset *HFADataset::Open( GDALOpenInfo * poOpenInfo )
3727 :
3728 : {
3729 : HFAHandle hHFA;
3730 : int i;
3731 :
3732 : /* -------------------------------------------------------------------- */
3733 : /* Verify that this is a HFA file. */
3734 : /* -------------------------------------------------------------------- */
3735 8618 : if( !Identify( poOpenInfo ) )
3736 7856 : return NULL;
3737 :
3738 : /* -------------------------------------------------------------------- */
3739 : /* Open the file. */
3740 : /* -------------------------------------------------------------------- */
3741 762 : if( poOpenInfo->eAccess == GA_Update )
3742 274 : hHFA = HFAOpen( poOpenInfo->pszFilename, "r+" );
3743 : else
3744 488 : hHFA = HFAOpen( poOpenInfo->pszFilename, "r" );
3745 :
3746 762 : if( hHFA == NULL )
3747 0 : return NULL;
3748 :
3749 : /* -------------------------------------------------------------------- */
3750 : /* Create a corresponding GDALDataset. */
3751 : /* -------------------------------------------------------------------- */
3752 : HFADataset *poDS;
3753 :
3754 762 : poDS = new HFADataset();
3755 :
3756 762 : poDS->hHFA = hHFA;
3757 762 : poDS->eAccess = poOpenInfo->eAccess;
3758 :
3759 : /* -------------------------------------------------------------------- */
3760 : /* Establish raster info. */
3761 : /* -------------------------------------------------------------------- */
3762 : HFAGetRasterInfo( hHFA, &poDS->nRasterXSize, &poDS->nRasterYSize,
3763 762 : &poDS->nBands );
3764 :
3765 762 : if( poDS->nBands == 0 )
3766 : {
3767 6 : delete poDS;
3768 : CPLError( CE_Failure, CPLE_AppDefined,
3769 : "Unable to open %s, it has zero usable bands.",
3770 6 : poOpenInfo->pszFilename );
3771 6 : return NULL;
3772 : }
3773 :
3774 756 : if( poDS->nRasterXSize == 0 || poDS->nRasterYSize == 0 )
3775 : {
3776 0 : delete poDS;
3777 : CPLError( CE_Failure, CPLE_AppDefined,
3778 : "Unable to open %s, it has no pixels.",
3779 0 : poOpenInfo->pszFilename );
3780 0 : return NULL;
3781 : }
3782 :
3783 : /* -------------------------------------------------------------------- */
3784 : /* Get geotransform, or if that fails, try to find XForms to */
3785 : /* build gcps, and metadata. */
3786 : /* -------------------------------------------------------------------- */
3787 756 : if( !HFAGetGeoTransform( hHFA, poDS->adfGeoTransform ) )
3788 : {
3789 428 : Efga_Polynomial *pasPolyListForward = NULL;
3790 428 : Efga_Polynomial *pasPolyListReverse = NULL;
3791 : int nStepCount =
3792 : HFAReadXFormStack( hHFA, &pasPolyListForward,
3793 428 : &pasPolyListReverse );
3794 :
3795 428 : if( nStepCount > 0 )
3796 : {
3797 : poDS->UseXFormStack( nStepCount,
3798 : pasPolyListForward,
3799 2 : pasPolyListReverse );
3800 2 : CPLFree( pasPolyListForward );
3801 2 : CPLFree( pasPolyListReverse );
3802 : }
3803 : }
3804 :
3805 : /* -------------------------------------------------------------------- */
3806 : /* Get the projection. */
3807 : /* -------------------------------------------------------------------- */
3808 756 : poDS->ReadProjection();
3809 :
3810 : /* -------------------------------------------------------------------- */
3811 : /* Read the camera model as metadata, if present. */
3812 : /* -------------------------------------------------------------------- */
3813 756 : char **papszCM = HFAReadCameraModel( hHFA );
3814 :
3815 756 : if( papszCM != NULL )
3816 : {
3817 2 : poDS->SetMetadata( papszCM, "CAMERA_MODEL" );
3818 2 : CSLDestroy( papszCM );
3819 : }
3820 :
3821 : /* -------------------------------------------------------------------- */
3822 : /* Create band information objects. */
3823 : /* -------------------------------------------------------------------- */
3824 3320 : for( i = 0; i < poDS->nBands; i++ )
3825 : {
3826 904 : poDS->SetBand( i+1, new HFARasterBand( poDS, i+1, -1 ) );
3827 : }
3828 :
3829 : /* -------------------------------------------------------------------- */
3830 : /* Collect GDAL custom Metadata, and "auxilary" metadata from */
3831 : /* well known HFA structures for the bands. We defer this till */
3832 : /* now to ensure that the bands are properly setup before */
3833 : /* interacting with PAM. */
3834 : /* -------------------------------------------------------------------- */
3835 1660 : for( i = 0; i < poDS->nBands; i++ )
3836 : {
3837 904 : HFARasterBand *poBand = (HFARasterBand *) poDS->GetRasterBand( i+1 );
3838 :
3839 904 : char **papszMD = HFAGetMetadata( hHFA, i+1 );
3840 904 : if( papszMD != NULL )
3841 : {
3842 14 : poBand->SetMetadata( papszMD );
3843 14 : CSLDestroy( papszMD );
3844 : }
3845 :
3846 904 : poBand->ReadAuxMetadata();
3847 904 : poBand->ReadHistogramMetadata();
3848 : }
3849 :
3850 : /* -------------------------------------------------------------------- */
3851 : /* Check for GDAL style metadata. */
3852 : /* -------------------------------------------------------------------- */
3853 756 : char **papszMD = HFAGetMetadata( hHFA, 0 );
3854 756 : if( papszMD != NULL )
3855 : {
3856 156 : poDS->SetMetadata( papszMD );
3857 156 : CSLDestroy( papszMD );
3858 : }
3859 :
3860 : /* -------------------------------------------------------------------- */
3861 : /* Check for dependent dataset value. */
3862 : /* -------------------------------------------------------------------- */
3863 756 : HFAInfo_t *psInfo = (HFAInfo_t *) hHFA;
3864 756 : HFAEntry *poEntry = psInfo->poRoot->GetNamedChild("DependentFile");
3865 756 : if( poEntry != NULL )
3866 : {
3867 : poDS->SetMetadataItem( "HFA_DEPENDENT_FILE",
3868 : poEntry->GetStringField( "dependent.string" ),
3869 32 : "HFA" );
3870 : }
3871 :
3872 : /* -------------------------------------------------------------------- */
3873 : /* Initialize any PAM information. */
3874 : /* -------------------------------------------------------------------- */
3875 756 : poDS->SetDescription( poOpenInfo->pszFilename );
3876 756 : poDS->TryLoadXML();
3877 :
3878 : /* -------------------------------------------------------------------- */
3879 : /* Check for external overviews. */
3880 : /* -------------------------------------------------------------------- */
3881 756 : poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
3882 :
3883 : /* -------------------------------------------------------------------- */
3884 : /* Clear dirty metadata flags. */
3885 : /* -------------------------------------------------------------------- */
3886 1660 : for( i = 0; i < poDS->nBands; i++ )
3887 : {
3888 904 : HFARasterBand *poBand = (HFARasterBand *) poDS->GetRasterBand( i+1 );
3889 904 : poBand->bMetadataDirty = FALSE;
3890 : }
3891 756 : poDS->bMetadataDirty = FALSE;
3892 :
3893 756 : return( poDS );
3894 : }
3895 :
3896 : /************************************************************************/
3897 : /* GetProjectionRef() */
3898 : /************************************************************************/
3899 :
3900 244 : const char *HFADataset::GetProjectionRef()
3901 :
3902 : {
3903 244 : return pszProjection;
3904 : }
3905 :
3906 : /************************************************************************/
3907 : /* SetProjection() */
3908 : /************************************************************************/
3909 :
3910 160 : CPLErr HFADataset::SetProjection( const char * pszNewProjection )
3911 :
3912 : {
3913 160 : CPLFree( pszProjection );
3914 160 : pszProjection = CPLStrdup( pszNewProjection );
3915 160 : bGeoDirty = TRUE;
3916 :
3917 160 : return CE_None;
3918 : }
3919 :
3920 : /************************************************************************/
3921 : /* SetMetadata() */
3922 : /************************************************************************/
3923 :
3924 244 : CPLErr HFADataset::SetMetadata( char **papszMDIn, const char *pszDomain )
3925 :
3926 : {
3927 244 : bMetadataDirty = TRUE;
3928 :
3929 244 : return GDALPamDataset::SetMetadata( papszMDIn, pszDomain );
3930 : }
3931 :
3932 : /************************************************************************/
3933 : /* SetMetadata() */
3934 : /************************************************************************/
3935 :
3936 32 : CPLErr HFADataset::SetMetadataItem( const char *pszTag, const char *pszValue,
3937 : const char *pszDomain )
3938 :
3939 : {
3940 32 : bMetadataDirty = TRUE;
3941 :
3942 32 : return GDALPamDataset::SetMetadataItem( pszTag, pszValue, pszDomain );
3943 : }
3944 :
3945 : /************************************************************************/
3946 : /* GetGeoTransform() */
3947 : /************************************************************************/
3948 :
3949 208 : CPLErr HFADataset::GetGeoTransform( double * padfTransform )
3950 :
3951 : {
3952 238 : if( adfGeoTransform[0] != 0.0
3953 6 : || adfGeoTransform[1] != 1.0
3954 6 : || adfGeoTransform[2] != 0.0
3955 6 : || adfGeoTransform[3] != 0.0
3956 6 : || adfGeoTransform[4] != 0.0
3957 6 : || adfGeoTransform[5] != 1.0 )
3958 : {
3959 202 : memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
3960 202 : return CE_None;
3961 : }
3962 : else
3963 6 : return GDALPamDataset::GetGeoTransform( padfTransform );
3964 : }
3965 :
3966 : /************************************************************************/
3967 : /* SetGeoTransform() */
3968 : /************************************************************************/
3969 :
3970 146 : CPLErr HFADataset::SetGeoTransform( double * padfTransform )
3971 :
3972 : {
3973 146 : memcpy( adfGeoTransform, padfTransform, sizeof(double)*6 );
3974 146 : bGeoDirty = TRUE;
3975 :
3976 146 : return CE_None;
3977 : }
3978 :
3979 : /************************************************************************/
3980 : /* IRasterIO() */
3981 : /* */
3982 : /* Multi-band raster io handler. Here we ensure that the block */
3983 : /* based loading is used for spill file rasters. That is */
3984 : /* because they are effectively pixel interleaved, so */
3985 : /* processing all bands for a given block together avoid extra */
3986 : /* seeks. */
3987 : /************************************************************************/
3988 :
3989 110 : CPLErr HFADataset::IRasterIO( GDALRWFlag eRWFlag,
3990 : int nXOff, int nYOff, int nXSize, int nYSize,
3991 : void *pData, int nBufXSize, int nBufYSize,
3992 : GDALDataType eBufType,
3993 : int nBandCount, int *panBandMap,
3994 : int nPixelSpace, int nLineSpace, int nBandSpace )
3995 :
3996 : {
3997 110 : if( hHFA->papoBand[panBandMap[0]-1]->fpExternal != NULL
3998 : && nBandCount > 1 )
3999 : return GDALDataset::BlockBasedRasterIO(
4000 : eRWFlag, nXOff, nYOff, nXSize, nYSize,
4001 : pData, nBufXSize, nBufYSize, eBufType,
4002 0 : nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace );
4003 : else
4004 : return
4005 : GDALDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
4006 : pData, nBufXSize, nBufYSize, eBufType,
4007 : nBandCount, panBandMap,
4008 110 : nPixelSpace, nLineSpace, nBandSpace );
4009 : }
4010 :
4011 : /************************************************************************/
4012 : /* UseXFormStack() */
4013 : /************************************************************************/
4014 :
4015 2 : void HFADataset::UseXFormStack( int nStepCount,
4016 : Efga_Polynomial *pasPLForward,
4017 : Efga_Polynomial *pasPLReverse )
4018 :
4019 : {
4020 : /* -------------------------------------------------------------------- */
4021 : /* Generate GCPs using the transform. */
4022 : /* -------------------------------------------------------------------- */
4023 : double dfXRatio, dfYRatio;
4024 :
4025 2 : nGCPCount = 0;
4026 2 : GDALInitGCPs( 36, asGCPList );
4027 :
4028 14 : for( dfYRatio = 0.0; dfYRatio < 1.001; dfYRatio += 0.2 )
4029 : {
4030 84 : for( dfXRatio = 0.0; dfXRatio < 1.001; dfXRatio += 0.2 )
4031 : {
4032 72 : double dfLine = 0.5 + (GetRasterYSize()-1) * dfYRatio;
4033 72 : double dfPixel = 0.5 + (GetRasterXSize()-1) * dfXRatio;
4034 72 : int iGCP = nGCPCount;
4035 :
4036 72 : asGCPList[iGCP].dfGCPPixel = dfPixel;
4037 72 : asGCPList[iGCP].dfGCPLine = dfLine;
4038 :
4039 72 : asGCPList[iGCP].dfGCPX = dfPixel;
4040 72 : asGCPList[iGCP].dfGCPY = dfLine;
4041 72 : asGCPList[iGCP].dfGCPZ = 0.0;
4042 :
4043 72 : if( HFAEvaluateXFormStack( nStepCount, FALSE, pasPLReverse,
4044 : &(asGCPList[iGCP].dfGCPX),
4045 : &(asGCPList[iGCP].dfGCPY) ) )
4046 72 : nGCPCount++;
4047 : }
4048 : }
4049 :
4050 : /* -------------------------------------------------------------------- */
4051 : /* Store the transform as metadata. */
4052 : /* -------------------------------------------------------------------- */
4053 : int iStep, i;
4054 :
4055 : GDALMajorObject::SetMetadataItem(
4056 : "XFORM_STEPS",
4057 : CPLString().Printf("%d",nStepCount),
4058 2 : "XFORMS" );
4059 :
4060 6 : for( iStep = 0; iStep < nStepCount; iStep++ )
4061 : {
4062 : GDALMajorObject::SetMetadataItem(
4063 : CPLString().Printf("XFORM%d_ORDER", iStep),
4064 4 : CPLString().Printf("%d",pasPLForward[iStep].order),
4065 4 : "XFORMS" );
4066 :
4067 4 : if( pasPLForward[iStep].order == 1 )
4068 : {
4069 20 : for( i = 0; i < 4; i++ )
4070 : GDALMajorObject::SetMetadataItem(
4071 : CPLString().Printf("XFORM%d_POLYCOEFMTX[%d]", iStep, i),
4072 : CPLString().Printf("%.15g",
4073 8 : pasPLForward[iStep].polycoefmtx[i]),
4074 8 : "XFORMS" );
4075 :
4076 12 : for( i = 0; i < 2; i++ )
4077 : GDALMajorObject::SetMetadataItem(
4078 : CPLString().Printf("XFORM%d_POLYCOEFVECTOR[%d]", iStep, i),
4079 : CPLString().Printf("%.15g",
4080 4 : pasPLForward[iStep].polycoefvector[i]),
4081 4 : "XFORMS" );
4082 :
4083 2 : continue;
4084 : }
4085 :
4086 : int nCoefCount;
4087 :
4088 2 : if( pasPLForward[iStep].order == 2 )
4089 0 : nCoefCount = 10;
4090 : else
4091 : {
4092 2 : CPLAssert( pasPLForward[iStep].order == 3 );
4093 2 : nCoefCount = 18;
4094 : }
4095 :
4096 76 : for( i = 0; i < nCoefCount; i++ )
4097 : GDALMajorObject::SetMetadataItem(
4098 : CPLString().Printf("XFORM%d_FWD_POLYCOEFMTX[%d]", iStep, i),
4099 : CPLString().Printf("%.15g",
4100 36 : pasPLForward[iStep].polycoefmtx[i]),
4101 36 : "XFORMS" );
4102 :
4103 12 : for( i = 0; i < 2; i++ )
4104 : GDALMajorObject::SetMetadataItem(
4105 : CPLString().Printf("XFORM%d_FWD_POLYCOEFVECTOR[%d]", iStep, i),
4106 : CPLString().Printf("%.15g",
4107 4 : pasPLForward[iStep].polycoefvector[i]),
4108 4 : "XFORMS" );
4109 :
4110 76 : for( i = 0; i < nCoefCount; i++ )
4111 : GDALMajorObject::SetMetadataItem(
4112 : CPLString().Printf("XFORM%d_REV_POLYCOEFMTX[%d]", iStep, i),
4113 : CPLString().Printf("%.15g",
4114 36 : pasPLReverse[iStep].polycoefmtx[i]),
4115 36 : "XFORMS" );
4116 :
4117 12 : for( i = 0; i < 2; i++ )
4118 : GDALMajorObject::SetMetadataItem(
4119 : CPLString().Printf("XFORM%d_REV_POLYCOEFVECTOR[%d]", iStep, i),
4120 : CPLString().Printf("%.15g",
4121 4 : pasPLReverse[iStep].polycoefvector[i]),
4122 4 : "XFORMS" );
4123 : }
4124 2 : }
4125 :
4126 : /************************************************************************/
4127 : /* GetGCPCount() */
4128 : /************************************************************************/
4129 :
4130 20 : int HFADataset::GetGCPCount()
4131 :
4132 : {
4133 20 : return nGCPCount;
4134 : }
4135 :
4136 : /************************************************************************/
4137 : /* GetGCPProjection() */
4138 : /************************************************************************/
4139 :
4140 0 : const char *HFADataset::GetGCPProjection()
4141 :
4142 : {
4143 0 : if( nGCPCount > 0 )
4144 0 : return pszProjection;
4145 : else
4146 0 : return "";
4147 : }
4148 :
4149 : /************************************************************************/
4150 : /* GetGCPs() */
4151 : /************************************************************************/
4152 :
4153 2 : const GDAL_GCP *HFADataset::GetGCPs()
4154 :
4155 : {
4156 2 : return asGCPList;
4157 : }
4158 :
4159 : /************************************************************************/
4160 : /* GetFileList() */
4161 : /************************************************************************/
4162 :
4163 174 : char **HFADataset::GetFileList()
4164 :
4165 : {
4166 174 : char **papszFileList = GDALPamDataset::GetFileList();
4167 :
4168 174 : if( HFAGetIGEFilename( hHFA ) != NULL )
4169 : {
4170 : papszFileList = CSLAddString( papszFileList,
4171 26 : HFAGetIGEFilename( hHFA ) );
4172 : }
4173 :
4174 : // Request an overview to force opening of dependent overview
4175 : // files.
4176 348 : if( nBands > 0
4177 174 : && GetRasterBand(1)->GetOverviewCount() > 0 )
4178 26 : GetRasterBand(1)->GetOverview(0);
4179 :
4180 174 : if( hHFA->psDependent != NULL )
4181 : {
4182 14 : HFAInfo_t *psDep = hHFA->psDependent;
4183 :
4184 : papszFileList =
4185 : CSLAddString( papszFileList,
4186 : CPLFormFilename( psDep->pszPath,
4187 14 : psDep->pszFilename, NULL ));
4188 :
4189 14 : if( HFAGetIGEFilename( psDep ) != NULL )
4190 : papszFileList = CSLAddString( papszFileList,
4191 10 : HFAGetIGEFilename( psDep ) );
4192 : }
4193 :
4194 174 : return papszFileList;
4195 : }
4196 :
4197 : /************************************************************************/
4198 : /* Create() */
4199 : /************************************************************************/
4200 :
4201 274 : GDALDataset *HFADataset::Create( const char * pszFilenameIn,
4202 : int nXSize, int nYSize, int nBands,
4203 : GDALDataType eType,
4204 : char ** papszParmList )
4205 :
4206 : {
4207 : int nHfaDataType;
4208 274 : int nBits = 0;
4209 : const char *pszPixelType;
4210 :
4211 :
4212 274 : if( CSLFetchNameValue( papszParmList, "NBITS" ) != NULL )
4213 4 : nBits = atoi(CSLFetchNameValue(papszParmList,"NBITS"));
4214 :
4215 : pszPixelType =
4216 274 : CSLFetchNameValue( papszParmList, "PIXELTYPE" );
4217 274 : if( pszPixelType == NULL )
4218 274 : pszPixelType = "";
4219 :
4220 : /* -------------------------------------------------------------------- */
4221 : /* Translate the data type. */
4222 : /* -------------------------------------------------------------------- */
4223 274 : switch( eType )
4224 : {
4225 : case GDT_Byte:
4226 132 : if( nBits == 1 )
4227 4 : nHfaDataType = EPT_u1;
4228 128 : else if( nBits == 2 )
4229 0 : nHfaDataType = EPT_u2;
4230 128 : else if( nBits == 4 )
4231 0 : nHfaDataType = EPT_u4;
4232 128 : else if( EQUAL(pszPixelType,"SIGNEDBYTE") )
4233 0 : nHfaDataType = EPT_s8;
4234 : else
4235 128 : nHfaDataType = EPT_u8;
4236 132 : break;
4237 :
4238 : case GDT_UInt16:
4239 22 : nHfaDataType = EPT_u16;
4240 22 : break;
4241 :
4242 : case GDT_Int16:
4243 14 : nHfaDataType = EPT_s16;
4244 14 : break;
4245 :
4246 : case GDT_Int32:
4247 16 : nHfaDataType = EPT_s32;
4248 16 : break;
4249 :
4250 : case GDT_UInt32:
4251 14 : nHfaDataType = EPT_u32;
4252 14 : break;
4253 :
4254 : case GDT_Float32:
4255 16 : nHfaDataType = EPT_f32;
4256 16 : break;
4257 :
4258 : case GDT_Float64:
4259 20 : nHfaDataType = EPT_f64;
4260 20 : break;
4261 :
4262 : case GDT_CFloat32:
4263 14 : nHfaDataType = EPT_c64;
4264 14 : break;
4265 :
4266 : case GDT_CFloat64:
4267 14 : nHfaDataType = EPT_c128;
4268 14 : break;
4269 :
4270 : default:
4271 : CPLError( CE_Failure, CPLE_NotSupported,
4272 : "Data type %s not supported by Erdas Imagine (HFA) format.\n",
4273 12 : GDALGetDataTypeName( eType ) );
4274 12 : return NULL;
4275 :
4276 : }
4277 :
4278 : /* -------------------------------------------------------------------- */
4279 : /* Create the new file. */
4280 : /* -------------------------------------------------------------------- */
4281 : HFAHandle hHFA;
4282 :
4283 : hHFA = HFACreate( pszFilenameIn, nXSize, nYSize, nBands,
4284 262 : nHfaDataType, papszParmList );
4285 262 : if( hHFA == NULL )
4286 4 : return NULL;
4287 :
4288 258 : HFAClose( hHFA );
4289 :
4290 : /* -------------------------------------------------------------------- */
4291 : /* Open the dataset normally. */
4292 : /* -------------------------------------------------------------------- */
4293 258 : HFADataset *poDS = (HFADataset *) GDALOpen( pszFilenameIn, GA_Update );
4294 :
4295 : /* -------------------------------------------------------------------- */
4296 : /* Special creation option to disable checking for UTM */
4297 : /* parameters when writing the projection. This is a special */
4298 : /* hack for sam.gillingham@nrm.qld.gov.au. */
4299 : /* -------------------------------------------------------------------- */
4300 258 : if( poDS != NULL )
4301 : {
4302 : poDS->bIgnoreUTM = CSLFetchBoolean( papszParmList, "IGNOREUTM",
4303 254 : FALSE );
4304 : }
4305 :
4306 : /* -------------------------------------------------------------------- */
4307 : /* Sometimes we can improve ArcGIS compatability by forcing */
4308 : /* generation of a PEString instead of traditional Imagine */
4309 : /* coordinate system descriptions. */
4310 : /* -------------------------------------------------------------------- */
4311 258 : if( poDS != NULL )
4312 : {
4313 : poDS->bForceToPEString =
4314 254 : CSLFetchBoolean( papszParmList, "FORCETOPESTRING", FALSE );
4315 : }
4316 :
4317 258 : return poDS;
4318 :
4319 : }
4320 :
4321 : /************************************************************************/
4322 : /* Rename() */
4323 : /* */
4324 : /* Custom Rename() implementation that knows how to update */
4325 : /* filename references in .img and .aux files. */
4326 : /************************************************************************/
4327 :
4328 2 : CPLErr HFADataset::Rename( const char *pszNewName, const char *pszOldName )
4329 :
4330 : {
4331 : /* -------------------------------------------------------------------- */
4332 : /* Rename all the files at the filesystem level. */
4333 : /* -------------------------------------------------------------------- */
4334 2 : GDALDriver *poDriver = (GDALDriver*) GDALGetDriverByName( "HFA" );
4335 :
4336 2 : CPLErr eErr = poDriver->DefaultRename( pszNewName, pszOldName );
4337 :
4338 2 : if( eErr != CE_None )
4339 0 : return eErr;
4340 :
4341 : /* -------------------------------------------------------------------- */
4342 : /* Now try to go into the .img file and update RRDNames[] */
4343 : /* lists. */
4344 : /* -------------------------------------------------------------------- */
4345 2 : CPLString osOldBasename, osNewBasename;
4346 :
4347 2 : osOldBasename = CPLGetBasename( pszOldName );
4348 2 : osNewBasename = CPLGetBasename( pszNewName );
4349 :
4350 2 : if( osOldBasename != osNewBasename )
4351 : {
4352 2 : HFAHandle hHFA = HFAOpen( pszNewName, "r+" );
4353 :
4354 2 : if( hHFA != NULL )
4355 : {
4356 2 : eErr = HFARenameReferences( hHFA, osNewBasename, osOldBasename );
4357 :
4358 2 : HFAGetOverviewCount( hHFA, 1 );
4359 :
4360 2 : if( hHFA->psDependent != NULL )
4361 : HFARenameReferences( hHFA->psDependent,
4362 2 : osNewBasename, osOldBasename );
4363 :
4364 2 : HFAClose( hHFA );
4365 : }
4366 : }
4367 :
4368 2 : return eErr;
4369 : }
4370 :
4371 : /************************************************************************/
4372 : /* CopyFiles() */
4373 : /* */
4374 : /* Custom CopyFiles() implementation that knows how to update */
4375 : /* filename references in .img and .aux files. */
4376 : /************************************************************************/
4377 :
4378 2 : CPLErr HFADataset::CopyFiles( const char *pszNewName, const char *pszOldName )
4379 :
4380 : {
4381 : /* -------------------------------------------------------------------- */
4382 : /* Rename all the files at the filesystem level. */
4383 : /* -------------------------------------------------------------------- */
4384 2 : GDALDriver *poDriver = (GDALDriver*) GDALGetDriverByName( "HFA" );
4385 :
4386 2 : CPLErr eErr = poDriver->DefaultCopyFiles( pszNewName, pszOldName );
4387 :
4388 2 : if( eErr != CE_None )
4389 0 : return eErr;
4390 :
4391 : /* -------------------------------------------------------------------- */
4392 : /* Now try to go into the .img file and update RRDNames[] */
4393 : /* lists. */
4394 : /* -------------------------------------------------------------------- */
4395 2 : CPLString osOldBasename, osNewBasename;
4396 :
4397 2 : osOldBasename = CPLGetBasename( pszOldName );
4398 2 : osNewBasename = CPLGetBasename( pszNewName );
4399 :
4400 2 : if( osOldBasename != osNewBasename )
4401 : {
4402 2 : HFAHandle hHFA = HFAOpen( pszNewName, "r+" );
4403 :
4404 2 : if( hHFA != NULL )
4405 : {
4406 2 : eErr = HFARenameReferences( hHFA, osNewBasename, osOldBasename );
4407 :
4408 2 : HFAGetOverviewCount( hHFA, 1 );
4409 :
4410 2 : if( hHFA->psDependent != NULL )
4411 : HFARenameReferences( hHFA->psDependent,
4412 2 : osNewBasename, osOldBasename );
4413 :
4414 2 : HFAClose( hHFA );
4415 : }
4416 : }
4417 :
4418 2 : return eErr;
4419 : }
4420 :
4421 : /************************************************************************/
4422 : /* CreateCopy() */
4423 : /************************************************************************/
4424 :
4425 : GDALDataset *
4426 92 : HFADataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
4427 : int bStrict, char ** papszOptions,
4428 : GDALProgressFunc pfnProgress, void * pProgressData )
4429 :
4430 : {
4431 : HFADataset *poDS;
4432 92 : GDALDataType eType = GDT_Byte;
4433 : int iBand;
4434 92 : int nBandCount = poSrcDS->GetRasterCount();
4435 92 : char **papszModOptions = CSLDuplicate( papszOptions );
4436 :
4437 : /* -------------------------------------------------------------------- */
4438 : /* Do we really just want to create an .aux file? */
4439 : /* -------------------------------------------------------------------- */
4440 92 : int bCreateAux = CSLFetchBoolean( papszOptions, "AUX", FALSE );
4441 :
4442 : /* -------------------------------------------------------------------- */
4443 : /* Establish a representative data type to use. */
4444 : /* -------------------------------------------------------------------- */
4445 92 : if( !pfnProgress( 0.0, NULL, pProgressData ) )
4446 0 : return NULL;
4447 :
4448 202 : for( iBand = 0; iBand < nBandCount; iBand++ )
4449 : {
4450 110 : GDALRasterBand *poBand = poSrcDS->GetRasterBand( iBand+1 );
4451 110 : eType = GDALDataTypeUnion( eType, poBand->GetRasterDataType() );
4452 : }
4453 :
4454 : /* -------------------------------------------------------------------- */
4455 : /* If we have PIXELTYPE metadadata in the source, pass it */
4456 : /* through as a creation option. */
4457 : /* -------------------------------------------------------------------- */
4458 140 : if( CSLFetchNameValue( papszOptions, "PIXELTYPE" ) == NULL
4459 : && nBandCount > 0
4460 : && eType == GDT_Byte
4461 : && poSrcDS->GetRasterBand(1)->GetMetadataItem( "PIXELTYPE",
4462 48 : "IMAGE_STRUCTURE" ) )
4463 : {
4464 : papszModOptions =
4465 : CSLSetNameValue( papszModOptions, "PIXELTYPE",
4466 : poSrcDS->GetRasterBand(1)->GetMetadataItem(
4467 0 : "PIXELTYPE", "IMAGE_STRUCTURE" ) );
4468 : }
4469 :
4470 : /* -------------------------------------------------------------------- */
4471 : /* Create the file. */
4472 : /* -------------------------------------------------------------------- */
4473 : poDS = (HFADataset *) Create( pszFilename,
4474 : poSrcDS->GetRasterXSize(),
4475 : poSrcDS->GetRasterYSize(),
4476 : nBandCount,
4477 92 : eType, papszModOptions );
4478 :
4479 92 : CSLDestroy( papszModOptions );
4480 :
4481 92 : if( poDS == NULL )
4482 10 : return NULL;
4483 :
4484 : /* -------------------------------------------------------------------- */
4485 : /* Does the source have a PCT for any of the bands? If so, */
4486 : /* copy it over. */
4487 : /* -------------------------------------------------------------------- */
4488 184 : for( iBand = 0; iBand < nBandCount; iBand++ )
4489 : {
4490 102 : GDALRasterBand *poBand = poSrcDS->GetRasterBand( iBand+1 );
4491 : GDALColorTable *poCT;
4492 :
4493 102 : poCT = poBand->GetColorTable();
4494 102 : if( poCT != NULL )
4495 : {
4496 2 : poDS->GetRasterBand(iBand+1)->SetColorTable(poCT);
4497 : }
4498 : }
4499 :
4500 : /* -------------------------------------------------------------------- */
4501 : /* Do we have metadata for any of the bands or the dataset as a */
4502 : /* whole? */
4503 : /* -------------------------------------------------------------------- */
4504 82 : if( poSrcDS->GetMetadata() != NULL )
4505 56 : poDS->SetMetadata( poSrcDS->GetMetadata() );
4506 :
4507 184 : for( iBand = 0; iBand < nBandCount; iBand++ )
4508 : {
4509 : int bSuccess;
4510 102 : GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
4511 102 : GDALRasterBand *poDstBand = poDS->GetRasterBand(iBand+1);
4512 :
4513 102 : if( poSrcBand->GetMetadata() != NULL )
4514 8 : poDstBand->SetMetadata( poSrcBand->GetMetadata() );
4515 :
4516 102 : if( strlen(poSrcBand->GetDescription()) > 0 )
4517 8 : poDstBand->SetDescription( poSrcBand->GetDescription() );
4518 :
4519 102 : double dfNoDataValue = poSrcBand->GetNoDataValue( &bSuccess );
4520 102 : if( bSuccess )
4521 4 : poDstBand->SetNoDataValue( dfNoDataValue );
4522 : }
4523 :
4524 : /* -------------------------------------------------------------------- */
4525 : /* Copy projection information. */
4526 : /* -------------------------------------------------------------------- */
4527 : double adfGeoTransform[6];
4528 : const char *pszProj;
4529 :
4530 164 : if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None
4531 82 : && (adfGeoTransform[0] != 0.0 || adfGeoTransform[1] != 1.0
4532 0 : || adfGeoTransform[2] != 0.0 || adfGeoTransform[3] != 0.0
4533 0 : || adfGeoTransform[4] != 0.0 || fabs(adfGeoTransform[5]) != 1.0))
4534 82 : poDS->SetGeoTransform( adfGeoTransform );
4535 :
4536 82 : pszProj = poSrcDS->GetProjectionRef();
4537 82 : if( pszProj != NULL && strlen(pszProj) > 0 )
4538 78 : poDS->SetProjection( pszProj );
4539 :
4540 : /* -------------------------------------------------------------------- */
4541 : /* Copy the imagery. */
4542 : /* -------------------------------------------------------------------- */
4543 82 : if( !bCreateAux )
4544 : {
4545 : CPLErr eErr;
4546 :
4547 : eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS,
4548 : (GDALDatasetH) poDS,
4549 82 : NULL, pfnProgress, pProgressData );
4550 :
4551 82 : if( eErr != CE_None )
4552 : {
4553 0 : delete poDS;
4554 0 : return NULL;
4555 : }
4556 : }
4557 :
4558 : /* -------------------------------------------------------------------- */
4559 : /* Do we want to generate statistics and a histogram? */
4560 : /* -------------------------------------------------------------------- */
4561 82 : if( CSLFetchBoolean( papszOptions, "STATISTICS", FALSE ) )
4562 : {
4563 4 : for( iBand = 0; iBand < nBandCount; iBand++ )
4564 : {
4565 2 : GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
4566 : double dfMin, dfMax, dfMean, dfStdDev;
4567 2 : char **papszStatsMD = NULL;
4568 :
4569 : // -----------------------------------------------------------
4570 : // Statistics
4571 : // -----------------------------------------------------------
4572 :
4573 4 : if( poSrcBand->GetStatistics( TRUE, FALSE, &dfMin, &dfMax,
4574 2 : &dfMean, &dfStdDev ) == CE_None
4575 : || poSrcBand->ComputeStatistics( TRUE, &dfMin, &dfMax,
4576 : &dfMean, &dfStdDev,
4577 2 : pfnProgress, pProgressData )
4578 : == CE_None )
4579 : {
4580 2 : CPLString osValue;
4581 :
4582 : papszStatsMD =
4583 : CSLSetNameValue( papszStatsMD, "STATISTICS_MINIMUM",
4584 2 : osValue.Printf( "%.15g", dfMin ) );
4585 : papszStatsMD =
4586 : CSLSetNameValue( papszStatsMD, "STATISTICS_MAXIMUM",
4587 2 : osValue.Printf( "%.15g", dfMax ) );
4588 : papszStatsMD =
4589 : CSLSetNameValue( papszStatsMD, "STATISTICS_MEAN",
4590 2 : osValue.Printf( "%.15g", dfMean ) );
4591 : papszStatsMD =
4592 : CSLSetNameValue( papszStatsMD, "STATISTICS_STDDEV",
4593 2 : osValue.Printf( "%.15g", dfStdDev ) );
4594 : }
4595 :
4596 : // -----------------------------------------------------------
4597 : // Histogram
4598 : // -----------------------------------------------------------
4599 :
4600 2 : int nBuckets, *panHistogram = NULL;
4601 :
4602 2 : if( poSrcBand->GetDefaultHistogram( &dfMin, &dfMax,
4603 : &nBuckets, &panHistogram,
4604 : TRUE,
4605 2 : pfnProgress, pProgressData )
4606 : == CE_None )
4607 : {
4608 2 : CPLString osValue;
4609 2 : char *pszBinValues = (char *) CPLCalloc(12,nBuckets+1);
4610 2 : int iBin, nBinValuesLen = 0;
4611 2 : double dfBinWidth = (dfMax - dfMin) / nBuckets;
4612 :
4613 : papszStatsMD = CSLSetNameValue(
4614 : papszStatsMD, "STATISTICS_HISTOMIN",
4615 2 : osValue.Printf( "%.15g", dfMin+dfBinWidth*0.5 ) );
4616 : papszStatsMD = CSLSetNameValue(
4617 : papszStatsMD, "STATISTICS_HISTOMAX",
4618 2 : osValue.Printf( "%.15g", dfMax-dfBinWidth*0.5 ) );
4619 : papszStatsMD =
4620 : CSLSetNameValue( papszStatsMD, "STATISTICS_HISTONUMBINS",
4621 2 : osValue.Printf( "%d", nBuckets ) );
4622 :
4623 514 : for( iBin = 0; iBin < nBuckets; iBin++ )
4624 : {
4625 :
4626 : strcat( pszBinValues+nBinValuesLen,
4627 512 : osValue.Printf( "%d", panHistogram[iBin]) );
4628 512 : strcat( pszBinValues+nBinValuesLen, "|" );
4629 512 : nBinValuesLen += strlen(pszBinValues+nBinValuesLen);
4630 : }
4631 : papszStatsMD =
4632 : CSLSetNameValue( papszStatsMD, "STATISTICS_HISTOBINVALUES",
4633 2 : pszBinValues );
4634 2 : CPLFree( pszBinValues );
4635 : }
4636 :
4637 2 : CPLFree(panHistogram);
4638 :
4639 2 : if( CSLCount(papszStatsMD) > 0 )
4640 2 : HFASetMetadata( poDS->hHFA, iBand+1, papszStatsMD );
4641 :
4642 2 : CSLDestroy( papszStatsMD );
4643 : }
4644 : }
4645 :
4646 : /* -------------------------------------------------------------------- */
4647 : /* All report completion. */
4648 : /* -------------------------------------------------------------------- */
4649 82 : if( !pfnProgress( 1.0, NULL, pProgressData ) )
4650 : {
4651 : CPLError( CE_Failure, CPLE_UserInterrupt,
4652 0 : "User terminated" );
4653 0 : delete poDS;
4654 :
4655 : GDALDriver *poHFADriver =
4656 0 : (GDALDriver *) GDALGetDriverByName( "HFA" );
4657 0 : poHFADriver->Delete( pszFilename );
4658 0 : return NULL;
4659 : }
4660 :
4661 82 : poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
4662 :
4663 82 : return poDS;
4664 : }
4665 :
4666 : /************************************************************************/
4667 : /* GDALRegister_HFA() */
4668 : /************************************************************************/
4669 :
4670 1135 : void GDALRegister_HFA()
4671 :
4672 : {
4673 : GDALDriver *poDriver;
4674 :
4675 1135 : if( GDALGetDriverByName( "HFA" ) == NULL )
4676 : {
4677 1093 : poDriver = new GDALDriver();
4678 :
4679 1093 : poDriver->SetDescription( "HFA" );
4680 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
4681 1093 : "Erdas Imagine Images (.img)" );
4682 : poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
4683 1093 : "frmt_hfa.html" );
4684 1093 : poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "img" );
4685 : poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES,
4686 1093 : "Byte Int16 UInt16 Int32 UInt32 Float32 Float64 CFloat32 CFloat64" );
4687 :
4688 : poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST,
4689 : "<CreationOptionList>"
4690 : " <Option name='BLOCKSIZE' type='integer' description='tile width/height (32-2048)' default='64'/>"
4691 : " <Option name='USE_SPILL' type='boolean' description='Force use of spill file'/>"
4692 : " <Option name='COMPRESSED' alias='COMPRESS' type='boolean' description='compress blocks'/>"
4693 : " <Option name='PIXELTYPE' type='string' description='By setting this to SIGNEDBYTE, a new Byte file can be forced to be written as signed byte'/>"
4694 : " <Option name='AUX' type='boolean' description='Create an .aux file'/>"
4695 : " <Option name='IGNOREUTM' type='boolean' description='Ignore UTM when selecting coordinate system - will use Transverse Mercator. Only used for Create() method'/>"
4696 : " <Option name='NBITS' type='integer' description='Create file with special sub-byte data type (1/2/4)'/>"
4697 : " <Option name='STATISTICS' type='boolean' description='Generate statistics and a histogram'/>"
4698 : " <Option name='DEPENDENT_FILE' type='string' description='Name of dependent file (must not have absolute path)'/>"
4699 : " <Option name='FORCETOPESTRING' type='boolean' description='Force use of ArcGIS PE String in file instead of Imagine coordinate system format'/>"
4700 1093 : "</CreationOptionList>" );
4701 :
4702 1093 : poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
4703 :
4704 1093 : poDriver->pfnOpen = HFADataset::Open;
4705 1093 : poDriver->pfnCreate = HFADataset::Create;
4706 1093 : poDriver->pfnCreateCopy = HFADataset::CreateCopy;
4707 1093 : poDriver->pfnIdentify = HFADataset::Identify;
4708 1093 : poDriver->pfnRename = HFADataset::Rename;
4709 1093 : poDriver->pfnCopyFiles = HFADataset::CopyFiles;
4710 :
4711 :
4712 1093 : GetGDALDriverManager()->RegisterDriver( poDriver );
4713 : }
4714 1135 : }
4715 :
|