// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui; import static org.junit.Assert.assertEquals; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.Arrays; import java.util.function.Function; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.openstreetmap.josm.JOSMFixture; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.coor.EastNorth; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.gui.MapViewState.MapViewPoint; import org.openstreetmap.josm.gui.MapViewState.MapViewRectangle; /** * Test {@link MapViewState} * @author Michael Zangl */ public class MapViewStateTest { private static final int WIDTH = 301; private static final int HEIGHT = 200; private MapViewState state; /** * Setup test. */ @BeforeClass public static void setUpBeforeClass() { JOSMFixture.createUnitTestFixture().init(); } /** * Create the default state. */ @Before public void setUp() { state = MapViewState.createDefaultState(WIDTH, HEIGHT); } private void doTestGetCenter(Function<MapViewState, MapViewPoint> getter, Function<Integer, Double> divider) { MapViewPoint center = getter.apply(state); assertHasViewCoords(divider.apply(WIDTH), divider.apply(HEIGHT), center); MapViewState newState = state.movedTo(center, new EastNorth(3, 4)); // state should not change, but new state should. center = getter.apply(state); assertHasViewCoords(divider.apply(WIDTH), divider.apply(HEIGHT), center); center = getter.apply(newState); assertEquals("east", 3, center.getEastNorth().east(), 0.01); assertEquals("north", 4, center.getEastNorth().north(), 0.01); } /** * Test {@link MapViewState#getCenter()} returns map view center. */ @Test public void testGetCenter() { doTestGetCenter(s -> s.getCenter(), t -> t / 2d); } /** * Test {@link MapViewState#getCenterAtPixel()} returns map view center. */ @Test public void testGetCenterAtPixel() { doTestGetCenter(s -> s.getCenterAtPixel(), t -> (double) (t / 2)); } private static void assertHasViewCoords(double x, double y, MapViewPoint center) { assertEquals("x", x, center.getInViewX(), 0.01); assertEquals("y", y, center.getInViewY(), 0.01); assertEquals("x", x, center.getInView().getX(), 0.01); assertEquals("y", y, center.getInView().getY(), 0.01); } /** * Test {@link MapViewState#getForView(double, double)} */ @Test public void testGetForView() { MapViewPoint corner = state.getForView(0, 0); assertHasViewCoords(0, 0, corner); MapViewPoint middle = state.getForView(120, 130); assertHasViewCoords(120, 130, middle); MapViewPoint fraction = state.getForView(0.12, 0.7); assertHasViewCoords(0.12, 0.7, fraction); MapViewPoint negative = state.getForView(-17, -30); assertHasViewCoords(-17, -30, negative); } /** * Test {@link MapViewState#getViewWidth()} and {@link MapViewState#getViewHeight()} */ @Test public void testGetViewSize() { assertEquals(WIDTH, state.getViewWidth(), 0.01); assertEquals(HEIGHT, state.getViewHeight(), 0.01); } /** * Tests that all coordinate conversions for the point work. */ @Test public void testPointConversions() { MapViewPoint p = state.getForView(WIDTH / 2d, HEIGHT / 2d); assertHasViewCoords(WIDTH / 2d, HEIGHT / 2d, p); EastNorth eastnorth = p.getEastNorth(); LatLon shouldLatLon = Main.getProjection().getWorldBoundsLatLon().getCenter(); EastNorth shouldEastNorth = Main.getProjection().latlon2eastNorth(shouldLatLon); assertEquals("east", shouldEastNorth.east(), eastnorth.east(), 0.01); assertEquals("north", shouldEastNorth.north(), eastnorth.north(), 0.01); MapViewPoint reversed = state.getPointFor(shouldEastNorth); assertHasViewCoords(WIDTH / 2d, HEIGHT / 2d, reversed); LatLon latlon = p.getLatLon(); assertEquals("lat", shouldLatLon.lat(), latlon.lat(), 0.01); assertEquals("lon", shouldLatLon.lon(), latlon.lon(), 0.01); MapViewPoint p2 = state.getPointFor(new EastNorth(2, 3)); assertEquals("east", 2, p2.getEastNorth().east(), 0.01); assertEquals("north", 3, p2.getEastNorth().north(), 0.01); } /** * Test {@link MapViewState#getAffineTransform()} */ @Test public void testGetAffineTransform() { for (EastNorth en : Arrays.asList(new EastNorth(100, 100), new EastNorth(0, 0), new EastNorth(300, 200), new EastNorth(-1, -2.5))) { MapViewPoint should = state.getPointFor(en); AffineTransform transform = state.getAffineTransform(); Point2D result = transform.transform(new Point2D.Double(en.getX(), en.getY()), null); assertEquals("x", should.getInViewX(), result.getX(), 0.01); assertEquals("y", should.getInViewY(), result.getY(), 0.01); } } /** * Test {@link MapViewState#OUTSIDE_BOTTOM} and similar constants. */ @Test public void testOutsideFlags() { assertEquals(1, Integer.bitCount(MapViewState.OUTSIDE_BOTTOM)); assertEquals(1, Integer.bitCount(MapViewState.OUTSIDE_TOP)); assertEquals(1, Integer.bitCount(MapViewState.OUTSIDE_LEFT)); assertEquals(1, Integer.bitCount(MapViewState.OUTSIDE_RIGHT)); assertEquals(4, Integer.bitCount(MapViewState.OUTSIDE_BOTTOM | MapViewState.OUTSIDE_TOP | MapViewState.OUTSIDE_LEFT | MapViewState.OUTSIDE_RIGHT)); } /** * Test {@link MapViewPoint#getOutsideRectangleFlags(MapViewRectangle)} */ @Test public void testPointGetOutsideRectangleFlags() { MapViewRectangle rect = state.getForView(0, 0).rectTo(state.getForView(10, 10)); assertEquals(0, state.getForView(1, 1).getOutsideRectangleFlags(rect)); assertEquals(0, state.getForView(1, 5).getOutsideRectangleFlags(rect)); assertEquals(0, state.getForView(9, 1).getOutsideRectangleFlags(rect)); assertEquals(0, state.getForView(10 - 1e-10, 1e-10).getOutsideRectangleFlags(rect)); assertEquals(0, state.getForView(10 - 1e-10, 10 - 1e-10).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_TOP, state.getForView(1, -11).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_TOP, state.getForView(1, -1e20).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_BOTTOM, state.getForView(1, 11).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_BOTTOM, state.getForView(1, 1e20).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_LEFT, state.getForView(-11, 1).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_LEFT, state.getForView(-1e20, 1).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_RIGHT, state.getForView(11, 1).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_RIGHT, state.getForView(1e20, 1).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_RIGHT | MapViewState.OUTSIDE_TOP, state.getForView(11, -11).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_RIGHT | MapViewState.OUTSIDE_BOTTOM, state.getForView(11, 11).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_LEFT | MapViewState.OUTSIDE_TOP, state.getForView(-11, -11).getOutsideRectangleFlags(rect)); assertEquals(MapViewState.OUTSIDE_LEFT | MapViewState.OUTSIDE_BOTTOM, state.getForView(-11, 11).getOutsideRectangleFlags(rect)); } /** * Test {@link MapViewPoint#oneNormInView(MapViewPoint)} */ @Test public void testPointOneNormInView() { MapViewPoint p = state.getForView(5, 15); assertEquals(0, p.oneNormInView(p), 1e-10); assertEquals(6, p.oneNormInView(state.getForView(-1, 15)), 1e-10); assertEquals(5, p.oneNormInView(state.getForView(5, 20)), 1e-10); assertEquals(22, p.oneNormInView(state.getForView(-1, -1)), 1e-10); assertEquals(40, p.oneNormInView(state.getForView(30, 30)), 1e-10); } /** * Test {@link MapViewState.MapViewViewPoint#toString()} and {@link MapViewState.MapViewEastNorthPoint#toString()} */ @Test public void testToString() { assertEquals("MapViewViewPoint [x=1.0, y=2.0]", state.getForView(1, 2).toString()); assertEquals("MapViewEastNorthPoint [eastNorth=EastNorth[e=0.0, n=0.0]]", state.getPointFor(new EastNorth(0, 0)).toString()); } }