diff --git a/vtm-android-example/src/org/oscim/android/test/SimpleMapActivity.java b/vtm-android-example/src/org/oscim/android/test/SimpleMapActivity.java
index 336eeac3..33cd85a0 100644
--- a/vtm-android-example/src/org/oscim/android/test/SimpleMapActivity.java
+++ b/vtm-android-example/src/org/oscim/android/test/SimpleMapActivity.java
@@ -1,6 +1,7 @@
 /*
  * Copyright 2013 Hannes Janetzek
  * Copyright 2016 devemux86
+ * Copyright 2016 Andrey Novikov
  *
  * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
  *
@@ -22,9 +23,9 @@ import android.os.Bundle;
 import org.oscim.backend.CanvasAdapter;
 import org.oscim.core.MapPosition;
 import org.oscim.core.MercatorProjection;
-import org.oscim.layers.GroupLayer;
 import org.oscim.layers.tile.buildings.BuildingLayer;
 import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.map.Layers;
 import org.oscim.renderer.BitmapRenderer;
 import org.oscim.renderer.GLViewport;
 import org.oscim.scalebar.DefaultMapScaleBar;
@@ -37,16 +38,22 @@ import org.oscim.theme.ThemeLoader;
 import org.oscim.theme.VtmThemes;
 
 public class SimpleMapActivity extends BaseMapActivity {
+    private static final int GROUP_MAPS = 1;
+    private static final int GROUP_3D_OBJECTS = 2;
+    private static final int GROUP_OVERLAYS = 3;
+
     private DefaultMapScaleBar mapScaleBar;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        GroupLayer groupLayer = new GroupLayer(mMap);
-        groupLayer.layers.add(new BuildingLayer(mMap, mBaseLayer));
-        groupLayer.layers.add(new LabelLayer(mMap, mBaseLayer));
-        mMap.layers().add(groupLayer);
+        Layers layers = mMap.layers();
+        layers.addGroup(GROUP_MAPS);
+        layers.add(new LabelLayer(mMap, mBaseLayer), GROUP_MAPS);
+        layers.addGroup(GROUP_3D_OBJECTS);
+        layers.add(new BuildingLayer(mMap, mBaseLayer), GROUP_3D_OBJECTS);
+        layers.addGroup(GROUP_OVERLAYS);
 
         mapScaleBar = new DefaultMapScaleBar(mMap, CanvasAdapter.dpi / 160);
         mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
@@ -58,7 +65,7 @@ public class SimpleMapActivity extends BaseMapActivity {
         BitmapRenderer renderer = mapScaleBarLayer.getRenderer();
         renderer.setPosition(GLViewport.Position.BOTTOM_LEFT);
         renderer.setOffset(5 * CanvasAdapter.dpi / 160, 0);
-        mMap.layers().add(mapScaleBarLayer);
+        layers.add(mapScaleBarLayer, GROUP_OVERLAYS);
 
         mMap.setTheme(VtmThemes.DEFAULT);
     }
diff --git a/vtm/src/org/oscim/map/Layers.java b/vtm/src/org/oscim/map/Layers.java
index 1d5ace03..7f88c5f8 100644
--- a/vtm/src/org/oscim/map/Layers.java
+++ b/vtm/src/org/oscim/map/Layers.java
@@ -1,6 +1,7 @@
 /*
  * Copyright 2013 Hannes Janetzek
  * Copyright 2016 devemux86
+ * Copyright 2016 Andrey Novikov
  *
  * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
  *
@@ -27,20 +28,25 @@ import org.oscim.map.Map.UpdateListener;
 import org.oscim.renderer.LayerRenderer;
 
 import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 public final class Layers extends AbstractList<Layer> {
 
-    private final CopyOnWriteArrayList<Layer> mLayerList;
     private final Map mMap;
 
+    private final List<Layer> mLayerList = new CopyOnWriteArrayList<>();
+    private final List<Integer> mGroupList = new ArrayList<>();
+    private final java.util.Map<Integer, Integer> mGroupIndex = new HashMap<>();
+
     private boolean mDirtyLayers;
     private LayerRenderer[] mLayerRenderer;
     private Layer[] mLayers;
 
     Layers(Map map) {
         mMap = map;
-        mLayerList = new CopyOnWriteArrayList<>();
     }
 
     @Override
@@ -79,6 +85,28 @@ public final class Layers extends AbstractList<Layer> {
         mDirtyLayers = true;
     }
 
+    /**
+     * Add using layer groups.
+     */
+    public synchronized void add(Layer layer, int group) {
+        int index = mGroupList.indexOf(group);
+        if (index < 0)
+            throw new IllegalArgumentException("unknown layer group");
+        if (mLayerList.contains(layer))
+            throw new IllegalArgumentException("layer added twice");
+
+        index++;
+        if (index == mGroupList.size())
+            add(layer);
+        else {
+            add(mGroupIndex.get(mGroupList.get(index)), layer);
+            for (int i = index; i < mGroupList.size(); i++) {
+                group = mGroupList.get(i);
+                mGroupIndex.put(group, mGroupIndex.get(group) + 1);
+            }
+        }
+    }
+
     @Override
     public synchronized Layer remove(int index) {
         mDirtyLayers = true;
@@ -102,6 +130,13 @@ public final class Layers extends AbstractList<Layer> {
             }
         }
 
+        // update layer group pointers
+        for (Integer group : mGroupIndex.keySet()) {
+            int pointer = mGroupIndex.get(group);
+            if (pointer > index)
+                mGroupIndex.put(group, pointer - 1);
+        }
+
         return remove;
     }
 
@@ -133,6 +168,14 @@ public final class Layers extends AbstractList<Layer> {
         return remove;
     }
 
+    public synchronized void addGroup(int group) {
+        if (mGroupList.contains(group))
+            throw new IllegalArgumentException("group added twice");
+
+        mGroupList.add(group);
+        mGroupIndex.put(group, mLayerList.size());
+    }
+
     /**
      * Should only be used by MapRenderer.
      *