/* * Copyright (c) 2017 wetransform GmbH * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * wetransform GmbH <http://www.wetransform.to> */ package eu.esdihumboldt.util.geometry.interpolation.split; import java.util.ArrayList; import java.util.Deque; import java.util.LinkedList; import java.util.List; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.LineString; import eu.esdihumboldt.util.geometry.interpolation.AbstractInterpolationAlgorithm; import eu.esdihumboldt.util.geometry.interpolation.ArcSegment; import eu.esdihumboldt.util.geometry.interpolation.InterpolationUtil; import eu.esdihumboldt.util.geometry.interpolation.model.Arc; import eu.esdihumboldt.util.geometry.interpolation.model.ArcByPoints; /** * Grid based interpolation algorithm. * * @author Simon Templer */ public class SplitInterpolation extends AbstractInterpolationAlgorithm { /** * Identifier of the algorithm in the extension point. */ public static final String EXTENSION_ID = "segment"; @Override public LineString interpolateArc(Arc arc) { if (InterpolationUtil.isStraightLine(arc)) { // this happens when slopes are close to equal ArcByPoints byPoints = arc.toArcByPoints(); // return points as-is return createLineString(new Coordinate[] { byPoints.getStartPoint(), byPoints.getMiddlePoint(), byPoints.getEndPoint() }, arc); } return interpolateToLineString(arc); } private LineString interpolateToLineString(Arc arc) { // arc segments to process Deque<ArcSegment> toProcess = new LinkedList<>(); // start with full arc as segment toProcess.addFirst(new ArcSplitSegment(arc, getMaxPositionalError())); // list to collect atomic parts List<ArcSegment> parts = new LinkedList<>(); // for every segment to process... while (!toProcess.isEmpty()) { ArcSegment segment = toProcess.pop(); if (segment.isAtomic()) { // segment cannot be split // -> use for result parts.add(segment); } else { // otherwise split the segment in two and handle the parts toProcess.addFirst(segment.getSecondPart()); toProcess.addFirst(segment.getFirstPart()); } } // combine the segments to a single LineString List<Coordinate> coords = new ArrayList<>(); for (int i = 0; i < parts.size(); i++) { ArcSegment part = parts.get(i); if (i == 0) { coords.add(part.getStartPoint()); } Coordinate middle = part.getMiddlePoint(); if (middle != null) { // should actually not occur InterpolationUtil.addIfDifferent(coords, middle); } InterpolationUtil.addIfDifferent(coords, part.getEndPoint()); } return createLineString(coords.toArray(new Coordinate[coords.size()]), arc); } }