CPLErr SDERasterBand::GetStatistics( int bApproxOK, int bForce,
                                      double *pdfMin, double *pdfMax, 
                                      double *pdfMean, double *pdfStdDev ) 
{
    // if SDE hasn't already cached our statistics, we'll depend on the 
    // GDALRasterBands's method for getting them.
    bool bHasStats;
    bHasStats = SE_rasbandinfo_has_stats (*poBand);
    if (!bHasStats) 
        return GDALRasterBand::GetStatistics(    bApproxOK,
                                                    bForce,
                                                    pdfMin,
                                                    pdfMax,
                                                    pdfMean,
                                                    pdfStdDev);

    // bForce has no effect currently.  We always go to SDE to get our 
    // stats if SDE has them.
    
    // bApproxOK has no effect currently.  If we're getting stats from 
    // SDE, we're hoping SDE calculates them in the way we want.
    long nSDEErr;
    nSDEErr = SE_rasbandinfo_get_stats_min(*poBand, pdfMin);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_stats_min" );
        return CE_Fatal;
    }  

    nSDEErr = SE_rasbandinfo_get_stats_max(*poBand, pdfMax);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_stats_max" );
        return CE_Fatal;
    } 

    nSDEErr = SE_rasbandinfo_get_stats_mean(*poBand, pdfMean);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_stats_mean" );
        return CE_Fatal;
    }

    nSDEErr = SE_rasbandinfo_get_stats_stddev(*poBand, pdfStdDev);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_stats_stddev" );
        return CE_Fatal;
    } 
    return CE_None;
}
Пример #2
0
const char *SDEDataset::GetProjectionRef()

{
    long nSDEErr;
    SE_COORDREF coordref;
    nSDEErr = SE_coordref_create(&coordref);

    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_coordref_create" );
        return FALSE;
    }

    if (!hRasterColumn){
        CPLError ( CE_Failure, CPLE_AppDefined,
                   "Raster Column not defined");
        return ("");
    }

    nSDEErr = SE_rascolinfo_get_coordref(hRasterColumn, coordref);

    if (nSDEErr == SE_NO_COORDREF) {
        return ("");
    }

    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_coordref" );
    }

    char szWKT[SE_MAX_SPATIALREF_SRTEXT_LEN];
    nSDEErr = SE_coordref_get_description(coordref, szWKT);
    if (nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_coordref_get_description");
    }
    SE_coordref_free(coordref);

    OGRSpatialReference *poSRS;
    CPLDebug ("SDERASTER", "SDE says the coordinate system is: %s'", szWKT);
    poSRS = new OGRSpatialReference(szWKT);
    poSRS->morphFromESRI();

    poSRS->exportToWkt(&pszWKT);
    poSRS->Release();

    return pszWKT;
}
Пример #3
0
GDALDataType SDERasterBand::GetRasterDataType(void)
{
    // Always ask SDE what it thinks our type is.
    LONG nSDEErr;

    nSDEErr = SE_rasbandinfo_get_pixel_type(*poBand, &nSDERasterType);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_pixel_type" );
        return GDT_Byte;
    }

    return MorphESRIRasterType(nSDERasterType);
}
int SDERasterBand::GetOverviewCount( void )
{
    // grab our existing overview count if we have already gotten it,
    // otherwise request it from SDE and set our member data with it.
    long nSDEErr;
    BOOL bSkipLevel;
    
    // return nothing if we were an overview band
    if (nOverview != -1)
        return 0;

    nSDEErr = SE_rasbandinfo_get_max_level(*poBand, 
                                           (long*)&nOverviews, 
                                           &bSkipLevel);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_band_size" );
    }
    
    return nOverviews;
    
} 
CPLErr SDERasterBand::IReadBlock( int nBlockXOff, 
                                  int nBlockYOff,
                                  void * pImage )

