WaySublineCollection WaySublineCollection::invert() const
{
  WaySublineCollection result;
  if (_sublines.size() == 0)
  {
    return result;
  }

  // We are going to sort all the way sublines so we can generate the inverted sublines starting
  // at the beginning and working on to the end. We'll maintain a simple variable for where the
  // next subline starts and then use a little simple logic to determine when we've found a legit
  // inverted subline and push it on to the result.

  // make a copy so we can sort.
  vector<WaySubline> sublines = _sublines;
  sort(sublines.begin(), sublines.end(), compareSublines);

  WayLocation sublineStart = WayLocation(_sublines[0].getMap(), sublines[0].getWay(), 0, 0);
  // go through all the sorted sublines
  for (size_t i = 0; i < sublines.size(); i++)
  {
    if (sublineStart.getWay() != sublines[i].getWay())
    {
      // if this isn't an empty subline
      if (sublineStart.isLast() == false)
      {
        result.addSubline(WaySubline(sublineStart,
          WayLocation::createAtEndOfWay(_sublines[0].getMap(), sublineStart.getWay())));
      }
      sublineStart = WayLocation(_sublines[0].getMap(), sublines[i].getWay(), 0, 0);
    }

    assert(sublineStart.getWay() == sublines[i].getWay());
    if (sublineStart == sublines[i].getStart())
    {
      // an empty subline at the beginning
      sublineStart = sublines[i].getEnd();
    }
    else
    {
      // add another subline from the sublineStart to the beginning of the next subline.
      result.addSubline(WaySubline(sublineStart, sublines[i].getStart()));
      // the next negative subline starts at the end of this positive subline
      sublineStart = sublines[i].getEnd();
    }
  }

  // if we haven't reached the end, then add one more subline for the end of the line.
  if (sublineStart.isLast() == false)
  {
    result.addSubline(WaySubline(sublineStart,
      WayLocation::createAtEndOfWay(_sublines[0].getMap(), sublineStart.getWay())));
  }

  return result;
}
Example #2
0
vector< shared_ptr<Way> > WaySplitter::split(WayLocation& splitPoint)
{
  vector< shared_ptr<Way> > result;

  if (splitPoint.isFirst() || splitPoint.isLast())
  {
    result.push_back(_a);
  }
  else
  {
    WayLocation first(_map, _a, 0, 0.0);
    WayLocation last(_map, _a, _a->getNodeCount() - 1, 0.0);

    result.push_back(WaySubline(first, splitPoint).toWay(_map, _nf.get()));
    result.push_back(WaySubline(splitPoint, last).toWay(_map, _nf.get()));

    _map->removeWay(_a);
    _map->addWay(result[0]);
    _map->addWay(result[1]);
  }

  return result;
}