WaySublineMatchString::WaySublineMatchString(const WaySublineMatchString& other, const OsmMapPtr& newMap) { _matches.resize(other._matches.size()); for (size_t i = 0; i < other.getMatches().size(); i++) { _matches[i] = WaySublineMatch(other.getMatches()[i], newMap); } }
MatchClassification HighwayExpertClassifier::classify(const ConstOsmMapPtr& map, ElementId /*eid1*/, ElementId /*eid2*/, const WaySublineMatchString &match) { // calculate the average classification. Is there a better approach? Max, min, mean? Dunno. MatchClassification result; for (size_t i = 0; i < match.getMatches().size(); i++) { MatchClassification m = classify(map, match.getMatches()[i]); result.setMatchP(m.getMatchP() + result.getMatchP()); result.setMissP(m.getMissP() + result.getMissP()); result.setReviewP(m.getReviewP() + result.getReviewP()); } result.normalize(); return result; }
MaximalSublineStringMatcher::ScoredMatch MaximalSublineStringMatcher::_evaluateMatch( const ConstOsmMapPtr &map, Meters maxDistance, const vector<ConstWayPtr>& ways1, const vector<ConstWayPtr> &ways2, const vector<bool>& reversed1, const vector<bool> &reversed2) const { vector<WaySublineMatch> matches; // make a copy of the map and the ways we need so we can reverse the ways as needed. set<ElementId> eids; _insertElementIds(ways1, eids); _insertElementIds(ways2, eids); OsmMapPtr copiedMap(new OsmMap(map->getProjection())); CopySubsetOp(map, eids).apply(copiedMap); vector<WayPtr> prep1 = _changeMap(ways1, copiedMap); vector<WayPtr> prep2 = _changeMap(ways2, copiedMap); // reversed ways as appropriate _reverseWays(prep1, reversed1); _reverseWays(prep2, reversed2); double scoreSum = 0; // go through and match each way against every other way for (size_t i = 0; i < prep1.size(); i++) { for (size_t j = 0; j < prep2.size(); j++) { double score; WaySublineMatchString m = _sublineMatcher->findMatch(copiedMap, prep1[i], prep2[j], score, maxDistance); scoreSum += score; matches.insert(matches.end(), m.getMatches().begin(), m.getMatches().end()); } } HashMap<long, bool> wayIdToReversed1, wayIdToReversed2; // create a map from way id to reverse status for (size_t i = 0; i < prep1.size(); i++) { wayIdToReversed1[prep1[i]->getId()] = reversed1[i]; } for (size_t i = 0; i < prep2.size(); i++) { wayIdToReversed2[prep2[i]->getId()] = reversed2[i]; } // go through all the matches for (size_t i = 0; i < matches.size(); i++) { WaySubline ws1, ws2; // if the direction is reversed on one but not both ways then mark the match as reversed. long m1Id = matches[i].getSubline1().getStart().getWay()->getId(); long m2Id = matches[i].getSubline2().getStart().getWay()->getId(); if (wayIdToReversed1[m1Id]) { // make sure the way subline is pointed to the right way (not reversed) ConstWayPtr w = map->getWay(matches[i].getSubline1().getElementId()); ws1 = matches[i].getSubline1().reverse(w); } else { ws1 = WaySubline(matches[i].getSubline1(), map); } if (wayIdToReversed2[m2Id]) { // make sure the way subline is pointed to the right way (not reversed) ConstWayPtr w = map->getWay(matches[i].getSubline2().getElementId()); ws2 = matches[i].getSubline2().reverse(w); } else { ws2 = WaySubline(matches[i].getSubline2(), map); } if (wayIdToReversed1[m1Id] != wayIdToReversed2[m2Id]) { matches[i] = WaySublineMatch(ws1, ws2, true); } else { matches[i] = WaySublineMatch(ws1, ws2, false); } } return ScoredMatch(scoreSum, matches); }