Ejemplo n.º 1
0
Colorization::Colorization(const pdal::filters::Colorization& filter, PointBuffer& buffer)
    : pdal::FilterSequentialIterator(filter, buffer)
    , m_stage(filter)
{

    m_forward_transform.assign(0.0);
    m_inverse_transform.assign(0.0);

#ifdef PDAL_HAVE_GDAL
    std::string filename = filter.getOptions().getValueOrThrow<std::string>("raster");

    filter.log()->get(logDEBUG) << "Using " << filename << " for raster" << std::endl;
    m_ds = GDALOpen(filename.c_str(), GA_ReadOnly);
    if (m_ds == NULL)
        throw pdal_error("Unable to open GDAL datasource!");
    
    if (GDALGetGeoTransform(m_ds, &(m_forward_transform.front())) != CE_None)
    {
        throw pdal_error("unable to fetch forward geotransform for raster!");
    }

    GDALInvGeoTransform(&(m_forward_transform.front()), &(m_inverse_transform.front()));

#endif 

    return;
}
Ejemplo n.º 2
0
void ColorizationFilter::ready(PointTableRef table)
{
    m_forward_transform.assign(0.0);
    m_inverse_transform.assign(0.0);

    log()->get(LogLevel::Debug) << "Using " << m_rasterFilename <<
        " for raster" << std::endl;
    m_ds = GDALOpen(m_rasterFilename.c_str(), GA_ReadOnly);
    if (m_ds == NULL)
        throw pdal_error("Unable to open GDAL datasource!");

    if (GDALGetGeoTransform(m_ds, &(m_forward_transform.front())) != CE_None)
        throw pdal_error("unable to fetch forward geotransform for raster!");

    if (!GDALInvGeoTransform(&(m_forward_transform.front()),
        &(m_inverse_transform.front())))
        throw pdal_error("unable to fetch inverse geotransform for raster!");

    for (auto bi = m_bands.begin(); bi != m_bands.end(); ++bi)
    {
        if (bi->m_dim == Dimension::Id::Unknown)
            bi->m_dim = table.layout()->findDim(bi->m_name);
        if (bi->m_dim == Dimension::Id::Unknown)
            throw pdal_error((std::string)"Can't colorize - no dimension " +
                bi->m_name);
    }
}
void *QgsImageWarper::addGeoToPixelTransform( GDALTransformerFunc GDALTransformer, void *GDALTransformerArg, double *padfGeotransform ) const
{
  TransformChain *chain = new TransformChain;
  chain->GDALTransformer = GDALTransformer;
  chain->GDALTransformerArg = GDALTransformerArg;
  memcpy( chain->adfGeotransform, padfGeotransform, sizeof( double )*6 );
  // TODO: In reality we don't require the full homogeneous matrix, so GeoToPixelTransform and matrix inversion could
  // be optimized for simple scale+offset if there's the need (e.g. for numerical or performance reasons).
  if ( !GDALInvGeoTransform( chain->adfGeotransform, chain->adfInvGeotransform ) )
  {
    // Error handling if inversion fails - although the inverse transform is not needed for warp operation
    return NULL;
  }
  return ( void* )chain;
}
Ejemplo n.º 4
0
const char *VRTSourcedRasterBand::GetMetadataItem( const char * pszName,
                                                   const char * pszDomain )

{
/* ==================================================================== */
/*      LocationInfo handling.                                          */
/* ==================================================================== */
    if( pszDomain != NULL 
        && EQUAL(pszDomain,"LocationInfo")
        && (EQUALN(pszName,"Pixel_",6) || EQUALN(pszName,"GeoPixel_",9)) )
    {
        int iPixel, iLine;

/* -------------------------------------------------------------------- */
/*      What pixel are we aiming at?                                    */
/* -------------------------------------------------------------------- */
        if( EQUALN(pszName,"Pixel_",6) )
        {
            if( sscanf( pszName+6, "%d_%d", &iPixel, &iLine ) != 2 )
                return NULL;
        }
        else if( EQUALN(pszName,"GeoPixel_",9) )
        {
            double adfGeoTransform[6];
            double adfInvGeoTransform[6];
            double dfGeoX, dfGeoY;

            if( sscanf( pszName+9, "%lf_%lf", &dfGeoX, &dfGeoY ) != 2 )
                return NULL;

            if( GetDataset() == NULL )
                return NULL;
            
            if( GetDataset()->GetGeoTransform( adfGeoTransform ) != CE_None )
                return NULL;
            
            if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) )
                return NULL;
                
            iPixel = (int) floor(
                adfInvGeoTransform[0] 
                + adfInvGeoTransform[1] * dfGeoX
                + adfInvGeoTransform[2] * dfGeoY );
            iLine = (int) floor(
                adfInvGeoTransform[3] 
                + adfInvGeoTransform[4] * dfGeoX
                + adfInvGeoTransform[5] * dfGeoY );
        }
        else
            return NULL;

        if( iPixel < 0 || iLine < 0 
            || iPixel >= GetXSize()
            || iLine >= GetYSize() )
            return NULL;

/* -------------------------------------------------------------------- */
/*      Find the file(s) at this location.                              */
/* -------------------------------------------------------------------- */
        char **papszFileList = NULL;
        int nListMaxSize = 0, nListSize = 0;
        CPLHashSet* hSetFiles = CPLHashSetNew(CPLHashSetHashStr,
                                              CPLHashSetEqualStr,
                                              NULL);
        
        for( int iSource = 0; iSource < nSources; iSource++ )
        {
            int nReqXOff, nReqYOff, nReqXSize, nReqYSize;
            int nOutXOff, nOutYOff, nOutXSize, nOutYSize;

            if (!papoSources[iSource]->IsSimpleSource())
                continue;

            VRTSimpleSource *poSrc = (VRTSimpleSource *) papoSources[iSource];

            if( !poSrc->GetSrcDstWindow( iPixel, iLine, 1, 1, 1, 1,
                                         &nReqXOff, &nReqYOff, 
                                         &nReqXSize, &nReqYSize,
                                         &nOutXOff, &nOutYOff, 
                                         &nOutXSize, &nOutYSize ) )
                continue;

            poSrc->GetFileList( &papszFileList, &nListSize, &nListMaxSize,
                                hSetFiles );
        }
        
/* -------------------------------------------------------------------- */
/*      Format into XML.                                                */
/* -------------------------------------------------------------------- */
        int i;

        osLastLocationInfo = "<LocationInfo>";
        for( i = 0; i < nListSize; i++ )
        {
            osLastLocationInfo += "<File>";
            char* pszXMLEscaped = CPLEscapeString(papszFileList[i], -1, CPLES_XML);
            osLastLocationInfo += pszXMLEscaped;
            CPLFree(pszXMLEscaped);
            osLastLocationInfo += "</File>";
        }
        osLastLocationInfo += "</LocationInfo>";

        CSLDestroy( papszFileList );
        CPLHashSetDestroy( hSetFiles );

        return osLastLocationInfo.c_str();
    }

