Example #1
0
void PlacesPoiMerger::apply(const OsmMapPtr& map, vector< pair<ElementId, ElementId> >& replaced)
  const
{
  set<ElementId> pois = getImpactedElementIds();

  // find the node with the best circular error.
  ElementId bestEid;
  Meters bestAcc = numeric_limits<Meters>::max();
  for (set<ElementId>::iterator it = pois.begin(); it != pois.end(); ++it)
  {
    ElementId eid = *it;

    const ConstNodePtr& n = map->getNode(eid.getId());
    if (n->getCircularError() < bestAcc || (n->getCircularError() == bestAcc && n->getStatus() == Status::Unknown1))
    {
      bestAcc = n->getCircularError();
      bestEid = eid;
    }
  }

  // the best circular error node becomes the geometry for the merger.
  const NodePtr& n = map->getNode(bestEid.getId());

  // grab the tags out of the best node.
  Tags tags = n->getTags();
  for (set<ElementId>::iterator it = pois.begin(); it != pois.end(); ++it)
  {
    ElementId eid = *it;

    // if this isn't the best node
    if (eid != bestEid)
    {
      // record that this ndoe is getting replaced.
      replaced.push_back(pair<ElementId, ElementId>(eid, bestEid));

      // use the default tag merging mechanism
      tags = _merger->mergeTags(tags, map->getNode(eid.getId())->getTags(), ElementType::Node);

      // if the POI has no parents, then simply remove it.
      if (map->getIndex().getParents(eid).size() == 0)
      {
        map->removeElement(eid);
      }
      // if the POI has parents, then remove all tags on the node.
      else
      {
        map->getNode(eid.getId())->getTags().clear();
      }
    }
  }

  n->setTags(tags);
  n->setStatus(Status::Conflated);
}
Example #2
0
void WayMergeManipulation::applyManipulation(OsmMapPtr map,
  set<ElementId> &impactedElements, set<ElementId> &newElements) const
{
  OsmMapPtr result = map;

  // insert the impacted ways
  impactedElements = getImpactedElementIds(map);
  impactedElements.erase(ElementId::way(_left));
  impactedElements.erase(ElementId::way(_right));

  // remove any ways that spanned the left & right
  _removeSpans(result, impactedElements);

  WayPtr left = result->getWay(_left);
  WayPtr right = result->getWay(_right);

  Meters minSplitSize = _minSplitSize;
  minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(left)->getLength() * .7);
  minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(right)->getLength() * .7);

  // split left into its maximal nearest sublines
  MaximalNearestSubline mns1(map, left, right, minSplitSize,
    left->getCircularError() + right->getCircularError());
  int mnsLeftIndex;
  vector< WayPtr > splitsLeft = mns1.splitWay(result, mnsLeftIndex);
  assert(splitsLeft.size() != 0);
  WayPtr mnsLeft = splitsLeft[mnsLeftIndex];

  // split right into its maximal nearest sublines
  MaximalNearestSubline mns2(map, right, mnsLeft, minSplitSize,
    left->getCircularError() + right->getCircularError());
  int mnsRightIndex;
  vector< WayPtr > splitsRight = mns2.splitWay(result, mnsRightIndex);
  assert(splitsRight.size() != 0);
  WayPtr mnsRight = splitsRight[mnsRightIndex];

  for (size_t i = 0; i < splitsLeft.size(); i++)
  {
    if ((int)i != mnsLeftIndex)
    {
      newElements.insert(ElementId::way(splitsLeft[i]->getId()));
    }
    result->addWay(splitsLeft[i]);
  }

  for (size_t i = 0; i < splitsRight.size(); i++)
  {
    if ((int)i != mnsRightIndex)
    {
      newElements.insert(ElementId::way(splitsRight[i]->getId()));
    }
    result->addWay(splitsRight[i]);
  }

  // average the two MNSs
  WayPtr w = WayAverager::average(map, mnsRight, mnsLeft);
  w->setStatus(Status::Conflated);

  RemoveWayOp::removeWay(result, _left);
  RemoveWayOp::removeWay(result, _right);

  result->addWay(w);

  // insert the new merged way
  newElements.insert(ElementId::way(w->getId()));

  for (set<ElementId>::iterator it = impactedElements.begin(); it != impactedElements.end(); ++it)
  {
    if (result->containsElement(*it) == false)
    {
      LOG_ERROR("" << "Internal error: bad way " << it->toString());
    }
  }
}
Example #3
0
void WayMergeManipulation::_splitWays(OsmMapPtr map, WayPtr& left,
  WayPtr& right) const
{
  OsmMapPtr result = map;

  // insert the impacted ways
  set<ElementId> impactedElements = getImpactedElementIds(map);
  impactedElements.erase(ElementId::way(_left));
  impactedElements.erase(ElementId::way(_right));

  // remove any ways that spanned the left & right
  _removeSpans(result, impactedElements);

  left = result->getWay(_left);
  right = result->getWay(_right);

  Meters minSplitSize = _minSplitSize;
  minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(left)->getLength() * .7);
  minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(right)->getLength() * .7);

  // split left into its maximal nearest sublines
  MaximalNearestSubline mns1(result, left, right, minSplitSize,
    left->getCircularError() + right->getCircularError());
  int mnsLeftIndex;
  vector< WayPtr > splitsLeft = mns1.splitWay(result, mnsLeftIndex);
  assert(splitsLeft.size() != 0);
  WayPtr mnsLeft = splitsLeft[mnsLeftIndex];

  // split right into its maximal nearest sublines
  MaximalNearestSubline mns2(result, right, mnsLeft, minSplitSize,
    left->getCircularError() + right->getCircularError());
  int mnsRightIndex;
  vector< WayPtr > splitsRight = mns2.splitWay(result, mnsRightIndex);
  assert(splitsRight.size() != 0);
  WayPtr mnsRight = splitsRight[mnsRightIndex];

  for (size_t i = 0; i < splitsLeft.size(); i++)
  {
    if (splitsLeft[i] != left)
    {
      result->addWay(splitsLeft[i]);
    }
  }

  for (size_t i = 0; i < splitsRight.size(); i++)
  {
    if (splitsRight[i] != right)
    {
      result->addWay(splitsRight[i]);
    }
  }

  RemoveWayOp::removeWay(result, _left);
  RemoveWayOp::removeWay(result, _right);

  for (set<ElementId>::iterator it = impactedElements.begin(); it != impactedElements.end(); ++it)
  {
    if (result->containsElement(*it) == false)
    {
      LOG_ERROR("" << "Internal error: bad way " << it->toString());
    }
  }
  left = mnsLeft;
  right = mnsRight;
}