/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2010, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.grid.hexagon;
import java.util.HashMap;
import java.util.Map;
import com.vividsolutions.jts.geom.Coordinate;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.grid.PolygonBuilder;
import org.geotools.grid.Neighbor;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Unit tests for the HexagonGridBuilder class.
*
* @author mbedward
* @since 2.7
*
*
* @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/grid/src/test/java/org/geotools/grid/hexagon/HexagonGridBuilderTest.java $
* @version $Id: HexagonsTest.java 35655 2010-06-03 02:36:24Z mbedward $
*/
public class HexagonGridBuilderTest extends HexagonTestBase {
private final ReferencedEnvelope bounds = new ReferencedEnvelope(0, 10, 0, 10, null);
private HexagonBuilder angledBuilder;
private HexagonBuilder flatBuilder;
@Before
public void setup() {
angledBuilder = new HexagonBuilder(bounds, SIDE_LEN, HexagonOrientation.ANGLED);
flatBuilder = new HexagonBuilder(bounds, SIDE_LEN, HexagonOrientation.FLAT);
}
@Test
public void validNeighborPosition() {
class Case {
HexagonOrientation o;
Neighbor n;
boolean valid;
public Case(HexagonOrientation o, Neighbor n, boolean valid) {
this.o = o;
this.n = n;
this.valid = valid;
}
}
Case[] cases = {
new Case(HexagonOrientation.ANGLED, Neighbor.LEFT, true),
new Case(HexagonOrientation.ANGLED, Neighbor.LOWER, false),
new Case(HexagonOrientation.ANGLED, Neighbor.LOWER_LEFT, true),
new Case(HexagonOrientation.ANGLED, Neighbor.LOWER_RIGHT, true),
new Case(HexagonOrientation.ANGLED, Neighbor.RIGHT, true),
new Case(HexagonOrientation.ANGLED, Neighbor.UPPER, false),
new Case(HexagonOrientation.ANGLED, Neighbor.UPPER_LEFT, true),
new Case(HexagonOrientation.ANGLED, Neighbor.UPPER_RIGHT, true),
new Case(HexagonOrientation.FLAT, Neighbor.LEFT, false),
new Case(HexagonOrientation.FLAT, Neighbor.LOWER, true),
new Case(HexagonOrientation.FLAT, Neighbor.LOWER_LEFT, true),
new Case(HexagonOrientation.FLAT, Neighbor.LOWER_RIGHT, true),
new Case(HexagonOrientation.FLAT, Neighbor.RIGHT, false),
new Case(HexagonOrientation.FLAT, Neighbor.UPPER, true),
new Case(HexagonOrientation.FLAT, Neighbor.UPPER_LEFT, true),
new Case(HexagonOrientation.FLAT, Neighbor.UPPER_RIGHT, true),
};
for (Case c : cases) {
if (c.o == HexagonOrientation.ANGLED) {
assertEquals("Failed for case: " + c.o + " " + c.n,
c.valid, angledBuilder.isValidNeighbor(c.n));
} else {
assertEquals("Failed for case: " + c.o + " " + c.n,
c.valid, flatBuilder.isValidNeighbor(c.n));
}
}
}
@Test
public void createNeighbor() {
Hexagon hn = null;
class Shift {
double dx;
double dy;
public Shift(double dx, double dy) {
this.dx = dx;
this.dy = dy;
}
}
final double MAJOR = 2.0 * SIDE_LEN;
final double MINOR = Math.sqrt(3.0) * SIDE_LEN;
Map<Neighbor, Shift> flatShifts = new HashMap<Neighbor, Shift>();
flatShifts.put(Neighbor.LOWER, new Shift(0.0, -MINOR));
flatShifts.put(Neighbor.LOWER_LEFT, new Shift(-0.75 * MAJOR, -0.5 * MINOR));
flatShifts.put(Neighbor.LOWER_RIGHT, new Shift(0.75 * MAJOR, -0.5 * MINOR));
flatShifts.put(Neighbor.UPPER, new Shift(0.0, MINOR));
flatShifts.put(Neighbor.UPPER_LEFT, new Shift(-0.75 * MAJOR, 0.5 * MINOR));
flatShifts.put(Neighbor.UPPER_RIGHT, new Shift(0.75 * MAJOR, 0.5 * MINOR));
Map<Neighbor, Shift> angledShifts = new HashMap<Neighbor, Shift>();
angledShifts.put(Neighbor.LEFT, new Shift(-MINOR, 0.0));
angledShifts.put(Neighbor.LOWER_LEFT, new Shift(-0.5 * MINOR, -0.75 * MAJOR));
angledShifts.put(Neighbor.LOWER_RIGHT, new Shift(0.5 * MINOR, -0.75 * MAJOR));
angledShifts.put(Neighbor.RIGHT, new Shift(MINOR, 0.0));
angledShifts.put(Neighbor.UPPER_LEFT, new Shift(-0.5 * MINOR, 0.75 * MAJOR));
angledShifts.put(Neighbor.UPPER_RIGHT, new Shift(0.5 * MINOR, 0.75 * MAJOR));
Map<HexagonOrientation, Map<Neighbor, Shift>> table = new HashMap<HexagonOrientation, Map<Neighbor, Shift>>();
table.put(HexagonOrientation.FLAT, flatShifts);
table.put(HexagonOrientation.ANGLED, angledShifts);
for (HexagonOrientation o : HexagonOrientation.values()) {
PolygonBuilder gridBuilder =
o == HexagonOrientation.ANGLED ? angledBuilder : flatBuilder;
Hexagon h0 = Hexagons.create(0.0, 0.0, SIDE_LEN, o, null);
for (Neighbor n : Neighbor.values()) {
boolean expectEx = !gridBuilder.isValidNeighbor(n);
boolean gotEx = false;
try {
hn = (Hexagon) gridBuilder.createNeighbor(h0, n);
} catch (IllegalArgumentException ex) {
gotEx = true;
}
assertEquals("Failed for case " + o + " " + n, expectEx, gotEx);
if (!gotEx) {
Shift shift = table.get(o).get(n);
assertNotNull("Error in test code", shift);
assertNeighborVertices(h0, hn, shift.dx, shift.dy);
}
}
}
}
private void assertNeighborVertices(Hexagon h0, Hexagon h1, double dx, double dy) {
Coordinate[] expected = h0.getVertices();
Coordinate[] result = h1.getVertices();
for (int i = 0; i < 6; i++) {
expected[i].x += dx;
expected[i].y += dy;
assertCoordinate(expected[i], result[i]);
}
}
}