/* ==================================================================== */
/*      Other domains.                                                  */
/* ==================================================================== */
    else
        return GDALRasterBand::GetMetadataItem( pszName, pszDomain );
}
Ejemplo n.º 5
0
static dErr VHTCaseSetUp_Jako(VHTCase scase)
{
  VHTCase_Jako *jako = scase->data;
  dErr err;
  OGRErr oerr;

  dFunctionBegin;
  jako->utmref = OSRNewSpatialReference(NULL);
  oerr = OSRSetProjCS(jako->utmref,"UTM 22N (WGS84)");dOGRCHK(oerr);
  oerr = OSRSetWellKnownGeogCS(jako->utmref,"WGS84");dOGRCHK(oerr);
  oerr = OSRSetUTM(jako->utmref,22,1);dOGRCHK(oerr);
  oerr = OSRSetLinearUnits(jako->utmref,SRS_UL_METER,1.0);dOGRCHK(oerr);

  jako->llref  = OSRNewSpatialReference(NULL);
  oerr = OSRSetWellKnownGeogCS(jako->llref,"WGS84");dOGRCHK(oerr);

  jako->ianref = OSRNewSpatialReference(NULL);
  oerr = OSRSetProjCS(jako->ianref,"Stereographic Greenland (WGS84)");dOGRCHK(oerr);
  oerr = OSRSetWellKnownGeogCS(jako->ianref,"WGS84");dOGRCHK(oerr);
  oerr = OSRSetStereographic(jako->ianref,70.0,-45.0,100.0,-217.75e3,-2302.0e3);dOGRCHK(oerr);

  // The computational domain is in UTM 22N
  jako->myref = OSRNewSpatialReference(NULL);
  oerr = OSRSetProjCS(jako->myref,"Computational Domain: UTM 22N (WGS84)");dOGRCHK(oerr);
  oerr = OSRSetWellKnownGeogCS(jako->myref,"WGS84");dOGRCHK(oerr);
  oerr = OSRSetUTM(jako->myref,22,1);dOGRCHK(oerr);
  oerr = OSRSetLinearUnits(jako->myref,SRS_UL_METER,1.0);dOGRCHK(oerr);

  jako->fromutm = OCTNewCoordinateTransformation(jako->utmref,jako->myref);
  jako->fromll  = OCTNewCoordinateTransformation(jako->llref,jako->myref);
  jako->fromian = OCTNewCoordinateTransformation(jako->ianref,jako->myref);

  if (jako->verbose) {err = VHTCaseView_Jako(scase,PETSC_VIEWER_STDOUT_WORLD);dCHK(err);}

  if (1) {
    GDALProgressFunc gdalprogress = jako->verbose ? GDALTermProgress : GDALDummyProgress;
    double x0,y0,Lx,Ly,dx,dy;
    GDALDatasetH filedata;
    GDALErr gerr;
    GDALRasterBandH band;
    CPLErr cplerr;

    x0 = scase->bbox[0][0];
    y0 = scase->bbox[1][0];
    Lx = scase->bbox[0][1] - x0;
    Ly = scase->bbox[1][1] - y0;
    // It appears from gdalwarp.cpp that pixels are cell centered
    dx = Lx / jako->nx;
    dy = Ly / jako->ny;

    // Extend the domain in the positive direction for slope evaluation
    jako->nx += 2;
    jako->ny += 2;
    Lx += 2*dx;
    Ly += 2*dy;

    // Convert a pixel to a physical coordinate in the current projection
    jako->mygeo[0] = x0 + dx/2;
    jako->mygeo[1] = dx;
    jako->mygeo[2] = 0;
    jako->mygeo[3] = y0 + Ly - dy/2; // Physical coordinates are "y up", pixels are "y down"
    jako->mygeo[4] = 0;
    jako->mygeo[5] = -dy;

    // Convert a physical coordinate in the current projection to a pixel coordinate
    gerr = GDALInvGeoTransform(jako->mygeo,jako->myinvgeo);dGDALCHK(gerr);
    if (jako->verbose) {
      dInt i,j;
      double a,b;
      err = dRealTableView(3,2,&scase->bbox[0][0],PETSC_VIEWER_STDOUT_WORLD,"bbox");dCHK(err);
      err = dRealTableView(2,3,jako->mygeo,PETSC_VIEWER_STDOUT_WORLD,"mygeo");dCHK(err);
      GDALApplyGeoTransform(jako->mygeo,0,0,&a,&b); printf("geo[0,0] = %f,%f\n",a,b);
      GDALApplyGeoTransform(jako->mygeo,1,1,&a,&b); printf("geo[1,1] = %f,%f\n",a,b);
      GDALApplyGeoTransform(jako->mygeo,0.5,0.5,&a,&b); printf("geo[0.5,0.5] = %f,%f\n",a,b);
      err = JakoFindPixel(scase,(dReal[]){scase->bbox[0][0],scase->bbox[1][0]},&i,&j);dCHK(err);
      printf("xmin,ymin: (%d,%d)\n",i,j);
      err = JakoFindPixel(scase,(dReal[]){scase->bbox[0][1],scase->bbox[1][1]},&i,&j);dCHK(err);
      printf("xmax,ymax: (%d,%d)\n",i,j);
    }
Ejemplo n.º 6
0
/*
 * Init()
 */
bool OGRNGWDataset::Init(int nOpenFlagsIn)
{
    // NOTE: Skip check API version at that moment. We expected API v3.

    // Get resource details.
    CPLJSONDocument oResourceDetailsReq;
    char **papszHTTPOptions = GetHeaders();
    bool bResult = oResourceDetailsReq.LoadUrl( NGWAPI::GetResource( osUrl,
        osResourceId ), papszHTTPOptions );

    CPLDebug("NGW", "Get resource %s details %s", osResourceId.c_str(),
        bResult ? "success" : "failed");

    if( bResult )
    {
        CPLJSONObject oRoot = oResourceDetailsReq.GetRoot();

        if( oRoot.IsValid() )
        {
            std::string osResourceType = oRoot.GetString("resource/cls");
            FillMetadata( oRoot );

            if( osResourceType == "resource_group" )
            {
                // Check feature paging.
                FillCapabilities( papszHTTPOptions );
                if( oRoot.GetBool( "resource/children", false ) ) {
                    // Get child resources.
                    bResult = FillResources( papszHTTPOptions, nOpenFlagsIn );
                }
            }
            else if( (osResourceType == "vector_layer" ||
                osResourceType == "postgis_layer") )
            {
                // Cehck feature paging.
                FillCapabilities( papszHTTPOptions );
                // Add vector layer.
                AddLayer( oRoot, papszHTTPOptions, nOpenFlagsIn );
            }
            else if( osResourceType == "mapserver_style" ||
                osResourceType == "qgis_vector_style" ||
                osResourceType == "raster_style" ||
                osResourceType == "wmsclient_layer" )
            {
                // GetExtent from parent.
                OGREnvelope stExtent;
                std::string osParentId = oRoot.GetString("resource/parent/id");
                bool bExtentResult = NGWAPI::GetExtent(osUrl, osParentId,
                    papszHTTPOptions, 3857, stExtent);

                if( !bExtentResult )
                {
                    // Set full extent for EPSG:3857.
                    stExtent.MinX = -20037508.34;
                    stExtent.MaxX = 20037508.34;
                    stExtent.MinY = -20037508.34;
                    stExtent.MaxY = 20037508.34;
                }

                CPLDebug("NGW", "Raster extent is: %f, %f, %f, %f",
                    stExtent.MinX, stExtent.MinY,
                    stExtent.MaxX, stExtent.MaxY);

                int nEPSG = 3857;
                // Get parent details. We can skip this as default SRS in NGW is 3857.
                if( osResourceType == "wmsclient_layer" )
                {
                    nEPSG = oRoot.GetInteger("wmsclient_layer/srs/id", nEPSG);
                }
                else
                {
                    CPLJSONDocument oResourceReq;
                    bResult = oResourceReq.LoadUrl( NGWAPI::GetResource( osUrl,
                        osResourceId ), papszHTTPOptions );

                    if( bResult )
                    {
                        CPLJSONObject oParentRoot = oResourceReq.GetRoot();
                        if( osResourceType == "mapserver_style" ||
                            osResourceType == "qgis_vector_style" )
                        {
                            nEPSG = oParentRoot.GetInteger("vector_layer/srs/id", nEPSG);
                        }
                        else if( osResourceType == "raster_style")
                        {
                            nEPSG = oParentRoot.GetInteger("raster_layer/srs/id", nEPSG);
                        }
                    }
                }

                // Create raster dataset.
                std::string osRasterUrl = NGWAPI::GetTMS(osUrl, osResourceId);
                char* pszRasterUrl = CPLEscapeString(osRasterUrl.c_str(), -1, CPLES_XML);
                const char *pszConnStr = CPLSPrintf("<GDAL_WMS><Service name=\"TMS\">"
            "<ServerUrl>%s</ServerUrl></Service><DataWindow>"
            "<UpperLeftX>-20037508.34</UpperLeftX><UpperLeftY>20037508.34</UpperLeftY>"
            "<LowerRightX>20037508.34</LowerRightX><LowerRightY>-20037508.34</LowerRightY>"
            "<TileLevel>%d</TileLevel><TileCountX>1</TileCountX>"
            "<TileCountY>1</TileCountY><YOrigin>top</YOrigin></DataWindow>"
            "<Projection>EPSG:%d</Projection><BlockSizeX>256</BlockSizeX>"
            "<BlockSizeY>256</BlockSizeY><BandsCount>%d</BandsCount>"
            "<Cache><Type>file</Type><Expires>%d</Expires><MaxSize>%d</MaxSize>"
            "</Cache><ZeroBlockHttpCodes>204,404</ZeroBlockHttpCodes></GDAL_WMS>",
                pszRasterUrl,
                22,      // NOTE: We have no limit in zoom levels.
                nEPSG,   // NOTE: Default SRS is EPSG:3857.
                4,
                nCacheExpires,
                nCacheMaxSize);

                CPLFree( pszRasterUrl );

                poRasterDS = reinterpret_cast<GDALDataset*>(GDALOpenEx(pszConnStr,
                    GDAL_OF_READONLY | GDAL_OF_RASTER | GDAL_OF_INTERNAL, nullptr,
                    nullptr, nullptr));

                if( poRasterDS )
                {
                    bResult = true;
                    nRasterXSize = poRasterDS->GetRasterXSize();
                    nRasterYSize = poRasterDS->GetRasterYSize();

                    for( int iBand = 1; iBand <= poRasterDS->GetRasterCount();
                            iBand++ )
                    {
                        SetBand( iBand, new NGWWrapperRasterBand(
                            poRasterDS->GetRasterBand( iBand )) );
                    }

                    // Set pixel limits.
                    bool bHasTransform = false;
                    double geoTransform[6] = { 0.0 };
                    double invGeoTransform[6] = { 0.0 };
                    if(poRasterDS->GetGeoTransform(geoTransform) == CE_None)
                    {
                        bHasTransform = GDALInvGeoTransform(geoTransform,
                            invGeoTransform) == TRUE;
                    }

                    if(bHasTransform)
                    {
                        GDALApplyGeoTransform(invGeoTransform, stExtent.MinX,
                            stExtent.MinY, &stPixelExtent.MinX, &stPixelExtent.MaxY);

                        GDALApplyGeoTransform(invGeoTransform, stExtent.MaxX,
                            stExtent.MaxY, &stPixelExtent.MaxX, &stPixelExtent.MinY);

                        CPLDebug("NGW", "Raster extent in px is: %f, %f, %f, %f",
                            stPixelExtent.MinX, stPixelExtent.MinY,
                            stPixelExtent.MaxX, stPixelExtent.MaxY);
                    }
                    else
                    {
                        stPixelExtent.MinX = 0.0;
                        stPixelExtent.MinY = 0.0;
                        stPixelExtent.MaxX = std::numeric_limits<double>::max();
                        stPixelExtent.MaxY = std::numeric_limits<double>::max();
                    }
                }
                else
                {
                    bResult = false;
                }
            }
            else if( osResourceType == "raster_layer" ) //FIXME: Do we need this check? && nOpenFlagsIn & GDAL_OF_RASTER )
            {
                AddRaster( oRoot, papszHTTPOptions );
            }
            else
            {
                bResult = false;
            }
            // TODO: Add support for baselayers, webmap, wfsserver_service, wmsserver_service.
        }
    }

    CSLDestroy( papszHTTPOptions );
    return bResult;
}
Ejemplo n.º 7
0
int main( int argc, char ** argv )

{
    const char         *pszLocX = NULL, *pszLocY = NULL;
    const char         *pszSrcFilename = NULL;
    char               *pszSourceSRS = NULL;
    std::vector<int>   anBandList;
    bool               bAsXML = false, bLIFOnly = false;
    bool               bQuiet = false, bValOnly = false;
    int                nOverview = -1;
    char             **papszOpenOptions = NULL;

    GDALAllRegister();
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    int i;

    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i],"-b") && i < argc-1 )
        {
            anBandList.push_back( atoi(argv[++i]) );
        }
        else if( EQUAL(argv[i],"-overview") && i < argc-1 )
        {
            nOverview = atoi(argv[++i]) - 1;
        }
        else if( EQUAL(argv[i],"-l_srs") && i < argc-1 )
        {
            CPLFree(pszSourceSRS);
            pszSourceSRS = SanitizeSRS(argv[++i]);
        }
        else if( EQUAL(argv[i],"-geoloc") )
        {
            CPLFree(pszSourceSRS);
            pszSourceSRS = CPLStrdup("-geoloc");
        }
        else if( EQUAL(argv[i],"-wgs84") )
        {
            CPLFree(pszSourceSRS);
            pszSourceSRS = SanitizeSRS("WGS84");
        }
        else if( EQUAL(argv[i],"-xml") )
        {
            bAsXML = true;
        }
        else if( EQUAL(argv[i],"-lifonly") )
        {
            bLIFOnly = true;
            bQuiet = true;
        }
        else if( EQUAL(argv[i],"-valonly") )
        {
            bValOnly = true;
            bQuiet = true;
        }
        else if( EQUAL(argv[i], "-oo") && i < argc-1 )
        {
            papszOpenOptions = CSLAddString( papszOpenOptions,
                                                argv[++i] );
        }
        else if( argv[i][0] == '-' && !isdigit(argv[i][1]) )
            Usage();

        else if( pszSrcFilename == NULL )
            pszSrcFilename = argv[i];

        else if( pszLocX == NULL )
            pszLocX = argv[i];

        else if( pszLocY == NULL )
            pszLocY = argv[i];

        else
            Usage();
    }

    if( pszSrcFilename == NULL || (pszLocX != NULL && pszLocY == NULL) )
        Usage();

