diff --git a/Pipfile b/Pipfile
index 17c4b913cdd89e63c8c2a3286acc7438a76f7dd0..1cf969a7bf9df7e9bfcb4c9f2521ba339635f40a 100644
--- a/Pipfile
+++ b/Pipfile
@@ -11,6 +11,7 @@ pandas = "*"
 networkx = "*"
 network2tikz = {editable = true,path = "/home/mark/Projekte/network2tikz"}
 requests = "*"
+rtree = "*"
 
 [requires]
 python_version = "3.7"
diff --git a/evrouting/osm/imports.py b/evrouting/osm/imports.py
index e14d10cfab9099160aee3afeeeafd9d9db732437..16c598d0a9fc3125f7c8970f0d50e001fcfa5ac9 100644
--- a/evrouting/osm/imports.py
+++ b/evrouting/osm/imports.py
@@ -15,15 +15,16 @@ Added :
 import copy
 import xml.sax
 import logging
+import itertools
 from collections import namedtuple
 
 import networkx as nx
-import requests
+import rtree
 
-from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY
+from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY, CONSUMPTION_KEY, DISTANCE_KEY
 from evrouting.osm.const import ms_to_kmh
 from evrouting.osm.profiles import speed
-from evrouting.osm.routing import find_nearest, haversine_distance
+from evrouting.osm.routing import point, haversine_distance
 
 logger = logging.getLogger(__name__)
 
@@ -38,40 +39,54 @@ def query_url(service, coordinates, osrm_config: OsrmConf):
            f'{";".join([f"{lon},{lat}" for lat, lon in coordinates])}'
 
 
-def insert_charging_stations(G, charging_stations):
-    """Insert Charging Stations"""
-    S = set()
-    for s in charging_stations:
-        lon = s['lon']
-        lat = s['lat']
-        n = find_nearest(G, (lat, lon), distance_limit=500)
-        if n:
-            G.nodes[n][CHARGING_COEFFICIENT_KEY] = s['power']
-            S.add(n)
-
-    return S
-
-
-class OsrmDistance:
+class OSMGraph(nx.DiGraph):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.charging_stations = set()
+        self._rtree = rtree.index.Index()
+        self._int_index = itertools.count()
+
+    def update_rtree(self, node):
+        info = self.nodes[node]
+        lat, lon = info['lat'], info['lon']
+        self._rtree.insert(next(self._int_index), (lon, lat, lon, lat), obj=node)
+
+    def insert_charging_stations(self, charging_stations):
+        """Insert Charging Stations"""
+        S = set()
+        for s in charging_stations:
+            lon = s['lon']
+            lat = s['lat']
+            n = self.find_nearest((lat, lon), distance_limit=500)
+            if n is not None:
+                self.nodes[n][CHARGING_COEFFICIENT_KEY] = s['power']
+                S.add(n)
+
+        self.charging_stations = S
+
+    def find_nearest(self, v: point, distance_limit=None):
+        """
+        Find nearest point to location v within radius
+        of distance_limit.
+        """
+        lat_v, lon_v = v
 
-    def __init__(self, osrm_config: OsrmConf = None):
-        self.osrm_config = osrm_config or OsrmConf(
-            server='localhost',
-            port=5000
-        )
+        n = next(self._rtree.nearest(
+            (lon_v, lat_v, lon_v, lat_v), 1, objects=True
+        )).object
 
-    def __call__(self, G, u, v):
-        """Calc distance between u and v on osrm."""
-        coordinates = [
-            (G.nodes[u]['lat'], G.nodes[u]['lon']),
-            (G.nodes[v]['lat'], G.nodes[v]['lon'])
-        ]
-        url = query_url('route', coordinates, self.osrm_config)
+        if distance_limit is not None:
+            d = haversine_distance(
+                self.nodes[n]['lat'],
+                self.nodes[n]['lon'],
+                lat_v,
+                lon_v,
+                unit_m=True
+            )
+            if d > distance_limit:
+                n = None
 
-        resp = requests.get(url, timeout=0.1)
-        resp.raise_for_status()
-        resp = resp.json()
-        return resp['routes'][0]['duration']
+        return n
 
 
 def read_osm(osm_xml_data, profile) -> nx.DiGraph:
