CPLErr MEMDataset::AddBand( GDALDataType eType, char **papszOptions )

{
    int nBandId = GetRasterCount() + 1;
    GByte *pData;
    int   nPixelSize = (GDALGetDataTypeSize(eType) / 8);

/* -------------------------------------------------------------------- */
/*      Do we need to allocate the memory ourselves?  This is the       */
/*      simple case.                                                    */
/* -------------------------------------------------------------------- */
    if( CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
    {

        pData = (GByte *) 
            VSICalloc(nPixelSize * GetRasterXSize(), GetRasterYSize() );

        if( pData == NULL )
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                      "Unable to create band arrays ... out of memory." );
            return CE_Failure;
        }

        SetBand( nBandId,
                 new MEMRasterBand( this, nBandId, pData, eType, nPixelSize, 
                                    nPixelSize * GetRasterXSize(), TRUE ) );

        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Get layout of memory and other flags.                           */
/* -------------------------------------------------------------------- */
    const char *pszOption;
    int nPixelOffset, nLineOffset;
    const char *pszDataPointer;

    pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER");
    pData = (GByte *) CPLScanPointer(pszDataPointer,
                                     strlen(pszDataPointer));
    
    pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET");
    if( pszOption == NULL )
        nPixelOffset = nPixelSize;
    else
        nPixelOffset = atoi(pszOption);

    pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET");
    if( pszOption == NULL )
        nLineOffset = GetRasterXSize() * nPixelOffset;
    else
        nLineOffset = atoi(pszOption);

    SetBand( nBandId,
             new MEMRasterBand( this, nBandId, pData, eType, 
                                nPixelOffset, nLineOffset, FALSE ) );

    return CE_None;
}
Beispiel #2
0
CPLErr PAuxDataset::GetGeoTransform( double * padfGeoTransform )

{
    if( CSLFetchNameValue(papszAuxLines, "UpLeftX") != NULL
        && CSLFetchNameValue(papszAuxLines, "UpLeftY") != NULL
        && CSLFetchNameValue(papszAuxLines, "LoRightX") != NULL
        && CSLFetchNameValue(papszAuxLines, "LoRightY") != NULL )
    {
        const double dfUpLeftX = CPLAtof(CSLFetchNameValue(papszAuxLines, "UpLeftX" ));
        const double dfUpLeftY = CPLAtof(CSLFetchNameValue(papszAuxLines, "UpLeftY" ));
        const double dfLoRightX = CPLAtof(CSLFetchNameValue(papszAuxLines, "LoRightX" ));
        const double dfLoRightY = CPLAtof(CSLFetchNameValue(papszAuxLines, "LoRightY" ));

        padfGeoTransform[0] = dfUpLeftX;
        padfGeoTransform[1] = (dfLoRightX - dfUpLeftX) / GetRasterXSize();
        padfGeoTransform[2] = 0.0;
        padfGeoTransform[3] = dfUpLeftY;
        padfGeoTransform[4] = 0.0;
        padfGeoTransform[5] = (dfLoRightY - dfUpLeftY) / GetRasterYSize();

        return CE_None;
    }
    else
    {
        padfGeoTransform[0] = 0.0;
        padfGeoTransform[1] = 1.0;
        padfGeoTransform[2] = 0.0;
        padfGeoTransform[3] = 0.0;
        padfGeoTransform[4] = 0.0;
        padfGeoTransform[5] = 1.0;

        return CE_Failure;
    }
}
Beispiel #3
0
CPLErr PAuxDataset::SetGeoTransform( double * padfGeoTransform )

{
    char szUpLeftX[128] = { '\0' };
    char szUpLeftY[128] = { '\0' };
    char szLoRightX[128] = { '\0' };
    char szLoRightY[128] = { '\0' };

    if( std::abs(padfGeoTransform[0]) < 181
        && std::abs(padfGeoTransform[1]) < 1 )
    {
        CPLsnprintf( szUpLeftX, sizeof(szUpLeftX), "%.12f",
                     padfGeoTransform[0] );
        CPLsnprintf( szUpLeftY, sizeof(szUpLeftY), "%.12f",
                     padfGeoTransform[3] );
        CPLsnprintf( szLoRightX, sizeof(szLoRightX), "%.12f",
                     padfGeoTransform[0] +
                     padfGeoTransform[1] * GetRasterXSize() );
        CPLsnprintf( szLoRightY, sizeof(szLoRightY), "%.12f",
                     padfGeoTransform[3] +
                     padfGeoTransform[5] * GetRasterYSize() );
    }
    else
    {
        CPLsnprintf( szUpLeftX, sizeof(szUpLeftX), "%.3f",
                     padfGeoTransform[0] );
        CPLsnprintf( szUpLeftY, sizeof(szUpLeftY), "%.3f",
                     padfGeoTransform[3] );
        CPLsnprintf( szLoRightX, sizeof(szLoRightX), "%.3f",
                     padfGeoTransform[0] +
                     padfGeoTransform[1] * GetRasterXSize() );
        CPLsnprintf( szLoRightY, sizeof(szLoRightY), "%.3f",
                     padfGeoTransform[3] +
                     padfGeoTransform[5] * GetRasterYSize() );
    }

    papszAuxLines = CSLSetNameValue( papszAuxLines, "UpLeftX", szUpLeftX );
    papszAuxLines = CSLSetNameValue( papszAuxLines, "UpLeftY", szUpLeftY );
    papszAuxLines = CSLSetNameValue( papszAuxLines, "LoRightX", szLoRightX );
    papszAuxLines = CSLSetNameValue( papszAuxLines, "LoRightY", szLoRightY );

    bAuxUpdated = TRUE;

    return CE_None;
}
Beispiel #4
0
CPLErr SDEDataset::GetGeoTransform( double * padfTransform )

{

    if (dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0)
        return CE_Fatal;

    padfTransform[0] = dfMinX - 0.5*(dfMaxX - dfMinX) / (GetRasterXSize()-1);
    padfTransform[3] = dfMaxY + 0.5*(dfMaxY - dfMinY) / (GetRasterYSize()-1);

    padfTransform[1] = (dfMaxX - dfMinX) / (GetRasterXSize()-1);
    padfTransform[2] = 0.0;

    padfTransform[4] = 0.0;
    padfTransform[5] = -1 * (dfMaxY - dfMinY) / (GetRasterYSize()-1);

    return CE_None;
}
Beispiel #5
0
CPLErr JDEMDataset::GetGeoTransform( double * padfTransform )

{
    const double dfLLLat = JDEMGetAngle( (char *) abyHeader + 29 );
    const double dfLLLong = JDEMGetAngle( (char *) abyHeader + 36 );
    const double dfURLat = JDEMGetAngle( (char *) abyHeader + 43 );
    const double dfURLong = JDEMGetAngle( (char *) abyHeader + 50 );

    padfTransform[0] = dfLLLong;
    padfTransform[3] = dfURLat;
    padfTransform[1] = (dfURLong - dfLLLong) / GetRasterXSize();
    padfTransform[2] = 0.0;

    padfTransform[4] = 0.0;
    padfTransform[5] = -1 * (dfURLat - dfLLLat) / GetRasterYSize();

    return CE_None;
}
Beispiel #6
0
void EnvisatDataset::ScanForGCPs_MERIS()

