package com.revolsys.geometry.test.old.linearref;
import com.revolsys.geometry.model.Geometry;
import com.revolsys.geometry.model.GeometryFactory;
import com.revolsys.geometry.model.Point;
import junit.framework.TestCase;
/**
* Base class for linear referencing class unit tests.
*/
public abstract class AbstractIndexedLineTest extends TestCase {
static final double TOLERANCE_DIST = 0.001;
private final GeometryFactory geometryFactory = GeometryFactory.DEFAULT_3D;
public AbstractIndexedLineTest(final String name) {
super(name);
}
protected void checkExpected(final Geometry result, final String expected) {
final Geometry subLine = read(expected);
final boolean isEqual = result.equalsExact(subLine, 1.0e-5);
if (!isEqual) {
// System.out.println("Computed result is: " + result);
}
assertTrue(isEqual);
}
protected abstract Point extractOffsetAt(Geometry input, Point testPt, double offsetDistance);
/**
* Checks that the point computed by <tt>indexOfAfter</tt>
* is the same as the input point.
* (This should be the case for all except pathological cases,
* such as the input test point being beyond the end of the line).
*
* @param input
* @param testPt
* @return true if the result of indexOfAfter is the same as the input point
*/
protected abstract boolean indexOfAfterCheck(Geometry input, Point testPt);
protected abstract boolean indexOfAfterCheck(Geometry input, Point testPt, Point afterPt);
protected abstract Geometry indicesOfThenExtract(Geometry input, Geometry subLine);
protected Geometry read(final String wkt) {
return this.geometryFactory.geometry(wkt);
}
protected void runIndexOfAfterTest(final String inputStr, final String testPtWKT)
// throws Exception
{
final Geometry input = read(inputStr);
final Geometry testPoint = read(testPtWKT);
final Point testPt = testPoint.getPoint();
final boolean resultOK = indexOfAfterCheck(input, testPt);
assertTrue(resultOK);
}
protected void runIndexOfAfterTest(final String inputStr, final String testPtWKT,
final String afterPtWKT)
// throws Exception
{
final Geometry input = read(inputStr);
final Geometry testPoint = read(testPtWKT);
final Point testPt = testPoint.getPoint();
final Geometry afterPoint = read(afterPtWKT);
final Point afterPt = afterPoint.getPoint();
final boolean resultOK = indexOfAfterCheck(input, testPt, afterPt);
assertTrue(resultOK);
}
protected void runIndicesOfThenExtract(final String inputStr, final String subLineStr)
// throws Exception
{
final Geometry input = read(inputStr);
final Geometry subLine = read(subLineStr);
final Geometry result = indicesOfThenExtract(input, subLine);
checkExpected(result, subLineStr);
}
protected void runOffsetTest(final String inputWKT, final String testPtWKT,
final double offsetDistance, final String expectedPtWKT)
// throws Exception
{
final Geometry input = read(inputWKT);
final Geometry testPoint = read(testPtWKT);
final Geometry expectedPoint = read(expectedPtWKT);
final Point testPt = testPoint.getPoint();
final Point expectedPt = expectedPoint.getPoint();
final Point offsetPt = extractOffsetAt(input, testPt, offsetDistance);
final boolean isOk = offsetPt.distancePoint(expectedPt) < TOLERANCE_DIST;
if (!isOk) {
// System.out.println("Expected = " + expectedPoint + " Actual = "
// + offsetPt);
}
assertTrue(isOk);
}
public void testFirst() {
runOffsetTest("LINESTRING (0 0, 20 20)", "POINT(20 20)", 0.0, "POINT (20 20)");
}
public void testIndexOfAfterBeyondEndRibbon() {
runIndexOfAfterTest("LINESTRING (0 0, 0 60, 50 60, 50 20, -20 20)", "POINT (-30 20)",
"POINT (-20 20)");
}
public void testIndexOfAfterRibbon() {
runIndexOfAfterTest("LINESTRING (0 0, 0 60, 50 60, 50 20, -20 20)", "POINT (0 20)");
runIndexOfAfterTest("LINESTRING (0 0, 0 60, 50 60, 50 20, -20 20)", "POINT (0 20)",
"POINT (30 60)");
}
public void testIndexOfAfterSquare() {
runIndexOfAfterTest("LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)", "POINT (0 0)");
}
public void testLoopWithEndingSubLine() {
runIndicesOfThenExtract("LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)",
"LINESTRING (10 10, 10 0, 0 0)");
}
// test a subline equal to the parent loop
public void testLoopWithIdenticalSubLine() {
runIndicesOfThenExtract("LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)",
"LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)");
}
/**
* Following tests check that correct portion of loop is identified.
* This requires that the correct vertex for (0,0) is selected.
*/
public void testLoopWithStartSubLine() {
runIndicesOfThenExtract("LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)",
"LINESTRING (0 0, 0 10, 10 10)");
}
public void testML() {
runIndicesOfThenExtract("MULTILINESTRING ((0 0, 10 10), (20 20, 30 30))",
"MULTILINESTRING ((1 1, 10 10), (20 20, 25 25))");
}
public void testOffsetEndPoint() {
runOffsetTest("LINESTRING (0 0, 20 20)", "POINT(20 20)", 0.0, "POINT (20 20)");
runOffsetTest("LINESTRING (0 0, 13 13, 20 20)", "POINT(20 20)", 0.0, "POINT (20 20)");
runOffsetTest("LINESTRING (0 0, 10 0, 20 0)", "POINT(20 0)", 1.0, "POINT (20 1)");
runOffsetTest("LINESTRING (0 0, 20 0)", "POINT(10 0)", 1.0, "POINT (10 1)"); // point
// on
// last
// segment
runOffsetTest("MULTILINESTRING ((0 0, 10 0), (10 0, 20 0))", "POINT(10 0)", -1.0,
"POINT (10 -1)");
runOffsetTest("MULTILINESTRING ((0 0, 10 0), (10 0, 20 0))", "POINT(20 0)", 1.0,
"POINT (20 1)");
}
/*
* // example of indicesOfThenLocate method private Geometry indicesOfThenLocate(LineString input,
* LineString subLine) { LocationIndexedLine indexedLine = new LocationIndexedLine(input);
* LineStringLocation[] loc = indexedLine.indicesOf(subLine); Geometry result =
* indexedLine.locate(loc[0], loc[1]); return result; }
*/
public void testOffsetStartPoint() {
runOffsetTest("LINESTRING (0 0, 10 10, 20 20)", "POINT(0 0)", 1.0,
"POINT (-0.7071067811865475 0.7071067811865475)");
runOffsetTest("LINESTRING (0 0, 10 10, 20 20)", "POINT(0 0)", -1.0,
"POINT (0.7071067811865475 -0.7071067811865475)");
runOffsetTest("LINESTRING (0 0, 10 10, 20 20)", "POINT(10 10)", 5.0,
"POINT (6.464466094067262 13.535533905932738)");
runOffsetTest("LINESTRING (0 0, 10 10, 20 20)", "POINT(10 10)", -5.0,
"POINT (13.535533905932738 6.464466094067262)");
}
public void testOffsetStartPointRepeatedPoint() {
runOffsetTest("LINESTRING (0 0, 10 10, 10 10, 20 20)", "POINT(0 0)", 1.0,
"POINT (-0.7071067811865475 0.7071067811865475)");
runOffsetTest("LINESTRING (0 0, 10 10, 10 10, 20 20)", "POINT(0 0)", -1.0,
"POINT (0.7071067811865475 -0.7071067811865475)");
// These tests work for LengthIndexedLine, but not LocationIndexedLine
// runOffsetTest("LINESTRING (0 0, 10 10, 10 10, 20 20)", "POINT(10 10)",
// 5.0, "POINT (6.464466094067262 13.535533905932738)");
// runOffsetTest("LINESTRING (0 0, 10 10, 10 10, 20 20)", "POINT(10 10)",
// -5.0, "POINT (13.535533905932738 6.464466094067262)");
}
/**
* Tests that duplicate coordinates are handled correctly.
*/
public void testPartOfSegmentContainingDuplicateCoords() {
runIndicesOfThenExtract("LINESTRING (0 0, 10 10, 10 10, 20 20)",
"LINESTRING (5 5, 10 10, 10 10, 15 15)");
}
public void testPartOfSegmentContainingVertex() {
runIndicesOfThenExtract("LINESTRING (0 0, 10 10, 20 20)", "LINESTRING (5 5, 10 10, 15 15)");
}
public void testPartOfSegmentNoVertex() {
runIndicesOfThenExtract("LINESTRING (0 0, 10 10, 20 20)", "LINESTRING (1 1, 9 9)");
}
// test a zero-length subline equal to a mid point
public void testZeroLenSubLineAtMidVertex() {
runIndicesOfThenExtract("LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)",
"LINESTRING (10 10, 10 10)");
}
// test a zero-length subline equal to the start point
public void testZeroLenSubLineAtStart() {
runIndicesOfThenExtract("LINESTRING (0 0, 0 10, 10 10, 10 0, 0 0)", "LINESTRING (0 0, 0 0)");
}
}