{
    // grab our Dataset to limit the casting we have to do.
    SDEDataset *poGDS = (SDEDataset *) poDS;


    // SDE manages the acquisition of raster data in "TileInfo" objects.  
    // The hTile is the only heap-allocated object in this method, and 
    // we should make sure to delete it at the end.  Once we get the 
    // pixel data, we'll memcopy it back on to the pImage pointer.

    SE_RASTILEINFO hTile;
    long nSDEErr;
    nSDEErr = SE_rastileinfo_create(&hTile);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rastileinfo_create" );
        return CE_Fatal;
    }

    hConstraint = InitializeConstraint( (long*) &nBlockXOff, (long*) &nBlockYOff );  
    if (!hConstraint)
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "ConstraintInfo initialization failed");   

    CPLErr error = QueryRaster(hConstraint);
    if (error != CE_None)
        return error;

    long level;
    nSDEErr = SE_rastileinfo_get_level(hTile, &level);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rastileinfo_get_level" );
        return CE_Fatal;
    }   

    nSDEErr = SE_stream_get_raster_tile(poGDS->hStream, hTile);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_stream_get_raster_tile" );
        return CE_Fatal;
    }        

    long row, column;
    nSDEErr = SE_rastileinfo_get_rowcol(hTile, &row, &column);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rastileinfo_get_level" );
        return CE_Fatal;
    }     

    long length;
    unsigned char* pixels;
    nSDEErr = SE_rastileinfo_get_pixel_data(hTile, (void**) &pixels, &length);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rastileinfo_get_pixel_data" );
        return CE_Fatal;
    }           

    int bits_per_pixel = static_cast<int>(dfDepth * 8 + 0.0001);
    int block_size = (nBlockXSize * bits_per_pixel + 7) / 8 * nBlockYSize;
    int bitmap_size = (nBlockXSize * nBlockYSize + 7) / 8;


    if (length == 0) {
        // ArcSDE says the block has no data in it.
        // Write 0's and be done with it
        memset( pImage, 0, 
                nBlockXSize*nBlockYSize*GDALGetDataTypeSize(eDataType)/8);
        return CE_None;
    }
    if ((length == block_size) || (length == (block_size + bitmap_size))) {
    if (bits_per_pixel >= 8) {
        memcpy(pImage, pixels, block_size);
    } else {
        GByte *p = reinterpret_cast<GByte*>(pImage);
        int bit_mask = (2 << bits_per_pixel) - 1;
        int i = 0;
        for (int y = 0; y < nBlockYSize; ++y) {
        for (int x = 0; x < nBlockXSize; ++x) {
            *p++ = (pixels[i >> 3] >> (i & 7)) & bit_mask;
            i += bits_per_pixel;
        }
        i = (i + 7) / 8 * 8;
        }
    }
    } else {
Пример #6
0
CPLErr SDEDataset::ComputeRasterInfo() {
    long nSDEErr;
    SE_RASTERINFO raster;

    nSDEErr = SE_rasterinfo_create(&raster);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasterinfo_create" );
        return CE_Fatal;
    }

    LONG nRasterColumnId = 0;

    nSDEErr = SE_rascolinfo_get_id( hRasterColumn,
                                    &nRasterColumnId);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" );
        return CE_Fatal;
    }

    nSDEErr = SE_raster_get_info_by_id( hConnection,
                                        nRasterColumnId,
                                        1,
                                        raster);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" );
        return CE_Fatal;
    }

    LONG nBandsRet;
    nSDEErr = SE_raster_get_bands(  hConnection,
                                    raster,
                                    &paohSDERasterBands,
                                    &nBandsRet);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_raster_get_bands" );
        return CE_Fatal;
    }

    nBands = nBandsRet;

    SE_RASBANDINFO band;

    // grab our other stuff from the first band and hope for the best
    band = paohSDERasterBands[0];

    LONG nXSRet, nYSRet;
    nSDEErr = SE_rasbandinfo_get_band_size( band, &nXSRet, &nYSRet );
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_band_size" );
        return CE_Fatal;
    }

    nRasterXSize = nXSRet;
    nRasterYSize = nYSRet;

    SE_ENVELOPE extent;
    nSDEErr = SE_rasbandinfo_get_extent(band, &extent);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_extent" );
        return CE_Fatal;
    }
    dfMinX = extent.minx;
    dfMinY = extent.miny;
    dfMaxX = extent.maxx;
    dfMaxY = extent.maxy;

    CPLDebug("SDERASTER", "minx: %.5f, miny: %.5f, maxx: %.5f, maxy: %.5f", dfMinX, dfMinY, dfMaxX, dfMaxY);

    // x0 roughly corresponds to dfMinX
    // y0 roughly corresponds to dfMaxY
    // They can be different than the extent parameters because
    // SDE uses offsets.  The following info is from Duarte Carreira
    // in relation to bug #2063 http://trac.osgeo.org/gdal/ticket/2063 :

    // Depending on how the data was loaded, the pixel width
    // or pixel height may include a pixel offset from the nearest
    // tile boundary. An offset will be indicated by aplus sign
    // "+" followed by a value. The value indicates the number
    // of pixels the nearest tile boundary is to the left of
    // the image for the x dimension or the number of
    // pixels the nearest tile boundary is above the image for
    // the y dimension. The offset information is only useful
    // for advanced application developers who need to know
    // where the image begins in relation to the underlying tile structure

    LFLOAT x0, y0;
    nSDEErr = SE_rasbandinfo_get_tile_origin(band, &x0, &y0);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_tile_origin" );
        return CE_Fatal;
    }
    CPLDebug("SDERASTER", "Tile origin: %.5f, %.5f", x0, y0);

    // we also need to adjust dfMaxX and dfMinY otherwise the cell size will change
    dfMaxX = (x0-dfMinX) + dfMaxX;
    dfMinY = (y0-dfMaxY) + dfMinY;

    // adjust the bbox based on the tile origin.
    dfMinX = MIN(x0, dfMinX);
    dfMaxY = MAX(y0, dfMaxY);

    nSDEErr = SE_rasterattr_create(&hAttributes, false);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasterattr_create" );
        return CE_Fatal;
    }

    // Grab the pointer for our member variable

    nSDEErr = SE_stream_create(hConnection, &hStream);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_stream_create" );
        return CE_Fatal;
    }


    for (int i=0; i < nBands; i++) {
        SetBand( i+1, new SDERasterBand( this, i+1, -1, &(paohSDERasterBands[i]) ));
    }

    GDALRasterBand* b = GetRasterBand(1);

    eDataType = b->GetRasterDataType();

    SE_rasterinfo_free(raster);

    return CE_None;
}
Пример #7
0
GDALDataset *SDEDataset::Open( GDALOpenInfo * poOpenInfo )