{
    int		nDatasetIndex, nNumDSR, nDSRSize;
    bool    isBrowseProduct ; 

/* -------------------------------------------------------------------- */
/*      Do we have a meaningful geolocation grid?  Seach for a          */
/*      DS_TYPE=A and a name containing "geolocation" or "tie           */
/*      points".                                                        */
/* -------------------------------------------------------------------- */
    nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile,
                                                 "Tie points ADS" );
    if( nDatasetIndex == -1 )
        return;

    if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex,
                                    NULL, NULL, NULL, NULL, NULL,
                                    &nNumDSR, &nDSRSize ) != SUCCESS )
        return;

    if( nNumDSR == 0 )
        return;

/* -------------------------------------------------------------------- */
/*      Figure out the tiepoint space, and how many we have.            */
/* -------------------------------------------------------------------- */
    int  nLinesPerTiePoint, nSamplesPerTiePoint;
    int  nTPPerLine, nTPPerColumn = nNumDSR;

    if( nNumDSR == 0 )
        return;

    nLinesPerTiePoint =
        EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
                                      "LINES_PER_TIE_PT", 0 );
    nSamplesPerTiePoint =
        EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
                                      "SAMPLES_PER_TIE_PT", 0 );

    if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 )
        return;

    nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1)
        / nSamplesPerTiePoint;

/* -------------------------------------------------------------------- */
/*      Find a Mesurement type dataset to use as a reference raster     */
/*      band.                                                           */
/* -------------------------------------------------------------------- */

    int		nMDSIndex;

    for( nMDSIndex = 0; TRUE; nMDSIndex++ )
    {
        char *pszDSType;
        if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nMDSIndex,
            NULL, &pszDSType, NULL, NULL, NULL, NULL, NULL ) == FAILURE )
        {
            CPLDebug("EnvisatDataset",
                            "Unable to find MDS in Envisat file.") ;
            return ;
    }
        if( EQUAL(pszDSType,"M") ) break;
    }

/* -------------------------------------------------------------------- */
/*      Get subset of TP ADS records matching the MDS records	*/
/* -------------------------------------------------------------------- */

    /* get the MDS line sampling time interval */
    TimeDelta tdMDSSamplingInterval( 0 , 0 ,  
        EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
                                      "LINE_TIME_INTERVAL", 0  ) );

    /* get range of TiePoint ADS records matching the measurements */
    ADSRangeLastAfter arTP( *hEnvisatFile , nDatasetIndex, 
        nMDSIndex , tdMDSSamplingInterval ) ; 
    
    /* check if there are any TPs to be used */ 
    if ( arTP.getDSRCount() <= 0 )
    {
        CPLDebug( "EnvisatDataset" , "No tiepoint covering "
            "the measurement records." ) ;
        return; /* No TPs - no extraction. */
    } 

    /* check if TPs cover the whole range of MDSRs */
    if(( arTP.getFirstOffset() < 0 )||( arTP.getLastOffset() < 0 ))
    {
        CPLDebug( "EnvisatDataset" , "The tiepoints do not cover "
            "whole range of measurement records." ) ;
        /* Not good but we can still extract some of the TPS, can we? */
    }

    /* check TP records spacing */
    if ((1+(arTP.getFirstOffset()+arTP.getLastOffset()+GetRasterYSize()-1) 
           / nLinesPerTiePoint ) != arTP.getDSRCount() )
    {
        CPLDebug( "EnvisatDataset", "Not enough tieponts per column! "
            "received=%d expected=%d", nTPPerColumn , 
                1 + (arTP.getFirstOffset()+arTP.getLastOffset()+
                      GetRasterYSize()-1) / nLinesPerTiePoint ) ; 
        return; /* That is far more serious - we risk missplaces TPs. */
    }

    if ( 50*nTPPerLine + 13 == nDSRSize ) /* regular product */
    {
        isBrowseProduct = false ; 
    } 
    else if ( 8*nTPPerLine + 13 == nDSRSize ) /* browse product */
    { 
        /* although BPs are rare there is no reason not to support them */
        isBrowseProduct = true ; 
    } 
    else 
    {
        CPLDebug( "EnvisatDataset", "Unexpectd size of 'Tie points ADS' !"
                " received=%d expected=%d or %d" , nDSRSize ,
                50*nTPPerLine+13, 8*nTPPerLine+13 ) ;
        return;
    }

/* -------------------------------------------------------------------- */
/*      Collect the first GCP set from each record.			*/
/* -------------------------------------------------------------------- */

    GByte	*pabyRecord = (GByte *) CPLMalloc(nDSRSize-13);
    int  	iGCP;

    GUInt32 *tpLat = ((GUInt32*)pabyRecord) + nTPPerLine*0 ; /* latitude */  
    GUInt32 *tpLon = ((GUInt32*)pabyRecord) + nTPPerLine*1 ; /* longitude */  
    GUInt32 *tpLtc = ((GUInt32*)pabyRecord) + nTPPerLine*4 ; /* lat. DEM correction */
    GUInt32 *tpLnc = ((GUInt32*)pabyRecord) + nTPPerLine*5 ; /* lon. DEM correction */ 

    nGCPCount = 0;
    pasGCPList = (GDAL_GCP *) CPLCalloc( sizeof(GDAL_GCP), 
                                        arTP.getDSRCount() * nTPPerLine );

    for( int ir = 0 ; ir < arTP.getDSRCount() ; ir++ )
    {
        int iRecord = ir + arTP.getFirstIndex() ; 

        double dfGCPLine = 0.5 + 
            ( iRecord*nLinesPerTiePoint - arTP.getFirstOffset() ) ; 

        if( EnvisatFile_ReadDatasetRecordChunk( hEnvisatFile, nDatasetIndex,
                    iRecord , pabyRecord, 13 , -1 ) != SUCCESS )
            continue;

        for( iGCP = 0; iGCP < nTPPerLine; iGCP++ )
        {
            char	szId[128];

            GDALInitGCPs( 1, pasGCPList + nGCPCount );

            CPLFree( pasGCPList[nGCPCount].pszId );

            sprintf( szId, "%d", nGCPCount+1 );
            pasGCPList[nGCPCount].pszId = CPLStrdup( szId );

            #define INT32(x)    ((GInt32)CPL_MSBWORD32(x)) 

            pasGCPList[nGCPCount].dfGCPX = 1e-6*INT32(tpLon[iGCP]) ; 
            pasGCPList[nGCPCount].dfGCPY = 1e-6*INT32(tpLat[iGCP]) ; 
            pasGCPList[nGCPCount].dfGCPZ = 0.0;

            if( !isBrowseProduct ) /* add DEM corrections */
            { 
                pasGCPList[nGCPCount].dfGCPX += 1e-6*INT32(tpLnc[iGCP]) ; 
                pasGCPList[nGCPCount].dfGCPY += 1e-6*INT32(tpLtc[iGCP]) ; 
            } 

            #undef INT32

            pasGCPList[nGCPCount].dfGCPLine = dfGCPLine ; 
            pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5;

            nGCPCount++;
        }
    }
    CPLFree( pabyRecord );
}
Beispiel #7
0
CPLErr VRTDataset::AddBand( GDALDataType eType, char **papszOptions )

