コード例 #1
0
CPLErr GDALWMSRasterBand::ZeroBlock(int x, int y, int to_buffer_band, void *buffer) {
    CPLErr ret = CE_None;

    for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) {
        if (ret == CE_None) {
            void *p = NULL;
            GDALRasterBlock *b = NULL;
            if ((buffer != NULL) && (ib == to_buffer_band)) {
                p = buffer;
            } else {
                GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib));
                if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview));
                if (!band->IsBlockInCache(x, y)) {
                    b = band->GetLockedBlockRef(x, y, true);
                    if (b != NULL) {
                        p = b->GetDataRef();
                        if (p == NULL) {
                          CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: GetDataRef returned NULL.");
                          ret = CE_Failure;
                        }
                    }
                }
            }
            if (p != NULL) {
                unsigned char *b = reinterpret_cast<unsigned char *>(p);
                int block_size = nBlockXSize * nBlockYSize * (GDALGetDataTypeSize(eDataType) / 8);
                for (int i = 0; i < block_size; ++i) b[i] = 0;
            }
            if (b != NULL) {
                b->DropLock();
            }
        }
    }

    return ret;
}
コード例 #2
0
CPLErr GDALWMSRasterBand::ReadBlocks(int x, int y, void *buffer, int bx0, int by0, int bx1, int by1, int advise_read) {
    CPLErr ret = CE_None;
    int i;

    int max_request_count = (bx1 - bx0 + 1) * (by1 - by0 + 1);
    int request_count = 0;
    CPLHTTPRequest *download_requests = NULL;
    GDALWMSCache *cache = m_parent_dataset->m_cache;
    struct BlockXY {
        int x, y;
    } *download_blocks = NULL;
    if (!m_parent_dataset->m_offline_mode) {
        download_requests = new CPLHTTPRequest[max_request_count];
        download_blocks = new BlockXY[max_request_count];
    }

    char **http_request_opts = NULL;
    if (m_parent_dataset->m_http_timeout != -1) {
	CPLString http_request_optstr;
        http_request_optstr.Printf("TIMEOUT=%d", m_parent_dataset->m_http_timeout);
        http_request_opts = CSLAddString(http_request_opts, http_request_optstr.c_str());
    }
    for (int iy = by0; iy <= by1; ++iy) {
        for (int ix = bx0; ix <= bx1; ++ix) {
            bool need_this_block = false;
            if (!advise_read) {
                for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) {
                    if ((ix == x) && (iy == y) && (ib == nBand)) {
                        need_this_block = true;
                    } else {
                        GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib));
                        if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview));
                        if (!band->IsBlockInCache(ix, iy)) need_this_block = true;
                    }
                }
            } else {
                need_this_block = true;
            }
            CPLString url;
            if (need_this_block) {
                CPLString file_name;
                AskMiniDriverForBlock(&url, ix, iy);
                if ((cache != NULL) && (cache->Read(url.c_str(), &file_name) == CE_None)) {
                    if (advise_read) {
                        need_this_block = false;
                    } else {
                        void *p = 0;
                        if ((ix == x) && (iy == y)) p = buffer;
                        if (ReadBlockFromFile(ix, iy, file_name.c_str(), nBand, p, 0) == CE_None) need_this_block = false;
                    }
                }
            }
            if (need_this_block) {
                if (m_parent_dataset->m_offline_mode) {
                    if (!advise_read) {
                        void *p = 0;
                        if ((ix == x) && (iy == y)) p = buffer;
                        if (ZeroBlock(ix, iy, nBand, p) != CE_None) {
                            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: ZeroBlock failed.");
                            ret = CE_Failure;
                        }
                    }
                } else {
                    CPLHTTPInitializeRequest(&download_requests[request_count], url.c_str(), http_request_opts);
                    download_blocks[request_count].x = ix;
                    download_blocks[request_count].y = iy;
                    ++request_count;
                }
            }
        }
    }
    if (http_request_opts != NULL) {
        CSLDestroy(http_request_opts);
    }

    if (request_count > 0) {
        char **opts = NULL;
        CPLString optstr;
        if (m_parent_dataset->m_http_max_conn != -1) {
            optstr.Printf("MAXCONN=%d", m_parent_dataset->m_http_max_conn);
            opts = CSLAddString(opts, optstr.c_str());
        }
        if (CPLHTTPFetchMulti(download_requests, request_count, opts) != CE_None) {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: CPLHTTPFetchMulti failed.");
            ret = CE_Failure;
        }
        if (opts != NULL) {
            CSLDestroy(opts);
        }
    }

    for (i = 0; i < request_count; ++i) {
        if (ret == CE_None) {
            if ((download_requests[i].nStatus == 200) && (download_requests[i].pabyData != NULL) && (download_requests[i].nDataLen > 0)) {
                CPLString file_name(BufferToVSIFile(download_requests[i].pabyData, download_requests[i].nDataLen));
                if (file_name.size() > 0) {
                    /* check for error xml */
                    if (download_requests[i].nDataLen >= 20) {
                        const char *download_data = reinterpret_cast<char *>(download_requests[i].pabyData);
                        if (EQUALN(download_data, "<?xml ", 6) 
                        || EQUALN(download_data, "<!DOCTYPE ", 10)
                        || EQUALN(download_data, "<ServiceException", 17)) {
                            if (ReportWMSException(file_name.c_str()) != CE_None) {
                                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned unknown exception.");
                            }
                            ret = CE_Failure;
                        }
                    }
                    if (ret == CE_None) {
                        if (advise_read && !m_parent_dataset->m_verify_advise_read) {
                            if (cache != NULL) {
                                cache->Write(download_requests[i].pszURL, file_name);
                            }
                        } else {
                            void *p = 0;
                            if ((download_blocks[i].x == x) && (download_blocks[i].y == y)) p = buffer;
                            if (ReadBlockFromFile(download_blocks[i].x, download_blocks[i].y, file_name.c_str(), nBand, p, advise_read) == CE_None) {
                                if (cache != NULL) {
                                    cache->Write(download_requests[i].pszURL, file_name);
                                }
                            } else {
                                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: ReadBlockFromFile (%s) failed.",
                                         download_requests[i].pszURL);
                                ret = CE_Failure;
                            }
                        }
                    }
                    VSIUnlink(file_name.c_str());
                }
            } else if (download_requests[i].nStatus == 204) {
                if (!advise_read) {
                    void *p = 0;
                    if ((download_blocks[i].x == x) && (download_blocks[i].y == y)) p = buffer;
                    if (ZeroBlock(download_blocks[i].x, download_blocks[i].y, nBand, p) != CE_None) {
                        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: ZeroBlock failed.");
                        ret = CE_Failure;
                    }
                }
            } else {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Unable to download block %d, %d.\n  URL: %s\n  HTTP status code: %d, error: %s.",
                    download_blocks[i].x, download_blocks[i].y, download_requests[i].pszURL, download_requests[i].nStatus, 
		    download_requests[i].pszError ? download_requests[i].pszError : "(null)");
                ret = CE_Failure;
            }
        }
        CPLHTTPCleanupRequest(&download_requests[i]);
    }
    if (!m_parent_dataset->m_offline_mode) {
        delete[] download_blocks;
        delete[] download_requests;
    }

    return ret;
}
コード例 #3
0
ファイル: gdalwmsdataset.cpp プロジェクト: garnertb/gdal
CPLErr GDALWMSDataset::Initialize(CPLXMLNode *config) {
    CPLErr ret = CE_None;

    char* pszXML = CPLSerializeXMLTree( config );
    if (pszXML)
    {
        m_osXML = pszXML;
        CPLFree(pszXML);
    }

    // Initialize the minidriver, which can set parameters for the dataset using member functions
    CPLXMLNode *service_node = CPLGetXMLNode(config, "Service");
    if (service_node != NULL)
    {
        const CPLString service_name = CPLGetXMLValue(service_node, "name", "");
        if (!service_name.empty())
        {
            GDALWMSMiniDriverManager *const mdm = GetGDALWMSMiniDriverManager();
            GDALWMSMiniDriverFactory *const mdf = mdm->Find(service_name);
            if (mdf != NULL)
            {
                m_mini_driver = mdf->New();
                m_mini_driver->m_parent_dataset = this;
                if (m_mini_driver->Initialize(service_node) == CE_None)
                {
                    m_mini_driver_caps.m_capabilities_version = -1;
                    m_mini_driver->GetCapabilities(&m_mini_driver_caps);
                    if (m_mini_driver_caps.m_capabilities_version == -1)
                    {
                        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Internal error, mini-driver capabilities version not set.");
                        ret = CE_Failure;
                    }
                }
                else
                {
                    delete m_mini_driver;
                    m_mini_driver = NULL;

                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize minidriver.");
                    ret = CE_Failure;
                }
            }
            else
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "GDALWMS: No mini-driver registered for '%s'.", service_name.c_str());
                ret = CE_Failure;
            }
        }
        else
        {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
            ret = CE_Failure;
        }
    }
    else
    {
        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
        ret = CE_Failure;
    }


    /*
      Parameters that could be set by minidriver already, based on server side information.
      If the size is set, minidriver has done this already
      A "server" side minidriver needs to set at least:
      - Blocksize (x and y)
      - Clamp flag (defaults to true)
      - DataWindow
      - Band Count
      - Data Type
      It should also initialize and register the bands and overviews.
    */

    if (m_data_window.m_sx<1)
    {
        int nOverviews = 0;

        if (ret == CE_None)
        {
            m_block_size_x = atoi(CPLGetXMLValue(config, "BlockSizeX", CPLString().Printf("%d", m_default_block_size_x)));
            m_block_size_y = atoi(CPLGetXMLValue(config, "BlockSizeY", CPLString().Printf("%d", m_default_block_size_y)));
            if (m_block_size_x <= 0 || m_block_size_y <= 0)
            {
                CPLError( CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value in BlockSizeX or BlockSizeY" );
                ret = CE_Failure;
            }
        }

        if (ret == CE_None)
        {
            m_clamp_requests = StrToBool(CPLGetXMLValue(config, "ClampRequests", "true"));
            if (m_clamp_requests<0)
            {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ClampRequests, true/false expected.");
                ret = CE_Failure;
            }
        }

        if (ret == CE_None)
        {
            CPLXMLNode *data_window_node = CPLGetXMLNode(config, "DataWindow");
            if (data_window_node == NULL && m_bNeedsDataWindow)
            {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow missing.");
                ret = CE_Failure;
            }
            else
            {
                CPLString osDefaultX0, osDefaultX1, osDefaultY0, osDefaultY1;
                CPLString osDefaultTileCountX, osDefaultTileCountY, osDefaultTileLevel;
                CPLString osDefaultOverviewCount;
                osDefaultX0.Printf("%.8f", m_default_data_window.m_x0);
                osDefaultX1.Printf("%.8f", m_default_data_window.m_x1);
                osDefaultY0.Printf("%.8f", m_default_data_window.m_y0);
                osDefaultY1.Printf("%.8f", m_default_data_window.m_y1);
                osDefaultTileCountX.Printf("%d", m_default_tile_count_x);
                osDefaultTileCountY.Printf("%d", m_default_tile_count_y);
                if (m_default_data_window.m_tlevel >= 0)
                    osDefaultTileLevel.Printf("%d", m_default_data_window.m_tlevel);
                if (m_default_overview_count >= 0)
                    osDefaultOverviewCount.Printf("%d", m_default_overview_count);
                const char *overview_count = CPLGetXMLValue(config, "OverviewCount", osDefaultOverviewCount);
                const char *ulx = CPLGetXMLValue(data_window_node, "UpperLeftX", osDefaultX0);
                const char *uly = CPLGetXMLValue(data_window_node, "UpperLeftY", osDefaultY0);
                const char *lrx = CPLGetXMLValue(data_window_node, "LowerRightX", osDefaultX1);
                const char *lry = CPLGetXMLValue(data_window_node, "LowerRightY", osDefaultY1);
                const char *sx = CPLGetXMLValue(data_window_node, "SizeX", "");
                const char *sy = CPLGetXMLValue(data_window_node, "SizeY", "");
                const char *tx = CPLGetXMLValue(data_window_node, "TileX", "0");
                const char *ty = CPLGetXMLValue(data_window_node, "TileY", "0");
                const char *tlevel = CPLGetXMLValue(data_window_node, "TileLevel", osDefaultTileLevel);
                const char *str_tile_count_x = CPLGetXMLValue(data_window_node, "TileCountX", osDefaultTileCountX);
                const char *str_tile_count_y = CPLGetXMLValue(data_window_node, "TileCountY", osDefaultTileCountY);
                const char *y_origin = CPLGetXMLValue(data_window_node, "YOrigin", "default");

                if (ret == CE_None)
                {
                    if ((ulx[0] != '\0') && (uly[0] != '\0') && (lrx[0] != '\0') && (lry[0] != '\0'))
                    {
                        m_data_window.m_x0 = CPLAtof(ulx);
                        m_data_window.m_y0 = CPLAtof(uly);
                        m_data_window.m_x1 = CPLAtof(lrx);
                        m_data_window.m_y1 = CPLAtof(lry);
                    }
                    else
                    {
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "GDALWMS: Mandatory elements of DataWindow missing: UpperLeftX, UpperLeftY, LowerRightX, LowerRightY.");
                        ret = CE_Failure;
                    }
                }

                m_data_window.m_tlevel = atoi(tlevel);

                if (ret == CE_None)
                {
                    if ((sx[0] != '\0') && (sy[0] != '\0'))
                    {
                        m_data_window.m_sx = atoi(sx);
                        m_data_window.m_sy = atoi(sy);
                    }
                    else if ((tlevel[0] != '\0') && (str_tile_count_x[0] != '\0') && (str_tile_count_y[0] != '\0'))
                    {
                        int tile_count_x = atoi(str_tile_count_x);
                        int tile_count_y = atoi(str_tile_count_y);
                        m_data_window.m_sx = tile_count_x * m_block_size_x * (1 << m_data_window.m_tlevel);
                        m_data_window.m_sy = tile_count_y * m_block_size_y * (1 << m_data_window.m_tlevel);
                    }
                    else
                    {
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "GDALWMS: Mandatory elements of DataWindow missing: SizeX, SizeY.");
                        ret = CE_Failure;
                    }
                }
                if (ret == CE_None)
                {
                    if ((tx[0] != '\0') && (ty[0] != '\0'))
                    {
                        m_data_window.m_tx = atoi(tx);
                        m_data_window.m_ty = atoi(ty);
                    }
                    else
                    {
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "GDALWMS: Mandatory elements of DataWindow missing: TileX, TileY.");
                        ret = CE_Failure;
                    }
                }

                if (ret == CE_None)
                {
                    if (overview_count[0] != '\0')
                    {
                        nOverviews = atoi(overview_count);
                    }
                    else if (tlevel[0] != '\0')
                    {
                        nOverviews = m_data_window.m_tlevel;
                    }
                    else
                    {
                        const int min_overview_size = MAX(32, MIN(m_block_size_x, m_block_size_y));
                        double a = log(static_cast<double>(MIN(m_data_window.m_sx, m_data_window.m_sy))) / log(2.0)
                            - log(static_cast<double>(min_overview_size)) / log(2.0);
                        nOverviews = MAX(0, MIN(static_cast<int>(ceil(a)), 32));
                    }
                }
                if (ret == CE_None)
                {
                    CPLString y_origin_str = y_origin;
                    if (y_origin_str == "top") {
                        m_data_window.m_y_origin = GDALWMSDataWindow::TOP;
                    } else if (y_origin_str == "bottom") {
                        m_data_window.m_y_origin = GDALWMSDataWindow::BOTTOM;
                    } else if (y_origin_str == "default") {
                        m_data_window.m_y_origin = GDALWMSDataWindow::DEFAULT;
                    } else {
                        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow YOrigin must be set to "
                                 "one of 'default', 'top', or 'bottom', not '%s'.", y_origin_str.c_str());
                        ret = CE_Failure;
                    }
                }
            }
        }

        if (ret == CE_None)
        {
            if (nBands<1)
                nBands=atoi(CPLGetXMLValue(config,"BandsCount","3"));
            if (nBands<1)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "GDALWMS: Bad number of bands.");
                ret = CE_Failure;
            }
        }

        if (ret == CE_None)
        {
            const char *data_type = CPLGetXMLValue(config, "DataType", "Byte");
            m_data_type = GDALGetDataTypeByName( data_type );
            if ( m_data_type == GDT_Unknown || m_data_type >= GDT_TypeCount )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "GDALWMS: Invalid value in DataType. Data type \"%s\" is not supported.", data_type );
                ret = CE_Failure;
            }
        }

        // Initialize the bands and the overviews.  Assumes overviews are powers of two
        if (ret == CE_None)
        {
            nRasterXSize = m_data_window.m_sx;
            nRasterYSize = m_data_window.m_sy;

            if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) ||
                !GDALCheckBandCount(nBands, TRUE))
            {
                return CE_Failure;
            }

            GDALColorInterp default_color_interp[4][4] = {
                { GCI_GrayIndex, GCI_Undefined, GCI_Undefined, GCI_Undefined },
                { GCI_GrayIndex, GCI_AlphaBand, GCI_Undefined, GCI_Undefined },
                { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_Undefined },
                { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_AlphaBand }
            };
            for (int i = 0; i < nBands; ++i)
            {
                GDALColorInterp color_interp = (nBands <= 4 && i <= 3 ? default_color_interp[nBands - 1][i] : GCI_Undefined);
                GDALWMSRasterBand *band = new GDALWMSRasterBand(this, i, 1.0);
                band->m_color_interp = color_interp;
                SetBand(i + 1, band);
                double scale = 0.5;
                for (int j = 0; j < nOverviews; ++j)
                {
                    band->AddOverview(scale);
                    band->m_color_interp = color_interp;
                    scale *= 0.5;
                }
            }
        }
    }
    
    // UserPwd 
    const char *pszUserPwd = CPLGetXMLValue(config, "UserPwd", "");
    if (pszUserPwd[0] != '\0')
        m_osUserPwd = pszUserPwd;

    const char *pszUserAgent = CPLGetXMLValue(config, "UserAgent", "");
    if (pszUserAgent[0] != '\0')
        m_osUserAgent = pszUserAgent;
    
    const char *pszReferer = CPLGetXMLValue(config, "Referer", "");
    if (pszReferer[0] != '\0')
        m_osReferer = pszReferer;
    
    if (ret == CE_None) {
        const char *pszHttpZeroBlockCodes = CPLGetXMLValue(config, "ZeroBlockHttpCodes", "");
        if(pszHttpZeroBlockCodes[0] == '\0') {
            m_http_zeroblock_codes.push_back(204);
        } else {
            char **kv = CSLTokenizeString2(pszHttpZeroBlockCodes,",",CSLT_HONOURSTRINGS);
            int nCount = CSLCount(kv);
            for(int i=0; i<nCount; i++) {
                int code = atoi(kv[i]);
                if(code <= 0) {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockHttpCodes \"%s\", comma separated HTTP response codes expected.",
                             kv[i]);
                    ret = CE_Failure;
                    break;
                }
                m_http_zeroblock_codes.push_back(code);
            }
            CSLDestroy(kv);
        }
    }

    if (ret == CE_None) {
        const char *pszZeroExceptions = CPLGetXMLValue(config, "ZeroBlockOnServerException", "");
        if(pszZeroExceptions[0] != '\0') {
            m_zeroblock_on_serverexceptions = StrToBool(pszZeroExceptions);
            if (m_zeroblock_on_serverexceptions == -1) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockOnServerException \"%s\", true/false expected.",
                         pszZeroExceptions);
                ret = CE_Failure;
            }
        }
    }

    if (ret == CE_None) {
        const char *max_conn = CPLGetXMLValue(config, "MaxConnections", "");
        if (max_conn[0] != '\0') {
            m_http_max_conn = atoi(max_conn);
        } else {
            m_http_max_conn = 2;
        }
    }
    if (ret == CE_None) {
        const char *timeout = CPLGetXMLValue(config, "Timeout", "");
        if (timeout[0] != '\0') {
            m_http_timeout = atoi(timeout);
        } else {
            m_http_timeout = 300;
        }
    }
    if (ret == CE_None) {
        const char *offline_mode = CPLGetXMLValue(config, "OfflineMode", "");
        if (offline_mode[0] != '\0') {
            const int offline_mode_bool = StrToBool(offline_mode);
            if (offline_mode_bool == -1) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of OfflineMode, true / false expected.");
                ret = CE_Failure;
            } else {
                m_offline_mode = offline_mode_bool;
            }
        } else {
            m_offline_mode = 0;
        }
    }

    if (ret == CE_None) {
        const char *advise_read = CPLGetXMLValue(config, "AdviseRead", "");
        if (advise_read[0] != '\0') {
            const int advise_read_bool = StrToBool(advise_read);
            if (advise_read_bool == -1) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of AdviseRead, true / false expected.");
                ret = CE_Failure;
            } else {
                m_use_advise_read = advise_read_bool;
            }
        } else {
            m_use_advise_read = 0;
        }
    }

    if (ret == CE_None) {
        const char *verify_advise_read = CPLGetXMLValue(config, "VerifyAdviseRead", "");
        if (m_use_advise_read) {
            if (verify_advise_read[0] != '\0') {
                const int verify_advise_read_bool = StrToBool(verify_advise_read);
                if (verify_advise_read_bool == -1) {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of VerifyAdviseRead, true / false expected.");
                    ret = CE_Failure;
                } else {
                    m_verify_advise_read = verify_advise_read_bool;
                }
            } else {
                m_verify_advise_read = 1;
            }
        }
    }

    // Let the local configuration override the minidriver supplied projection

    if (ret == CE_None) {
        const char *proj = CPLGetXMLValue(config, "Projection", "");
        if (proj[0] != '\0') {
            m_projection = ProjToWKT(proj);
            if (m_projection.size() == 0) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad projection specified.");
                ret = CE_Failure;
            }
        }
    }

    // Same for Min, Max and NoData, defined per band or per dataset
    // If they are set as null strings, they clear the server declared values
    if (ret == CE_None) {
        // Data values are attributes, they include NoData Min and Max
        // TODO: document those options
        if (0!=CPLGetXMLNode(config,"DataValues")) {
            const char *nodata=CPLGetXMLValue(config,"DataValues.NoData",NULL);
            if (nodata!=NULL) WMSSetNoDataValue(nodata);
            const char *min=CPLGetXMLValue(config,"DataValues.min",NULL);
            if (min!=NULL) WMSSetMinValue(min);
            const char *max=CPLGetXMLValue(config,"DataValues.max",NULL);
            if (max!=NULL) WMSSetMaxValue(max);
        }
    }

    if (ret == CE_None) {
        CPLXMLNode *cache_node = CPLGetXMLNode(config, "Cache");
        if (cache_node != NULL) {
            m_cache = new GDALWMSCache();
            if (m_cache->Initialize(cache_node) != CE_None) {
                delete m_cache;
                m_cache = NULL;
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize cache.");
                ret = CE_Failure;
            }
        }
    }
    
    if (ret == CE_None) {
    	const int v = StrToBool(CPLGetXMLValue(config, "UnsafeSSL", "false"));
    	if (v == -1) {
	    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of UnsafeSSL: true or false expected.");
	    ret = CE_Failure;
	} else {
	    m_unsafeSsl = v;
	}
    }

    if (ret == CE_None) {
        /* If we dont have projection already set ask mini-driver. */
        if (!m_projection.size()) {
            const char *proj = m_mini_driver->GetProjectionInWKT();
            if (proj != NULL) {
                m_projection = proj;
            }
        }
    }

    return ret;
}
コード例 #4
0
CPLErr GDALWMSRasterBand::ReadBlockFromFile(int x, int y, const char *file_name, int to_buffer_band, void *buffer, int advise_read) {
    CPLErr ret = CE_None;
    GDALDataset *ds = 0;
    GByte *color_table = NULL;
    int i;

    //CPLDebug("WMS", "ReadBlockFromFile: to_buffer_band=%d, (x,y)=(%d, %d)", to_buffer_band, x, y);

    /* expected size */
    const int esx = MIN(MAX(0, (x + 1) * nBlockXSize), nRasterXSize) - MIN(MAX(0, x * nBlockXSize), nRasterXSize);
    const int esy = MIN(MAX(0, (y + 1) * nBlockYSize), nRasterYSize) - MIN(MAX(0, y * nBlockYSize), nRasterYSize);
    ds = reinterpret_cast<GDALDataset*>(GDALOpen(file_name, GA_ReadOnly));
    if (ds != NULL) {
        int sx = ds->GetRasterXSize();
        int sy = ds->GetRasterYSize();
        bool accepted_as_no_alpha = false;  // if the request is for 4 bands but the wms returns 3  
        /* Allow bigger than expected so pre-tiled constant size images work on corners */
        if ((sx > nBlockXSize) || (sy > nBlockYSize) || (sx < esx) || (sy < esy)) {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect size %d x %d of downloaded block, expected %d x %d, max %d x %d.",
                sx, sy, esx, esy, nBlockXSize, nBlockYSize);
            ret = CE_Failure;
        }
        if (ret == CE_None) {
            int nDSRasterCount = ds->GetRasterCount();
            if (nDSRasterCount != m_parent_dataset->nBands) {
                /* Maybe its an image with color table */
                bool accepted_as_ct = false;
                if ((eDataType == GDT_Byte) && (ds->GetRasterCount() == 1)) {
                    GDALRasterBand *rb = ds->GetRasterBand(1);
                    if (rb->GetRasterDataType() == GDT_Byte) {
                        GDALColorTable *ct = rb->GetColorTable();
                        if (ct != NULL) {
                            accepted_as_ct = true;
                            if (!advise_read) {
                                color_table = new GByte[256 * 4];
                                const int count = MIN(256, ct->GetColorEntryCount());
                                for (i = 0; i < count; ++i) {
                                    GDALColorEntry ce;
                                    ct->GetColorEntryAsRGB(i, &ce);
                                    color_table[i] = static_cast<GByte>(ce.c1);
                                    color_table[i + 256] = static_cast<GByte>(ce.c2);
                                    color_table[i + 512] = static_cast<GByte>(ce.c3);
                                    color_table[i + 768] = static_cast<GByte>(ce.c4);
                                }
                                for (i = count; i < 256; ++i) {
                                    color_table[i] = 0;
                                    color_table[i + 256] = 0;
                                    color_table[i + 512] = 0;
                                    color_table[i + 768] = 0;
                                }
                            }
                        }
                    }
                }

                if (nDSRasterCount == 4 && m_parent_dataset->nBands == 3)
                {
                    /* metacarta TMS service sometimes return a 4 band PNG instead of the expected 3 band... */
                }
                else if (!accepted_as_ct) {
                   if (ds->GetRasterCount()==3 && m_parent_dataset->nBands == 4 && (eDataType == GDT_Byte))
                   { // WMS returned a file with no alpha so we will fill the alpha band with "opaque" 
                      accepted_as_no_alpha = true;
                   }
                   else
                   {
                      CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.",
                         nDSRasterCount, m_parent_dataset->nBands);
                      ret = CE_Failure;
                   }
                }
            }
        }
        if (!advise_read) {
            for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) {
                if (ret == CE_None) {
                    void *p = NULL;
                    GDALRasterBlock *b = NULL;
                    if ((buffer != NULL) && (ib == to_buffer_band)) {
                        p = buffer;
                    } else {
                        GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib));
                        if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview));
                        if (!band->IsBlockInCache(x, y)) {
                            b = band->GetLockedBlockRef(x, y, true);
                            if (b != NULL) {
                                p = b->GetDataRef();
                                if (p == NULL) {
                                  CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: GetDataRef returned NULL.");
                                  ret = CE_Failure;
                                }
                            }
                        }
                        else
                        {
                            //CPLDebug("WMS", "Band %d, block (x,y)=(%d, %d) already in cache", band->GetBand(), x, y);
                        }
                    }
                    if (p != NULL) {
                        int pixel_space = GDALGetDataTypeSize(eDataType) / 8;
                        int line_space = pixel_space * nBlockXSize;
                        if (color_table == NULL) {
                            if( ib <= ds->GetRasterCount()) {
                               if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, &ib, pixel_space, line_space, 0) != CE_None) {
                                   CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block.");
                                   ret = CE_Failure;
                               }
                            }
                            else
                            {  // parent expects 4 bands but file only has 3 so generate a all "opaque" 4th band
                               if (accepted_as_no_alpha)
                               {
                                  // the file had 3 bands and we are reading band 4 (Alpha) so fill with 255 (no alpha)
                                  GByte *byte_buffer = reinterpret_cast<GByte *>(p);
                                  for (int y = 0; y < sy; ++y) {
                                     for (int x = 0; x < sx; ++x) {
                                        const int offset = x + y * line_space;
                                        byte_buffer[offset] = 255;  // fill with opaque
                                     }
                                  }
                               }
                               else
                               {  // we should never get here because this case was caught above
                                  CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.",
                                     ds->GetRasterCount(), m_parent_dataset->nBands);
                                  ret = CE_Failure;
                               }     
                            }
                        } else if (ib <= 4) {
                            if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, NULL, pixel_space, line_space, 0) != CE_None) {
                                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block.");
                                ret = CE_Failure;
                            }
                            if (ret == CE_None) {
                                GByte *band_color_table = color_table + 256 * (ib - 1);
                                GByte *byte_buffer = reinterpret_cast<GByte *>(p);
                                for (int y = 0; y < sy; ++y) {
                                    for (int x = 0; x < sx; ++x) {
                                        const int offset = x + y * line_space;
                                        byte_buffer[offset] = band_color_table[byte_buffer[offset]];
                                    }
                                }
                            }
                        } else {
                            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Color table supports at most 4 components.");
                            ret = CE_Failure;
                        }
                    }
                    if (b != NULL) {
                        b->DropLock();
                    }
                }
            }
        }
        GDALClose(ds);
    } else {
        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Unable to open downloaded block.");
        ret = CE_Failure;
    }

    if (color_table != NULL) {
        delete[] color_table;
    }

    return ret;
}
コード例 #5
0
ファイル: dataset.cpp プロジェクト: Chaduke/bah.mod
CPLErr GDALWMSDataset::Initialize(CPLXMLNode *config) {
    CPLErr ret = CE_None;

    if (ret == CE_None) {
        const char *max_conn = CPLGetXMLValue(config, "MaxConnections", "");
        if (max_conn[0] != '\0') {
            m_http_max_conn = atoi(max_conn);
        } else {
            m_http_max_conn = 2;
        }
    }
    if (ret == CE_None) {
        const char *timeout = CPLGetXMLValue(config, "Timeout", "");
        if (timeout[0] != '\0') {
            m_http_timeout = atoi(timeout);
        } else {
            m_http_timeout = 300;
        }
    }
    if (ret == CE_None) {
        const char *offline_mode = CPLGetXMLValue(config, "OfflineMode", "");
        if (offline_mode[0] != '\0') {
            const int offline_mode_bool = StrToBool(offline_mode);
            if (offline_mode_bool == -1) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of OfflineMode, true / false expected.");
                ret = CE_Failure;
            } else {
                m_offline_mode = offline_mode_bool;
            }
        } else {
            m_offline_mode = 0;
        }
    }
    if (ret == CE_None) {
        const char *advise_read = CPLGetXMLValue(config, "AdviseRead", "");
        if (advise_read[0] != '\0') {
            const int advise_read_bool = StrToBool(advise_read);
            if (advise_read_bool == -1) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of AdviseRead, true / false expected.");
                ret = CE_Failure;
            } else {
                m_use_advise_read = advise_read_bool;
            }
        } else {
            m_use_advise_read = 0;
        }
    }
    if (ret == CE_None) {
        const char *verify_advise_read = CPLGetXMLValue(config, "VerifyAdviseRead", "");
        if (m_use_advise_read) {
            if (verify_advise_read[0] != '\0') {
                const int verify_advise_read_bool = StrToBool(verify_advise_read);
                if (verify_advise_read_bool == -1) {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of VerifyAdviseRead, true / false expected.");
                    ret = CE_Failure;
                } else {
                    m_verify_advise_read = verify_advise_read_bool;
                }
            } else {
                m_verify_advise_read = 1;
            }
        }
    }
    if (ret == CE_None) {
        const char *block_size_x = CPLGetXMLValue(config, "BlockSizeX", "1024");
        const char *block_size_y = CPLGetXMLValue(config, "BlockSizeY", "1024");
        m_block_size_x = atoi(block_size_x);
        m_block_size_y = atoi(block_size_y);
        if (m_block_size_x <= 0 || m_block_size_y <= 0)
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "GDALWMS: Invalid value in BlockSizeX or BlockSizeY" );
            ret = CE_Failure;
        }
    }
    if (ret == CE_None)
    {
        const char *data_type = CPLGetXMLValue(config, "DataType", "Byte");
        m_data_type = GDALGetDataTypeByName( data_type );
        if ( m_data_type == GDT_Unknown || m_data_type >= GDT_TypeCount )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "GDALWMS: Invalid value in DataType. Data type \"%s\" is not supported.", data_type );
            ret = CE_Failure;
        }
    }
    if (ret == CE_None) {
    	const int clamp_requests_bool = StrToBool(CPLGetXMLValue(config, "ClampRequests", "true"));
    	if (clamp_requests_bool == -1) {
	    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ClampRequests, true / false expected.");
	    ret = CE_Failure;
	} else {
	    m_clamp_requests = clamp_requests_bool;
	}
    }
    if (ret == CE_None) {
        CPLXMLNode *data_window_node = CPLGetXMLNode(config, "DataWindow");
        if (data_window_node == NULL) {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow missing.");
            ret = CE_Failure;
        } else {
            const char *overview_count = CPLGetXMLValue(config, "OverviewCount", "");
            const char *ulx = CPLGetXMLValue(data_window_node, "UpperLeftX", "-180.0");
            const char *uly = CPLGetXMLValue(data_window_node, "UpperLeftY", "90.0");
            const char *lrx = CPLGetXMLValue(data_window_node, "LowerRightX", "180.0");
            const char *lry = CPLGetXMLValue(data_window_node, "LowerRightY", "-90.0");
            const char *sx = CPLGetXMLValue(data_window_node, "SizeX", "");
            const char *sy = CPLGetXMLValue(data_window_node, "SizeY", "");
            const char *tx = CPLGetXMLValue(data_window_node, "TileX", "0");
            const char *ty = CPLGetXMLValue(data_window_node, "TileY", "0");
            const char *tlevel = CPLGetXMLValue(data_window_node, "TileLevel", "");
            const char *str_tile_count_x = CPLGetXMLValue(data_window_node, "TileCountX", "1");
            const char *str_tile_count_y = CPLGetXMLValue(data_window_node, "TileCountY", "1");
            const char *y_origin = CPLGetXMLValue(data_window_node, "YOrigin", "default");

            if (ret == CE_None) {
                if ((ulx[0] != '\0') && (uly[0] != '\0') && (lrx[0] != '\0') && (lry[0] != '\0')) {
                    m_data_window.m_x0 = atof(ulx);
                    m_data_window.m_y0 = atof(uly);
                    m_data_window.m_x1 = atof(lrx);
                    m_data_window.m_y1 = atof(lry);
                } else {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: UpperLeftX, UpperLeftY, LowerRightX, LowerRightY.");
                    ret = CE_Failure;
                }
            }
            if (ret == CE_None) {
                if (tlevel[0] != '\0') {
                    m_data_window.m_tlevel = atoi(tlevel);
                } else {
                    m_data_window.m_tlevel = 0;
                }
            }
            if (ret == CE_None) {
                if ((sx[0] != '\0') && (sy[0] != '\0')) {
                    m_data_window.m_sx = atoi(sx);
                    m_data_window.m_sy = atoi(sy);
                } else if ((tlevel[0] != '\0') && (str_tile_count_x[0] != '\0') && (str_tile_count_y[0] != '\0')) {
                    int tile_count_x = atoi(str_tile_count_x);
                    int tile_count_y = atoi(str_tile_count_y);
                    m_data_window.m_sx = tile_count_x * m_block_size_x * (1 << m_data_window.m_tlevel);
                    m_data_window.m_sy = tile_count_y * m_block_size_y * (1 << m_data_window.m_tlevel);
                } else {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: SizeX, SizeY.");
                    ret = CE_Failure;
                }
            }
            if (ret == CE_None) {
                if ((tx[0] != '\0') && (ty[0] != '\0')) {
                    m_data_window.m_tx = atoi(tx);
                    m_data_window.m_ty = atoi(ty);
                } else {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: TileX, TileY.");
                    ret = CE_Failure;
                }
            }
            if (ret == CE_None) {
                if (overview_count[0] != '\0') {
                    m_overview_count = atoi(overview_count);
                } else if (tlevel[0] != '\0') {
                    m_overview_count = m_data_window.m_tlevel;
                } else {
                    const int min_overview_size = MAX(32, MIN(m_block_size_x, m_block_size_y));
                    double a = log(static_cast<double>(MIN(m_data_window.m_sx, m_data_window.m_sy))) / log(2.0) 
                                - log(static_cast<double>(min_overview_size)) / log(2.0);
                    m_overview_count = MAX(0, MIN(static_cast<int>(ceil(a)), 32));
                }
            }
            if (ret == CE_None) {
                CPLString y_origin_str = y_origin;
                if (y_origin_str == "top") {
                    m_data_window.m_y_origin = GDALWMSDataWindow::TOP;
                } else if (y_origin_str == "bottom") {
                    m_data_window.m_y_origin = GDALWMSDataWindow::BOTTOM;
                } else if (y_origin_str == "default") {
                    m_data_window.m_y_origin = GDALWMSDataWindow::DEFAULT;
                } else {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow YOrigin must be set to " 
                                "one of 'default', 'top', or 'bottom', not '%s'.", y_origin_str.c_str());
                    ret = CE_Failure;
                }
            }
        }
    }
    if (ret == CE_None) {
        const char *proj = CPLGetXMLValue(config, "Projection", "");
        if (proj[0] != '\0') {
            m_projection = ProjToWKT(proj);
            if (m_projection.size() == 0) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad projection specified.");
                ret = CE_Failure;
            }
        }
    }
    
    const char *bands_count = CPLGetXMLValue(config, "BandsCount", "3");
    int nBandCount = atoi(bands_count);
    
    if (ret == CE_None) {
        CPLXMLNode *cache_node = CPLGetXMLNode(config, "Cache");
        if (cache_node != NULL) {
            m_cache = new GDALWMSCache();
            if (m_cache->Initialize(cache_node) != CE_None) {
                delete m_cache;
                m_cache = NULL;
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize cache.");
                ret = CE_Failure;
            }
        }
    }
    if (ret == CE_None) {
        CPLXMLNode *service_node = CPLGetXMLNode(config, "Service");
        if (service_node != NULL) {
            const char *service_name = CPLGetXMLValue(service_node, "name", "");
            if (service_name[0] != '\0') {
                GDALWMSMiniDriverManager *const mdm = GetGDALWMSMiniDriverManager();
                GDALWMSMiniDriverFactory *const mdf = mdm->Find(CPLString(service_name));
                if (mdf != NULL) {
                    m_mini_driver = mdf->New();
                    m_mini_driver->m_parent_dataset = this;
                    if (m_mini_driver->Initialize(service_node) == CE_None) {
                        m_mini_driver_caps.m_capabilities_version = -1;
                        m_mini_driver->GetCapabilities(&m_mini_driver_caps);
                        if (m_mini_driver_caps.m_capabilities_version == -1) {
                            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Internal error, mini-driver capabilities version not set.");
                            ret = CE_Failure;
                        }
                    } else {
                        delete m_mini_driver;
                        m_mini_driver = NULL;

                        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize minidriver.");
                        ret = CE_Failure;
                    }
                } else {
                    CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No mini-driver registered for '%s'.", service_name);
                    ret = CE_Failure;
                }
            } else {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
                ret = CE_Failure;
            }
        } else {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
            ret = CE_Failure;
        }
    }
    if (ret == CE_None) {
        nRasterXSize = m_data_window.m_sx;
        nRasterYSize = m_data_window.m_sy;

        if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) ||
            !GDALCheckBandCount(nBandCount, TRUE))
        {
            return CE_Failure;
        }

        for (int i = 0; i < nBandCount; ++i) {
            GDALWMSRasterBand *band = new GDALWMSRasterBand(this, i, 1.0);
            SetBand(i + 1, band);
            double scale = 0.5;
            for (int j = 0; j < m_overview_count; ++j) {
                band->AddOverview(scale);
                scale *= 0.5;
            }
        }
    }

    if (ret == CE_None) {
        /* If we dont have projection already set ask mini-driver. */
        if (!m_projection.size()) {
            const char *proj = m_mini_driver->GetProjectionInWKT();
            if (proj != NULL) {
                m_projection = proj;
            }
        }
    }

    return ret;
}