CPLErr HDF5ImageDataset::CreateProjections() { switch(iSubdatasetType) { case CSK_PRODUCT: { const char *osMissionLevel = NULL; int productType = PROD_UNKNOWN; if(GetMetadataItem("Product_Type")!=NULL) { //Get the format's level osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type"); if(EQUALN(osMissionLevel,"RAW",3)) productType = PROD_CSK_L0; if(EQUALN(osMissionLevel,"SSC",3)) productType = PROD_CSK_L1A; if(EQUALN(osMissionLevel,"DGM",3)) productType = PROD_CSK_L1B; if(EQUALN(osMissionLevel,"GEC",3)) productType = PROD_CSK_L1C; if(EQUALN(osMissionLevel,"GTC",3)) productType = PROD_CSK_L1D; } CaptureCSKGeoTransform(productType); CaptureCSKGeolocation(productType); CaptureCSKGCPs(productType); break; } case UNKNOWN_PRODUCT: { #define NBGCPLAT 100 #define NBGCPLON 30 hid_t LatitudeDatasetID = -1; hid_t LongitudeDatasetID = -1; hid_t LatitudeDataspaceID; hid_t LongitudeDataspaceID; float* Latitude; float* Longitude; int i,j; int nDeltaLat; int nDeltaLon; nDeltaLat = nRasterYSize / NBGCPLAT; nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { return CE_None; } /* -------------------------------------------------------------------- */ /* The Lattitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { Latitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); Longitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon; pasGCPList = ( GDAL_GCP * ) CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; int nYLimit = ((int)nRasterYSize/nDeltaLat) * nDeltaLat; int nXLimit = ((int)nRasterXSize/nDeltaLon) * nDeltaLon; for( j = 0; j < nYLimit; j+=nDeltaLat ) { for( i = 0; i < nXLimit; i+=nDeltaLon ) { int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = ( double ) Longitude[iGCP]+180.0; pasGCPList[k].dfGCPY = ( double ) Latitude[iGCP]; pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } if( LatitudeDatasetID > 0 ) H5Dclose(LatitudeDatasetID); if( LongitudeDatasetID > 0 ) H5Dclose(LongitudeDatasetID); break; } } return CE_None; }
CPLErr HDF5ImageDataset::CreateProjections() { switch(iSubdatasetType) { case CSK_PRODUCT: { const char *osMissionLevel = NULL; int productType = PROD_UNKNOWN; if(GetMetadataItem("Product_Type")!=NULL) { //Get the format's level osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type"); if(STARTS_WITH_CI(osMissionLevel, "RAW")) productType = PROD_CSK_L0; if(STARTS_WITH_CI(osMissionLevel, "SSC")) productType = PROD_CSK_L1A; if(STARTS_WITH_CI(osMissionLevel, "DGM")) productType = PROD_CSK_L1B; if(STARTS_WITH_CI(osMissionLevel, "GEC")) productType = PROD_CSK_L1C; if(STARTS_WITH_CI(osMissionLevel, "GTC")) productType = PROD_CSK_L1D; } CaptureCSKGeoTransform(productType); CaptureCSKGeolocation(productType); CaptureCSKGCPs(productType); break; } case UNKNOWN_PRODUCT: { static const int NBGCPLAT = 100; static const int NBGCPLON = 30; const int nDeltaLat = nRasterYSize / NBGCPLAT; const int nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { if( GetMetadataItem("where_projdef") != NULL ) return CreateODIMH5Projection(); return CE_None; } /* -------------------------------------------------------------------- */ /* The Latitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ const hid_t LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); // LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); const hid_t LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); // LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { float * const Latitude = static_cast<float *>( CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) ); float * const Longitude = static_cast<float *>( CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = (nRasterYSize/nDeltaLat) * (nRasterXSize/nDeltaLon); pasGCPList = static_cast<GDAL_GCP *>( CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; const int nYLimit = (static_cast<int>(nRasterYSize)/nDeltaLat) * nDeltaLat; const int nXLimit = (static_cast<int>(nRasterXSize)/nDeltaLon) * nDeltaLon; // The original code in https://trac.osgeo.org/gdal/changeset/8066 // always add +180 to the longitudes, but without justification // I suspect this might be due to handling products crossing the // antimeridian. Trying to do it just when needed through a heuristics. bool bHasLonNearMinus180 = false; bool bHasLonNearPlus180 = false; bool bHasLonNearZero = false; for( int j = 0; j < nYLimit; j+=nDeltaLat ) { for( int i = 0; i < nXLimit; i+=nDeltaLon ) { const int iGCP = j * nRasterXSize + i; if( Longitude[iGCP] > 170 && Longitude[iGCP] <= 180 ) bHasLonNearPlus180 = true; if( Longitude[iGCP] < -170 && Longitude[iGCP] >= -180 ) bHasLonNearMinus180 = true; if( fabs(Longitude[iGCP]) < 90 ) bHasLonNearZero = true; } } const char* pszShiftGCP = CPLGetConfigOption("HDF5_SHIFT_GCPX_BY_180", NULL); const bool bAdd180 = (bHasLonNearPlus180 && bHasLonNearMinus180 && !bHasLonNearZero && pszShiftGCP == NULL) || (pszShiftGCP != NULL && CPLTestBool(pszShiftGCP)); for( int j = 0; j < nYLimit; j+=nDeltaLat ) { for( int i = 0; i < nXLimit; i+=nDeltaLon ) { const int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = static_cast<double>(Longitude[iGCP]); if( bAdd180 ) pasGCPList[k].dfGCPX += 180.0; pasGCPList[k].dfGCPY = static_cast<double>(Latitude[iGCP]); pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } if( LatitudeDatasetID > 0 ) H5Dclose(LatitudeDatasetID); if( LongitudeDatasetID > 0 ) H5Dclose(LongitudeDatasetID); break; } } return CE_None; }