{
    int i;

    const char *pszSubClass = CSLFetchNameValue(papszOptions, "subclass");

    bNeedsFlush = 1;

/* ==================================================================== */
/*      Handle a new raw band.                                          */
/* ==================================================================== */
    if( pszSubClass != NULL && EQUAL(pszSubClass,"VRTRawRasterBand") )
    {
        int nWordDataSize = GDALGetDataTypeSize( eType ) / 8;
        vsi_l_offset nImageOffset = 0;
        int nPixelOffset = nWordDataSize;
        int nLineOffset = nWordDataSize * GetRasterXSize();
        const char *pszFilename;
        const char *pszByteOrder = NULL;
        int bRelativeToVRT = FALSE;

/* -------------------------------------------------------------------- */
/*      Collect required information.                                   */
/* -------------------------------------------------------------------- */
        if( CSLFetchNameValue(papszOptions, "ImageOffset") != NULL )
            nImageOffset = atoi(CSLFetchNameValue(papszOptions, "ImageOffset"));

        if( CSLFetchNameValue(papszOptions, "PixelOffset") != NULL )
            nPixelOffset = atoi(CSLFetchNameValue(papszOptions,"PixelOffset"));

        if( CSLFetchNameValue(papszOptions, "LineOffset") != NULL )
            nLineOffset = atoi(CSLFetchNameValue(papszOptions, "LineOffset"));

        if( CSLFetchNameValue(papszOptions, "ByteOrder") != NULL )
            pszByteOrder = CSLFetchNameValue(papszOptions, "ByteOrder");

        if( CSLFetchNameValue(papszOptions, "SourceFilename") != NULL )
            pszFilename = CSLFetchNameValue(papszOptions, "SourceFilename");
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "AddBand() requires a SourceFilename option for VRTRawRasterBands." );
            return CE_Failure;
        }
        
        bRelativeToVRT = 
            CSLFetchBoolean( papszOptions, "RelativeToVRT", FALSE );

/* -------------------------------------------------------------------- */
/*      Create and initialize the band.                                 */
/* -------------------------------------------------------------------- */
        CPLErr eErr;

        VRTRawRasterBand *poBand = 
            new VRTRawRasterBand( this, GetRasterCount() + 1, eType );

        eErr = 
            poBand->SetRawLink( pszFilename, NULL, FALSE, 
                                nImageOffset, nPixelOffset, nLineOffset, 
                                pszByteOrder );
        if( eErr != CE_None )
        {
            delete poBand;
            return eErr;
        }

        SetBand( GetRasterCount() + 1, poBand );

        return CE_None;
    }

/* ==================================================================== */
/*      Handle a new "sourced" band.                                    */
/* ==================================================================== */
    else
    {
        VRTSourcedRasterBand *poBand;

	/* ---- Check for our sourced band 'derived' subclass ---- */
        if(pszSubClass != NULL && EQUAL(pszSubClass,"VRTDerivedRasterBand")) {

            /* We'll need a pointer to the subclass in case we need */
            /* to set the new band's pixel function below. */
            VRTDerivedRasterBand* poDerivedBand;

            poDerivedBand = new VRTDerivedRasterBand
                (this, GetRasterCount() + 1, eType,
                 GetRasterXSize(), GetRasterYSize());

            /* Set the pixel function options it provided. */
            const char* pszFuncName =
                CSLFetchNameValue(papszOptions, "PixelFunctionType");
            if (pszFuncName != NULL)
                poDerivedBand->SetPixelFunctionName(pszFuncName);

            const char* pszTransferTypeName =
                CSLFetchNameValue(papszOptions, "SourceTransferType");
            if (pszTransferTypeName != NULL) {
                GDALDataType eTransferType =
                    GDALGetDataTypeByName(pszTransferTypeName);
                if (eTransferType == GDT_Unknown) {
                    CPLError( CE_Failure, CPLE_AppDefined,
                              "invalid SourceTransferType: \"%s\".",
                              pszTransferTypeName);
                    delete poDerivedBand;
                    return CE_Failure;
                }
                poDerivedBand->SetSourceTransferType(eTransferType);
            }

            /* We're done with the derived band specific stuff, so */
            /* we can assigned the base class pointer now. */
            poBand = poDerivedBand;
        }
	else {

	    /* ---- Standard sourced band ---- */
	    poBand = new VRTSourcedRasterBand
		(this, GetRasterCount() + 1, eType, 
		 GetRasterXSize(), GetRasterYSize());
	}

        SetBand( GetRasterCount() + 1, poBand );

        for( i=0; papszOptions != NULL && papszOptions[i] != NULL; i++ )
        {
            if( EQUALN(papszOptions[i],"AddFuncSource=", 14) )
            {
                VRTImageReadFunc pfnReadFunc = NULL;
                void             *pCBData = NULL;
                double           dfNoDataValue = VRT_NODATA_UNSET;

                char **papszTokens = CSLTokenizeStringComplex( papszOptions[i]+14,
                                                               ",", TRUE, FALSE );

                if( CSLCount(papszTokens) < 1 )
                {
                    CPLError( CE_Failure, CPLE_AppDefined, 
                              "AddFuncSource() ... required argument missing." );
                }

                sscanf( papszTokens[0], "%p", &pfnReadFunc );
                if( CSLCount(papszTokens) > 1 )
                    sscanf( papszTokens[1], "%p", &pCBData );
                if( CSLCount(papszTokens) > 2 )
                    dfNoDataValue = atof( papszTokens[2] );

                poBand->AddFuncSource( pfnReadFunc, pCBData, dfNoDataValue );
            }
        }

        return CE_None;
    }
}
Beispiel #8
0
CPLXMLNode *VRTDataset::SerializeToXML( const char *pszVRTPath )

