/* * Copyright (c) 2016 Martin Davis. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * * http://www.eclipse.org/org/documents/edl-v10.php. */ package org.locationtech.jts.index.kdtree; import java.util.Arrays; import java.util.List; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.CoordinateArrays; import org.locationtech.jts.geom.Envelope; import junit.framework.TestCase; import junit.textui.TestRunner; import test.jts.util.IOUtil; public class KdTreeTest extends TestCase { public static void main(String args[]) { TestRunner.run(KdTreeTest.class); } public KdTreeTest(String name) { super(name); } public void testSinglePoint() { KdTree index = new KdTree(.001); KdNode node1 = index.insert(new Coordinate(1, 1)); KdNode node2 = index.insert(new Coordinate(1, 1)); assertTrue("Inserting 2 identical points should create one node", node1 == node2); Envelope queryEnv = new Envelope(0, 10, 0, 10); List result = index.query(queryEnv); assertTrue(result.size() == 1); KdNode node = (KdNode) result.get(0); assertTrue(node.getCount() == 2); assertTrue(node.isRepeated()); } public void testMultiplePoint() { testQuery("MULTIPOINT ( (1 1), (2 2) )", 0, new Envelope(0, 10, 0, 10), "MULTIPOINT ( (1 1), (2 2) )"); } public void testSubset() { testQuery("MULTIPOINT ( (1 1), (2 2), (3 3), (4 4) )", 0, new Envelope(1.5, 3.4, 1.5, 3.5), "MULTIPOINT ( (2 2), (3 3) )"); } public void testToleranceFailure() { testQuery("MULTIPOINT ( (0 0), (-.1 1), (.1 1) )", 1, new Envelope(-9, 9, -9, 9), "MULTIPOINT ( (0 0), (-.1 1) )"); } public void testTolerance2() { testQuery("MULTIPOINT ((10 60), (20 60), (30 60), (30 63))", 9, new Envelope(0,99, 0, 99), "MULTIPOINT ((10 60), (20 60), (30 60))"); } public void testTolerance2_perturbedY() { testQuery("MULTIPOINT ((10 60), (20 61), (30 60), (30 63))", 9, new Envelope(0,99, 0, 99), "MULTIPOINT ((10 60), (20 61), (30 60))"); } public void testSnapToNearest() { testQueryRepeated("MULTIPOINT ( (10 60), (20 60), (16 60))", 5, new Envelope(0,99, 0, 99), "MULTIPOINT ( (10 60), (20 60), (20 60))"); } private void testQuery(String wktInput, double tolerance, Envelope queryEnv, String wktExpected) { KdTree index = build(wktInput, tolerance); testQuery( index, queryEnv, false, IOUtil.read(wktExpected).getCoordinates()); } private void testQueryRepeated(String wktInput, double tolerance, Envelope queryEnv, String wktExpected) { KdTree index = build(wktInput, tolerance); testQuery( index, queryEnv, true, IOUtil.read(wktExpected).getCoordinates()); } private void testQuery(KdTree index, Envelope queryEnv, Coordinate[] expectedCoord) { Coordinate[] result = KdTree.toCoordinates(index.query(queryEnv)); Arrays.sort(result); Arrays.sort(expectedCoord); assertTrue("Result count = " + result.length + ", expected count = " + expectedCoord.length, result.length == expectedCoord.length); boolean isMatch = CoordinateArrays.equals(result, expectedCoord); assertTrue("Expected result coordinates not found", isMatch); } private void testQuery(KdTree index, Envelope queryEnv, boolean includeRepeated, Coordinate[] expectedCoord) { Coordinate[] result = KdTree.toCoordinates(index.query(queryEnv), includeRepeated); Arrays.sort(result); Arrays.sort(expectedCoord); assertTrue("Result count = " + result.length + ", expected count = " + expectedCoord.length, result.length == expectedCoord.length); boolean isMatch = CoordinateArrays.equals(result, expectedCoord); assertTrue("Expected result coordinates not found", isMatch); } private KdTree build(String wktInput, double tolerance) { final KdTree index = new KdTree(tolerance); Coordinate[] coords = IOUtil.read(wktInput).getCoordinates(); for (int i = 0; i < coords.length; i++) { index.insert(coords[i]); } return index; } }