/// filter all posterities by status filter and replace current children
/// Do not check whether the cloud data is ready because directory mode is displayed by default
NodePtrs DesktopNode::filterPosterity(bool recursive)
{
    NodePtrs result;

    // do not rescan
    if (ContainerNode::filterPosterity(result, false, statusFilter(), recursive) > 0)
    {
        return result;
    }

    static NodePtrs empty_result;
    return empty_result;
}
vector<long> DividedHighwayMerger::_findOtherWays(boost::shared_ptr<const hoot::Way> baseWay)
{
  shared_ptr<OneWayFilter> owFilter(new OneWayFilter());
  shared_ptr<StatusFilter> statusFilter(new StatusFilter(baseWay->getStatus()));

  shared_ptr<WayBufferFilter> distanceFilter(new WayBufferFilter(_map, baseWay,
    _maxSeparation, _matchPercent));
  shared_ptr<ParallelWayFilter> parallelFilter(new ParallelWayFilter(_map, baseWay));
  shared_ptr<WayDirectionFilter> directionFilter(new WayDirectionFilter(_map, baseWay, false));
  WayFilterChain filter;

  filter.addFilter(owFilter);
  filter.addFilter(statusFilter);
  filter.addFilter(distanceFilter);
  filter.addFilter(parallelFilter);
  filter.addFilter(directionFilter);

  return _map->filterWays(filter);
}
void DesktopNode::upload(bool exec_now)
{
    if (id().empty())
    {
        // Cannot upload until the id of root is retrieved
        NodeLoadingFinishedArgs upload_done_args;
        upload_done_args.succeeded = false;
        upload_done_args.type = NodeLoadingFinishedArgs::NODE_LOADING_TYPE_UPLOAD;
        upload_done_args.reason = "Root node is missing";
        upload_done_args.current_node_path = absolutePath();
        FireEvent(EventNodeLoadingFinished, upload_done_args);
    }

    RetrieveChildrenResult ret = RETRIEVE_FAILED;
    NodePtrs waiting_children = children(ret, false, statusFilter());
    if (ret == RETRIEVE_DONE)
    {
        for (size_t i = 0; i < waiting_children.size(); i++)
        {
            NodePtr child = waiting_children[i];
            NodeType child_type = child->type();
            if (child_type != NODE_TYPE_FILE_LOCAL_DOCUMENT &&
                child_type != NODE_TYPE_FILE_LOCAL_BOOK_STORE_BOOK)
            {
                child->upload(exec_now);
            }
            else
            {
                if (child->selected() && child_type == NODE_TYPE_FILE_LOCAL_DOCUMENT)
                {
                    child->upload(exec_now);
                }
            }
        }
    }

    if (!exec_now)
    {
        MiCloudService* cloud_service = XiaoMiServiceFactory::GetMiCloudService();
        cloud_service->flushPendingTasks();
    }
    return;
}
vector<long> DividedHighwayMerger::_findCenterWays(shared_ptr<const Way> w1,
                                                   shared_ptr<const Way> w2)
{
  shared_ptr<OneWayFilter> owFilter(new OneWayFilter(false));

  Status s;
  if (w1->getStatus() == Status::Unknown1)
  {
    s = Status::Unknown2;
  }
  else
  {
    s = Status::Unknown1;
  }

  shared_ptr<StatusFilter> statusFilter(new StatusFilter(s));
  shared_ptr<ParallelWayFilter> parallelFilter(new ParallelWayFilter(_map, w1));

  ElementConverter ec(_map);
  shared_ptr<LineString> ls2 = ec.convertToLineString(w2);
  if (DirectionFinder::isSimilarDirection(_map, w1, w2) == false)
  {
    ls2.reset(dynamic_cast<LineString*>(ls2->reverse()));
  }

  // calculate the center line of two ways.
  shared_ptr<LineString> center = LineStringAverager::average(
    ec.convertToLineString(w1), ls2);
  shared_ptr<WayBufferFilter> distanceFilter(new WayBufferFilter(_map, center, 0.0,
    (w1->getCircularError() + w2->getCircularError()) / 2.0, _matchPercent));
  WayFilterChain filter;

  filter.addFilter(owFilter);
  filter.addFilter(statusFilter);
  filter.addFilter(parallelFilter);
  filter.addFilter(distanceFilter);

  return _map->filterWays(filter);
}