{
    /* -------------------------------------------------------------------- */
    /*      Setup root node and attributes.                                 */
    /* -------------------------------------------------------------------- */
    CPLXMLNode *psDSTree = NULL;
    CPLXMLNode *psMD = NULL;
    char       szNumber[128];

    psDSTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTDataset" );

    sprintf( szNumber, "%d", GetRasterXSize() );
    CPLSetXMLValue( psDSTree, "#rasterXSize", szNumber );

    sprintf( szNumber, "%d", GetRasterYSize() );
    CPLSetXMLValue( psDSTree, "#rasterYSize", szNumber );

 /* -------------------------------------------------------------------- */
 /*      SRS                                                             */
 /* -------------------------------------------------------------------- */
    if( pszProjection != NULL && strlen(pszProjection) > 0 )
        CPLSetXMLValue( psDSTree, "SRS", pszProjection );

 /* -------------------------------------------------------------------- */
 /*      Geotransform.                                                   */
 /* -------------------------------------------------------------------- */
    if( bGeoTransformSet )
    {
        CPLSetXMLValue( psDSTree, "GeoTransform", 
                        CPLSPrintf( "%24.16e,%24.16e,%24.16e,%24.16e,%24.16e,%24.16e",
                                    adfGeoTransform[0],
                                    adfGeoTransform[1],
                                    adfGeoTransform[2],
                                    adfGeoTransform[3],
                                    adfGeoTransform[4],
                                    adfGeoTransform[5] ) );
    }

/* -------------------------------------------------------------------- */
/*      Metadata                                                        */
/* -------------------------------------------------------------------- */
    psMD = oMDMD.Serialize();
    if( psMD != NULL )
        CPLAddXMLChild( psDSTree, psMD );

 /* -------------------------------------------------------------------- */
 /*      GCPs                                                            */
 /* -------------------------------------------------------------------- */
    if( nGCPCount > 0 )
    {
        CPLXMLNode *psGCPList = CPLCreateXMLNode( psDSTree, CXT_Element, 
                                                  "GCPList" );

        CPLXMLNode* psLastChild = NULL;

        if( pszGCPProjection != NULL && strlen(pszGCPProjection) > 0 )
        {
            CPLSetXMLValue( psGCPList, "#Projection", pszGCPProjection );
            psLastChild = psGCPList->psChild;
        }

        for( int iGCP = 0; iGCP < nGCPCount; iGCP++ )
        {
            CPLXMLNode *psXMLGCP;
            GDAL_GCP *psGCP = pasGCPList + iGCP;

            psXMLGCP = CPLCreateXMLNode( NULL, CXT_Element, "GCP" );

            if( psLastChild == NULL )
                psGCPList->psChild = psXMLGCP;
            else
                psLastChild->psNext = psXMLGCP;
            psLastChild = psXMLGCP;

            CPLSetXMLValue( psXMLGCP, "#Id", psGCP->pszId );

            if( psGCP->pszInfo != NULL && strlen(psGCP->pszInfo) > 0 )
                CPLSetXMLValue( psXMLGCP, "Info", psGCP->pszInfo );

            CPLSetXMLValue( psXMLGCP, "#Pixel", 
                            CPLSPrintf( "%.4f", psGCP->dfGCPPixel ) );

            CPLSetXMLValue( psXMLGCP, "#Line", 
                            CPLSPrintf( "%.4f", psGCP->dfGCPLine ) );

            CPLSetXMLValue( psXMLGCP, "#X", 
                            CPLSPrintf( "%.12E", psGCP->dfGCPX ) );

            CPLSetXMLValue( psXMLGCP, "#Y", 
                            CPLSPrintf( "%.12E", psGCP->dfGCPY ) );

            if( psGCP->dfGCPZ != 0.0 )
                CPLSetXMLValue( psXMLGCP, "#GCPZ", 
                                CPLSPrintf( "%.12E", psGCP->dfGCPZ ) );
        }
    }

    /* -------------------------------------------------------------------- */
    /*      Serialize bands.                                                */
    /* -------------------------------------------------------------------- */
    for( int iBand = 0; iBand < nBands; iBand++ )
    {
        CPLXMLNode *psBandTree = 
            ((VRTRasterBand *) papoBands[iBand])->SerializeToXML(pszVRTPath);

        if( psBandTree != NULL )
            CPLAddXMLChild( psDSTree, psBandTree );
    }

    /* -------------------------------------------------------------------- */
    /*      Serialize dataset mask band.                                    */
    /* -------------------------------------------------------------------- */
    if (poMaskBand)
    {
        CPLXMLNode *psBandTree =
            poMaskBand->SerializeToXML(pszVRTPath);

        if( psBandTree != NULL )
        {
            CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psDSTree, CXT_Element, 
                                                              "MaskBand" );
            CPLAddXMLChild( psMaskBandElement, psBandTree );
        }
    }

    return psDSTree;
}
void BAGDataset::LoadMetadata()

{
/* -------------------------------------------------------------------- */
/*      Load the metadata from the file.                                */
/* -------------------------------------------------------------------- */
    hid_t hMDDS = H5Dopen( hHDF5, "/BAG_root/metadata" );
    hid_t datatype     = H5Dget_type( hMDDS );
    hid_t dataspace    = H5Dget_space( hMDDS );
    hid_t native       = H5Tget_native_type( datatype, H5T_DIR_ASCEND );
    hsize_t dims[3], maxdims[3];

    H5Sget_simple_extent_dims( dataspace, dims, maxdims );

    pszXMLMetadata = (char *) CPLCalloc(dims[0]+1,1);

    H5Dread( hMDDS, native, H5S_ALL, dataspace, H5P_DEFAULT, pszXMLMetadata );

    H5Sclose( dataspace );
    H5Tclose( datatype );
    H5Dclose( hMDDS );

    if( strlen(pszXMLMetadata) == 0 )
        return;

/* -------------------------------------------------------------------- */
/*      Try to get the geotransform.                                    */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot = CPLParseXMLString( pszXMLMetadata );

    if( psRoot == NULL )
        return;

    CPLStripXMLNamespace( psRoot, NULL, TRUE );

    CPLXMLNode *psGeo = CPLSearchXMLNode( psRoot, "=MD_Georectified" );

    if( psGeo != NULL )
    {
        char **papszCornerTokens = 
            CSLTokenizeStringComplex( 
                CPLGetXMLValue( psGeo, "cornerPoints.Point.coordinates", "" ),
                " ,", FALSE, FALSE );

        if( CSLCount(papszCornerTokens ) == 4 )
        {
            double dfLLX = atof( papszCornerTokens[0] );
            double dfLLY = atof( papszCornerTokens[1] );
            double dfURX = atof( papszCornerTokens[2] );
            double dfURY = atof( papszCornerTokens[3] );

            adfGeoTransform[0] = dfLLX;
            adfGeoTransform[1] = (dfURX - dfLLX) / (GetRasterXSize()-1);
            adfGeoTransform[3] = dfURY;
            adfGeoTransform[5] = (dfLLY - dfURY) / (GetRasterYSize()-1);

            adfGeoTransform[0] -= adfGeoTransform[1] * 0.5;
            adfGeoTransform[3] -= adfGeoTransform[5] * 0.5;
        }
        CSLDestroy( papszCornerTokens );
    }

    CPLDestroyXMLNode( psRoot );

/* -------------------------------------------------------------------- */
/*      Try to get the coordinate system.                               */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;

    if( OGR_SRS_ImportFromISO19115( &oSRS, pszXMLMetadata )
        == OGRERR_NONE )
    {
        oSRS.exportToWkt( &pszProjection );
    }
}
Beispiel #10
0
CPLErr MEMDataset::AddBand( GDALDataType eType, char **papszOptions )

