/* * 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.grid; import com.vividsolutions.jts.geom.Coordinate; import eu.esdihumboldt.util.geometry.interpolation.ArcSegment; import eu.esdihumboldt.util.geometry.interpolation.model.Angle; import eu.esdihumboldt.util.geometry.interpolation.model.Arc; import eu.esdihumboldt.util.geometry.interpolation.model.ArcByCenterPoint; import eu.esdihumboldt.util.geometry.interpolation.model.ArcByPoints; import eu.esdihumboldt.util.geometry.interpolation.model.impl.ArcByCenterPointImpl; /** * Segment of an arc for gridded interpolation. * * @author Simon Templer */ public class ArcGridSegment implements ArcSegment { private final Arc arc; private final Coordinate start; private final Coordinate end; private final Coordinate middle; private final double gridSize; private final boolean atomic; /** * Create a new arc segment. * * @param arc the arc the segment should represent * @param moveAllToGrid if all points should be moved to the grid * @param gridSize the grid size, i.e. the grid cell height and width */ public ArcGridSegment(Arc arc, boolean moveAllToGrid, double gridSize) { this.arc = arc; this.gridSize = gridSize; ArcByPoints byPoints = arc.toArcByPoints(); Coordinate startOnGrid = GridUtil.movePointToGrid(byPoints.getStartPoint(), gridSize); Coordinate endOnGrid = GridUtil.movePointToGrid(byPoints.getEndPoint(), gridSize); // determine if Arc can be split Coordinate middleOnGrid = GridUtil.movePointToGrid(byPoints.getMiddlePoint(), gridSize); atomic = middleOnGrid.equals(startOnGrid) || middleOnGrid.equals(endOnGrid); // determine middle if (atomic) { // same as start or end middle = null; } else { if (moveAllToGrid) { middle = middleOnGrid; } else if (arc instanceof ArcByPoints) { // original arc already features the point // -> use as is middle = byPoints.getMiddlePoint(); } else { // point was not explicitly defined - use grid point middle = middleOnGrid; } } start = moveAllToGrid ? startOnGrid : byPoints.getStartPoint(); end = moveAllToGrid ? endOnGrid : byPoints.getEndPoint(); } @Override public boolean isAtomic() { return atomic; } @Override public ArcSegment getSecondPart() { ArcByCenterPoint byCenter = arc.toArcByCenterPoint(); Angle middleAngle = Angle.fromRadians(byCenter.getStartAngle().getRadians() + 0.5 * byCenter.getAngleBetween().getRadians()); Arc part = new ArcByCenterPointImpl(byCenter.getCenterPoint(), byCenter.getRadius(), middleAngle, byCenter.getEndAngle(), byCenter.isClockwise()); // always move points in sub-segments to grid, but assure the points // match the parent segment's return new FixedStartEndGridSegment(part, true, gridSize, getMiddlePoint(), getEndPoint()); } @Override public ArcSegment getFirstPart() { ArcByCenterPoint byCenter = arc.toArcByCenterPoint(); Angle middleAngle = Angle.fromRadians(byCenter.getStartAngle().getRadians() + 0.5 * byCenter.getAngleBetween().getRadians()); Arc part = new ArcByCenterPointImpl(byCenter.getCenterPoint(), byCenter.getRadius(), byCenter.getStartAngle(), middleAngle, byCenter.isClockwise()); // always move points in sub-segments to grid, but assure the points // match the parent segment's return new FixedStartEndGridSegment(part, true, gridSize, getStartPoint(), getMiddlePoint()); } @Override public Coordinate getStartPoint() { return start; } @Override public Coordinate getMiddlePoint() { return middle; } @Override public Coordinate getEndPoint() { return end; } }