コード例 #1
0
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);
  }
}
コード例 #2
0
bool WaySublineMatchString::touches(const WaySublineMatchString& other) const
{
  WaySublineCollection wss1 = getSublineString1();
  WaySublineCollection wss2 = getSublineString2();
  WaySublineCollection owss1 = other.getSublineString1();
  WaySublineCollection owss2 = other.getSublineString2();
  return wss1.touches(owss1) ||
      wss2.touches(owss2) ||
      wss1.touches(owss2) ||
      wss2.touches(owss1);
}
コード例 #3
0
WaySublineMatchString MaximalSublineStringMatcher::findMatch(const ConstOsmMapPtr& map,
  const ConstElementPtr& e1, const ConstElementPtr& e2, Meters maxRelevantDistance) const
{
  assert(_maxAngle >= 0);
  if (maxRelevantDistance == -1)
  {
    maxRelevantDistance = e1->getCircularError() + e2->getCircularError();
  }

  // make sure the inputs are legit. If either element isn't legit then throw a NeedsReviewException
  _validateElement(map, e1->getElementId());
  _validateElement(map, e2->getElementId());

  // extract the ways from the elements. In most cases it will return a vector of 1, but
  // multilinestrings may contain multiple ways
  vector<ConstWayPtr> ways1 = ExtractWaysVisitor::extractWays(map, e1);
  vector<ConstWayPtr> ways2 = ExtractWaysVisitor::extractWays(map, e2);

  if ((ways1.size() > 4 && ways2.size() > 4) || (ways1.size() + ways2.size() > 7))
  {
    throw NeedsReviewException("Elements contain too many ways and the computational complexity "
                               "is unreasonable.");
  }

  // Try with all combinations of forward and reversed ways. This is very expensive for
  // multilinestrings with lots of ways in them. Though those shouldn't be common.
  vector<bool> reversed1(ways1.size(), false), reversed2(ways2.size(), false);
  ScoredMatch scoredResult = _findBestMatch(map, maxRelevantDistance, ways1, ways2, reversed1,
    reversed2);

  // convert the best match into a WaySublineStringMatch and return.
  try
  {
    WaySublineMatchString result = scoredResult.matches;
    // this likely shouldn't be necessary. See #4593
    result.removeEmptyMatches();
    return result;
  }
  catch(OverlappingMatchesException &e)
  {
    throw NeedsReviewException("Internal Error: Multiple overlapping way matches were found within "
      "one set of ways.  Please report this to [email protected].");
  }
}
コード例 #4
0
ファイル: NetworkDetails.cpp プロジェクト: Nanonid/hootenanny
bool NetworkDetails::isReversed(ConstNetworkEdgePtr e1, ConstNetworkEdgePtr e2)
{
  assert(e1->getMembers().size() == 1);
  assert(e2->getMembers().size() == 1);

  ConstWayPtr w1 = dynamic_pointer_cast<const Way>(e1->getMembers()[0]);
  ConstWayPtr w2 = dynamic_pointer_cast<const Way>(e2->getMembers()[0]);

  // calculated the shared sublines
  WaySublineMatchString sublineMatch = _sublineMatcher->findMatch(_map, w1, w2,
    ConfigOptions().getSearchRadiusHighway());

  if (sublineMatch.getReverseVector2().size() != 1)
  {
    throw NotImplementedException();
  }

  return sublineMatch.getReverseVector2()[0];
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: NetworkDetails.cpp プロジェクト: Nanonid/hootenanny
double NetworkDetails::getPartialEdgeMatchScore(ConstNetworkEdgePtr e1, ConstNetworkEdgePtr e2)
{
  assert(e1->getMembers().size() == 1);
  assert(e2->getMembers().size() == 1);

  ConstWayPtr w1 = dynamic_pointer_cast<const Way>(e1->getMembers()[0]);
  ConstWayPtr w2 = dynamic_pointer_cast<const Way>(e2->getMembers()[0]);

  //LOG_VAR(ElementConverter(_map).convertToGeometry(w1)->toString());
  //LOG_VAR(ElementConverter(_map).convertToGeometry(w2)->toString());

  // calculated the shared sublines
  WaySublineMatchString sublineMatch = _sublineMatcher->findMatch(_map, w1, w2,
    ConfigOptions().getSearchRadiusHighway());

  MatchClassification c;
  if (sublineMatch.isValid())
  {
    // calculate the match score
    c = _classifier->classify(_map, w1->getElementId(), w2->getElementId(), sublineMatch);
  }

  return c.getMatchP();
}
コード例 #7
0
Handle<Value> SublineStringMatcherJs::extractMatchingSublines(const Arguments& args)
{
    HandleScope scope;

    SublineStringMatcherJs* smJs = ObjectWrap::Unwrap<SublineStringMatcherJs>(args.This());
    SublineStringMatcherPtr sm = smJs->getSublineStringMatcher();

    OsmMapJs* mapJs = ObjectWrap::Unwrap<OsmMapJs>(args[0]->ToObject());
    ElementJs* e1Js = ObjectWrap::Unwrap<ElementJs>(args[1]->ToObject());
    ElementJs* e2Js = ObjectWrap::Unwrap<ElementJs>(args[2]->ToObject());
    ConstOsmMapPtr m = mapJs->getConstMap();
    ConstElementPtr e1 = e1Js->getConstElement();
    ConstElementPtr e2 = e2Js->getConstElement();

    Handle<Value> result;

    try
    {
        WaySublineMatchString match = sm->findMatch(m, e1, e2);

        if (match.isEmpty())
        {
            return Undefined();
        }

        // convert match into elements in a new map.
        set<ElementId> eids;
        eids.insert(e1->getElementId());
        eids.insert(e2->getElementId());
        OsmMapPtr copiedMap(new OsmMap(m->getProjection()));
        CopySubsetOp(m, eids).apply(copiedMap);
        WaySublineMatchString copiedMatch(match, copiedMap);

        // split the shared line based on the matching subline
        ElementPtr match1, scraps1;
        ElementPtr match2, scraps2;
        WaySublineString string1 = copiedMatch.getSublineString1();
        WaySublineString string2 = copiedMatch.getSublineString2();

        try
        {
            MultiLineStringSplitter().split(copiedMap, string1, copiedMatch.getReverseVector1(), match1,
                                            scraps1);
            MultiLineStringSplitter().split(copiedMap, string2, copiedMatch.getReverseVector2(), match2,
                                            scraps2);
        }
        catch (const IllegalArgumentException& e)
        {
            // this is unusual print out some information useful to debugging.
            MapReprojector::reprojectToWgs84(copiedMap);
            LOG_WARN(OsmWriter::toString(copiedMap));
            throw e;
        }

        if (!match1 || !match2)
        {
            result = Undefined();
        }
        else
        {
            Handle<Object> obj = Object::New();
            obj->Set(String::NewSymbol("map"), OsmMapJs::create(copiedMap));
            obj->Set(String::NewSymbol("match1"), ElementJs::New(match1));
            obj->Set(String::NewSymbol("match2"), ElementJs::New(match2));
            result = obj;
        }
    }
    catch (const HootException& e)
    {
        return v8::ThrowException(HootExceptionJs::create(e));
    }

    return scope.Close(result);
}
コード例 #8
0
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);
}