{
    const int nBandId = GetRasterCount() + 1;
    const GSpacing nPixelSize = GDALGetDataTypeSizeBytes(eType);

/* -------------------------------------------------------------------- */
/*      Do we need to allocate the memory ourselves?  This is the       */
/*      simple case.                                                    */
/* -------------------------------------------------------------------- */
    if( CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
    {
        const GSpacing nTmp = nPixelSize * GetRasterXSize();
        GByte *pData = NULL;
#if SIZEOF_VOIDP == 4
        if( nTmp > INT_MAX )
            pData = NULL;
        else
#endif
            pData = reinterpret_cast<GByte *>(
                VSI_CALLOC_VERBOSE((size_t)nTmp, GetRasterYSize() ) );

        if( pData == NULL )
        {
            return CE_Failure;
        }

        SetBand( nBandId,
                 new MEMRasterBand( this, nBandId, pData, eType, nPixelSize,
                                    nPixelSize * GetRasterXSize(), TRUE ) );

        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Get layout of memory and other flags.                           */
/* -------------------------------------------------------------------- */
    const char *pszDataPointer = CSLFetchNameValue(papszOptions, "DATAPOINTER");
    GByte *pData = reinterpret_cast<GByte *>(
        CPLScanPointer( pszDataPointer,
                        static_cast<int>(strlen(pszDataPointer)) ) );

    const char *pszOption = CSLFetchNameValue(papszOptions, "PIXELOFFSET");
    GSpacing nPixelOffset;
    if( pszOption == NULL )
        nPixelOffset = nPixelSize;
    else
        nPixelOffset = CPLAtoGIntBig(pszOption);

    pszOption = CSLFetchNameValue(papszOptions, "LINEOFFSET");
    GSpacing nLineOffset;
    if( pszOption == NULL )
        nLineOffset = GetRasterXSize() * static_cast<size_t>( nPixelOffset );
    else
        nLineOffset = CPLAtoGIntBig(pszOption);

    SetBand( nBandId,
             new MEMRasterBand( this, nBandId, pData, eType,
                                nPixelOffset, nLineOffset, FALSE ) );

    return CE_None;
}
Beispiel #11
0
CPLXMLNode *VRTWarpedDataset::SerializeToXML( const char *pszVRTPath )

{
    CPLXMLNode *psTree;

    psTree = VRTDataset::SerializeToXML( pszVRTPath );

    if( psTree == NULL )
        return psTree;

/* -------------------------------------------------------------------- */
/*      Set subclass.                                                   */
/* -------------------------------------------------------------------- */
    CPLCreateXMLNode( 
        CPLCreateXMLNode( psTree, CXT_Attribute, "subClass" ), 
        CXT_Text, "VRTWarpedDataset" );

/* -------------------------------------------------------------------- */
/*      Serialize the block size.                                       */
/* -------------------------------------------------------------------- */
    CPLCreateXMLElementAndValue( psTree, "BlockXSize",
                                 CPLSPrintf( "%d", nBlockXSize ) );
    CPLCreateXMLElementAndValue( psTree, "BlockYSize",
                                 CPLSPrintf( "%d", nBlockYSize ) );

/* -------------------------------------------------------------------- */
/*      Serialize the overview list.                                    */
/* -------------------------------------------------------------------- */
    if( nOverviewCount > 0 )
    {
        char *pszOverviewList;
        int iOverview;
        
        pszOverviewList = (char *) CPLMalloc(nOverviewCount*8 + 10);
        pszOverviewList[0] = '\0';
        for( iOverview = 0; iOverview < nOverviewCount; iOverview++ )
        {
            int nOvFactor;

            nOvFactor = (int) 
                (0.5+GetRasterXSize() 
                 / (double) papoOverviews[iOverview]->GetRasterXSize());

            sprintf( pszOverviewList + strlen(pszOverviewList), 
                     "%d ", nOvFactor );
        }

        CPLCreateXMLElementAndValue( psTree, "OverviewList", pszOverviewList );

        CPLFree( pszOverviewList );
    }

/* ==================================================================== */
/*      Serialize the warp options.                                     */
/* ==================================================================== */
    CPLXMLNode *psWOTree;

    if( poWarper != NULL )
    {
/* -------------------------------------------------------------------- */
/*      We reset the destination dataset name so it doesn't get         */
/*      written out in the serialize warp options.                      */
/* -------------------------------------------------------------------- */
        char *pszSavedName = CPLStrdup(GetDescription());
        SetDescription("");

        psWOTree = GDALSerializeWarpOptions( poWarper->GetOptions() );
        CPLAddXMLChild( psTree, psWOTree );

        SetDescription( pszSavedName );
        CPLFree( pszSavedName );

/* -------------------------------------------------------------------- */
/*      We need to consider making the source dataset relative to       */
/*      the VRT file if possible.  Adjust accordingly.                  */
/* -------------------------------------------------------------------- */
        CPLXMLNode *psSDS = CPLGetXMLNode( psWOTree, "SourceDataset" );
        int bRelativeToVRT;
        char *pszRelativePath;

        pszRelativePath = 
            CPLStrdup(
                CPLExtractRelativePath( pszVRTPath, psSDS->psChild->pszValue, 
                                        &bRelativeToVRT ) );

        CPLFree( psSDS->psChild->pszValue );
        psSDS->psChild->pszValue = pszRelativePath;

        CPLCreateXMLNode( 
            CPLCreateXMLNode( psSDS, CXT_Attribute, "relativeToVRT" ), 
            CXT_Text, bRelativeToVRT ? "1" : "0" );
    }

    return psTree;
}
Beispiel #12
0
CPLErr 
VRTWarpedDataset::IBuildOverviews( const char *pszResampling, 
                                   int nOverviews, int *panOverviewList, 
                                   int nListBands, int *panBandList,
                                   GDALProgressFunc pfnProgress, 
                                   void * pProgressData )
    
{
/* -------------------------------------------------------------------- */
/*      Initial progress result.                                        */
/* -------------------------------------------------------------------- */
    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Establish which of the overview levels we already have, and     */
/*      which are new.                                                  */
/* -------------------------------------------------------------------- */
    int   i, nNewOverviews, *panNewOverviewList = NULL;

    nNewOverviews = 0;
    panNewOverviewList = (int *) CPLCalloc(sizeof(int),nOverviews);
    for( i = 0; i < nOverviews; i++ )
    {
        int   j;

        for( j = 0; j < nOverviewCount; j++ )
        {
            int    nOvFactor;
            VRTWarpedDataset *poOverview = papoOverviews[j];
            
            nOvFactor = (int) 
                (0.5+GetRasterXSize() / (double) poOverview->GetRasterXSize());

            if( nOvFactor == panOverviewList[i] 
                || nOvFactor == GDALOvLevelAdjust( panOverviewList[i], 
                                                   GetRasterXSize() ) )
                panOverviewList[i] *= -1;
        }

        if( panOverviewList[i] > 0 )
            panNewOverviewList[nNewOverviews++] = panOverviewList[i];
    }

/* -------------------------------------------------------------------- */
/*      Create each missing overview (we don't need to do anything      */
/*      to update existing overviews).                                  */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nNewOverviews; i++ )
    {
        int    nOXSize, nOYSize, iBand;
        VWOTInfo *psInfo;
        VRTWarpedDataset *poOverviewDS;
        
/* -------------------------------------------------------------------- */
/*      What size should this overview be.                              */
/* -------------------------------------------------------------------- */
        nOXSize = (GetRasterXSize() + panNewOverviewList[i] - 1) 
            / panNewOverviewList[i];
                                 
        nOYSize = (GetRasterYSize() + panNewOverviewList[i] - 1) 
            / panNewOverviewList[i];

/* -------------------------------------------------------------------- */
/*      Create the overview dataset.                                    */
/* -------------------------------------------------------------------- */
        poOverviewDS = new VRTWarpedDataset( nOXSize, nOYSize );
        
        for( iBand = 0; iBand < GetRasterCount(); iBand++ )
        {
            GDALRasterBand *poOldBand = GetRasterBand(iBand+1);
            VRTWarpedRasterBand *poNewBand = 
                new VRTWarpedRasterBand( poOverviewDS, iBand+1, 
                                         poOldBand->GetRasterDataType() );
            
            poNewBand->CopyCommonInfoFrom( poOldBand );
            poOverviewDS->SetBand( iBand+1, poNewBand );
        }

        nOverviewCount++;
        papoOverviews = (VRTWarpedDataset **)
            CPLRealloc( papoOverviews, sizeof(void*) * nOverviewCount );

        papoOverviews[nOverviewCount-1] = poOverviewDS;
        
/* -------------------------------------------------------------------- */
/*      Prepare update transformation information that will apply       */
/*      the overview decimation.                                        */
/* -------------------------------------------------------------------- */
        GDALWarpOptions *psWO = (GDALWarpOptions *) poWarper->GetOptions();
        psInfo = (VWOTInfo *) CPLCalloc(sizeof(VWOTInfo),1);

        strcpy( psInfo->sTI.szSignature, "GTI" );
        psInfo->sTI.pszClassName = "VRTWarpedOverviewTransform";
        psInfo->sTI.pfnTransform = VRTWarpedOverviewTransform;
        psInfo->sTI.pfnCleanup = VRTWarpedOverviewCleanup;
        psInfo->sTI.pfnSerialize = NULL;

        psInfo->pfnBaseTransformer = psWO->pfnTransformer;
        psInfo->pBaseTransformerArg = psWO->pTransformerArg;

        psInfo->dfXOverviewFactor = GetRasterXSize() / (double) nOXSize;
        psInfo->dfYOverviewFactor = GetRasterYSize() / (double) nOYSize;

/* -------------------------------------------------------------------- */
/*      Initialize the new dataset with adjusted warp options, and      */
/*      then restore to original condition.                             */
/* -------------------------------------------------------------------- */
        psWO->pfnTransformer = VRTWarpedOverviewTransform;
        psWO->pTransformerArg = psInfo;

        poOverviewDS->Initialize( psWO );

        psWO->pfnTransformer = psInfo->pfnBaseTransformer;
        psWO->pTransformerArg = psInfo->pBaseTransformerArg;
    }

    CPLFree( panNewOverviewList );

/* -------------------------------------------------------------------- */
/*      Progress finished.                                              */
/* -------------------------------------------------------------------- */
    pfnProgress( 1.0, NULL, pProgressData );

    SetNeedsFlush();

    return CE_None;
}
Beispiel #13
0
bool TerragenDataset::write_header()
{
    char szHeader[16];
    memcpy(szHeader, "TERRAGENTERRAIN ", sizeof(szHeader));

    if(1 != VSIFWriteL( reinterpret_cast<void *>( szHeader ), sizeof(szHeader), 1, m_fp ))
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Couldn't write to Terragen file %s.\n"
                  "Is file system full?",
                  m_pszFilename );
        VSIFCloseL( m_fp );

        return false;
    }

