예제 #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(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;
}
예제 #2
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(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;
            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])+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;
}