예제 #1
0
double NodeMatcher::scorePair(long nid1, long nid2)
{
  shared_ptr<const Node> n1 = _map->getNode(nid1);
  shared_ptr<const Node> n2 = _map->getNode(nid2);

  const set<long>& wids1 = _map->getIndex().getNodeToWayMap()->at(nid1);
  const set<long>& wids2 = _map->getIndex().getNodeToWayMap()->at(nid2);

  double acc = 0;
  for (set<long>::const_iterator it = wids1.begin(); it != wids1.end(); ++it)
  {
    acc = max(acc, _map->getWay(*it)->getCircularError());
  }
  for (set<long>::const_iterator it = wids2.begin(); it != wids2.end(); ++it)
  {
    acc = max(acc, _map->getWay(*it)->getCircularError());
  }

  vector<Radians> theta1 = calculateAngles(_map.get(), nid1, wids1);
  vector<Radians> theta2 = calculateAngles(_map.get(), nid2, wids2);

  int s1 = theta1.size();
  int s2 = theta2.size();

  if (s1 < 3 || s2 < 3)
  {
    return 0.0;
  }

  double d = n1->toCoordinate().distance(n2->toCoordinate());

  /// @todo this isnt right Talk to mike
  double distanceScore = 1 - (Normal::phi(d, acc * 1.5) - 0.5) * 2.0;

  if (theta1.size() < theta2.size())
  {
    swap(theta1, theta2);
  }

  double thetaScore;
  // this is very unsual and will slow things down.
  if (theta1.size() > 6 && theta2.size() > 6)
  {
    LOG_WARN("7 intersections at one spot? Odd. Giving it a high angleScore.");
    LOG_VAR(nid1);
    LOG_VAR(nid2);
    LOG_VAR(wids1);
    LOG_VAR(wids2);
    thetaScore = 1.0;
  }
  else
  {
    vector<bool> exclude(theta1.size(), false);
    thetaScore = _calculateAngleScore(theta1, theta2, exclude, 0);
  }

  // simple stupid heuristic. Replace w/ some cosine fanciness later.
  int diff = abs((int)s1 - (int)s2);
  return (min(s1, s2) - diff) * thetaScore * distanceScore;
}
예제 #2
0
double NodeMatcher::_calculateAngleScore(const vector<Radians>& theta1,
  const vector<Radians>& theta2, vector<bool>& exclude, size_t depth, bool debug)
{
  assert(theta1.size() <= theta2.size());
  if (depth == theta1.size())
  {
    return 1.0;
  }

  double max = 0;
  for (int j = 0; j < (int)theta2.size(); j++)
  {
    if (exclude[j] == false)
    {
      Radians m = WayHeading::deltaMagnitude(theta1[depth], theta2[j]);
      double r = 0;
      if (m < M_PI / 2.0)
      {
        r = pow(cos(WayHeading::deltaMagnitude(theta1[depth], theta2[j])), _strictness);
      }
      exclude[j] = true;
      double v = r * _calculateAngleScore(theta1, theta2, exclude, depth + 1, debug);
      exclude[j] = false;
      if (v > max)
      {
        max = v;
      }
    }
  }
  return max;
}
예제 #3
0
double NodeMatcher::_calculateAngleScore(const vector<Radians>& theta1,
  const vector<Radians>& theta2, vector<bool>& exclude, size_t depth)
{
  if (depth == theta1.size())
  {
    return 1.0;
  }
  //LOG_INFO("depth: " << depth << " exclude: " << exclude);

  double max = 0;
  for (int j = 0; j < (int)theta2.size(); j++)
  {
    if (exclude[j] == false)
    {
      double r = pow(cos(WayHeading::deltaMagnitude(theta1[depth], theta2[j])), _strictness);
      exclude[j] = true;
      double v = r * _calculateAngleScore(theta1, theta2, exclude, depth + 1);
      exclude[j] = false;
      if (v > max)
      {
        max = v;
      }
    }
  }
  return max;
}
예제 #4
0
double NodeMatcher::scorePair(long nid1, long nid2)
{
  ConstNodePtr n1 = _map->getNode(nid1);
  ConstNodePtr n2 = _map->getNode(nid2);

  const set<long>& wids1 = _map->getIndex().getNodeToWayMap()->at(nid1);
  const set<long>& wids2 = _map->getIndex().getNodeToWayMap()->at(nid2);

  double acc = 0;
  for (set<long>::const_iterator it = wids1.begin(); it != wids1.end(); ++it)
  {
    acc = max(acc, _map->getWay(*it)->getCircularError());
  }
  for (set<long>::const_iterator it = wids2.begin(); it != wids2.end(); ++it)
  {
    acc = max(acc, _map->getWay(*it)->getCircularError());
  }

  vector<Radians> theta1 = calculateAngles(_map.get(), nid1, wids1, _delta);
  vector<Radians> theta2 = calculateAngles(_map.get(), nid2, wids2, _delta);

  int s1 = theta1.size();
  int s2 = theta2.size();

  if (s1 < 3 || s2 < 3)
  {
    return 0.0;
  }

  double d = n1->toCoordinate().distance(n2->toCoordinate());

  // TODO: this isnt right; Talk to mike
  double distanceScore = 1 - (Normal::phi(d, acc * 1.5) - 0.5) * 2.0;
  LOG_VART(nid1);
  LOG_VART(nid2);
  LOG_VART(distanceScore);
  LOG_VART(acc);
  LOG_VART(d);
  LOG_VART(Normal::phi(d, acc * 1.5));
  LOG_VART(Normal::phi(d, acc / 2.0));

  if (theta1.size() < theta2.size())
  {
    swap(theta1, theta2);
  }

  double thetaScore;
  // this is very unsual and will slow things down.
  if (theta1.size() > 6 && theta2.size() > 6)
  {
    if (logWarnCount < Log::getWarnMessageLimit())
    {
      LOG_WARN("Greater than seven intersections at one spot? Odd.  Giving it a high angleScore.");
    }
    else if (logWarnCount == Log::getWarnMessageLimit())
    {
      LOG_WARN(className() << ": " << Log::LOG_WARN_LIMIT_REACHED_MESSAGE);
    }
    logWarnCount++;
    LOG_VART(nid1);
    LOG_VART(nid2);
    LOG_VART(wids1);
    LOG_VART(wids2);
    thetaScore = 1.0;
  }
  else
  {
    if (theta2.size() < theta1.size())
    {
      vector<bool> exclude(theta2.size(), false);
      thetaScore = _calculateAngleScore(theta2, theta1, exclude, 0);
    }
    else
    {
      vector<bool> exclude(theta1.size(), false);
      thetaScore = _calculateAngleScore(theta1, theta2, exclude, 0);
    }
  }

  // simple stupid heuristic. Replace w/ some cosine fanciness later.
  int diff = abs((int)s1 - (int)s2);

  double result = (min(s1, s2) - diff) * thetaScore * distanceScore;

  LOG_VART(result);
  return result;
}