/* -------------------------------------------------------------------- */
/*      Open source file.                                               */
/* -------------------------------------------------------------------- */
    GDALDatasetH hSrcDS = NULL;

    hSrcDS = GDALOpenEx( pszSrcFilename, GDAL_OF_RASTER, NULL,
                           (const char* const* )papszOpenOptions, NULL );
    if( hSrcDS == NULL )
        exit( 1 );

/* -------------------------------------------------------------------- */
/*      Setup coordinate transformation, if required                    */
/* -------------------------------------------------------------------- */
    OGRSpatialReferenceH hSrcSRS = NULL, hTrgSRS = NULL;
    OGRCoordinateTransformationH hCT = NULL;
    if( pszSourceSRS != NULL && !EQUAL(pszSourceSRS,"-geoloc") )
    {

        hSrcSRS = OSRNewSpatialReference( pszSourceSRS );
        hTrgSRS = OSRNewSpatialReference( GDALGetProjectionRef( hSrcDS ) );

        hCT = OCTNewCoordinateTransformation( hSrcSRS, hTrgSRS );
        if( hCT == NULL )
            exit( 1 );
    }

/* -------------------------------------------------------------------- */
/*      If no bands were requested, we will query them all.             */
/* -------------------------------------------------------------------- */
    if( anBandList.size() == 0 )
    {
        for( i = 0; i < GDALGetRasterCount( hSrcDS ); i++ )
            anBandList.push_back( i+1 );
    }
    