@@ -82,7 +97,7 @@ def read_osm(osm_xml_data, profile) -> nx.DiGraph:
     """
 
     osm = OSM(osm_xml_data)
-    G = nx.DiGraph()
+    G = OSMGraph()
 
     # Add ways
     for w in osm.ways.values():
@@ -101,11 +116,17 @@ def read_osm(osm_xml_data, profile) -> nx.DiGraph:
 
             if w.tags.get('oneway', 'no') == 'yes':
                 # ONLY ONE DIRECTION
-                G.add_edge(u_id, v_id, weight=d)
+                G.add_edge(u_id, v_id, **{
+                    DISTANCE_KEY: d
+                })
             else:
                 # BOTH DIRECTION
-                G.add_edge(u_id, v_id, weight=d)
-                G.add_edge(v_id, u_id, weight=d)
+                G.add_edge(u_id, v_id,**{
+                    DISTANCE_KEY: d
+                })
+                G.add_edge(v_id, u_id, **{
+                    DISTANCE_KEY: d
+                })
 
     # Complete the used nodes' information
     for n_id in G.nodes():
@@ -113,6 +134,7 @@ def read_osm(osm_xml_data, profile) -> nx.DiGraph:
         G.nodes[n_id]['lat'] = n.lat
         G.nodes[n_id]['lon'] = n.lon
         G.nodes[n_id]['id'] = n.id
+        G.update_rtree(n_id)
 
     return G
 
diff --git a/evrouting/osm/routing.py b/evrouting/osm/routing.py
index fbf877a085c12fcf543feea745e49ed7633f3180..fe636d4ca8ff54cbc17f70bbfb48661a271daa26 100644
--- a/evrouting/osm/routing.py
+++ b/evrouting/osm/routing.py
@@ -30,38 +30,10 @@ def haversine_distance(lon1, lat1, lon2, lat2, unit_m=True):
     return c * r
 
 
-def find_nearest(G, v: point, distance_limit=None):
-    """
-    Find nearest point to location v within radius
-    of distance_limit.
-    """
-    min_dist = None
-    closest_node = None
-
-    lat_v, lon_v = v
-
-    for n in G.nodes:
-        d = haversine_distance(
-            G.nodes[n]['lat'],
-            G.nodes[n]['lon'],
-            lat_v,
-            lon_v,
-            unit_m=True
-        )
-        if min_dist is None or d < min_dist:
-            closest_node = n
-            min_dist = d
-
-    if distance_limit:
-        return closest_node if min_dist <= distance_limit else None
-    else:
-        return closest_node
-
-
 def shortest_path(G, s: point, t: point, profile):
     """Calc A* shortest path."""
-    _s = find_nearest(G, s)
-    _t = find_nearest(G, t)
+    _s = G.find_nearest(s)
+    _t = G.find_nearest(t)
 
     def dist(u, v):
         return haversine_distance(
@@ -82,6 +54,7 @@ def to_coordinates(G, path):
     Note: Coordinates are (lon, lat) to conform to
         geojson.
     """
+
     def get_coordinates(n):
         lat = G.nodes[n]['lat']
         lon = G.nodes[n]['lon']
diff --git a/setup.py b/setup.py
index 0e84d01775835dce914c80a0db40f9c54dbf9a3d..5d2f8bc989bd61ae9ab58aa73de56a6544b49f3f 100644
--- a/setup.py
+++ b/setup.py
@@ -29,6 +29,7 @@ setup(
     python_requires='>=3.4.*, <4',
     install_requires=[
         'networkx',
-        'requests'
+        'requests',
+        'rtree'
     ]
 )
diff --git a/tests/osm/test_osm_charge.py b/tests/osm/test_osm_charge.py
index 5a2bbb0161d305c87bd5871b16f99d0751fa7b6f..becf5d5e595a27c52bc46f5365c842c3359dad98 100644
--- a/tests/osm/test_osm_charge.py
+++ b/tests/osm/test_osm_charge.py
@@ -1,10 +1,8 @@
 import os
 
 import pytest
-import networkx as nx
-import rtree
 
-from evrouting.osm.imports import read_osm, insert_charging_stations
+from evrouting.osm.imports import read_osm, OSMGraph
 from evrouting.osm.profiles import car
 from evrouting.osm.routing import shortest_path
 from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY
@@ -12,8 +10,7 @@ from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY
 
 @pytest.fixture
 def graph():
-    G = nx.DiGraph()
-    G.rtree = rtree.index.Index()
+    G = OSMGraph()
 
     node_coordinates = [
         (51.7705832, 7.0002595),
@@ -24,7 +21,7 @@ def graph():
         lat, lon = coordinates
         # Add two nodes, that exist in osm test map
         G.add_node(n_id, lat=lat, lon=lon)
-        G.rtree.insert(n_id, (lon, lat, lon, lat))
+        G.update_rtree(n_id)
 
     yield G
     del G
@@ -42,7 +39,7 @@ def test_insert_charging_stations_close(graph):
     # Close two node 1
     S = [{"lon": 7.0002593, "lat": 51.7705832, "power": 22.0}]
 
-    graph = insert_charging_stations(graph, S)
+    graph.insert_charging_stations(S)
 
     assert graph.nodes[0][CHARGING_COEFFICIENT_KEY] == 22.0
     assert CHARGING_COEFFICIENT_KEY not in graph.nodes[1]
@@ -52,7 +49,7 @@ def test_insert_charging_stations_eq(graph):
     # Close exactly at node 1
     S = [{"lon": 7.0002595, "lat": 51.7705832, "power": 22.0}]
 
-    graph = insert_charging_stations(graph, S)
+    graph.insert_charging_stations(S)
 
     assert graph.nodes[0][CHARGING_COEFFICIENT_KEY] == 22.0
     assert CHARGING_COEFFICIENT_KEY not in graph.nodes[1]