// --------------------------------------------------------------------
//      Write out the heightfield dimensions, etc.
// --------------------------------------------------------------------

    const int nXSize = GetRasterXSize();
    const int nYSize = GetRasterYSize();

    write_next_tag( "SIZE" );
    put( static_cast<GInt16>( std::min( nXSize, nYSize ) - 1 ) );
    pad( sizeof(GInt16) );

    if(nXSize != nYSize)
    {
        write_next_tag( "XPTS" );
        put( static_cast<GInt16>( nXSize ) );
        pad( sizeof(GInt16) );
        write_next_tag( "YPTS" );
        put( static_cast<GInt16>( nYSize ) );
        pad( sizeof(GInt16) );
    }

	if(m_bIsGeo)
    {
		/*
			With a geographic projection (degrees),
			m_dGroundScale will be in degrees and
			m_dMetersPerGroundUnit is undefined.
			So we're going to estimate a m_dMetersPerGroundUnit
			value here (i.e., meters per degree).

			We figure out the degree size of one
			pixel, and then the latitude degrees
			of the heightfield's center. The circumference of
			the latitude's great circle lets us know how
			wide the pixel is in meters, and we
			average that with the pixel's meter breadth,
			which is based on the polar circumference.
		*/

		/*const double m_dDegLongPerPixel =
			fabs(m_adfTransform[1]);*/

        const double m_dDegLatPerPixel = std::abs(m_adfTransform[5]);

		/*const double m_dCenterLongitude =
			m_adfTransform[0] +
			(0.5 * m_dDegLongPerPixel * (nXSize-1));*/

		const double m_dCenterLatitude =
			m_adfTransform[3] +
			(0.5 * m_dDegLatPerPixel * (nYSize-1));


        const double dLatCircum = kdEarthCircumEquat
            * std::sin( degrees_to_radians( 90.0 - m_dCenterLatitude ) );

		const double dMetersPerDegLongitude = dLatCircum / 360;
		/*const double dMetersPerPixelX =
			(m_dDegLongPerPixel / 360) * dLatCircum;*/

		const double dMetersPerDegLatitude =
			kdEarthCircumPolar / 360;
		/*const double dMetersPerPixelY =
			(m_dDegLatPerPixel / 360) * kdEarthCircumPolar;*/

		m_dMetersPerGroundUnit =
			average(dMetersPerDegLongitude, dMetersPerDegLatitude);
    }

	m_dSCAL = m_dGroundScale * m_dMetersPerGroundUnit;

	if(m_dSCAL != 30.0)
    {
        const float sc = static_cast<float>( m_dSCAL );
        write_next_tag( "SCAL" );
        put( sc );
        put( sc );
        put( sc );
    }

    if( !write_next_tag( "ALTW" ) )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Couldn't write to Terragen file %s.\n"
                  "Is file system full?",
                  m_pszFilename );
        VSIFCloseL( m_fp );

        return false;
    }

	// Compute physical scales and offsets.
	m_span_m[0] = m_dLogSpan[0] * m_dMetersPerElevUnit;
	m_span_m[1] = m_dLogSpan[1] * m_dMetersPerElevUnit;

	m_span_px[0] = m_span_m[0] / m_dSCAL;
	m_span_px[1] = m_span_m[1] / m_dSCAL;

	const double span_px = m_span_px[1] - m_span_px[0];
    m_nHeightScale = static_cast<GInt16>( span_px );
	if(m_nHeightScale == 0)
		m_nHeightScale++;

// TODO(schwehr): Make static functions.
#define P2L_PX(n, hs, bh) (static_cast<double>( n ) / 65536.0 * (hs) + (bh))

#define L2P_PX(n, hs, bh) (static_cast<int>( ((n)-(bh)) * 65536.0 / (hs) ) )

	// Increase the heightscale until the physical span
	// fits within a 16-bit range. The smaller the logical span,
	// the more necessary this becomes.
    int hs = m_nHeightScale;
    int bh = 0;
    for( ; hs <= 32767; hs++)
    {
        double prevdelta = 1.0e30;
        for( bh = -32768; bh <= 32767; bh++ )
        {
            const int nValley = L2P_PX(m_span_px[0], hs, bh);
            if(nValley < -32768) continue;
            const int nPeak = L2P_PX(m_span_px[1], hs, bh);
            if(nPeak > 32767) continue;

			// now see how closely the baseheight gets
			// to the pixel span.
            const double d = P2L_PX(nValley, hs, bh);
            const double delta = std::abs(d - m_span_px[0]);
			if(delta < prevdelta) // Converging?
				prevdelta = delta;
			else
			{
				// We're diverging, so use the previous bh
				// and stop looking.
				bh--;
				break;
			}
        }
        if(bh != 32768) break;
    }
    if(hs == 32768)
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Couldn't write to Terragen file %s.\n"
                  "Cannot find adequate heightscale/baseheight combination.",
                  m_pszFilename );
        VSIFCloseL( m_fp );

        return false;
    }

    m_nHeightScale = static_cast<GInt16>( hs );
    m_nBaseHeight = static_cast<GInt16>( bh );


	// m_nHeightScale is the one that gives us the
	// widest use of the 16-bit space. However, there
	// might be larger heightscales that, even though
	// the reduce the space usage, give us a better fit
	// for preserving the span extents.


    return put(m_nHeightScale) && put(m_nBaseHeight);
}
Beispiel #14
0
/**
 * Retrieves and stores the GCPs from a COSMO-SKYMED dataset
 * It only retrieves the GCPs for L0, L1A and L1B products
 * for L1C and L1D products, geotransform is provided.
 * The GCPs provided will be the Image's corners.
 * @param iProductType type of CSK product @see HDF5CSKProductEnum
 */
