1 : /******************************************************************************
2 : * $Id: hdf5imagedataset.cpp 25311 2012-12-15 12:48:14Z rouault $
3 : *
4 : * Project: Hierarchical Data Format Release 5 (HDF5)
5 : * Purpose: Read subdatasets of HDF5 file.
6 : * Author: Denis Nadeau <denis.nadeau@gmail.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #define H5_USE_16_API
31 :
32 : #include "hdf5.h"
33 :
34 : #include "gdal_pam.h"
35 : #include "gdal_priv.h"
36 : #include "cpl_string.h"
37 : #include "hdf5dataset.h"
38 : #include "ogr_spatialref.h"
39 :
40 : CPL_CVSID("$Id: hdf5imagedataset.cpp 25311 2012-12-15 12:48:14Z rouault $");
41 :
42 : CPL_C_START
43 : void GDALRegister_HDF5Image(void);
44 : CPL_C_END
45 :
46 : /* release 1.6.3 or 1.6.4 changed the type of count in some api functions */
47 :
48 : #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6 \
49 : && (H5_VERS_MINOR < 6 || H5_VERS_RELEASE < 3)
50 : # define H5OFFSET_TYPE hssize_t
51 : #else
52 : # define H5OFFSET_TYPE hsize_t
53 : #endif
54 :
55 : class HDF5ImageDataset : public HDF5Dataset
56 : {
57 :
58 : friend class HDF5ImageRasterBand;
59 :
60 : char *pszProjection;
61 : char *pszGCPProjection;
62 : GDAL_GCP *pasGCPList;
63 : int nGCPCount;
64 : OGRSpatialReference oSRS;
65 :
66 : hsize_t *dims,*maxdims;
67 : HDF5GroupObjects *poH5Objects;
68 : int ndims,dimensions;
69 : hid_t dataset_id;
70 : hid_t dataspace_id;
71 : hsize_t size;
72 : haddr_t address;
73 : hid_t datatype;
74 : hid_t native;
75 : H5T_class_t clas;
76 :
77 : public:
78 : HDF5ImageDataset();
79 : ~HDF5ImageDataset();
80 :
81 : CPLErr CreateProjections( );
82 : static GDALDataset *Open( GDALOpenInfo * );
83 : static int Identify( GDALOpenInfo * );
84 :
85 : const char *GetProjectionRef();
86 : virtual int GetGCPCount( );
87 : virtual const char *GetGCPProjection();
88 : virtual const GDAL_GCP *GetGCPs( );
89 :
90 : };
91 :
92 : /************************************************************************/
93 : /* ==================================================================== */
94 : /* HDF5ImageDataset */
95 : /* ==================================================================== */
96 : /************************************************************************/
97 :
98 : /************************************************************************/
99 : /* HDF5ImageDataset() */
100 : /************************************************************************/
101 10 : HDF5ImageDataset::HDF5ImageDataset()
102 : {
103 10 : nGCPCount = 0;
104 10 : pszProjection = NULL;
105 10 : pszGCPProjection= NULL;
106 10 : pasGCPList = NULL;
107 10 : poH5Objects = NULL;
108 10 : poH5RootGroup = NULL;
109 10 : dims = NULL;
110 10 : maxdims = NULL;
111 10 : papszMetadata = NULL;
112 10 : }
113 :
114 : /************************************************************************/
115 : /* ~HDF5ImageDataset() */
116 : /************************************************************************/
117 10 : HDF5ImageDataset::~HDF5ImageDataset( )
118 : {
119 10 : FlushCache();
120 :
121 10 : CPLFree(pszProjection);
122 10 : CPLFree(pszGCPProjection);
123 :
124 10 : if( dims )
125 10 : CPLFree( dims );
126 :
127 10 : if( maxdims )
128 10 : CPLFree( maxdims );
129 :
130 10 : if( nGCPCount > 0 )
131 : {
132 0 : for( int i = 0; i < nGCPCount; i++ )
133 : {
134 0 : if( pasGCPList[i].pszId )
135 0 : CPLFree( pasGCPList[i].pszId );
136 0 : if( pasGCPList[i].pszInfo )
137 0 : CPLFree( pasGCPList[i].pszInfo );
138 : }
139 :
140 0 : CPLFree( pasGCPList );
141 : }
142 10 : }
143 :
144 : /************************************************************************/
145 : /* ==================================================================== */
146 : /* Hdf5imagerasterband */
147 : /* ==================================================================== */
148 : /************************************************************************/
149 : class HDF5ImageRasterBand : public GDALPamRasterBand
150 : {
151 : friend class HDF5ImageDataset;
152 :
153 : int bNoDataSet;
154 : double dfNoDataValue;
155 :
156 : public:
157 :
158 : HDF5ImageRasterBand( HDF5ImageDataset *, int, GDALDataType );
159 : ~HDF5ImageRasterBand();
160 :
161 : virtual CPLErr IReadBlock( int, int, void * );
162 : virtual double GetNoDataValue( int * );
163 : virtual CPLErr SetNoDataValue( double );
164 : /* virtual CPLErr IWriteBlock( int, int, void * ); */
165 : };
166 :
167 : /************************************************************************/
168 : /* ~HDF5ImageRasterBand() */
169 : /************************************************************************/
170 :
171 10 : HDF5ImageRasterBand::~HDF5ImageRasterBand()
172 : {
173 :
174 10 : }
175 : /************************************************************************/
176 : /* HDF5ImageRasterBand() */
177 : /************************************************************************/
178 10 : HDF5ImageRasterBand::HDF5ImageRasterBand( HDF5ImageDataset *poDS, int nBand,
179 10 : GDALDataType eType )
180 :
181 : {
182 : char **papszMetaGlobal;
183 10 : this->poDS = poDS;
184 10 : this->nBand = nBand;
185 10 : eDataType = eType;
186 10 : bNoDataSet = FALSE;
187 10 : dfNoDataValue = -9999;
188 10 : nBlockXSize = poDS->GetRasterXSize( );
189 10 : nBlockYSize = 1;
190 :
191 : /* -------------------------------------------------------------------- */
192 : /* Take a copy of Global Metadata since I can't pass Raster */
193 : /* variable to Iterate function. */
194 : /* -------------------------------------------------------------------- */
195 10 : papszMetaGlobal = CSLDuplicate( poDS->papszMetadata );
196 10 : CSLDestroy( poDS->papszMetadata );
197 10 : poDS->papszMetadata = NULL;
198 :
199 10 : if( poDS->poH5Objects->nType == H5G_DATASET ) {
200 10 : poDS->CreateMetadata( poDS->poH5Objects, H5G_DATASET );
201 : }
202 :
203 : /* -------------------------------------------------------------------- */
204 : /* Recover Global Metadat and set Band Metadata */
205 : /* -------------------------------------------------------------------- */
206 :
207 10 : SetMetadata( poDS->papszMetadata );
208 :
209 10 : CSLDestroy( poDS->papszMetadata );
210 10 : poDS->papszMetadata = CSLDuplicate( papszMetaGlobal );
211 10 : CSLDestroy( papszMetaGlobal );
212 :
213 : /* check for chunksize and set it as the blocksize (optimizes read) */
214 10 : hid_t listid = H5Dget_create_plist(((HDF5ImageDataset * )poDS)->dataset_id);
215 10 : if (listid>0)
216 : {
217 10 : if(H5Pget_layout(listid) == H5D_CHUNKED)
218 : {
219 : hsize_t panChunkDims[3];
220 0 : int nDimSize = H5Pget_chunk(listid, 3, panChunkDims);
221 0 : nBlockXSize = (int) panChunkDims[nDimSize-1];
222 0 : nBlockYSize = (int) panChunkDims[nDimSize-2];
223 : }
224 10 : H5Pclose(listid);
225 : }
226 :
227 10 : }
228 :
229 : /************************************************************************/
230 : /* GetNoDataValue() */
231 : /************************************************************************/
232 3 : double HDF5ImageRasterBand::GetNoDataValue( int * pbSuccess )
233 :
234 : {
235 3 : if( bNoDataSet )
236 : {
237 0 : if( pbSuccess )
238 0 : *pbSuccess = bNoDataSet;
239 :
240 0 : return dfNoDataValue;
241 : }
242 : else
243 3 : return GDALPamRasterBand::GetNoDataValue( pbSuccess );
244 : }
245 :
246 : /************************************************************************/
247 : /* SetNoDataValue() */
248 : /************************************************************************/
249 0 : CPLErr HDF5ImageRasterBand::SetNoDataValue( double dfNoData )
250 :
251 : {
252 0 : bNoDataSet = TRUE;
253 0 : dfNoDataValue = dfNoData;
254 :
255 0 : return CE_None;
256 : }
257 :
258 : /************************************************************************/
259 : /* IReadBlock() */
260 : /************************************************************************/
261 919 : CPLErr HDF5ImageRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
262 : void * pImage )
263 : {
264 : herr_t status;
265 : hsize_t count[3];
266 : H5OFFSET_TYPE offset[3];
267 : int nSizeOfData;
268 : hid_t memspace;
269 : hsize_t col_dims[3];
270 : hsize_t rank;
271 :
272 919 : HDF5ImageDataset *poGDS = ( HDF5ImageDataset * ) poDS;
273 :
274 919 : if( poGDS->eAccess == GA_Update ) {
275 : memset( pImage, 0,
276 : nBlockXSize * nBlockYSize *
277 0 : GDALGetDataTypeSize( eDataType )/8 );
278 0 : return CE_None;
279 : }
280 :
281 919 : rank=2;
282 :
283 919 : if( poGDS->ndims == 3 ){
284 0 : rank=3;
285 0 : offset[0] = nBand-1;
286 0 : count[0] = 1;
287 0 : col_dims[0] = 1;
288 : }
289 :
290 919 : offset[poGDS->ndims - 2] = nBlockYOff*nBlockYSize;
291 919 : offset[poGDS->ndims - 1] = nBlockXOff*nBlockXSize;
292 919 : count[poGDS->ndims - 2] = nBlockYSize;
293 919 : count[poGDS->ndims - 1] = nBlockXSize;
294 :
295 919 : nSizeOfData = H5Tget_size( poGDS->native );
296 919 : memset( pImage,0,nBlockXSize*nBlockYSize*nSizeOfData );
297 :
298 : /* blocksize may not be a multiple of imagesize */
299 1845 : count[poGDS->ndims - 2] = MIN( size_t(nBlockYSize),
300 : poDS->GetRasterYSize() -
301 1845 : offset[poGDS->ndims - 2]);
302 2757 : count[poGDS->ndims - 1] = MIN( size_t(nBlockXSize),
303 : poDS->GetRasterXSize()-
304 2757 : offset[poGDS->ndims - 1]);
305 :
306 : /* -------------------------------------------------------------------- */
307 : /* Select block from file space */
308 : /* -------------------------------------------------------------------- */
309 : status = H5Sselect_hyperslab( poGDS->dataspace_id,
310 : H5S_SELECT_SET,
311 : offset, NULL,
312 919 : count, NULL );
313 :
314 : /* -------------------------------------------------------------------- */
315 : /* Create memory space to receive the data */
316 : /* -------------------------------------------------------------------- */
317 919 : col_dims[poGDS->ndims-2]=nBlockYSize;
318 919 : col_dims[poGDS->ndims-1]=nBlockXSize;
319 919 : memspace = H5Screate_simple( (int) rank, col_dims, NULL );
320 919 : H5OFFSET_TYPE mem_offset[3] = {0, 0, 0};
321 : status = H5Sselect_hyperslab(memspace,
322 : H5S_SELECT_SET,
323 : mem_offset, NULL,
324 919 : count, NULL);
325 :
326 : status = H5Dread ( poGDS->dataset_id,
327 : poGDS->native,
328 : memspace,
329 : poGDS->dataspace_id,
330 : H5P_DEFAULT,
331 919 : pImage );
332 :
333 919 : H5Sclose( memspace );
334 :
335 919 : if( status < 0 )
336 : {
337 : CPLError( CE_Failure, CPLE_AppDefined,
338 0 : "H5Dread() failed for block." );
339 0 : return CE_Failure;
340 : }
341 : else
342 919 : return CE_None;
343 : }
344 :
345 : /************************************************************************/
346 : /* Identify() */
347 : /************************************************************************/
348 :
349 10091 : int HDF5ImageDataset::Identify( GDALOpenInfo *poOpenInfo )
350 :
351 : {
352 10091 : if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) )
353 10091 : return FALSE;
354 : else
355 0 : return TRUE;
356 : }
357 :
358 : /************************************************************************/
359 : /* Open() */
360 : /************************************************************************/
361 1728 : GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo )
362 : {
363 : int i;
364 : HDF5ImageDataset *poDS;
365 : char szFilename[2048];
366 :
367 1728 : if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) ||
368 : strlen(poOpenInfo->pszFilename) > sizeof(szFilename) - 3 )
369 1718 : return NULL;
370 :
371 : /* -------------------------------------------------------------------- */
372 : /* Confirm the requested access is supported. */
373 : /* -------------------------------------------------------------------- */
374 10 : if( poOpenInfo->eAccess == GA_Update )
375 : {
376 : CPLError( CE_Failure, CPLE_NotSupported,
377 : "The HDF5ImageDataset driver does not support update access to existing"
378 0 : " datasets.\n" );
379 0 : return NULL;
380 : }
381 :
382 10 : poDS = new HDF5ImageDataset();
383 :
384 : /* -------------------------------------------------------------------- */
385 : /* Create a corresponding GDALDataset. */
386 : /* -------------------------------------------------------------------- */
387 : /* printf("poOpenInfo->pszFilename %s\n",poOpenInfo->pszFilename); */
388 : char **papszName =
389 : CSLTokenizeString2( poOpenInfo->pszFilename,
390 10 : ":", CSLT_HONOURSTRINGS|CSLT_PRESERVEESCAPES );
391 :
392 10 : if( !((CSLCount(papszName) == 3) || (CSLCount(papszName) == 4)) )
393 : {
394 0 : CSLDestroy(papszName);
395 0 : delete poDS;
396 0 : return NULL;
397 : }
398 :
399 10 : poDS->SetDescription( poOpenInfo->pszFilename );
400 :
401 : /* -------------------------------------------------------------------- */
402 : /* Check for drive name in windows HDF5:"D:\... */
403 : /* -------------------------------------------------------------------- */
404 10 : strcpy(szFilename, papszName[1]);
405 :
406 10 : if( strlen(papszName[1]) == 1 && papszName[3] != NULL )
407 : {
408 0 : strcat(szFilename, ":");
409 0 : strcat(szFilename, papszName[2]);
410 :
411 0 : poDS->SetSubdatasetName( papszName[3] );
412 : }
413 : else
414 10 : poDS->SetSubdatasetName( papszName[2] );
415 :
416 10 : CSLDestroy(papszName);
417 10 : papszName = NULL;
418 :
419 10 : if( !H5Fis_hdf5(szFilename) ) {
420 0 : delete poDS;
421 0 : return NULL;
422 : }
423 :
424 10 : poDS->SetPhysicalFilename( szFilename );
425 :
426 : /* -------------------------------------------------------------------- */
427 : /* Try opening the dataset. */
428 : /* -------------------------------------------------------------------- */
429 : poDS->hHDF5 = H5Fopen(szFilename,
430 : H5F_ACC_RDONLY,
431 10 : H5P_DEFAULT );
432 :
433 10 : if( poDS->hHDF5 < 0 )
434 : {
435 0 : delete poDS;
436 0 : return NULL;
437 : }
438 :
439 10 : poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" );
440 10 : if( poDS->hGroupID < 0 )
441 : {
442 0 : poDS->bIsHDFEOS=false;
443 0 : delete poDS;
444 0 : return NULL;
445 : }
446 :
447 : /* -------------------------------------------------------------------- */
448 : /* THIS IS AN HDF5 FILE */
449 : /* -------------------------------------------------------------------- */
450 10 : poDS->bIsHDFEOS=TRUE;
451 10 : poDS->ReadGlobalAttributes( FALSE );
452 :
453 : /* -------------------------------------------------------------------- */
454 : /* Create HDF5 Data Hierarchy in a link list */
455 : /* -------------------------------------------------------------------- */
456 : poDS->poH5Objects =
457 : poDS->HDF5FindDatasetObjectsbyPath( poDS->poH5RootGroup,
458 10 : (char *)poDS->GetSubdatasetName() );
459 :
460 10 : if( poDS->poH5Objects == NULL ) {
461 0 : delete poDS;
462 0 : return NULL;
463 : }
464 : /* -------------------------------------------------------------------- */
465 : /* Retrieve HDF5 data information */
466 : /* -------------------------------------------------------------------- */
467 10 : poDS->dataset_id = H5Dopen( poDS->hHDF5,poDS->poH5Objects->pszPath );
468 10 : poDS->dataspace_id = H5Dget_space( poDS->dataset_id );
469 10 : poDS->ndims = H5Sget_simple_extent_ndims( poDS->dataspace_id );
470 10 : poDS->dims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) );
471 10 : poDS->maxdims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) );
472 : poDS->dimensions = H5Sget_simple_extent_dims( poDS->dataspace_id,
473 : poDS->dims,
474 10 : poDS->maxdims );
475 10 : poDS->datatype = H5Dget_type( poDS->dataset_id );
476 10 : poDS->clas = H5Tget_class( poDS->datatype );
477 10 : poDS->size = H5Tget_size( poDS->datatype );
478 10 : poDS->address = H5Dget_offset( poDS->dataset_id );
479 10 : poDS->native = H5Tget_native_type( poDS->datatype, H5T_DIR_ASCEND );
480 :
481 10 : poDS->nRasterYSize=(int)poDS->dims[poDS->ndims-2]; // Y
482 10 : poDS->nRasterXSize=(int)poDS->dims[poDS->ndims-1]; // X alway last
483 :
484 10 : poDS->nBands=1;
485 :
486 10 : if( poDS->ndims == 3 ) poDS->nBands=(int) poDS->dims[0];
487 :
488 :
489 20 : for( i = 1; i <= poDS->nBands; i++ ) {
490 : HDF5ImageRasterBand *poBand =
491 : new HDF5ImageRasterBand( poDS, i,
492 10 : poDS->GetDataType( poDS->native ) );
493 :
494 10 : poDS->SetBand( i, poBand );
495 10 : if( poBand->bNoDataSet )
496 0 : poBand->SetNoDataValue( 255 );
497 : }
498 :
499 10 : poDS->CreateProjections( );
500 :
501 10 : poDS->SetMetadata( poDS->papszMetadata );
502 :
503 : /* -------------------------------------------------------------------- */
504 : /* Setup/check for pam .aux.xml. */
505 : /* -------------------------------------------------------------------- */
506 10 : poDS->TryLoadXML();
507 :
508 : /* -------------------------------------------------------------------- */
509 : /* Setup overviews. */
510 : /* -------------------------------------------------------------------- */
511 10 : poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" );
512 :
513 10 : return( poDS );
514 : }
515 :
516 :
517 : /************************************************************************/
518 : /* GDALRegister_HDF5Image() */
519 : /************************************************************************/
520 582 : void GDALRegister_HDF5Image( )
521 :
522 : {
523 : GDALDriver *poDriver;
524 :
525 582 : if (! GDAL_CHECK_VERSION("HDF5Image driver"))
526 0 : return;
527 :
528 582 : if( GDALGetDriverByName( "HDF5Image" ) == NULL )
529 : {
530 561 : poDriver = new GDALDriver( );
531 :
532 561 : poDriver->SetDescription( "HDF5Image" );
533 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
534 561 : "HDF5 Dataset" );
535 : poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
536 561 : "frmt_hdf5.html" );
537 561 : poDriver->pfnOpen = HDF5ImageDataset::Open;
538 561 : poDriver->pfnIdentify = HDF5ImageDataset::Identify;
539 :
540 561 : GetGDALDriverManager( )->RegisterDriver( poDriver );
541 : }
542 : }
543 :
544 : /************************************************************************/
545 : /* CreateProjections() */
546 : /************************************************************************/
547 10 : CPLErr HDF5ImageDataset::CreateProjections()
548 : {
549 : #define NBGCPLAT 100
550 : #define NBGCPLON 30
551 :
552 10 : hid_t LatitudeDatasetID = -1;
553 10 : hid_t LongitudeDatasetID = -1;
554 : hid_t LatitudeDataspaceID;
555 : hid_t LongitudeDataspaceID;
556 : float* Latitude;
557 : float* Longitude;
558 : int i,j;
559 : int nDeltaLat;
560 : int nDeltaLon;
561 :
562 10 : nDeltaLat = nRasterYSize / NBGCPLAT;
563 10 : nDeltaLon = nRasterXSize / NBGCPLON;
564 :
565 10 : if( nDeltaLat == 0 || nDeltaLon == 0 )
566 8 : return CE_None;
567 :
568 : /* -------------------------------------------------------------------- */
569 : /* Create HDF5 Data Hierarchy in a link list */
570 : /* -------------------------------------------------------------------- */
571 2 : poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" );
572 2 : if( !poH5Objects ) {
573 2 : return CE_None;
574 : }
575 : /* -------------------------------------------------------------------- */
576 : /* The Lattitude and Longitude arrays must have a rank of 2 to */
577 : /* retrieve GCPs. */
578 : /* -------------------------------------------------------------------- */
579 0 : if( poH5Objects->nRank != 2 ) {
580 0 : return CE_None;
581 : }
582 :
583 : /* -------------------------------------------------------------------- */
584 : /* Retrieve HDF5 data information */
585 : /* -------------------------------------------------------------------- */
586 0 : LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath );
587 0 : LatitudeDataspaceID = H5Dget_space( dataset_id );
588 :
589 0 : poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" );
590 0 : LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath );
591 0 : LongitudeDataspaceID = H5Dget_space( dataset_id );
592 :
593 0 : if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) {
594 :
595 : Latitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize,
596 0 : sizeof( float ) );
597 : Longitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize,
598 0 : sizeof( float ) );
599 0 : memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) );
600 0 : memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) );
601 :
602 : H5Dread ( LatitudeDatasetID,
603 : H5T_NATIVE_FLOAT,
604 : H5S_ALL,
605 : H5S_ALL,
606 : H5P_DEFAULT,
607 0 : Latitude );
608 :
609 : H5Dread ( LongitudeDatasetID,
610 : H5T_NATIVE_FLOAT,
611 : H5S_ALL,
612 : H5S_ALL,
613 : H5P_DEFAULT,
614 0 : Longitude );
615 :
616 0 : oSRS.SetWellKnownGeogCS( "WGS84" );
617 0 : CPLFree(pszProjection);
618 0 : CPLFree(pszGCPProjection);
619 0 : oSRS.exportToWkt( &pszProjection );
620 0 : oSRS.exportToWkt( &pszGCPProjection );
621 :
622 : /* -------------------------------------------------------------------- */
623 : /* Fill the GCPs list. */
624 : /* -------------------------------------------------------------------- */
625 0 : nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon;
626 :
627 : pasGCPList = ( GDAL_GCP * )
628 0 : CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) );
629 :
630 0 : GDALInitGCPs( nGCPCount, pasGCPList );
631 0 : int k=0;
632 :
633 0 : int nYLimit = ((int)nRasterYSize/nDeltaLat) * nDeltaLat;
634 0 : int nXLimit = ((int)nRasterXSize/nDeltaLon) * nDeltaLon;
635 0 : for( j = 0; j < nYLimit; j+=nDeltaLat )
636 : {
637 0 : for( i = 0; i < nXLimit; i+=nDeltaLon )
638 : {
639 0 : int iGCP = j * nRasterXSize + i;
640 0 : pasGCPList[k].dfGCPX = ( double ) Longitude[iGCP]+180.0;
641 0 : pasGCPList[k].dfGCPY = ( double ) Latitude[iGCP];
642 :
643 0 : pasGCPList[k].dfGCPPixel = i + 0.5;
644 0 : pasGCPList[k++].dfGCPLine = j + 0.5;
645 :
646 : }
647 : }
648 :
649 0 : CPLFree( Latitude );
650 0 : CPLFree( Longitude );
651 : }
652 0 : return CE_None;
653 :
654 : }
655 : /************************************************************************/
656 : /* GetProjectionRef() */
657 : /************************************************************************/
658 :
659 0 : const char *HDF5ImageDataset::GetProjectionRef( )
660 :
661 : {
662 0 : if( pszProjection )
663 0 : return pszProjection;
664 : else
665 0 : return GDALPamDataset::GetProjectionRef();
666 : }
667 :
668 : /************************************************************************/
669 : /* GetGCPCount() */
670 : /************************************************************************/
671 :
672 0 : int HDF5ImageDataset::GetGCPCount( )
673 :
674 : {
675 0 : if( nGCPCount > 0 )
676 0 : return nGCPCount;
677 : else
678 0 : return GDALPamDataset::GetGCPCount();
679 : }
680 :
681 : /************************************************************************/
682 : /* GetGCPProjection() */
683 : /************************************************************************/
684 :
685 0 : const char *HDF5ImageDataset::GetGCPProjection( )
686 :
687 : {
688 0 : if( nGCPCount > 0 )
689 0 : return pszGCPProjection;
690 : else
691 0 : return GDALPamDataset::GetGCPProjection();
692 : }
693 :
694 : /************************************************************************/
695 : /* GetGCPs() */
696 : /************************************************************************/
697 :
698 0 : const GDAL_GCP *HDF5ImageDataset::GetGCPs( )
699 : {
700 0 : if( nGCPCount > 0 )
701 0 : return pasGCPList;
702 : else
703 0 : return GDALPamDataset::GetGCPs();
704 : }
|