/* -------------------------------------------------------------------- */
/*      Turn the location into a pixel and line location.               */
/* -------------------------------------------------------------------- */
    int inputAvailable = 1;
    double dfGeoX;
    double dfGeoY;
    CPLString osXML;

    if( pszLocX == NULL && pszLocY == NULL )
    {
        if (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2)
        {
            inputAvailable = 0;
        }
    }
    else
    {
        dfGeoX = CPLAtof(pszLocX);
        dfGeoY = CPLAtof(pszLocY);
    }

    while (inputAvailable)
    {
        int iPixel, iLine;

        if (hCT)
        {
            if( !OCTTransform( hCT, 1, &dfGeoX, &dfGeoY, NULL ) )
                exit( 1 );
        }
    
        if( pszSourceSRS != NULL )
        {
            double adfGeoTransform[6], adfInvGeoTransform[6];
    
            if( GDALGetGeoTransform( hSrcDS, adfGeoTransform ) != CE_None )
            {
                CPLError(CE_Failure, CPLE_AppDefined, "Cannot get geotransform");
                exit( 1 );
            }
    
            if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) )
            {
                CPLError(CE_Failure, CPLE_AppDefined, "Cannot invert geotransform");
                exit( 1 );
            }
    
            iPixel = (int) floor(
                adfInvGeoTransform[0] 
                + adfInvGeoTransform[1] * dfGeoX
                + adfInvGeoTransform[2] * dfGeoY );
            iLine = (int) floor(
                adfInvGeoTransform[3] 
                + adfInvGeoTransform[4] * dfGeoX
                + adfInvGeoTransform[5] * dfGeoY );
        }
        else
        {
            iPixel = (int) floor(dfGeoX);
            iLine  = (int) floor(dfGeoY);
        }

    /* -------------------------------------------------------------------- */
    /*      Prepare report.                                                 */
    /* -------------------------------------------------------------------- */
        CPLString osLine;
    
        if( bAsXML )
        {
            osLine.Printf( "<Report pixel=\"%d\" line=\"%d\">", 
                          iPixel, iLine );
            osXML += osLine;
        }
        else if( !bQuiet )
        {
            printf( "Report:\n" );
            printf( "  Location: (%dP,%dL)\n", iPixel, iLine );
        }

        int bPixelReport = TRUE;

        if( iPixel < 0 || iLine < 0 
            || iPixel >= GDALGetRasterXSize( hSrcDS )
            || iLine  >= GDALGetRasterYSize( hSrcDS ) )
        {
            if( bAsXML )
                osXML += "<Alert>Location is off this file! No further details to report.</Alert>";
            else if( bValOnly )
                printf("\n");
            else if( !bQuiet )
                printf( "\nLocation is off this file! No further details to report.\n");
            bPixelReport = FALSE;
        }

    /* -------------------------------------------------------------------- */
    /*      Process each band.                                              */
    /* -------------------------------------------------------------------- */
        for( i = 0; bPixelReport && i < (int) anBandList.size(); i++ )
        {
            GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, anBandList[i] );

            int iPixelToQuery = iPixel;
            int iLineToQuery = iLine;

            if (nOverview >= 0 && hBand != NULL)
            {
                GDALRasterBandH hOvrBand = GDALGetOverview(hBand, nOverview);
                if (hOvrBand != NULL)
                {
                    int nOvrXSize = GDALGetRasterBandXSize(hOvrBand);
                    int nOvrYSize = GDALGetRasterBandYSize(hOvrBand);
                    iPixelToQuery = (int)(0.5 + 1.0 * iPixel / GDALGetRasterXSize( hSrcDS ) * nOvrXSize);
                    iLineToQuery = (int)(0.5 + 1.0 * iLine / GDALGetRasterYSize( hSrcDS ) * nOvrYSize);
                    if (iPixelToQuery >= nOvrXSize)
                        iPixelToQuery = nOvrXSize - 1;
                    if (iLineToQuery >= nOvrYSize)
                        iLineToQuery = nOvrYSize - 1;
                }
                else
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Cannot get overview %d of band %d",
                             nOverview + 1, anBandList[i] );
                }
                hBand = hOvrBand;
            }

            if (hBand == NULL)
                continue;

            if( bAsXML )
            {
                osLine.Printf( "<BandReport band=\"%d\">", anBandList[i] );
                osXML += osLine;
            }
            else if( !bQuiet )
            {
                printf( "  Band %d:\n", anBandList[i] );
            }
    
    /* -------------------------------------------------------------------- */
    /*      Request location info for this location.  It is possible        */
    /*      only the VRT driver actually supports this.                     */
    /* -------------------------------------------------------------------- */
            CPLString osItem;
            
            osItem.Printf( "Pixel_%d_%d", iPixelToQuery, iLineToQuery );
            
            const char *pszLI = GDALGetMetadataItem( hBand, osItem, "LocationInfo");
    
            if( pszLI != NULL )
            {
                if( bAsXML )
                    osXML += pszLI;
                else if( !bQuiet )
                    printf( "    %s\n", pszLI );
                else if( bLIFOnly )
                {
                    /* Extract all files, if any. */
                 
                    CPLXMLNode *psRoot = CPLParseXMLString( pszLI );
                    
                    if( psRoot != NULL 
                        && psRoot->psChild != NULL
                        && psRoot->eType == CXT_Element
                        && EQUAL(psRoot->pszValue,"LocationInfo") )
                    {
                        CPLXMLNode *psNode;
    
                        for( psNode = psRoot->psChild;
                             psNode != NULL;
                             psNode = psNode->psNext )
                        {
                            if( psNode->eType == CXT_Element
                                && EQUAL(psNode->pszValue,"File") 
                                && psNode->psChild != NULL )
                            {
                                char* pszUnescaped = CPLUnescapeString(
                                    psNode->psChild->pszValue, NULL, CPLES_XML);
                                printf( "%s\n", pszUnescaped );
                                CPLFree(pszUnescaped);
                            }
                        }
                    }
                    CPLDestroyXMLNode( psRoot );
                }
            }
    
    /* -------------------------------------------------------------------- */
    /*      Report the pixel value of this band.                            */
    /* -------------------------------------------------------------------- */
            double adfPixel[2];
    
            if( GDALRasterIO( hBand, GF_Read, iPixelToQuery, iLineToQuery, 1, 1, 
                              adfPixel, 1, 1, GDT_CFloat64, 0, 0) == CE_None )
            {
                CPLString osValue;
    
                if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) )
                    osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] );
                else
                    osValue.Printf( "%.15g", adfPixel[0] );
    
                if( bAsXML )
                {
                    osXML += "<Value>";
                    osXML += osValue;
                    osXML += "</Value>";
                }
                else if( !bQuiet )
                    printf( "    Value: %s\n", osValue.c_str() );
                else if( bValOnly )
                    printf( "%s\n", osValue.c_str() );
    
                // Report unscaled if we have scale/offset values.
                int bSuccess;
                
                double dfOffset = GDALGetRasterOffset( hBand, &bSuccess );
                double dfScale  = GDALGetRasterScale( hBand, &bSuccess );
    
                if( dfOffset != 0.0 || dfScale != 1.0 )
                {
                    adfPixel[0] = adfPixel[0] * dfScale + dfOffset;
                    adfPixel[1] = adfPixel[1] * dfScale + dfOffset;
    
                    if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) )
                        osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] );
                    else
                        osValue.Printf( "%.15g", adfPixel[0] );
    
                    if( bAsXML )
                    {
                        osXML += "<DescaledValue>";
                        osXML += osValue;
                        osXML += "</DescaledValue>";
                    }
                    else if( !bQuiet )
                        printf( "    Descaled Value: %s\n", osValue.c_str() );
                }
            }
    
            if( bAsXML )
                osXML += "</BandReport>";
        }

        osXML += "</Report>";
    
        if( (pszLocX != NULL && pszLocY != NULL)  ||
            (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) )
        {
            inputAvailable = 0;
        }
            
    }

