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); }
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()); } } }
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; }