diff --git a/src/org/oscim/utils/quadtree/QuadTree.java b/src/org/oscim/utils/quadtree/QuadTree.java
new file mode 100644
index 00000000..d8bfe19b
--- /dev/null
+++ b/src/org/oscim/utils/quadtree/QuadTree.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 Hannes Janetzek
+ *
+ * This program 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, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see .
+ */
+package org.oscim.utils.quadtree;
+
+public class QuadTree {
+ public QuadTree parent;
+ public QuadTree child00;
+ public QuadTree child10;
+ public QuadTree child01;
+ public QuadTree child11;
+
+ public T item;
+
+ // id of this child relative to parent
+ byte id;
+
+ // number of children and grandchildren
+ int refs = 0;
+
+ public T get(int i){
+ switch (i) {
+ case 0:
+ return (child00 != null) ? child00.item : null;
+ case 1:
+ return (child01 != null) ? child01.item : null;
+ case 2:
+ return (child10 != null) ? child10.item : null;
+ case 3:
+ return (child11 != null) ? child11.item : null;
+ }
+ return null;
+ }
+}
diff --git a/src/org/oscim/utils/quadtree/QuadTreeIndex.java b/src/org/oscim/utils/quadtree/QuadTreeIndex.java
new file mode 100644
index 00000000..02e8e6be
--- /dev/null
+++ b/src/org/oscim/utils/quadtree/QuadTreeIndex.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2013 Hannes Janetzek
+ *
+ * This program 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, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see .
+ */
+package org.oscim.utils.quadtree;
+
+public abstract class QuadTreeIndex {
+
+
+ QuadTree pool;
+
+ QuadTree root;
+
+ public QuadTreeIndex() {
+ root = new QuadTree();
+ root.parent = root;
+ }
+
+ static boolean checkIndex(int x, int y, int z) {
+ if (x < 0 || x >= 1 << z) {
+ //Log.d(TAG, "invalid position");
+ return false;
+ }
+ if (y < 0 || y >= 1 << z) {
+ //Log.d(TAG, "invalid position");
+ return false;
+ }
+ return true;
+ }
+
+ public abstract T create(int x, int y, int z);
+
+ public abstract void remove(T item);
+
+ public QuadTree add(int x, int y, int z) {
+
+ if (!checkIndex(x, y, z))
+ return null;
+
+ QuadTree leaf = root;
+
+ for (int level = z - 1; level >= 0; level--) {
+
+ int id = ((x >> level) & 1) | ((y >> level) & 1) << 1;
+
+ leaf.refs++;
+
+ QuadTree cur = null;
+
+ switch (id) {
+ case 0:
+ cur = leaf.child00;
+ break;
+ case 1:
+ cur = leaf.child01;
+ break;
+ case 2:
+ cur = leaf.child10;
+ break;
+ case 3:
+ cur = leaf.child11;
+ break;
+ }
+
+ if (cur != null) {
+ leaf = cur;
+ continue;
+ }
+
+ if (pool != null) {
+ cur = pool;
+ pool = pool.parent;
+ } else {
+ cur = new QuadTree();
+ }
+
+ cur.refs = 0;
+ cur.id = (byte) id;
+ cur.parent = leaf;
+
+ switch (id) {
+ case 0:
+ cur.parent.child00 = cur;
+ break;
+ case 1:
+ cur.parent.child01 = cur;
+ break;
+ case 2:
+ cur.parent.child10 = cur;
+ break;
+ case 3:
+ cur.parent.child11 = cur;
+ break;
+ }
+
+ leaf = cur;
+ }
+
+ leaf.refs++;
+
+ return leaf;
+ }
+
+ public T getTile(int x, int y, int z) {
+
+ if (!checkIndex(x, y, z))
+ return null;
+
+ QuadTree leaf = root;
+
+ for (int level = z - 1; level >= 0; level--) {
+
+ int id = ((x >> level) & 1) | ((y >> level) & 1) << 1;
+
+ switch (id) {
+ case 0:
+ leaf = leaf.child00;
+ break;
+ case 1:
+ leaf = leaf.child01;
+ break;
+ case 2:
+ leaf = leaf.child10;
+ break;
+ case 3:
+ leaf = leaf.child11;
+ break;
+ }
+
+ if (leaf == null)
+ return null;
+
+ if (level == 0) {
+ return leaf.item;
+ }
+ }
+ return null;
+ }
+
+ public boolean remove(QuadTree item) {
+
+ QuadTree cur = item;
+ QuadTree next;
+
+ for (; cur != root;) {
+ if (cur == null)
+ throw new IllegalArgumentException("QuadTree.remove: item not in index");
+
+ // keep pointer to parent
+ next = cur.parent;
+ cur.refs--;
+
+ // if current node has no children
+ if (cur.refs == 0) {
+ // unhook from parent
+
+ switch (cur.id) {
+ case 0:
+ next.child00 = null;
+ break;
+ case 1:
+ next.child01 = null;
+ break;
+ case 2:
+ next.child10 = null;
+ break;
+ case 3:
+ next.child11 = null;
+ break;
+ }
+
+ // add item back to pool
+ cur.parent = pool;
+ pool = cur;
+ }
+ cur = next;
+ }
+
+ root.refs--;
+
+ return true;
+ }
+}