/* -------------------------------------------------------------------- */
/*      Finalize xml report and print.                                  */
/* -------------------------------------------------------------------- */
    if( bAsXML )
    {
        CPLXMLNode *psRoot;
        char *pszFormattedXML;


        psRoot = CPLParseXMLString( osXML );
        pszFormattedXML = CPLSerializeXMLTree( psRoot );
        CPLDestroyXMLNode( psRoot );

        printf( "%s", pszFormattedXML );
        CPLFree( pszFormattedXML );
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    if (hCT) {
        OSRDestroySpatialReference( hSrcSRS );
        OSRDestroySpatialReference( hTrgSRS );
        OCTDestroyCoordinateTransformation( hCT );
    }

    if (hSrcDS)
        GDALClose(hSrcDS);

    GDALDumpOpenDatasets( stderr );
    GDALDestroyDriverManager();
    CPLFree(pszSourceSRS);
    CSLDestroy(papszOpenOptions);

    CSLDestroy( argv );

    return 0;
}
Ejemplo n.º 8
0
const char *GDALWMSRasterBand::GetMetadataItem( const char * pszName,
                                                const char * pszDomain )
{
/* ==================================================================== */
/*      LocationInfo handling.                                          */
/* ==================================================================== */
    if( pszDomain != NULL
        && EQUAL(pszDomain,"LocationInfo")
        && (STARTS_WITH_CI(pszName, "Pixel_") || STARTS_WITH_CI(pszName, "GeoPixel_")) )
    {
        int iPixel, iLine;

/* -------------------------------------------------------------------- */
/*      What pixel are we aiming at?                                    */
/* -------------------------------------------------------------------- */
        if( STARTS_WITH_CI(pszName, "Pixel_") )
        {
            if( sscanf( pszName+6, "%d_%d", &iPixel, &iLine ) != 2 )
                return NULL;
        }
        else if( STARTS_WITH_CI(pszName, "GeoPixel_") )
        {
            double adfGeoTransform[6];
            double adfInvGeoTransform[6];
            double dfGeoX, dfGeoY;

            {
                dfGeoX = CPLAtof(pszName + 9);
                const char* pszUnderscore = strchr(pszName + 9, '_');
                if( !pszUnderscore )
                    return NULL;
                dfGeoY = CPLAtof(pszUnderscore+1);
            }

            if( m_parent_dataset->GetGeoTransform( adfGeoTransform ) != CE_None )
                return NULL;

            if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) )
                return NULL;

            iPixel = (int) floor(
                adfInvGeoTransform[0]
                + adfInvGeoTransform[1] * dfGeoX
                + adfInvGeoTransform[2] * dfGeoY );
            iLine = (int) floor(
                adfInvGeoTransform[3]
                + adfInvGeoTransform[4] * dfGeoX
                + adfInvGeoTransform[5] * dfGeoY );

            /* The GetDataset() for the WMS driver is always the main overview level, so rescale */
            /* the values if we are an overview */
            if (m_overview >= 0)
            {
                iPixel = (int) (1.0 * iPixel * GetXSize() / m_parent_dataset->GetRasterBand(1)->GetXSize());
                iLine = (int) (1.0 * iLine * GetYSize() / m_parent_dataset->GetRasterBand(1)->GetYSize());
            }
        }
        else
            return NULL;

        if( iPixel < 0 || iLine < 0
            || iPixel >= GetXSize()
            || iLine >= GetYSize() )
            return NULL;

        if (nBand != 1)
        {
            GDALRasterBand* poFirstBand = m_parent_dataset->GetRasterBand(1);
            if (m_overview >= 0)
                poFirstBand = poFirstBand->GetOverview(m_overview);
            if (poFirstBand)
                return poFirstBand->GetMetadataItem(pszName, pszDomain);
        }

        GDALWMSImageRequestInfo iri;
        GDALWMSTiledImageRequestInfo tiri;
        int nBlockXOff = iPixel / nBlockXSize;
        int nBlockYOff = iLine / nBlockYSize;

        ComputeRequestInfo(iri, tiri, nBlockXOff, nBlockYOff);

        CPLString url;
        m_parent_dataset->m_mini_driver->GetTiledImageInfo(&url,
                                                           iri, tiri,
                                                           iPixel % nBlockXSize,
                                                           iLine % nBlockXSize);


        char* pszRes = NULL;

        if (url.size() != 0)
        {
            if (url == osMetadataItemURL)
            {
                return osMetadataItem.size() != 0 ? osMetadataItem.c_str() : NULL;
            }
            osMetadataItemURL = url;

            char **http_request_opts = BuildHTTPRequestOpts();
            CPLHTTPResult* psResult = CPLHTTPFetch( url.c_str(), http_request_opts);
            if( psResult && psResult->pabyData )
                pszRes = CPLStrdup((const char*) psResult->pabyData);
            CPLHTTPDestroyResult(psResult);
            CSLDestroy(http_request_opts);
        }

        if (pszRes)
        {
            osMetadataItem = "<LocationInfo>";
            CPLPushErrorHandler(CPLQuietErrorHandler);
            CPLXMLNode* psXML = CPLParseXMLString(pszRes);
            CPLPopErrorHandler();
            if (psXML != NULL && psXML->eType == CXT_Element)
            {
                if (strcmp(psXML->pszValue, "?xml") == 0)
                {
                    if (psXML->psNext)
                    {
                        char* pszXML = CPLSerializeXMLTree(psXML->psNext);
                        osMetadataItem += pszXML;
                        CPLFree(pszXML);
                    }
                }
                else
                {
                    osMetadataItem += pszRes;
                }
            }
            else
            {
                char* pszEscapedXML = CPLEscapeString(pszRes, -1, CPLES_XML_BUT_QUOTES);
                osMetadataItem += pszEscapedXML;
                CPLFree(pszEscapedXML);
            }
            if (psXML != NULL)
                CPLDestroyXMLNode(psXML);

            osMetadataItem += "</LocationInfo>";
            CPLFree(pszRes);
            return osMetadataItem.c_str();
        }
        else
        {
            osMetadataItem = "";
            return NULL;
        }
    }

    return GDALPamRasterBand::GetMetadataItem(pszName, pszDomain);
}
Ejemplo n.º 9
0
int GDALRPCTransform( void *pTransformArg, int bDstToSrc, 
                      int nPointCount, 
                      double *padfX, double *padfY, double *padfZ,
                      int *panSuccess )

{
    VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 );

    GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg;
    GDALRPCInfo *psRPC = &(psTransform->sRPC);
    int i;

    if( psTransform->bReversed )
        bDstToSrc = !bDstToSrc;

    int bands[1] = {1};
    int nRasterXSize = 0, nRasterYSize = 0;

/* -------------------------------------------------------------------- */
/*      Lazy opening of the optionnal DEM file.                         */
/* -------------------------------------------------------------------- */
    if(psTransform->pszDEMPath != NULL &&
       psTransform->bHasTriedOpeningDS == FALSE)
    {
        int bIsValid = FALSE;
        psTransform->bHasTriedOpeningDS = TRUE;
        psTransform->poDS = (GDALDataset *)
                                GDALOpen( psTransform->pszDEMPath, GA_ReadOnly );
        if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1)
        {
            const char* pszSpatialRef = psTransform->poDS->GetProjectionRef();
            if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0')
            {
                OGRSpatialReference* poWGSSpaRef =
                        new OGRSpatialReference(SRS_WKT_WGS84);
                OGRSpatialReference* poDSSpaRef =
                        new OGRSpatialReference(pszSpatialRef);
                if(!poWGSSpaRef->IsSame(poDSSpaRef))
                    psTransform->poCT =OGRCreateCoordinateTransformation(
                                                    poWGSSpaRef, poDSSpaRef );
                delete poWGSSpaRef;
                delete poDSSpaRef;
            }

            if (psTransform->poDS->GetGeoTransform(
                                psTransform->adfGeoTransform) == CE_None &&
                GDALInvGeoTransform( psTransform->adfGeoTransform,
                                     psTransform->adfReverseGeoTransform ))
            {
                bIsValid = TRUE;
            }
        }

        if (!bIsValid && psTransform->poDS != NULL)
        {
            GDALClose(psTransform->poDS);
            psTransform->poDS = NULL;
        }
    }
    if (psTransform->poDS)
    {
        nRasterXSize = psTransform->poDS->GetRasterXSize();
        nRasterYSize = psTransform->poDS->GetRasterYSize();
    }

/* -------------------------------------------------------------------- */
/*      The simple case is transforming from lat/long to pixel/line.    */
/*      Just apply the equations directly.                              */
/* -------------------------------------------------------------------- */
    if( bDstToSrc )
    {
        for( i = 0; i < nPointCount; i++ )
        {
            if(psTransform->poDS)
            {
                double dfX, dfY;
                //check if dem is not in WGS84 and transform points padfX[i], padfY[i]
                if(psTransform->poCT)
                {
                    double dfXOrig = padfX[i];
                    double dfYOrig = padfY[i];
                    double dfZOrig = padfZ[i];
                    if (!psTransform->poCT->Transform(
                                                1, &dfXOrig, &dfYOrig, &dfZOrig))
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                    GDALApplyGeoTransform( psTransform->adfReverseGeoTransform,
                                           dfXOrig, dfYOrig, &dfX, &dfY );
                }
                else
                    GDALApplyGeoTransform( psTransform->adfReverseGeoTransform,
                                           padfX[i], padfY[i], &dfX, &dfY );
                int dX = int(dfX);
                int dY = int(dfY);

                if (!(dX >= 0 && dY >= 0 &&
                      dX+2 <= nRasterXSize && dY+2 <= nRasterYSize))
                {
                    panSuccess[i] = FALSE;
                    continue;
                }

                double dfDEMH(0);
                double dfDeltaX = dfX - dX;
                double dfDeltaY = dfY - dY;
                
                if(psTransform->eResampleAlg == DRA_Cubic)
                {
                    int dXNew = dX - 1;
                    int dYNew = dY - 1;
                    if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize))
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                    //cubic interpolation
                    int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
                    CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4,
                                                              &adElevData, 4, 4,
                                                              GDT_Int32, 1, bands, 0, 0, 0);
                    if(eErr != CE_None)
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }

                    double dfSumH(0);
                    for ( int i = 0; i < 5; i++ )
                    {
                        // Loop across the X axis
                        for ( int j = 0; j < 5; j++ )
                        {
                            // Calculate the weight for the specified pixel according
                            // to the bicubic b-spline kernel we're using for
                            // interpolation
                            int dKernIndX = j - 1;
                            int dKernIndY = i - 1;
                            double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY);

                            // Create a sum of all values
                            // adjusted for the pixel's calculated weight
                            dfSumH += adElevData[j + i * 4] * dfPixelWeight;
                        }
                    }
                    dfDEMH = dfSumH;
                }
                else if(psTransform->eResampleAlg == DRA_Bilinear)
                {
                    if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize))
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                    //bilinear interpolation
                    int anElevData[4] = {0,0,0,0};
                    CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2,
                                                              &anElevData, 2, 2,
                                                              GDT_Int32, 1, bands, 0, 0, 0);
                    if(eErr != CE_None)
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                    double dfDeltaX1 = 1.0 - dfDeltaX;                
                    double dfDeltaY1 = 1.0 - dfDeltaY;

                    double dfXZ1 = anElevData[0] * dfDeltaX1 + anElevData[1] * dfDeltaX;
                    double dfXZ2 = anElevData[2] * dfDeltaX1 + anElevData[3] * dfDeltaX;
                    double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY;
                    dfDEMH = dfYZ;
                }
                else
                {
                    if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize))
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                    CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1,
                                                              &dfDEMH, 1, 1,
                                                              GDT_Int32, 1, bands, 0, 0, 0);
                    if(eErr != CE_None)
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }              
                }                

                RPCTransformPoint( psRPC, padfX[i], padfY[i], 
                                   padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) *
                                                psTransform->dfHeightScale, 
                                   padfX + i, padfY + i );
            }
            else
                RPCTransformPoint( psRPC, padfX[i], padfY[i], 
                                   padfZ[i] + psTransform->dfHeightOffset *
                                              psTransform->dfHeightScale, 
                                   padfX + i, padfY + i );
            panSuccess[i] = TRUE;
        }

        return TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Compute the inverse (pixel/line/height to lat/long).  This      */
