zoukankan      html  css  js  c++  java
  • 开发 Windows 8 Bing地图应用(5)

    TripOptimizerImpl::OptimizeTripAsync方法调用TripOptimizer::OptimizeTrip方法作为异步操作的一部分,TripOptimizer::OptimizeTrip方法调用TripOptimizer::CreateGraph创建出行路线的图像,每个位置由一个节点表示,并且每个节点对由棱边相连,一个节点包含了一个位置的名称,经纬度等信息,而棱边包含两点间的距离,相关代码如下。

    //创建表示出游地形的图像

    void TripOptimizerImpl::CreateGraph(

    const vector<wstring>& waypoints,

    vector<shared_ptr<Node>>& nodes,

    vector<shared_ptr<Edge>>& edges)

    {

    // 创建一个节点对象,每个对象包含的字符串代表一个位置

    for_each(begin(waypoints), end(waypoints), [&nodes](const wstring& waypoint) {

    // 对集合添加节点对象

    nodes.push_back(make_shared<Node>(waypoint));

    });

    //

    // 创建棱边,形成节点全连接的图像

    //

    for (auto iter = begin(nodes); iter != end(nodes); ++iter) {

    auto node1 = *iter;

    for_each(iter + 1, end(nodes), [this, &node1, &edges](shared_ptr<Node> node2) {

    //创建棱边对

    edges.push_back(make_shared<Edge>(node1, node2));

    });

    }

    }

    TripOptimizerImpl::OptimizeTrip方法在3个阶段执行线路优化操作。第一个阶段中,这个方法获取Bing Maps传来的位置信息数据;第二个阶段中,这个方法获取路线中每两点间,可能的路由信息;第三阶段中,这个方法执行线路优化算法。任务的Continuation(Continuation意为在每件事完成之后还要做的事)使得任务完成后可接着运行一个或多个任务。但注意,由于Continuation在后台的运行,需要存储在这些任务中共享的变量,从而使任务可以稍后就能访问它们。TripOptimizerImpl类定义了OptimizeTripParams结构体,这个结构体保留着对TripOptimizer::OptimizeTripAsync方法,和任务间共享变量的输入,有关代码如下。

    // 包含出行优化整个过程中,所使用的变量

    // 创建这个结构体为的是,使通用参数轻松在连续的任务间传递。

    struct OptimizeTripParams

    {

    //

    // 对OptimizeTripAsync的输入

    std::vector<std::wstring> Waypoints;

    std::wstring TravelMode;

    std::wstring Optimize;

    std::wstring BingMapsKey;

    double Alpha;

    double Beta;

    double Rho;

    unsigned long Iterations;

    bool Parallel;

    //

    // 定时器变量

    // 以下时间作为进度信息发送出去

    // 总体时间

    ULONGLONG TotalTime;

    // 总体时间和所花费的HTTP请求时间

    ULONGLONG HttpTime;

    // 执行优化算法花费的时间

    ULONGLONG SimulationTime;

    // 位置图像

    // 节点对象的集合,每个位置一个节点

    std::vector<std::shared_ptr<AntSystem::Node>> Nodes;

    // 棱边对象的集合,有(n * (n - 1) / 2)个棱边,其中n代表节点个数

    std::vector<std::shared_ptr<AntSystem::Edge>> Edges;

    // 对目前批处理挂起的HTTP请求数量

    long RequestsPending;

    // 保留在线路优化过程的第一阶段未解决的位置

    Concurrency::concurrent_vector<std::shared_ptr<AntSystem::Node>> UnresolvedLocations;

    };

    通过使用一个std::shared_ptr对象,TripOptimizer::OptimizeTripAsync方法创建一个OptimizeTripParams结构体,并将其传递任务链中的每个Continuation,代码如下。

    auto params = make_shared<OptimizeTripParams>();

    for_each(begin(waypoints), end(waypoints), [params](String^ waypoint) {

    params->Waypoints.push_back(waypoint->Data());

    });

    params->TravelMode = wstring(travelMode->Data());

    params->Optimize = wstring(optimize->Data());

    params->BingMapsKey = UriEncode(bingMapsKey->Data());

    params->Alpha = alpha;

    params->Beta = beta;

    params->Rho = rho;

    params->Iterations = iterations;

    params->Parallel = parallel;

    5)HTTP相关处理。C++组件定义了HttpRequest类处理HTTP请求,本类使用IXMLHTTPRequest2接口处理HTTP请求。IXMLHTTPRequest2接口只支持异步操作,为使调用函数更容易使用这些异步的操作,HttpRequest::StartDownload方法返回一个Concurrency::task<std::tuple<HRESULT, std::wstring>>对象,这个对象将状态码和HTTP响应作为一个字符串包含其中。

    由于IXMLHTTPRequest2只支持异步操作,所以从HTTP服务器请求数据时,必须提供一个IXMLHTTPRequest2Callback对象。HttpRequest.cpp文件定义了HttpRequestCallback类,此类是从IXMLHTTPRequest2Callback继承来的,并实现其方法。

    Concurrency::task_completion_event类是很重要的一部分,在其他异步任务完成时,它使得HttpReader类创建一个任务,这个类在将任务对象,还有通过回调函数完成的异步操作,组合在一起的时候很有用。当下载操作完成时,HttpRequestCallback::OnResponseReceived方法设置结束事件,代码如下。

    m_completionEvent.set(make_tuple<HRESULT, wstring>(S_OK, ss.str()));

    相应地,HttpRequestCallback::OnError方法在错误发生时设置结束事件,这种情况下,任务的输出结果会是错误代码和空字符串,代码如下。

    m_completionEvent.set(make_tuple<HRESULT, wstring>(hrError, wstring()));

    HttpRequestCallback类同样在下载任务取消时,设置结束事件,这种情况下,任务的输出结果会是S_OK和空字符串,代码如下。

    m_completionEvent.set(make_tuple<HRESULT, wstring>(S_OK, wstring()));

    HttpRequest::StartDownload函数打开异步请求,创建一个HttpRequestCallback对象,之后其创建一个task对象,在HttpRequestCallback对象的任务结束事件完成时就结束,代码如下。

    // 开始指定URI的下载

    task<tuple<HRESULT, wstring>> HttpRequest::StartDownload(

    const wstring& method,

    const wstring& uri,

    cancellation_token cancellationToken)

    {

    // 创建一个IXMLHTTPRequest2对象

    IXMLHTTPRequest2* xhr;

    HRESULT hr = CoCreateInstance(

    __uuidof(FreeThreadedXMLHTTP60),

    nullptr,

    CLSCTX_INPROC,

    __uuidof(IXMLHTTPRequest2),

    reinterpret_cast<void**>(&xhr));

    SUCCEEDED(hr) ? 0 : throw hr;

    // 创建回调函数

    auto callback = new HttpRequestCallback(xhr, cancellationToken);

    callback->AddRef();

    // 打开并发送请求

    hr = xhr->Open(method.c_str(), uri.c_str(), callback, nullptr, nullptr, nullptr, nullptr);

    SUCCEEDED(hr) ? 0 : throw hr;

    hr = xhr->Send(nullptr, 0);

    SUCCEEDED(hr) ? 0 : throw hr;

    // 操作结束时返回一个完成的任务

    task<tuple<HRESULT, wstring>> result(callback->m_completionEvent);

    return result.then([callback](task<tuple<HRESULT, wstring>> previousTask) {

    callback->Release();

    return previousTask;

    });

    }

  • 相关阅读:
    自定义一个运行时异常
    对象的知识点正确解释
    decimal模块
    B+树
    Web框架系列之Tornado
    初识git
    Mysql表的操作
    MySQl创建用户和授权
    MySql安装和基本管理
    为什么用Mysql?
  • 原文地址:https://www.cnblogs.com/finehappy/p/2858185.html
Copyright © 2011-2022 走看看