示例#1
0
double LengthIndexOfPoint::indexOfFromStart(const Coordinate& inputPt, double minIndex) const
{
	double minDistance = numeric_limits<double>::max();

	double ptMeasure = minIndex;
	double segmentStartMeasure = 0.0;
	LineSegment seg;
	LinearIterator it(linearGeom);
	while (it.hasNext())
	{
		if (! it.isEndOfLine())
		{
			seg.p0 = it.getSegmentStart();
			seg.p1 = it.getSegmentEnd();
			double segDistance = seg.distance(inputPt);
			double segMeasureToPt = segmentNearestMeasure(&seg, inputPt, segmentStartMeasure);
			if (segDistance < minDistance
					&& segMeasureToPt > minIndex)
			{
				ptMeasure = segMeasureToPt;
				minDistance = segDistance;
			}
			segmentStartMeasure += seg.getLength();
		}
		it.next();
	}
	return ptMeasure;
}
示例#2
0
WayLocation LocationOfPoint::locate(const Coordinate& inputPt) const
{
  double minDistance = std::numeric_limits<double>().max();
  int minIndex = 0;
  double minFrac = -1.0;

  LineSegment seg;

  if (_length == -1)
  {
    _length = ElementConverter(_map).convertToLineString(_way)->getLength();
  }

  if (_length <= 0.0)
  {
    return WayLocation(_map, _way, 0, 0);
  }

  for (size_t i = 0; i < _way->getNodeCount() - 1; i++) {
    seg.p0 = _map->getNode(_way->getNodeId(i))->toCoordinate();
    seg.p1 = _map->getNode(_way->getNodeId(i + 1))->toCoordinate();
    double segDistance = seg.distance(inputPt);
    double segFrac = segmentFraction(seg, inputPt);

    if (segDistance < minDistance) {
      minIndex = i;
      minFrac = segFrac;
      minDistance = segDistance;
    }
  }

  return WayLocation(_map, _way, minIndex, minFrac);
}
示例#3
0
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;
}
示例#4
0
/* NOTE: this is called findSegmentIndexToSnap in JTS */
CoordinateList::iterator
LineStringSnapper::findSegmentToSnap(
			const Coordinate& snapPt,
			CoordinateList::iterator from,
			CoordinateList::iterator too_far)
{
	LineSegment seg;
	double minDist = snapTolerance; // make sure the first closer then
	                                // snapTolerance is accepted
	CoordinateList::iterator match=too_far;

	// TODO: use std::find_if
	for ( ; from != too_far; ++from)
	{
		seg.p0 = *from; 
		CoordinateList::iterator to = from;
		++to;
		seg.p1 = *to;

#if GEOS_DEBUG
cerr << " Checking segment " << seg << endl;
#endif

		/**
		 * Check if the snap pt is equal to one of
		 * the segment endpoints.
		 *
		 * If the snap pt is already in the src list,
		 * don't snap at all (unless allowSnappingToSourceVertices
		 * is set to true)
		 */
		if ( seg.p0.equals2D(snapPt) || seg.p1.equals2D(snapPt) )
		{

			if (allowSnappingToSourceVertices) {
#if GEOS_DEBUG
cerr << "   snap point matches a segment endpoint, checking next segment"
     << endl;
#endif
				continue;
			} else {
#if GEOS_DEBUG
cerr << "   snap point matches a segment endpoint, giving up seek" << endl;
#endif
				return too_far;
			}
		}

		double dist = seg.distance(snapPt);
		if ( dist >= minDist) {
#if GEOS_DEBUG
cerr << "   snap point distance " << dist
     << " not smaller than tolerance "
     << snapTolerance << " or previous closest "
     << minDist << endl;
#endif
      continue;
    }

#if GEOS_DEBUG
    cerr << "   snap point distance " << dist << " within tolerance "
         << snapTolerance << " and closer than previous candidate "
         << minDist << endl;
#endif

    if ( dist == 0.0 ) return from; // can't find any closer

    match = from;
    minDist = dist;

	}

	return match;
}