/*      function uses an iterative method from an initial linear        */
/*      approximation.                                                  */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nPointCount; i++ )
    {
        double dfResultX, dfResultY;

        if(psTransform->poDS)
        {
            RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], 
                      padfZ[i] + psTransform->dfHeightOffset *
                                 psTransform->dfHeightScale,
                      &dfResultX, &dfResultY );

            double dfX, dfY;
            //check if dem is not in WGS84 and transform points padfX[i], padfY[i]
            if(psTransform->poCT)
            {
                double dfZ = 0;
                if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ))
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
            }

            GDALApplyGeoTransform( psTransform->adfReverseGeoTransform,
                                    dfResultX, dfResultY, &dfX, &dfY );
            int dX = int(dfX);
            int dY = int(dfY);

            double dfDEMH(0);
            double dfDeltaX = dfX - dX;
            double dfDeltaY = dfY - dY;

            if(psTransform->eResampleAlg == DRA_Cubic)
            {
                int dXNew = dX - 1;
                int dYNew = dY - 1;
                if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize))
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
                //cubic interpolation
                int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
                CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4,
                                                          &adElevData, 4, 4,
                                                          GDT_Int32, 1, bands, 0, 0, 0);
                if(eErr != CE_None)
                {
                    panSuccess[i] = FALSE;
                    continue;
                }

                double dfSumH(0);
                for ( int i = 0; i < 5; i++ )
                {
                    // Loop across the X axis
                    for ( int j = 0; j < 5; j++ )
                    {
                        // Calculate the weight for the specified pixel according
                        // to the bicubic b-spline kernel we're using for
                        // interpolation
                        int dKernIndX = j - 1;
                        int dKernIndY = i - 1;
                        double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY);

                        // Create a sum of all values
                        // adjusted for the pixel's calculated weight
                        dfSumH += adElevData[j + i * 4] * dfPixelWeight;
                    }
                }
                dfDEMH = dfSumH;
            }
            else if(psTransform->eResampleAlg == DRA_Bilinear)
            {
                if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize))
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
                //bilinear interpolation
                int adElevData[4] = {0,0,0,0};
                CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2,
                                                          &adElevData, 2, 2,
                                                          GDT_Int32, 1, bands, 0, 0, 0);
                if(eErr != CE_None)
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
                double dfDeltaX1 = 1.0 - dfDeltaX;                
                double dfDeltaY1 = 1.0 - dfDeltaY;

                double dfXZ1 = adElevData[0] * dfDeltaX1 + adElevData[1] * dfDeltaX;
                double dfXZ2 = adElevData[2] * dfDeltaX1 + adElevData[3] * dfDeltaX;
                double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY;
                dfDEMH = dfYZ;
            }
            else
            {
                if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize))
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
                CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1,
                                                          &dfDEMH, 1, 1,
                                                          GDT_Int32, 1, bands, 0, 0, 0);
                if(eErr != CE_None)
                {
                    panSuccess[i] = FALSE;
                    continue;
                }           
            }

            RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], 
                                      padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) *
                                                  psTransform->dfHeightScale,
                                      &dfResultX, &dfResultY );
        }
        else
        {
            RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], 
                                      padfZ[i] + psTransform->dfHeightOffset *
                                                 psTransform->dfHeightScale,
                                      &dfResultX, &dfResultY );

        }
        padfX[i] = dfResultX;
        padfY[i] = dfResultY;

        panSuccess[i] = TRUE;
    }

    return TRUE;
}
Ejemplo n.º 10
0
void *GDALCreateRPCTransformer( GDALRPCInfo *psRPCInfo, int bReversed, 
                                double dfPixErrThreshold,
                                char **papszOptions )