void HDF5ImageDataset::CaptureCSKGCPs(int iProductType)
{
    //Only retrieve GCPs for L0,L1A and L1B products
    if(iProductType == PROD_CSK_L0||iProductType == PROD_CSK_L1A||
       iProductType == PROD_CSK_L1B)
    {
        int i;
        double *pdCornerCoordinates;

        nGCPCount=4;
        pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),4);
        CPLString osCornerName[4];
        double pdCornerPixel[4];
        double pdCornerLine[4];

        const char *pszSubdatasetName = GetSubdatasetName();

        //Load the subdataset name first
        for(i=0;i <4;i++)
            osCornerName[i] = pszSubdatasetName;

        //Load the attribute name, and raster coordinates for
        //all the corners
        osCornerName[0] += "/Top Left Geodetic Coordinates";
        pdCornerPixel[0] = 0;
        pdCornerLine[0] = 0;

        osCornerName[1] += "/Top Right Geodetic Coordinates";
        pdCornerPixel[1] = GetRasterXSize();
        pdCornerLine[1] = 0;

        osCornerName[2] += "/Bottom Left Geodetic Coordinates";
        pdCornerPixel[2] = 0;
        pdCornerLine[2] = GetRasterYSize();

        osCornerName[3] += "/Bottom Right Geodetic Coordinates";
        pdCornerPixel[3] = GetRasterXSize();
        pdCornerLine[3] = GetRasterYSize();

        //For all the image's corners
        for(i=0;i<4;i++)
        {
            GDALInitGCPs( 1, pasGCPList + i );

            CPLFree( pasGCPList[i].pszId );
            pasGCPList[i].pszId = NULL;

            //Retrieve the attributes
            if(HDF5ReadDoubleAttr(osCornerName[i].c_str(), 
                                  &pdCornerCoordinates) == CE_Failure)
            {
                CPLError( CE_Failure, CPLE_OpenFailed,
                             "Error retrieving CSK GCPs\n" );
                // Free on failure, e.g. in case of QLK subdataset.
                for( int i = 0; i < 4; i++ )
                {
                    if( pasGCPList[i].pszId )
                        CPLFree( pasGCPList[i].pszId );
                    if( pasGCPList[i].pszInfo )
                        CPLFree( pasGCPList[i].pszInfo );
	            }
                CPLFree( pasGCPList );
                pasGCPList = NULL;
                nGCPCount = 0;
                break;
            }

            //Fill the GCPs name
            pasGCPList[i].pszId = CPLStrdup( osCornerName[i].c_str() );

            //Fill the coordinates
            pasGCPList[i].dfGCPX = pdCornerCoordinates[1];
            pasGCPList[i].dfGCPY = pdCornerCoordinates[0];
            pasGCPList[i].dfGCPZ = pdCornerCoordinates[2];
            pasGCPList[i].dfGCPPixel = pdCornerPixel[i];
            pasGCPList[i].dfGCPLine = pdCornerLine[i];

            //Free the returned coordinates
            CPLFree(pdCornerCoordinates);
        }
    }
}
bool OsmAnd::HeightmapTileProvider_P::obtainData(
    const TileId tileId,
    const ZoomLevel zoom,
    std::shared_ptr<MapTiledData>& outTiledData,
    const IQueryController* const queryController)
{
    // Obtain raw data from DB
    QByteArray data;
    bool ok = _tileDb.obtainTileData(tileId, zoom, data);
    if (!ok || data.length() == 0)
    {
        // There was no data at all, to avoid further requests, mark this tile as empty
        outTiledData.reset();
        return true;
    }

    // We have the data, use GDAL to decode this GeoTIFF
    const auto tileSize = getTileSize();
    bool success = false;
    QString vmemFilename;
    vmemFilename.sprintf("/vsimem/heightmapTile@%p", data.data());
    VSIFileFromMemBuffer(qPrintable(vmemFilename), reinterpret_cast<GByte*>(data.data()), data.length(), FALSE);
    auto dataset = reinterpret_cast<GDALDataset*>(GDALOpen(qPrintable(vmemFilename), GA_ReadOnly));
    if (dataset != nullptr)
    {
        bool bad = false;
        bad = bad || dataset->GetRasterCount() != 1;
        bad = bad || dataset->GetRasterXSize() != tileSize;
        bad = bad || dataset->GetRasterYSize() != tileSize;
        if (bad)
        {
            if (dataset->GetRasterCount() != 1)
                LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %d bands instead of 1", tileId.x, tileId.y, zoom, dataset->GetRasterCount());
            if (dataset->GetRasterXSize() != tileSize || dataset->GetRasterYSize() != tileSize)
            {
                LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %dx%x size instead of %d", tileId.x, tileId.y, zoom,
                    dataset->GetRasterXSize(), dataset->GetRasterYSize(), tileSize);
            }
        }
        else
        {
            auto band = dataset->GetRasterBand(1);

            bad = bad || band->GetColorTable() != nullptr;
            bad = bad || band->GetRasterDataType() != GDT_Int16;

            if (bad)
            {
                if (band->GetColorTable() != nullptr)
                    LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has color table", tileId.x, tileId.y, zoom);
                if (band->GetRasterDataType() != GDT_Int16)
                    LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %s data type in band 1", tileId.x, tileId.y, zoom, GDALGetDataTypeName(band->GetRasterDataType()));
            }
            else
            {
                auto buffer = new float[tileSize*tileSize];

                auto res = dataset->RasterIO(GF_Read, 0, 0, tileSize, tileSize, buffer, tileSize, tileSize, GDT_Float32, 1, nullptr, 0, 0, 0);
                if (res != CE_None)
                {
                    delete[] buffer;
                    LogPrintf(LogSeverityLevel::Error, "Failed to decode height tile %dx%d@%d: %s", tileId.x, tileId.y, zoom, CPLGetLastErrorMsg());
                }
                else
                {
                    outTiledData.reset(new ElevationDataTile(buffer, sizeof(float)*tileSize, tileSize, tileId, zoom));
                    success = true;
                }
            }
        }

        GDALClose(dataset);
    }
    VSIUnlink(qPrintable(vmemFilename));

    return success;
}
Beispiel #16
0
void EnvisatDataset::ScanForGCPs_MERIS()