{

/* -------------------------------------------------------------------- */
/*      If we aren't prefixed with SDE: then ignore this datasource.    */
/* -------------------------------------------------------------------- */
    if( !STARTS_WITH_CI(poOpenInfo->pszFilename, "SDE:") )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Parse arguments on comma.  We expect (layer is optional):       */
/*        SDE:server,instance,database,username,password,layer          */
/* -------------------------------------------------------------------- */
    char **papszTokens = CSLTokenizeStringComplex(  poOpenInfo->pszFilename+4,
                                                    ",",
                                                    TRUE,
                                                    TRUE );
    CPLDebug(   "SDERASTER", "Open(\"%s\") revealed %d tokens.",
                poOpenInfo->pszFilename,
                CSLCount( papszTokens ) );


    if( CSLCount( papszTokens ) < 5 || CSLCount( papszTokens ) > 7 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "SDE connect string had wrong number of arguments.\n"
                  "Expected 'SDE:server,instance,database,username,password,layer'\n"
                  "The layer name value is optional.\n"
                  "Got '%s'",
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */

    SDEDataset *poDS;

    poDS = new SDEDataset();
/* -------------------------------------------------------------------- */
/*      Try to establish connection.                                    */
/* -------------------------------------------------------------------- */
    int         nSDEErr;
    SE_ERROR    hSDEErrorInfo;
    nSDEErr = SE_connection_create( papszTokens[0],
                                    papszTokens[1],
                                    papszTokens[2],
                                    papszTokens[3],
                                    papszTokens[4],
                                    &(hSDEErrorInfo),
                                    &(poDS->hConnection) );

    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_connection_create" );
        return NULL;
    }


/* -------------------------------------------------------------------- */
/*      Set unprotected concurrency policy, suitable for single         */
/*      threaded access.                                                */
/* -------------------------------------------------------------------- */
    nSDEErr = SE_connection_set_concurrency( poDS->hConnection,
                                             SE_UNPROTECTED_POLICY);

    if( nSDEErr != SE_SUCCESS) {
        IssueSDEError( nSDEErr, NULL );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      If we were given a layer name, use that directly, otherwise     */
/*      query for subdatasets.                                          */
/* -------------------------------------------------------------------- */

    // Get the RASTER column name if it was set
    if (CSLCount (papszTokens) == 7) {
        poDS->pszColumnName = CPLStrdup( papszTokens[6] );
    }
    else {
        poDS->pszColumnName = CPLStrdup( "RASTER" );
    }

    CPLDebug ("SDERASTER", "SDE Column name is '%s'", poDS->pszColumnName);

    if (CSLCount( papszTokens ) >= 6 ) {

        poDS->pszLayerName = CPLStrdup( papszTokens[5] );

        nSDEErr =   SE_rascolinfo_create  (&(poDS->hRasterColumn));
        if( nSDEErr != SE_SUCCESS )
        {
            IssueSDEError( nSDEErr, "SE_rastercolumn_create" );
            return NULL;
        }
        CPLDebug( "SDERASTER", "'%s' raster layer specified... "\
                               "using it directly with '%s' as the raster column name.",
                  poDS->pszLayerName,
                  poDS->pszColumnName);
        nSDEErr = SE_rastercolumn_get_info_by_name( poDS->hConnection,
                                                    poDS->pszLayerName,
                                                    poDS->pszColumnName,
                                                    poDS->hRasterColumn);
        if( nSDEErr != SE_SUCCESS )
        {
            IssueSDEError( nSDEErr, "SE_rastercolumn_get_info_by_name" );
            return NULL;
        }
        poDS->ComputeRasterInfo();



    } else {

        nSDEErr = SE_rastercolumn_get_info_list(poDS->hConnection,
                                                &(poDS->paohSDERasterColumns),
                                                &(poDS->nSubDataCount));
        if( nSDEErr != SE_SUCCESS )
        {
            IssueSDEError( nSDEErr, "SE_rascolinfo_get_info_list" );
            return NULL;
        }

        CPLDebug( "SDERASTER", "No layername specified, %d subdatasets available.",
                  poDS->nSubDataCount);

        for (int i = 0; i < poDS->nSubDataCount; i++) {

              char         szTableName[SE_QUALIFIED_TABLE_NAME+1];
              char         szColumnName[SE_MAX_COLUMN_LEN+1];
            nSDEErr = SE_rascolinfo_get_raster_column (poDS->paohSDERasterColumns[i],
                                                       szTableName,
                                                       szColumnName);
            CPLDebug(   "SDERASTER",
                        "Layer '%s' with column '%s' found.",
                        szTableName,
                        szColumnName);

            if( nSDEErr != SE_SUCCESS )
            {
                IssueSDEError( nSDEErr, "SE_rascolinfo_get_raster_column" );
                return NULL;
            }
        }

    return NULL;
    }
    CSLDestroy( papszTokens);
    return( poDS );
}