package org.oscim.utils; import static java.lang.System.currentTimeMillis; import static java.lang.System.out; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.junit.Assert; import org.junit.Test; import org.oscim.core.Box; import org.oscim.utils.SpatialIndex.SearchCb; public class QuadTreeTest { final static Random rand = new Random((long) (Math.PI * 10000000)); public class Item { final int val; final Box bbox;; Item(Box bbox, int val) { this.val = val; this.bbox = new Box(bbox); } @Override public String toString() { return String.valueOf(val) + ' ' + bbox; } } ArrayList<Item> fillRandomTree(SpatialIndex<Item> q, int numItems) { Box box = new Box(); ArrayList<Item> items = new ArrayList<Item>(numItems + 16); for (int i = 0; i < numItems; i++) { box.xmin = (int) (rand.nextDouble() * 10000 - 5000); box.ymin = (int) (rand.nextDouble() * 10000 - 5000); box.xmax = (int) (box.xmin + rand.nextDouble() * 500); box.ymax = (int) (box.ymin + rand.nextDouble() * 500); Item it = new Item(box, i); q.insert(box, it); items.add(it); } return items; } @Test public void shouldWork0() { SpatialIndex<Item> q = new QuadTree<Item>(Short.MAX_VALUE + 1, 16); //SpatialIndex<Item> q = new RTree<Item>(); int numItems = 10000; List<Item> items = fillRandomTree(q, numItems); final int[] found = { 0 }; final int[] matched = { 0 }; for (Item it : items) { int f = matched[0]; q.search(it.bbox, new SearchCb<Item>() { @Override public boolean call(Item item, Object context) { found[0]++; if (context == item) { matched[0]++; return false; } return true; } }, it); if (f == matched[0]) out.println((it.bbox.xmax - it.bbox.xmin) + " x " + (it.bbox.ymax - it.bbox.ymin) + " ==> " + it); } //out.println("m:" + matched[0] + " f:" + found[0]); Assert.assertEquals(numItems, matched[0]); Assert.assertEquals(numItems, q.size()); } @Test public void shouldWork1() { long time = currentTimeMillis(); for (int i = 0; i < 10; i++) { shouldWork0(); } long now = currentTimeMillis(); out.println("==>" + (now - time) / 10.0f + "ms"); } @Test public void shouldWork6() { SpatialIndex<Item> q = new QuadTree<Item>(Short.MAX_VALUE + 1, 16); Box box = new Box(-4184.653317773969, 3183.6174297948446, -4088.3197324911957, 3222.7770427421046); Item it = new Item(box, 1); q.insert(box, it); q.search(it.bbox, new SearchCb<Item>() { @Override public boolean call(Item item, Object context) { out.println("==> " + item + " " + (context == item)); return true; } }, it); Assert.assertEquals(1, q.size()); } @Test public void shouldWork7() { SpatialIndex<Item> q = new QuadTree<Item>(Short.MAX_VALUE + 1, 14); //SpatialIndex<Item> q = new RTree<Item>(); int numItems = 10000; List<Item> items = fillRandomTree(q, numItems); Assert.assertEquals(numItems, q.size()); int cnt = numItems; for (Item it : items) { if (!q.remove(it.bbox, it)) { out.println((it.bbox.xmax - it.bbox.xmin) + " x " + (it.bbox.ymax - it.bbox.ymin) + " ==> " + it); q.search(it.bbox, new SearchCb<Item>() { @Override public boolean call(Item item, Object context) { if (context == item) { out.println("found..."); return false; } return true; } }, it); } Assert.assertEquals(--cnt, q.size()); } items = fillRandomTree(q, numItems); Assert.assertEquals(numItems, q.size()); cnt = numItems; for (Item it : items) { if (!q.remove(it.bbox, it)) out.println((it.bbox.xmax - it.bbox.xmin) + " x " + (it.bbox.ymax - it.bbox.ymin) + " => " + it); Assert.assertEquals(--cnt, q.size()); } Assert.assertEquals(0, q.size()); out.println(""); } @Test public void shouldWork8() { SpatialIndex<Item> q = new QuadTree<Item>(Short.MAX_VALUE + 1, 16); //SpatialIndex<Item> q = new RTree<Item>(); int numItems = 10000; List<Item> items = fillRandomTree(q, numItems); final int[] found = { 0 }; final int[] matched = { 0 }; for (Item it : items) { int f = matched[0]; int cnt = 0; for (Item it2 : items) { if (it2.bbox.overlap(it.bbox)) cnt++; } found[0] = 0; q.search(it.bbox, new SearchCb<Item>() { @Override public boolean call(Item item, Object context) { found[0]++; if (context == item) { matched[0]++; //return false; } return true; } }, it); if (found[0] != cnt) { out.println("not found " + (found[0] - cnt)); } //Assert.assertEquals(cnt, found[0]); if (f == matched[0]) out.println((it.bbox.xmax - it.bbox.xmin) + " x " + (it.bbox.ymax - it.bbox.ymin) + " ==> " + it); } //out.println("m:" + matched[0] + " f:" + found[0]); Assert.assertEquals(numItems, matched[0]); Assert.assertEquals(numItems, q.size()); } public static void main(String[] args) { QuadTreeTest qt = new QuadTreeTest(); long time = currentTimeMillis(); for (int i = 0; i < 100; i++) { qt.shouldWork0(); long now = currentTimeMillis(); out.println("==>" + (now - time)); time = now; } } }