{
    GDALRPCTransformInfo *psTransform;

/* -------------------------------------------------------------------- */
/*      Initialize core info.                                           */
/* -------------------------------------------------------------------- */
    psTransform = (GDALRPCTransformInfo *) 
        CPLCalloc(sizeof(GDALRPCTransformInfo),1);

    memcpy( &(psTransform->sRPC), psRPCInfo, sizeof(GDALRPCInfo) );
    psTransform->bReversed = bReversed;
    psTransform->dfPixErrThreshold = dfPixErrThreshold;
    psTransform->dfHeightOffset = 0.0;
    psTransform->dfHeightScale = 1.0;

    strcpy( psTransform->sTI.szSignature, "GTI" );
    psTransform->sTI.pszClassName = "GDALRPCTransformer";
    psTransform->sTI.pfnTransform = GDALRPCTransform;
    psTransform->sTI.pfnCleanup = GDALDestroyRPCTransformer;
    psTransform->sTI.pfnSerialize = GDALSerializeRPCTransformer;
   
/* -------------------------------------------------------------------- */
/*      Do we have a "average height" that we want to consider all      */
/*      elevations to be relative to?                                   */
/* -------------------------------------------------------------------- */
    const char *pszHeight = CSLFetchNameValue( papszOptions, "RPC_HEIGHT" );
    if( pszHeight != NULL )
        psTransform->dfHeightOffset = CPLAtof(pszHeight);

/* -------------------------------------------------------------------- */
/*                       The "height scale"                             */
/* -------------------------------------------------------------------- */
    const char *pszHeightScale = CSLFetchNameValue( papszOptions, "RPC_HEIGHT_SCALE" );
    if( pszHeightScale != NULL )
        psTransform->dfHeightScale = CPLAtof(pszHeightScale);

/* -------------------------------------------------------------------- */
/*                       The DEM file name                              */
/* -------------------------------------------------------------------- */
    const char *pszDEMPath = CSLFetchNameValue( papszOptions, "RPC_DEM" );
    if( pszDEMPath != NULL )
        psTransform->pszDEMPath = CPLStrdup(pszDEMPath);

/* -------------------------------------------------------------------- */
/*                      The DEM interpolation                           */
/* -------------------------------------------------------------------- */
    const char *pszDEMInterpolation = CSLFetchNameValueDef( papszOptions, "RPC_DEMINTERPOLATION", "bilinear" );
    if(EQUAL(pszDEMInterpolation, "near" ))
        psTransform->eResampleAlg = DRA_NearestNeighbour;
    else if(EQUAL(pszDEMInterpolation, "bilinear" ))
        psTransform->eResampleAlg = DRA_Bilinear;
    else if(EQUAL(pszDEMInterpolation, "cubic" ))
        psTransform->eResampleAlg = DRA_Cubic;
    else
        psTransform->eResampleAlg = DRA_Bilinear;
       
/* -------------------------------------------------------------------- */
/*      Establish a reference point for calcualating an affine          */
/*      geotransform approximate transformation.                        */
/* -------------------------------------------------------------------- */
    double adfGTFromLL[6], dfRefPixel = -1.0, dfRefLine = -1.0;
    double dfRefLong = 0.0, dfRefLat = 0.0;

    if( psRPCInfo->dfMIN_LONG != -180 || psRPCInfo->dfMAX_LONG != 180 )
    {
        dfRefLong = (psRPCInfo->dfMIN_LONG + psRPCInfo->dfMAX_LONG) * 0.5;
        dfRefLat  = (psRPCInfo->dfMIN_LAT  + psRPCInfo->dfMAX_LAT ) * 0.5;

        RPCTransformPoint( psRPCInfo, dfRefLong, dfRefLat, 0.0, 
                           &dfRefPixel, &dfRefLine );
    }

    // Try with scale and offset if we don't can't use bounds or
    // the results seem daft. 
    if( dfRefPixel < 0.0 || dfRefLine < 0.0
        || dfRefPixel > 100000 || dfRefLine > 100000 )
    {
        dfRefLong = psRPCInfo->dfLONG_OFF;
        dfRefLat  = psRPCInfo->dfLAT_OFF;

        RPCTransformPoint( psRPCInfo, dfRefLong, dfRefLat, 0.0, 
                           &dfRefPixel, &dfRefLine );
    }

/* -------------------------------------------------------------------- */
/*      Transform nearby locations to establish affine direction        */
/*      vectors.                                                        */
/* -------------------------------------------------------------------- */
    double dfRefPixelDelta, dfRefLineDelta, dfLLDelta = 0.0001;
    
    RPCTransformPoint( psRPCInfo, dfRefLong+dfLLDelta, dfRefLat, 0.0, 
                       &dfRefPixelDelta, &dfRefLineDelta );
    adfGTFromLL[1] = (dfRefPixelDelta - dfRefPixel) / dfLLDelta;
    adfGTFromLL[2] = (dfRefLineDelta - dfRefLine) / dfLLDelta;
    
    RPCTransformPoint( psRPCInfo, dfRefLong, dfRefLat+dfLLDelta, 0.0, 
                       &dfRefPixelDelta, &dfRefLineDelta );
    adfGTFromLL[4] = (dfRefPixelDelta - dfRefPixel) / dfLLDelta;
    adfGTFromLL[5] = (dfRefLineDelta - dfRefLine) / dfLLDelta;

    adfGTFromLL[0] = dfRefPixel 
        - adfGTFromLL[1] * dfRefLong - adfGTFromLL[2] * dfRefLat;
    adfGTFromLL[3] = dfRefLine 
        - adfGTFromLL[4] * dfRefLong - adfGTFromLL[5] * dfRefLat;

    GDALInvGeoTransform( adfGTFromLL, psTransform->adfPLToLatLongGeoTransform);
    
    return psTransform;
}
Ejemplo n.º 11
0
void wxGISRasterRGBRenderer::Draw(wxGISDataset* pRasterDataset, wxGISEnumDrawPhase DrawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel)
{
	wxGISRasterDataset* pRaster = dynamic_cast<wxGISRasterDataset*>(pRasterDataset);
	if(!pRaster)
		return;
	IDisplayTransformation* pDisplayTransformation = pDisplay->GetDisplayTransformation();
	OGRSpatialReference* pDisplaySpatialReference = pDisplayTransformation->GetSpatialReference();
	OGRSpatialReference* pRasterSpatialReference = pRaster->GetSpatialReference();
	bool IsSpaRefSame(true);
	if(pDisplaySpatialReference && pDisplaySpatialReference)
		IsSpaRefSame = pDisplaySpatialReference->IsSame(pRasterSpatialReference);
	OGREnvelope VisibleBounds = pDisplayTransformation->GetVisibleBounds();
	OGREnvelope* pRasterExtent = pRaster->GetEnvelope();
	OGREnvelope RasterEnvelope, DisplayEnvelope;

	if(!IsSpaRefSame)
	{
		RasterEnvelope = TransformEnvelope(pRasterExtent, pRasterSpatialReference, pDisplaySpatialReference);
	}
	else
	{
		RasterEnvelope = *pRasterExtent;
	}
	bool IsZoomIn(false);
	//IsZoomIn = RasterEnvelope.Contains(VisibleBounds);
	IsZoomIn = RasterEnvelope.MaxX > VisibleBounds.MaxX || RasterEnvelope.MaxY > VisibleBounds.MaxY || RasterEnvelope.MinX < VisibleBounds.MinX || RasterEnvelope.MinY < VisibleBounds.MinY;
	if(IsZoomIn)
	{
		//intersect bounds
		OGREnvelope DrawBounds;
		DrawBounds.MinX = MAX(RasterEnvelope.MinX, VisibleBounds.MinX);
		DrawBounds.MinY = MAX(RasterEnvelope.MinY, VisibleBounds.MinY);
		DrawBounds.MaxX = MIN(RasterEnvelope.MaxX, VisibleBounds.MaxX);
		DrawBounds.MaxY = MIN(RasterEnvelope.MaxY, VisibleBounds.MaxY);

		OGRRawPoint OGRRawPoints[2];
		OGRRawPoints[0].x = DrawBounds.MinX;
		OGRRawPoints[0].y = DrawBounds.MinY;
		OGRRawPoints[1].x = DrawBounds.MaxX;
		OGRRawPoints[1].y = DrawBounds.MaxY;
		wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2);	

		if(!pDCPoints)
		{
			wxDELETEA(pDCPoints);
			return;
		}

		int nDCXOrig = pDCPoints[0].x;
		int nDCYOrig = pDCPoints[1].y;
		int nWidth = pDCPoints[1].x - pDCPoints[0].x;
		int nHeight = pDCPoints[0].y - pDCPoints[1].y;
		wxDELETEA(pDCPoints);

        if(nWidth <= 20 || nHeight <= 20)
			return;

		GDALDataset* pGDALDataset = pRaster->GetRaster();

		int nBandCount = pGDALDataset->GetRasterCount();
		//hack!
		int bands[3];
		if(nBandCount < 3)
		{
			bands[0] = 1;
			bands[1] = 1;
			bands[2] = 1;	
		}
		else
		{
			bands[0] = 1;
			bands[1] = 2;
			bands[2] = 3;		
		}

		double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
        double adfReverseGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
		CPLErr err = pGDALDataset->GetGeoTransform(adfGeoTransform);
        bool bNoTransform(false);
        if(err != CE_None)
        {
            bNoTransform = true;
        }
        else
        {
            int nRes = GDALInvGeoTransform( adfGeoTransform, adfReverseGeoTransform );
        }

		//2. get image data from raster - draw part of the raster
		if(IsSpaRefSame)
		{
			double rMinX, rMinY, rMaxX, rMaxY;

            int nXSize = pGDALDataset->GetRasterXSize();
            int nYSize = pGDALDataset->GetRasterYSize();

            if(bNoTransform)
            {
                rMinX = DrawBounds.MinX;
                rMaxX = DrawBounds.MaxX;
                rMaxY = nYSize - DrawBounds.MinY;
                rMinY = nYSize - DrawBounds.MaxY;
            }
            else
            {
    			GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MinX, DrawBounds.MinY, &rMinX, &rMaxY );
	    		GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MaxX, DrawBounds.MaxY, &rMaxX, &rMinY );
            }
            //double rRealMinX, rRealMinY, rRealMaxX, rRealMaxY;
            //rRealMinX = MIN(rMinX, rMaxX);
            //rRealMinY = MIN(rMinY, rMaxY);
            //rRealMaxX = MAX(rMinX, rMaxX);
            //rRealMaxY = MAX(rMinY, rMaxY);

            double rImgWidth = rMaxX - rMinX;
            double rImgHeight = rMaxY - rMinY;
			int nImgWidth = ceil(rImgWidth) + 1;
			int nImgHeight = ceil(rImgHeight) + 1;
            
			//read in buffer
            int nMinX = floor(rMinX);
            int nMinY = floor(rMinY);
			if(nMinX < 0) nMinX = 0;
			if(nMinY < 0) nMinY = 0;

            if(nImgWidth > nXSize - nMinX) nImgWidth -= 1;
            if(nImgHeight > nYSize - nMinY) nImgHeight -= 1;

		    //create buffer
			int nWidthOut = nWidth > nImgWidth ? nImgWidth : (double)nWidth + 1.0  /*/ 1.2 / 2 * 2/ 1.5 + 1) / 2*/;
			int nHeightOut = nHeight > nImgHeight ? nImgHeight : (double)nHeight + 1.0  /*/ 1.2 / 2 * 2 / 1.5 + 1) / 2*/;
			double rImgWidthOut = nWidth > nImgWidth ? rImgWidth : (double)nWidthOut * rImgWidth / nImgWidth;
			double rImgHeightOut = nHeight > nImgHeight ? rImgHeight : (double)nHeightOut * rImgHeight / nImgHeight;


		    unsigned char* data = new unsigned char[nWidthOut * nHeightOut * 3];

		    err = pGDALDataset->AdviseRead(nMinX, nMinY, nImgWidth, nImgHeight, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, NULL);
		    if(err != CE_None)
		    {
			    wxDELETEA(data);//delete[](data);
			    return;
		    }

		    err = pGDALDataset->RasterIO(GF_Read, nMinX, nMinY, nImgWidth, nImgHeight, data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char));
		    if(err != CE_None)
		    {
			    wxDELETEA(data);//delete[](data);
			    return;
		    }
		    //scale pTempData to data using interpolation methods
		    pDisplay->DrawBitmap(Scale(data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, rImgWidthOut/*rImgWidth*/, rImgHeightOut/*rImgHeight*/, nWidth + 1 , nHeight + 1, rMinX - nMinX, rMinY - nMinY, /*enumGISQualityNearest*/enumGISQualityBilinear, pTrackCancel), nDCXOrig, nDCYOrig);

            wxDELETEA(data);
		}
		else
		{
		//void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1 );
		//GDALDestroyGenImgProjTransformer( hTransformArg );
	////		//get new envelope - it may rotate
	////		OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pDisplaySpatialReference, pRasterSpatialReference);
	//////		get real envelope
	//////		poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MaxY);
	//////		poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MinY);
	//////		poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MinY);
	//////		poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MaxY);
	////		OCTDestroyCoordinateTransformation(poCT);
		}
	}
	else
	{
		//1. convert newrasterenvelope to DC		
		OGRRawPoint OGRRawPoints[2];
		OGRRawPoints[0].x = RasterEnvelope.MinX;
		OGRRawPoints[0].y = RasterEnvelope.MinY;
		OGRRawPoints[1].x = RasterEnvelope.MaxX;
		OGRRawPoints[1].y = RasterEnvelope.MaxY;
		wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2);	

		//2. get image data from raster - buffer size = DC_X and DC_Y - draw full raster
		if(!pDCPoints)
		{
			wxDELETEA(pDCPoints);
			return;
		}
		int nDCXOrig = pDCPoints[0].x;
		int nDCYOrig = pDCPoints[1].y;
		int nWidth = pDCPoints[1].x - pDCPoints[0].x;
		int nHeight = pDCPoints[0].y - pDCPoints[1].y;
		delete[](pDCPoints);

		GDALDataset* pGDALDataset = pRaster->GetRaster();
		int nImgWidth = pGDALDataset->GetRasterXSize();
		int nImgHeight = pGDALDataset->GetRasterYSize();

		int nBandCount = pGDALDataset->GetRasterCount();
		//hack!
		int bands[3];
		if(nBandCount < 3)
		{
			bands[0] = 1;
			bands[1] = 1;
			bands[2] = 1;	
		}
		else
		{
			bands[0] = 1;
			bands[1] = 2;
			bands[2] = 3;		
		}

		//create buffer
		unsigned char* data = new unsigned char[nWidth * nHeight * 3];
		if(IsSpaRefSame)
		{
			//read in buffer
			CPLErr err = pGDALDataset->RasterIO(GF_Read, 0, 0, nImgWidth, nImgHeight, data, nWidth, nHeight, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char));
			if(err != CE_None)
			{
				wxDELETEA(data);
				return;
			}
		}
		else
		{
			//1. calc Width & Height of TempData with same aspect ratio of raster
			//2. create pTempData buffer
			unsigned char* pTempData;
			//3. fill data
			//4. for each pixel of data buffer get pixel from pTempData using OGRCreateCoordinateTransformation
			//delete[](data);
		}
		//3. draw //think about transparancy!
		wxImage ResultImage(nWidth, nHeight, data);
		pDisplay->DrawBitmap(ResultImage, nDCXOrig, nDCYOrig);

		//delete[](data);
	}
}
Ejemplo n.º 12
0
int GDALRPCTransform( void *pTransformArg, int bDstToSrc,
                      int nPointCount,
                      double *padfX, double *padfY, double *padfZ,
                      int *panSuccess )

