/* * 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; import static org.junit.Assert.assertEquals; import java.awt.Color; import java.awt.geom.Arc2D; import java.io.IOException; import java.util.function.Consumer; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.LineString; 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.ArcString; import eu.esdihumboldt.util.svg.test.AbstractSVGPainterTest; import eu.esdihumboldt.util.svg.test.PaintSettings; import eu.esdihumboldt.util.svg.test.SVGPainter; /** * Base class for Arc based tests. * * @author Simon Templer */ public abstract class AbstractArcTest extends AbstractSVGPainterTest { /** * Prepare a canvas to draw an arc, perform the given draw operation and * save the drawing. * * @param arc the arc to draw * @param draw function that draws on the canvas * @throws IOException if saving the drawing fails */ protected void withArcCanvas(Arc arc, Consumer<SVGPainter> draw) throws IOException { Envelope envelope = getArcEnvelope(arc); PaintSettings settings = new PaintSettings(envelope, 1000, 10); SVGPainter svg = new SVGPainter(settings); svg.setCanvasSize(1000, 1000); draw.accept(svg); saveDrawing("arc", svg); } private Envelope getArcEnvelope(Arc arc) { Envelope envelope = new Envelope(arc.toArcByCenterPoint().getCenterPoint()); envelope.expandBy(arc.toArcByCenterPoint().getRadius()); return envelope; } /** * Prepare a canvas to draw an arc, perform the given draw operation and * save the drawing. * * @param arcs the arc string to draw * @param draw function that draws on the canvas * @throws IOException if saving the drawing fails */ protected void withArcStringCanvas(ArcString arcs, Consumer<SVGPainter> draw) throws IOException { Envelope envelope = new Envelope(); for (Arc arc : arcs.getArcs()) { envelope.expandToInclude(getArcEnvelope(arc)); } PaintSettings settings = new PaintSettings(envelope, 1000, 10); SVGPainter svg = new SVGPainter(settings); svg.setCanvasSize(1000, 1000); draw.accept(svg); saveDrawing("arc-string", svg); } /** * Draw a name. * * @param svg the SVG painter * @param name the name */ protected void drawName(SVGPainter svg, String name) { if (name == null) { return; } svg.setColor(Color.DARK_GRAY); // LineMetrics fontMetrics = svg.getGraphics2D().getFontMetrics().getLineMetrics(name, svg.getGraphics2D()); svg.getGraphics2D().setFont(svg.getGraphics2D().getFont() .deriveFont(40.0f)/* .deriveFont(Font.BOLD) */); svg.getGraphics2D().drawString(name, 30, 70); } /** * Draw an arc with markers for the points defining the arc. Saves the * resulting drawing. * * @param arc the arc to draw * @throws IOException if saving the drawing fails */ protected void drawArcWithMarkers(Arc arc) throws IOException { drawArcWithMarkers(arc, null); } /** * Draw an arc with markers for the points defining the arc. Saves the * resulting drawing. * * @param arc the arc to draw * @param name an optional name for the drawing * @throws IOException if saving the drawing fails */ protected void drawArcWithMarkers(Arc arc, String name) throws IOException { withArcCanvas(arc, svg -> { String arcName = name; if (arcName == null) { arcName = arc.toString(); // StackTraceElement[] trace = Thread.currentThread().getStackTrace(); // if (trace.length >= 3) { // name = trace[2].getMethodName() + " - " + name; // } } drawName(svg, arcName); drawArcWithMarkers(svg, arc); }); } /** * Draw an interpolated arc with debug information. Saves the resulting * drawing. * * @param arc the arc to draw * @param gridSize the grid size * @param interpolated the interpolated geometry * @throws IOException if saving the drawing fails */ protected void drawGridInterpolatedArc(Arc arc, double gridSize, LineString interpolated) throws IOException { withArcCanvas(arc, svg -> { drawGrid(svg, gridSize); drawName(svg, arc.toString()); drawArcWithMarkers(svg, arc); if (interpolated != null) { svg.setColor(Color.BLACK); svg.setStroke(2.5f); svg.drawLineString(interpolated); } }); } /** * Draw an interpolated arc with debug information. Saves the resulting * drawing. * * @param arc the arc to draw * @param interpolated the interpolated geometry * @throws IOException if saving the drawing fails */ protected void drawInterpolatedArc(Arc arc, LineString interpolated) throws IOException { withArcCanvas(arc, svg -> { if (interpolated != null) { svg.setColor(Color.DARK_GRAY); for (Coordinate coord : interpolated.getCoordinates()) { svg.drawPoint(coord); } } drawName(svg, arc.toString()); drawArcWithMarkers(svg, arc); if (interpolated != null) { svg.setColor(Color.BLACK); svg.setStroke(2.5f); svg.drawLineString(interpolated); } }); } /** * Draw an interpolated arc string with debug information. Saves the * resulting drawing. * * @param arcs the arc string to draw * @param gridSize the grid size * @param interpolated the interpolated geometry * @throws IOException if saving the drawing fails */ protected void drawGridInterpolatedArcString(ArcString arcs, double gridSize, LineString interpolated) throws IOException { withArcStringCanvas(arcs, svg -> { drawGrid(svg, gridSize); for (Arc arc : arcs.getArcs()) { drawArcWithMarkers(svg, arc); } if (interpolated != null) { svg.setColor(Color.BLACK); svg.setStroke(2.5f); svg.drawLineString(interpolated); } }); } /** * Draw an interpolated arc string with debug information. Saves the * resulting drawing. * * @param arcs the arc string to draw * @param interpolated the interpolated geometry * @throws IOException if saving the drawing fails */ protected void drawInterpolatedArcString(ArcString arcs, LineString interpolated) throws IOException { withArcStringCanvas(arcs, svg -> { if (interpolated != null) { svg.setColor(Color.DARK_GRAY); for (Coordinate coord : interpolated.getCoordinates()) { svg.drawPoint(coord); } } for (Arc arc : arcs.getArcs()) { drawArcWithMarkers(svg, arc); } if (interpolated != null) { svg.setColor(Color.BLACK); svg.setStroke(2.5f); svg.drawLineString(interpolated); } }); } /** * Draw a grid with a specified grid size. * * @param svg the SVG painter * @param gridSize the grid size, i.e. the height/width of grid cells */ private void drawGrid(SVGPainter svg, double gridSize) { svg.setStroke(1.0f); svg.setColor(Color.GREEN.darker()); double scaledStep = gridSize * svg.getSettings().getScaleFactor(); double maxY = svg.getSettings().getMaxY(); maxY = Math.floor(maxY / gridSize) * gridSize; // match to grid maxY = svg.getSettings().convertY(maxY); double capY = maxY + svg.getSettings().getCanvasSize().getHeight(); double minX = svg.getSettings().getMinX(); minX = Math.ceil(minX / gridSize) * gridSize; // match to grid minX = svg.getSettings().convertX(minX); double capX = minX + svg.getSettings().getCanvasSize().getWidth(); double y = maxY; while (y <= capY) { svg.getGraphics2D().drawLine((int) Math.round(minX), (int) Math.round(y), (int) Math.round(capX), (int) Math.round(y)); y = y + scaledStep; } double x = minX; while (x <= capX) { svg.getGraphics2D().drawLine((int) Math.round(x), (int) Math.round(maxY), (int) Math.round(x), (int) Math.round(capY)); x = x + scaledStep; } } /** * Draw an arc with markers for the points defining the arc. * * @param painter the SVG painter * @param arc the arc to draw */ protected void drawArcWithMarkers(SVGPainter painter, Arc arc) { painter.setColor(Color.DARK_GRAY); painter.setStroke(2.0f); drawArc(painter, arc); if (arc instanceof ArcByPoints) { painter.setColor(Color.GREEN); } else { painter.setColor(Color.BLUE); } ArcByPoints bp = arc.toArcByPoints(); painter.drawPoint(bp.getStartPoint()); painter.drawPoint(bp.getEndPoint()); painter.setColor(Color.RED); painter.drawPoint(bp.getMiddlePoint()); if (arc instanceof ArcByCenterPoint) { painter.setColor(Color.GREEN); } else { painter.setColor(Color.BLUE); } ArcByCenterPoint bc = arc.toArcByCenterPoint(); painter.drawPoint(bc.getCenterPoint()); } /** * Draw an arc. * * @param painter the SVG painter * @param arc the arc to draw */ protected void drawArc(SVGPainter painter, Arc arc) { Arc2D arcShape = createArcShape(arc, painter.getSettings()); painter.getGraphics2D().draw(arcShape); } /** * Create an Arc AWT shape from a given arc. * * @param arc the arc * @param paintSettings the paint settings for coordinate conversion * @return the arc shape */ protected Arc2D createArcShape(Arc arc, PaintSettings paintSettings) { ArcByCenterPoint a = arc.toArcByCenterPoint(); // FIXME probably not the right position Coordinate center = paintSettings.convertPoint(a.getCenterPoint()); double radius = a.getRadius() * paintSettings.getScaleFactor(); double startAngle = a.getStartAngle().getDegrees(); double angleExtent = a.getAngleBetween().getDegrees(); Arc2D.Double arcShape = new Arc2D.Double(); arcShape.setArcByCenter(center.x, center.y, radius, startAngle, angleExtent, Arc2D.OPEN); return arcShape; } /** * Test coordinates being equal using a lax comparison for X and Y. * * @param expected the expected coordinate * @param other the coordinate to compare */ public void assertEqualsCoord(Coordinate expected, Coordinate other) { assertEquals(expected.x, other.x, 1e-3); assertEquals(expected.y, other.y, 1e-3); } }