public double getLength(LinearLocation loc) { double totalLength = 0.0; LinearIterator it = new LinearIterator(linearGeom); while (it.hasNext()) { if (! it.isEndOfLine()) { Coordinate p0 = it.getSegmentStart(); Coordinate p1 = it.getSegmentEnd(); double segLen = p1.distance(p0); // length falls in this segment if (loc.getComponentIndex() == it.getComponentIndex() && loc.getSegmentIndex() == it.getVertexIndex()) { return totalLength + segLen * loc.getSegmentFraction(); } totalLength += segLen; } it.next(); } return totalLength; } }
/** * Moves the iterator ahead to the next vertex and (possibly) linear component. */ public void next() { if (! hasNext()) return; vertexIndex++; if (vertexIndex >= currentLine.getNumPoints()) { componentIndex++; loadCurrentLine(); vertexIndex = 0; } }
private double indexOfFromStart(Coordinate inputPt, double minIndex) { double minDistance = Double.MAX_VALUE; double ptMeasure = minIndex; double segmentStartMeasure = 0.0; LineSegment seg = new LineSegment(); LinearIterator it = new LinearIterator(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; }
/** * Creates an iterator starting at * a specified component and vertex in a linear {@link Geometry} * * @param linearGeom the linear geometry to iterate over * @param componentIndex the component to start at * @param vertexIndex the vertex to start at * @throws IllegalArgumentException if linearGeom is not lineal */ public LinearIterator(Geometry linearGeom, int componentIndex, int vertexIndex) { if (! (linearGeom instanceof Lineal)) throw new IllegalArgumentException("Lineal geometry is required"); this.linearGeom = linearGeom; numLines = linearGeom.getNumGeometries(); this.componentIndex = componentIndex; this.vertexIndex = vertexIndex; loadCurrentLine(); }
/** * Gets the second {@link Coordinate} of the current segment. * (the coordinate of the next vertex). * If the iterator is at the end of a line, <code>null</code> is returned. * * @return a {@link Coordinate} or <code>null</code> */ public Coordinate getSegmentEnd() { if (vertexIndex < getLine().getNumPoints() - 1) return currentLine.getCoordinateN(vertexIndex + 1); return null; } }
LinearIterator it = new LinearIterator(linearGeom); while (it.hasNext()) { if (it.isEndOfLine()) { if (totalLength == length) { int compIndex = it.getComponentIndex(); int segIndex = it.getVertexIndex(); return new LinearLocation(compIndex, segIndex, 0.0); Coordinate p0 = it.getSegmentStart(); Coordinate p1 = it.getSegmentEnd(); double segLen = p1.distance(p0); int compIndex = it.getComponentIndex(); int segIndex = it.getVertexIndex(); return new LinearLocation(compIndex, segIndex, frac); it.next();
for (LinearIterator it = new LinearIterator(linearGeom); it.hasNext(); it.next()) { if (! it.isEndOfLine()) { seg.p0 = it.getSegmentStart(); seg.p1 = it.getSegmentEnd(); double segDistance = seg.distance(inputPt); double segFrac = seg.segmentFraction(inputPt); int candidateComponentIndex = it.getComponentIndex(); int candidateSegmentIndex = it.getVertexIndex(); if (segDistance < minDistance) {
/** * Assumes input is valid (e.g. start <= end) * * @param start * @param end * @return a linear geometry */ private Geometry computeLinear(LinearLocation start, LinearLocation end) { LinearGeometryBuilder builder = new LinearGeometryBuilder(line.getFactory()); builder.setFixInvalidLines(true); if (! start.isVertex()) builder.add(start.getCoordinate(line)); for (LinearIterator it = new LinearIterator(line, start); it.hasNext(); it.next()) { if (end.compareLocationValues(it.getComponentIndex(), it.getVertexIndex(), 0.0) < 0) break; Coordinate pt = it.getSegmentStart(); builder.add(pt); if (it.isEndOfLine()) builder.endLine(); } if (! end.isVertex()) builder.add(end.getCoordinate(line)); return builder.getGeometry(); }