void MaximalSubline::_snapToTerminal(WayLocation& wl, bool startOfLines, double thresh) { Meters d1 = wl.calculateDistanceOnWay(); // if we're not at the start of the line if (!startOfLines) { // calculate the distance from the end to this way location. d1 = ElementConverter(wl.getMap()).convertToLineString(wl.getWay())->getLength() - d1; } if (thresh == -1) { thresh = _minSplitSize; } // if we should snap the end points if (d1 <= thresh) { // if we're at the start of the line if (startOfLines) { // snap to the beginning wl = WayLocation(wl.getMap(), wl.getWay(), 0, 0.0); } // if we're at the end of the line else { // snap to the end wl = WayLocation(wl.getMap(), wl.getWay(), wl.getWay()->getNodeCount(), 0.0); } } }
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; }
WayLocation LocationOfPoint::locateAfter(const Coordinate& inputPt, const WayLocation& minLocation) const { if (minLocation.isValid() == false) { return locate(inputPt); } assert(minLocation.getWay() == _way); double minDistance = std::numeric_limits<double>().max(); WayLocation nextClosestLocation = minLocation; LineSegment seg; size_t startIndex = 0; startIndex = (size_t)minLocation.getSegmentIndex(); for (size_t i = startIndex; i < _way->getNodeCount() - 1; i++) { seg.p0 = _map->getNode(_way->getNodeId(i))->toCoordinate(); seg.p1 = _map->getNode(_way->getNodeId(i + 1))->toCoordinate(); if (i == startIndex) { seg.p0 = minLocation.getCoordinate(); } double segDistance = seg.distance(inputPt); double segFrac = segmentFraction(seg, inputPt); if (segDistance < minDistance) { // if this is the first case (a partial line segment) if (i == startIndex) { // recalculate the segFrac in terms of the whole line segment. segFrac = minLocation.getSegmentFraction() + (1 - minLocation.getSegmentFraction()) * segFrac; } nextClosestLocation = WayLocation(_map, _way, i, segFrac); minDistance = segDistance; } } // Return the minDistanceLocation found. // This will not be null, since it was initialized to minLocation Assert::isFalse(nextClosestLocation >= minLocation, "computed location is before specified minimum location"); return nextClosestLocation; }