{
    int		nDatasetIndex, nNumDSR, nDSRSize, iRecord;

/* -------------------------------------------------------------------- */
/*      Do we have a meaningful geolocation grid?  Seach for a          */
/*      DS_TYPE=A and a name containing "geolocation" or "tie           */
/*      points".                                                        */
/* -------------------------------------------------------------------- */
    nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile,
                                                 "Tie points ADS" );
    if( nDatasetIndex == -1 )
        return;

    if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex,
                                    NULL, NULL, NULL, NULL, NULL,
                                    &nNumDSR, &nDSRSize ) != SUCCESS )
        return;

    if( nNumDSR == 0 )
        return;

/* -------------------------------------------------------------------- */
/*      Figure out the tiepoint space, and how many we have.            */
/* -------------------------------------------------------------------- */
    int  nLinesPerTiePoint, nSamplesPerTiePoint;
    int  nTPPerLine, nTPPerColumn = nNumDSR;

    if( nNumDSR == 0 )
        return;

    nLinesPerTiePoint =
        EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
                                      "LINES_PER_TIE_PT", 0 );
    nSamplesPerTiePoint =
        EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
                                      "SAMPLES_PER_TIE_PT", 0 );

    if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 )
        return;

    nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1)
        / nSamplesPerTiePoint;

    if( (GetRasterYSize() + nLinesPerTiePoint - 1)
        / nLinesPerTiePoint != nTPPerColumn )
    {
        CPLDebug( "EnvisatDataset", "Got %d instead of %d nTPPerColumn.",
                  (GetRasterYSize()+nLinesPerTiePoint-1)/nLinesPerTiePoint,
                  nTPPerColumn );
        return;
    }

    if( 50*nTPPerLine + 13 != nDSRSize )
    {
        CPLDebug( "EnvisatDataset",
                  "DSRSize=%d instead of expected %d for tiepoints ADS.",
                  nDSRSize, 50*nTPPerLine + 13 );
        return;
    }

/* -------------------------------------------------------------------- */
/*      Collect the first GCP set from each record.			*/
/* -------------------------------------------------------------------- */
    GByte	*pabyRecord = (GByte *) CPLMalloc(nDSRSize);
    int  	iGCP;
    GUInt32 	unValue;

    nGCPCount = 0;
    pasGCPList = (GDAL_GCP *)
        CPLCalloc(sizeof(GDAL_GCP),nNumDSR * nTPPerLine);

    for( iRecord = 0; iRecord < nNumDSR; iRecord++ )
    {
        if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex,
                                           iRecord, pabyRecord ) != SUCCESS )
            continue;

        memcpy( &unValue, pabyRecord + 13, 4 );

        for( iGCP = 0; iGCP < nTPPerLine; iGCP++ )
        {
            char	szId[128];

            GDALInitGCPs( 1, pasGCPList + nGCPCount );

            CPLFree( pasGCPList[nGCPCount].pszId );

            sprintf( szId, "%d", nGCPCount+1 );
            pasGCPList[nGCPCount].pszId = CPLStrdup( szId );

            memcpy( &unValue, pabyRecord + 13 + nTPPerLine*4 + iGCP*4, 4 );
            pasGCPList[nGCPCount].dfGCPX =
                ((int)CPL_MSBWORD32(unValue))*0.000001;

            memcpy( &unValue, pabyRecord + 13 + iGCP*4, 4 );
            pasGCPList[nGCPCount].dfGCPY =
                ((int)CPL_MSBWORD32(unValue))*0.000001;

            pasGCPList[nGCPCount].dfGCPZ = 0.0;

            pasGCPList[nGCPCount].dfGCPLine = iRecord*nLinesPerTiePoint + 0.5;
            pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5;

            nGCPCount++;
        }
    }
    CPLFree( pabyRecord );
}
Beispiel #17
0
void BAGDataset::LoadMetadata()

{
    // Load the metadata from the file.
    const hid_t hMDDS = H5Dopen(hHDF5, "/BAG_root/metadata");
    const hid_t datatype = H5Dget_type(hMDDS);
    const hid_t dataspace = H5Dget_space(hMDDS);
    const hid_t native = H5Tget_native_type(datatype, H5T_DIR_ASCEND);
    hsize_t dims[3] = {
        static_cast<hsize_t>(0),
        static_cast<hsize_t>(0),
        static_cast<hsize_t>(0)
    };
    hsize_t maxdims[3] = {
        static_cast<hsize_t>(0),
        static_cast<hsize_t>(0),
        static_cast<hsize_t>(0)
    };

    H5Sget_simple_extent_dims(dataspace, dims, maxdims);

    pszXMLMetadata =
        static_cast<char *>(CPLCalloc(static_cast<int>(dims[0] + 1), 1));

    H5Dread(hMDDS, native, H5S_ALL, dataspace, H5P_DEFAULT, pszXMLMetadata);

    H5Tclose(native);
    H5Sclose(dataspace);
    H5Tclose(datatype);
    H5Dclose(hMDDS);

    if( strlen(pszXMLMetadata) == 0 )
        return;

    // Try to get the geotransform.
    CPLXMLNode *psRoot = CPLParseXMLString(pszXMLMetadata);

    if( psRoot == nullptr )
        return;

    CPLStripXMLNamespace(psRoot, nullptr, TRUE);

    CPLXMLNode *const psGeo = CPLSearchXMLNode(psRoot, "=MD_Georectified");

    if( psGeo != nullptr )
    {
        char **papszCornerTokens = CSLTokenizeStringComplex(
            CPLGetXMLValue(psGeo, "cornerPoints.Point.coordinates", ""), " ,",
            FALSE, FALSE);

        if( CSLCount(papszCornerTokens) == 4 )
        {
            const double dfLLX = CPLAtof(papszCornerTokens[0]);
            const double dfLLY = CPLAtof(papszCornerTokens[1]);
            const double dfURX = CPLAtof(papszCornerTokens[2]);
            const double dfURY = CPLAtof(papszCornerTokens[3]);

            adfGeoTransform[0] = dfLLX;
            adfGeoTransform[1] = (dfURX - dfLLX) / (GetRasterXSize() - 1);
            adfGeoTransform[3] = dfURY;
            adfGeoTransform[5] = (dfLLY - dfURY) / (GetRasterYSize() - 1);

            adfGeoTransform[0] -= adfGeoTransform[1] * 0.5;
            adfGeoTransform[3] -= adfGeoTransform[5] * 0.5;
        }
        CSLDestroy(papszCornerTokens);
    }

    // Try to get the coordinate system.
    OGRSpatialReference oSRS;

    if( OGR_SRS_ImportFromISO19115(&oSRS, pszXMLMetadata) == OGRERR_NONE )
    {
        oSRS.exportToWkt(&pszProjection);
    }
    else
    {
        ParseWKTFromXML(pszXMLMetadata);
    }

    // Fetch acquisition date.
    CPLXMLNode *const psDateTime = CPLSearchXMLNode(psRoot, "=dateTime");
    if( psDateTime != nullptr )
    {
        const char *pszDateTimeValue = CPLGetXMLValue(psDateTime, nullptr, "");
        if( pszDateTimeValue )
            SetMetadataItem("BAG_DATETIME", pszDateTimeValue);
    }

    CPLDestroyXMLNode(psRoot);
}