Beispiel #1
0
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;
}