package com.vividsolutions.jump.algorithm; //Martin made a decision to create this duplicate of a class from JCS. //[Jon Aquino 2004-10-25] import com.vividsolutions.jts.geom.*; /** * Provides various ways of computing the actual value * of a point a given length along a line. */ public class LocatePoint { /** * Computes the location of a point a given length along a {@link LineSegment}. * If the length exceeds the length of the line segment the last * point of the segment is returned. * If the length is negative the first point * of the segment is returned. * * @param seg the line segment * @param length the length to the desired point * @return the {@link Coordinate} of the desired point */ public static Coordinate pointAlongSegment(LineSegment seg, double length) { return pointAlongSegment(seg.p0, seg.p1, length); } /** * Computes the location of a point a given length along a line segment. * If the length exceeds the length of the line segment the last * point of the segment is returned. * If the length is negative the first point * of the segment is returned. * * @param p0 the first point of the line segment * @param p1 the last point of the line segment * @param length the length to the desired point * @return the {@link Coordinate} of the desired point */ public static Coordinate pointAlongSegment(Coordinate p0, Coordinate p1, double length) { double segLen = p1.distance(p0); double frac = length / segLen; if (frac <= 0.0) return p0; if (frac >= 1.0) return p1; double x = (p1.x - p0.x) * frac + p0.x; double y = (p1.y - p0.y) * frac + p0.y; return new Coordinate(x, y); } /** * Computes the location of a point a given fraction along a line segment. * If the fraction exceeds 1 the last point of the segment is returned. * If the fraction is negative the first point of the segment is returned. * * @param p0 the first point of the line segment * @param p1 the last point of the line segment * @param frac the fraction of the segment to the desired point * @return the {@link Coordinate} of the desired point */ public static Coordinate pointAlongSegmentByFraction(Coordinate p0, Coordinate p1, double frac) { if (frac <= 0.0) return p0; if (frac >= 1.0) return p1; double x = (p1.x - p0.x) * frac + p0.x; double y = (p1.y - p0.y) * frac + p0.y; return new Coordinate(x, y); } /** * Computes the {@link Coordinate} of the point a given length * along a {@link LineString}. * * @param line * @param length * @return the {@link Coordinate} of the desired point */ public static Coordinate pointAlongLine(LineString line, double length) { LocatePoint loc = new LocatePoint(line, length); return loc.getPoint(); } private Coordinate pt; private int index; public LocatePoint(LineString line, double length) { compute(line, length); } private void compute(LineString line, double length) { // <TODO> handle negative distances (measure from opposite end of line) double totalLength = 0.0; Coordinate[] coord = line.getCoordinates(); for (int i = 0; i < coord.length - 1; i++) { Coordinate p0 = coord[i]; Coordinate p1 = coord[i+1]; double segLen = p1.distance(p0); if (totalLength + segLen > length) { pt = pointAlongSegment(p0, p1, length - totalLength); index = i; return; } totalLength += segLen; } // distance is greater than line length pt = new Coordinate(coord[coord.length - 1]); index = coord.length; } public Coordinate getPoint() { return pt; } /** * Returns the index of the segment containing the computed point */ public int getIndex() { return index; } }