{
    VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 );

    GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg;
    GDALRPCInfo *psRPC = &(psTransform->sRPC);
    int i;

    if( psTransform->bReversed )
        bDstToSrc = !bDstToSrc;

    /* -------------------------------------------------------------------- */
    /*      Lazy opening of the optionnal DEM file.                         */
    /* -------------------------------------------------------------------- */
    if(psTransform->pszDEMPath != NULL &&
            psTransform->bHasTriedOpeningDS == FALSE)
    {
        int bIsValid = FALSE;
        psTransform->bHasTriedOpeningDS = TRUE;
        psTransform->poDS = (GDALDataset *)
                            GDALOpen( psTransform->pszDEMPath, GA_ReadOnly );
        if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1)
        {
            const char* pszSpatialRef = psTransform->poDS->GetProjectionRef();
            if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0')
            {
                OGRSpatialReference* poWGSSpaRef =
                    new OGRSpatialReference(SRS_WKT_WGS84);
                OGRSpatialReference* poDSSpaRef =
                    new OGRSpatialReference(pszSpatialRef);
                if(!poWGSSpaRef->IsSame(poDSSpaRef))
                    psTransform->poCT =OGRCreateCoordinateTransformation(
                                           poWGSSpaRef, poDSSpaRef );
                delete poWGSSpaRef;
                delete poDSSpaRef;
            }

            if (psTransform->poDS->GetGeoTransform(
                        psTransform->adfGeoTransform) == CE_None &&
                    GDALInvGeoTransform( psTransform->adfGeoTransform,
                                         psTransform->adfReverseGeoTransform ))
            {
                bIsValid = TRUE;
            }
        }

        if (!bIsValid && psTransform->poDS != NULL)
        {
            GDALClose(psTransform->poDS);
            psTransform->poDS = NULL;
        }
    }

    /* -------------------------------------------------------------------- */
    /*      The simple case is transforming from lat/long to pixel/line.    */
    /*      Just apply the equations directly.                              */
    /* -------------------------------------------------------------------- */
    if( bDstToSrc )
    {
        for( i = 0; i < nPointCount; i++ )
        {
            if(psTransform->poDS)
            {
                double dfX, dfY;
                //check if dem is not in WGS84 and transform points padfX[i], padfY[i]
                if(psTransform->poCT)
                {
                    double dfXOrig = padfX[i];
                    double dfYOrig = padfY[i];
                    double dfZOrig = padfZ[i];
                    if (!psTransform->poCT->Transform(
                                1, &dfXOrig, &dfYOrig, &dfZOrig))
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                    GDALApplyGeoTransform( psTransform->adfReverseGeoTransform,
                                           dfXOrig, dfYOrig, &dfX, &dfY );
                }
                else
                    GDALApplyGeoTransform( psTransform->adfReverseGeoTransform,
                                           padfX[i], padfY[i], &dfX, &dfY );

                double dfDEMH(0);
                if( !GDALRPCGetDEMHeight( psTransform, dfX, dfY, &dfDEMH) )
                {
                    if( psTransform->bHasDEMMissingValue )
                        dfDEMH = psTransform->dfDEMMissingValue;
                    else
                    {
                        panSuccess[i] = FALSE;
                        continue;
                    }
                }

                RPCTransformPoint( psRPC, padfX[i], padfY[i],
                                   padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) *
                                   psTransform->dfHeightScale,
                                   padfX + i, padfY + i );
            }
            else
                RPCTransformPoint( psRPC, padfX[i], padfY[i],
                                   padfZ[i] + psTransform->dfHeightOffset *
                                   psTransform->dfHeightScale,
                                   padfX + i, padfY + i );
            panSuccess[i] = TRUE;
        }

        return TRUE;
    }

    /* -------------------------------------------------------------------- */
    /*      Compute the inverse (pixel/line/height to lat/long).  This      */
    /*      function uses an iterative method from an initial linear        */
    /*      approximation.                                                  */
    /* -------------------------------------------------------------------- */
    for( i = 0; i < nPointCount; i++ )
    {
        double dfResultX, dfResultY;

        if(psTransform->poDS)
        {
            RPCInverseTransformPoint( psTransform, padfX[i], padfY[i],
                                      padfZ[i] + psTransform->dfHeightOffset *
                                      psTransform->dfHeightScale,
                                      &dfResultX, &dfResultY );

            double dfX, dfY;
            //check if dem is not in WGS84 and transform points padfX[i], padfY[i]
            if(psTransform->poCT)
            {
                double dfZ = 0;
                if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ))
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
            }

            GDALApplyGeoTransform( psTransform->adfReverseGeoTransform,
                                   dfResultX, dfResultY, &dfX, &dfY );

            double dfDEMH(0);
            if( !GDALRPCGetDEMHeight( psTransform, dfX, dfY, &dfDEMH) )
            {
                if( psTransform->bHasDEMMissingValue )
                    dfDEMH = psTransform->dfDEMMissingValue;
                else
                {
                    panSuccess[i] = FALSE;
                    continue;
                }
            }

            RPCInverseTransformPoint( psTransform, padfX[i], padfY[i],
                                      padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) *
                                      psTransform->dfHeightScale,
                                      &dfResultX, &dfResultY );
        }
        else
        {
            RPCInverseTransformPoint( psTransform, padfX[i], padfY[i],
                                      padfZ[i] + psTransform->dfHeightOffset *
                                      psTransform->dfHeightScale,
                                      &dfResultX, &dfResultY );

        }
        padfX[i] = dfResultX;
        padfY[i] = dfResultY;

        panSuccess[i] = TRUE;
    }

    return TRUE;
}