From 18ee0a393fbfdb2ed8ad1c9e1ab18a0845f1e2cb Mon Sep 17 00:00:00 2001
From: Jan Lippert <lippertsjan@gmail.com>
Date: Mon, 13 Apr 2020 18:55:27 +0200
Subject: [PATCH] Update vtm-jeo module (#770)

---
 build.gradle                                  |   1 -
 settings.gradle                               |   2 +-
 vtm-android-example/AndroidManifest.xml       |   4 +-
 vtm-android-example/build.gradle              |   2 +-
 .../oscim/android/test/JeoIndoorActivity.java | 371 +++++++-------
 .../src/org/oscim/android/test/Samples.java   |   2 +-
 vtm-jeo/build.gradle                          |   5 +-
 vtm-jeo/src/org/oscim/jeo/JeoUtils.java       |   2 +-
 .../src/org/oscim/layers/JeoTileSource.java   |   8 +-
 .../src/org/oscim/layers/JeoVectorLayer.java  |  17 +-
 vtm-jeo/src/org/oscim/layers/JtsLayer.java    |   9 +-
 .../src/org/oscim/layers/OSMIndoorLayer.java  |  13 +-
 vtm-jeo/src/org/oscim/test/JeoTest.java       |  51 +-
 .../org/oscim/theme/carto/BasicFeature.java   | 452 ++++++++++++++++++
 .../org/oscim/theme/carto/MatcherFeature.java |  19 -
 .../org/oscim/theme/carto/RenderTheme.java    |  12 +-
 vtm-playground/build.gradle                   |   2 +-
 .../src/org/oscim/test/jeo/LayerTest.java     | 184 +++----
 .../src/org/oscim/test/jeo/ThemeTest.java     | 100 ++--
 19 files changed, 829 insertions(+), 427 deletions(-)
 create mode 100644 vtm-jeo/src/org/oscim/theme/carto/BasicFeature.java

diff --git a/build.gradle b/build.gradle
index dcf7061b..1777d526 100644
--- a/build.gradle
+++ b/build.gradle
@@ -42,7 +42,6 @@ def versionName() { return version }
 subprojects {
     repositories {
         google()
-        //maven { url 'https://repo.boundlessgeo.com/main/' }
         jcenter()
         maven { url 'https://jitpack.io' }
     }
diff --git a/settings.gradle b/settings.gradle
index 814da947..ddc74185 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,7 +14,7 @@ include ':vtm-gdx-poi3d'
 include ':vtm-http'
 include ':vtm-ios'
 include ':vtm-ios-example'
-//include ':vtm-jeo'
+include ':vtm-jeo'
 include ':vtm-json'
 include ':vtm-jts'
 include ':vtm-models'
diff --git a/vtm-android-example/AndroidManifest.xml b/vtm-android-example/AndroidManifest.xml
index 00f2c5e1..62e58c0c 100644
--- a/vtm-android-example/AndroidManifest.xml
+++ b/vtm-android-example/AndroidManifest.xml
@@ -42,9 +42,9 @@
         <activity
             android:name=".GdxPoi3DActivity"
             android:configChanges="keyboardHidden|orientation|screenSize" />
-        <!--<activity
+        <activity
             android:name=".JeoIndoorActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize" />-->
+            android:configChanges="keyboardHidden|orientation|screenSize" />
         <activity
             android:name=".LineTexActivity"
             android:configChanges="keyboardHidden|orientation|screenSize" />
diff --git a/vtm-android-example/build.gradle b/vtm-android-example/build.gradle
index 6373c096..c6a7e332 100644
--- a/vtm-android-example/build.gradle
+++ b/vtm-android-example/build.gradle
@@ -5,7 +5,7 @@ dependencies {
     implementation project(':vtm-android-mvt')
     implementation project(':vtm-extras')
     implementation project(':vtm-http')
-    //implementation project(':vtm-jeo')
+    implementation project(':vtm-jeo')
     implementation project(':vtm-json')
     implementation project(':vtm-jts')
     implementation project(':vtm-mvt')
diff --git a/vtm-android-example/src/org/oscim/android/test/JeoIndoorActivity.java b/vtm-android-example/src/org/oscim/android/test/JeoIndoorActivity.java
index c5eda5e0..809cd770 100644
--- a/vtm-android-example/src/org/oscim/android/test/JeoIndoorActivity.java
+++ b/vtm-android-example/src/org/oscim/android/test/JeoIndoorActivity.java
@@ -1,186 +1,185 @@
-///*
-// * Copyright 2014 Hannes Janetzek
-// * Copyright 2016-2018 devemux86
-// *
-// * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
-// *
-// * 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 <http://www.gnu.org/licenses/>.
-// */
-//package org.oscim.android.test;
-//
-//import android.content.Context;
-//import android.os.Bundle;
-//import android.view.View;
-//import android.widget.Toast;
-//import android.widget.ToggleButton;
-//
-//import org.jeo.map.Style;
-//import org.jeo.vector.VectorDataset;
-//import org.oscim.backend.CanvasAdapter;
-//import org.oscim.backend.canvas.Color;
-//import org.oscim.layers.OSMIndoorLayer;
-//import org.oscim.layers.tile.buildings.BuildingLayer;
-//import org.oscim.layers.tile.vector.labeling.LabelLayer;
-//import org.oscim.test.JeoTest;
-//import org.oscim.theme.VtmThemes;
-//import org.oscim.theme.styles.TextStyle;
-//import org.oscim.utils.IOUtils;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//
-//import java.io.IOException;
-//import java.io.InputStream;
-//import java.net.URL;
-//import java.net.URLConnection;
-//import java.util.Arrays;
-//
-//public class JeoIndoorActivity extends BaseMapActivity {
-//    public static final Logger log = LoggerFactory.getLogger(JeoIndoorActivity.class);
-//
-//    // from http://overpass-turbo.eu/s/2vp
-//    String PATH = "https://gist.githubusercontent.com/anonymous/09062103a66844a96048f25626078c8d/raw/1d3af6a5a55e9ea4adc9551fa633a051a44a5a9c/overpass.geojson";
-//
-//    private OSMIndoorLayer mIndoorLayer;
-//
-//    public JeoIndoorActivity() {
-//        super(R.layout.jeo_indoor_map);
-//    }
-//
-//    @Override
-//    public void onCreate(Bundle savedInstanceState) {
-//        super.onCreate(savedInstanceState);
-//
-//        mMap.addTask(new Runnable() {
-//            @Override
-//            public void run() {
-//                showToast("load data");
-//                InputStream is = null;
-//                try {
-//                    //    File file = new File(Environment.getExternalStorageDirectory()
-//                    //        .getAbsolutePath(), "osmindoor.json");
-//                    //    is = new FileInputStream(file);
-//
-//                    URL url = new URL(PATH);
-//                    URLConnection conn = url.openConnection();
-//                    is = conn.getInputStream();
-//                    loadJson(is);
-//                } catch (IOException e) {
-//                    e.printStackTrace();
-//                } finally {
-//                    IOUtils.closeQuietly(is);
-//                }
-//            }
-//        });
-//
-//        mMap.setTheme(VtmThemes.DEFAULT);
-//
-//        mMap.layers().add(new BuildingLayer(mMap, mBaseLayer));
-//        mMap.layers().add(new LabelLayer(mMap, mBaseLayer));
-//
-//        //    String file = Environment.getExternalStorageDirectory().getAbsolutePath();
-//        //    VectorDataset data = (VectorDataset) JeoTest.getJsonData(file + "/states.json", true);
-//        //    Style style = JeoTest.getStyle();
-//        //    mMap.layers().add(new JeoVectorLayer(mMap, data, style));
-//    }
-//
-//    void loadJson(InputStream is) {
-//        showToast("got data");
-//
-//        VectorDataset data = JeoTest.readGeoJson(is);
-//        Style style = JeoTest.getStyle();
-//        TextStyle textStyle = TextStyle.builder()
-//                .isCaption(true)
-//                .fontSize(16 * CanvasAdapter.getScale()).color(Color.BLACK)
-//                .strokeWidth(2.2f * CanvasAdapter.getScale()).strokeColor(Color.WHITE)
-//                .build();
-//        mIndoorLayer = new OSMIndoorLayer(mMap, data, style, textStyle);
-//        mMap.layers().add(mIndoorLayer);
-//
-//        showToast("data ready");
-//        mMap.updateMap(true);
-//
-//        mIndoorLayer.activeLevels[0] = true;
-//        shift();
-//    }
-//
-//    public void showToast(final String text) {
-//        final Context ctx = this;
-//        runOnUiThread(new Runnable() {
-//            @Override
-//            public void run() {
-//                Toast toast = Toast.makeText(ctx, text, Toast.LENGTH_SHORT);
-//                toast.show();
-//            }
-//        });
-//    }
-//
-//    boolean mShift = true;
-//
-//    public void shift() {
-//        if (!mShift)
-//            return;
-//
-//        mMap.postDelayed(new Runnable() {
-//
-//            @Override
-//            public void run() {
-//                for (int i = 0; i < 10; i++) {
-//                    if (mIndoorLayer.activeLevels[i]) {
-//                        mIndoorLayer.activeLevels[i] = false;
-//                        mIndoorLayer.activeLevels[(i + 1) % 9] = true;
-//                        mIndoorLayer.update();
-//                        break;
-//                    }
-//                }
-//                shift();
-//            }
-//        }, 200);
-//
-//    }
-//
-//    public void onClick(View v) {
-//        mShift = false;
-//
-//        if (mIndoorLayer == null)
-//            return;
-//
-//        int i = 0;
-//
-//        if (v instanceof ToggleButton) {
-//            ToggleButton b = (ToggleButton) v;
-//            i = (b.getTextOn().charAt(0) - '0') + 1;
-//        }
-//
-//        if (i < 0 || i > 9)
-//            i = 0;
-//
-//        mIndoorLayer.activeLevels[i] ^= true;
-//        if (v instanceof ToggleButton)
-//            ((ToggleButton) v).setChecked(mIndoorLayer.activeLevels[i]);
-//        log.debug(Arrays.toString(mIndoorLayer.activeLevels));
-//        mIndoorLayer.update();
-//    }
-//
-//    @Override
-//    protected void onStop() {
-//        super.onStop();
-//    }
-//
-//    @Override
-//    protected void onResume() {
-//        super.onResume();
-//
-//        /* ignore saved position */
-//        //mMap.setMapPosition(49.417, 8.673, 1 << 17);
-//        mMap.setMapPosition(53.5620092, 9.9866457, 1 << 16);
-//    }
-//}
+/*
+ * Copyright 2014 Hannes Janetzek
+ * Copyright 2016-2018 devemux86
+ *
+ * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.android.test;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Toast;
+import android.widget.ToggleButton;
+import io.jeo.map.Style;
+import io.jeo.vector.VectorDataset;
+import org.oscim.backend.CanvasAdapter;
+import org.oscim.backend.canvas.Color;
+import org.oscim.layers.OSMIndoorLayer;
+import org.oscim.layers.tile.buildings.BuildingLayer;
+import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.test.JeoTest;
+import org.oscim.theme.VtmThemes;
+import org.oscim.theme.styles.TextStyle;
+import org.oscim.utils.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+
+public class JeoIndoorActivity extends BaseMapActivity {
+    public static final Logger log = LoggerFactory.getLogger(JeoIndoorActivity.class);
+
+    // from http://overpass-turbo.eu/s/2vp
+    String PATH = "https://gist.githubusercontent.com/anonymous/09062103a66844a96048f25626078c8d/raw/1d3af6a5a55e9ea4adc9551fa633a051a44a5a9c/overpass.geojson";
+
+    private OSMIndoorLayer mIndoorLayer;
+
+    public JeoIndoorActivity() {
+        super(R.layout.jeo_indoor_map);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mMap.addTask(new Runnable() {
+            @Override
+            public void run() {
+                showToast("load data");
+                InputStream is = null;
+                try {
+                    //    File file = new File(Environment.getExternalStorageDirectory()
+                    //        .getAbsolutePath(), "osmindoor.json");
+                    //    is = new FileInputStream(file);
+
+                    URL url = new URL(PATH);
+                    URLConnection conn = url.openConnection();
+                    is = conn.getInputStream();
+                    loadJson(is);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                } finally {
+                    IOUtils.closeQuietly(is);
+                }
+            }
+        });
+
+        mMap.setTheme(VtmThemes.DEFAULT);
+
+        mMap.layers().add(new BuildingLayer(mMap, mBaseLayer));
+        mMap.layers().add(new LabelLayer(mMap, mBaseLayer));
+
+        //    String file = Environment.getExternalStorageDirectory().getAbsolutePath();
+        //    VectorDataset data = (VectorDataset) JeoTest.getJsonData(file + "/states.json", true);
+        //    Style style = JeoTest.getStyle();
+        //    mMap.layers().add(new JeoVectorLayer(mMap, data, style));
+    }
+
+    void loadJson(InputStream is) {
+        showToast("got data");
+
+        VectorDataset data = JeoTest.readGeoJson(is);
+        Style style = JeoTest.getStyle();
+        TextStyle textStyle = TextStyle.builder()
+                .isCaption(true)
+                .fontSize(16 * CanvasAdapter.getScale()).color(Color.BLACK)
+                .strokeWidth(2.2f * CanvasAdapter.getScale()).strokeColor(Color.WHITE)
+                .build();
+        mIndoorLayer = new OSMIndoorLayer(mMap, data, style, textStyle);
+        mMap.layers().add(mIndoorLayer);
+
+        showToast("data ready");
+        mMap.updateMap(true);
+
+        mIndoorLayer.activeLevels[0] = true;
+        shift();
+    }
+
+    public void showToast(final String text) {
+        final Context ctx = this;
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast toast = Toast.makeText(ctx, text, Toast.LENGTH_SHORT);
+                toast.show();
+            }
+        });
+    }
+
+    boolean mShift = true;
+
+    public void shift() {
+        if (!mShift)
+            return;
+
+        mMap.postDelayed(new Runnable() {
+
+            @Override
+            public void run() {
+                for (int i = 0; i < 10; i++) {
+                    if (mIndoorLayer.activeLevels[i]) {
+                        mIndoorLayer.activeLevels[i] = false;
+                        mIndoorLayer.activeLevels[(i + 1) % 9] = true;
+                        mIndoorLayer.update();
+                        break;
+                    }
+                }
+                shift();
+            }
+        }, 200);
+
+    }
+
+    public void onClick(View v) {
+        mShift = false;
+
+        if (mIndoorLayer == null)
+            return;
+
+        int i = 0;
+
+        if (v instanceof ToggleButton) {
+            ToggleButton b = (ToggleButton) v;
+            i = (b.getTextOn().charAt(0) - '0') + 1;
+        }
+
+        if (i < 0 || i > 9)
+            i = 0;
+
+        mIndoorLayer.activeLevels[i] ^= true;
+        if (v instanceof ToggleButton)
+            ((ToggleButton) v).setChecked(mIndoorLayer.activeLevels[i]);
+        log.debug(Arrays.toString(mIndoorLayer.activeLevels));
+        mIndoorLayer.update();
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        /* ignore saved position */
+        //mMap.setMapPosition(49.417, 8.673, 1 << 17);
+        mMap.setMapPosition(53.5620092, 9.9866457, 1 << 16);
+    }
+}
diff --git a/vtm-android-example/src/org/oscim/android/test/Samples.java b/vtm-android-example/src/org/oscim/android/test/Samples.java
index 2f862a5a..79fdd26b 100644
--- a/vtm-android-example/src/org/oscim/android/test/Samples.java
+++ b/vtm-android-example/src/org/oscim/android/test/Samples.java
@@ -128,7 +128,7 @@ public class Samples extends Activity {
         linearLayout.addView(createLabel("Experiments"));
         linearLayout.addView(createButton(ReverseGeocodeActivity.class));
         linearLayout.addView(createButton(ThemeStylerActivity.class));
-        //linearLayout.addView(createButton(JeoIndoorActivity.class));
+        linearLayout.addView(createButton(JeoIndoorActivity.class));
         linearLayout.addView(createButton(GdxPoi3DActivity.class));
         linearLayout.addView(createButton(OverpassActivity.class));
         linearLayout.addView(createButton(ClusterMarkerOverlayActivity.class));
diff --git a/vtm-jeo/build.gradle b/vtm-jeo/build.gradle
index 40044a22..827ded29 100644
--- a/vtm-jeo/build.gradle
+++ b/vtm-jeo/build.gradle
@@ -3,10 +3,7 @@ apply plugin: 'maven'
 
 dependencies {
     api project(':vtm')
-    api('org.jeo:jeo:0-SNAPSHOT') {
-        exclude group: 'org.slf4j', module: 'slf4j-jdk14'
-    }
-    api('org.jeo:jeo-carto:0-SNAPSHOT') {
+    api('com.github.jeo.jeo:jeo-carto:master-SNAPSHOT') {
         exclude group: 'org.slf4j', module: 'slf4j-jdk14'
     }
 }
diff --git a/vtm-jeo/src/org/oscim/jeo/JeoUtils.java b/vtm-jeo/src/org/oscim/jeo/JeoUtils.java
index def14a68..ce6c804a 100644
--- a/vtm-jeo/src/org/oscim/jeo/JeoUtils.java
+++ b/vtm-jeo/src/org/oscim/jeo/JeoUtils.java
@@ -1,6 +1,6 @@
 package org.oscim.jeo;
 
-import org.jeo.map.RGB;
+import io.jeo.map.RGB;
 
 public class JeoUtils {
     public static int color(RGB rgb) {
diff --git a/vtm-jeo/src/org/oscim/layers/JeoTileSource.java b/vtm-jeo/src/org/oscim/layers/JeoTileSource.java
index 9cade819..c84ba9af 100644
--- a/vtm-jeo/src/org/oscim/layers/JeoTileSource.java
+++ b/vtm-jeo/src/org/oscim/layers/JeoTileSource.java
@@ -16,8 +16,8 @@
  */
 package org.oscim.layers;
 
-import org.jeo.tile.Tile;
-import org.jeo.tile.TileDataset;
+import io.jeo.tile.Tile;
+import io.jeo.tile.TileDataset;
 import org.oscim.backend.CanvasAdapter;
 import org.oscim.backend.canvas.Bitmap;
 import org.oscim.layers.tile.MapTile;
@@ -30,9 +30,7 @@ import org.slf4j.LoggerFactory;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 
-import static org.oscim.tiling.QueryResult.FAILED;
-import static org.oscim.tiling.QueryResult.SUCCESS;
-import static org.oscim.tiling.QueryResult.TILE_NOT_FOUND;
+import static org.oscim.tiling.QueryResult.*;
 
 public class JeoTileSource extends TileSource {
     static final Logger log = LoggerFactory.getLogger(JeoTileSource.class);
diff --git a/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java b/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java
index 4a6339fa..9c43ca0b 100644
--- a/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java
+++ b/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java
@@ -19,16 +19,11 @@ package org.oscim.layers;
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.LineString;
-
-import org.jeo.geom.Geom;
-import org.jeo.map.CartoCSS;
-import org.jeo.map.RGB;
-import org.jeo.map.Rule;
-import org.jeo.map.RuleList;
-import org.jeo.map.Style;
-import org.jeo.vector.Feature;
-import org.jeo.vector.VectorDataset;
-import org.jeo.vector.VectorQuery;
+import io.jeo.geom.Geom;
+import io.jeo.map.*;
+import io.jeo.vector.Feature;
+import io.jeo.vector.VectorDataset;
+import io.jeo.vector.VectorQuery;
 import org.oscim.jeo.JeoUtils;
 import org.oscim.map.Map;
 import org.oscim.renderer.bucket.LineBucket;
@@ -77,7 +72,7 @@ public class JeoVectorLayer extends JtsLayer {
             VectorQuery q = new VectorQuery().bounds(b);
             if (dbg)
                 log.debug("query {}", b);
-            for (Feature f : mDataset.cursor(q)) {
+            for (Feature f : mDataset.read(q)) {
                 if (dbg)
                     log.debug("feature {}", f);
 
diff --git a/vtm-jeo/src/org/oscim/layers/JtsLayer.java b/vtm-jeo/src/org/oscim/layers/JtsLayer.java
index 68d5b950..8e751194 100644
--- a/vtm-jeo/src/org/oscim/layers/JtsLayer.java
+++ b/vtm-jeo/src/org/oscim/layers/JtsLayer.java
@@ -21,13 +21,8 @@ package org.oscim.layers;
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
-
-import org.jeo.geom.CoordinatePath;
-import org.oscim.core.Box;
-import org.oscim.core.GeometryBuffer;
-import org.oscim.core.MapPosition;
-import org.oscim.core.MercatorProjection;
-import org.oscim.core.Tile;
+import io.jeo.geom.CoordinatePath;
+import org.oscim.core.*;
 import org.oscim.layers.vector.AbstractVectorLayer;
 import org.oscim.map.Map;
 import org.oscim.renderer.bucket.LineBucket;
diff --git a/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java b/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java
index 2c88dd4e..5eafe063 100644
--- a/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java
+++ b/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java
@@ -21,13 +21,12 @@ package org.oscim.layers;
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.LineString;
-
-import org.jeo.map.CartoCSS;
-import org.jeo.map.RGB;
-import org.jeo.map.Rule;
-import org.jeo.map.Style;
-import org.jeo.vector.Feature;
-import org.jeo.vector.VectorDataset;
+import io.jeo.map.CartoCSS;
+import io.jeo.map.RGB;
+import io.jeo.map.Rule;
+import io.jeo.map.Style;
+import io.jeo.vector.Feature;
+import io.jeo.vector.VectorDataset;
 import org.oscim.backend.canvas.Color;
 import org.oscim.jeo.JeoUtils;
 import org.oscim.map.Map;
diff --git a/vtm-jeo/src/org/oscim/test/JeoTest.java b/vtm-jeo/src/org/oscim/test/JeoTest.java
index 3f46e529..be96b93b 100644
--- a/vtm-jeo/src/org/oscim/test/JeoTest.java
+++ b/vtm-jeo/src/org/oscim/test/JeoTest.java
@@ -18,21 +18,15 @@
 package org.oscim.test;
 
 import com.vividsolutions.jts.geom.Geometry;
-
-import org.jeo.carto.Carto;
-import org.jeo.data.Dataset;
-import org.jeo.data.mem.MemVector;
-import org.jeo.data.mem.MemWorkspace;
-import org.jeo.geojson.GeoJSONDataset;
-import org.jeo.geojson.GeoJSONReader;
-import org.jeo.geom.GeomBuilder;
-import org.jeo.map.Style;
-import org.jeo.vector.Feature;
-import org.jeo.vector.Features;
-import org.jeo.vector.Schema;
-import org.jeo.vector.SchemaBuilder;
-import org.jeo.vector.VectorDataset;
-import org.jeo.vector.VectorQuery;
+import io.jeo.carto.Carto;
+import io.jeo.data.Dataset;
+import io.jeo.data.mem.MemVectorDataset;
+import io.jeo.data.mem.MemWorkspace;
+import io.jeo.geojson.GeoJSONDataset;
+import io.jeo.geojson.GeoJSONReader;
+import io.jeo.geom.GeomBuilder;
+import io.jeo.map.Style;
+import io.jeo.vector.*;
 import org.oscim.backend.canvas.Color;
 import org.oscim.layers.OSMIndoorLayer;
 import org.oscim.layers.tile.buildings.BuildingLayer;
@@ -42,11 +36,7 @@ import org.oscim.renderer.MapRenderer;
 import org.oscim.theme.styles.TextStyle;
 import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 
 public class JeoTest {
 
@@ -101,13 +91,13 @@ public class JeoTest {
         GeoJSONReader r = new GeoJSONReader();
 
         @SuppressWarnings("resource")
-        MemWorkspace mem = new MemWorkspace();
+        MemWorkspace mem = new MemWorkspace("");
 
         //mem.put("layer", data);
         try {
             Schema s = new SchemaBuilder("way").schema();
 
-            MemVector memData = mem.create(s);
+            MemVectorDataset memData = mem.create(s);
 
             for (Feature f : r.features(is)) {
                 //System.out.println("loaded: " + f);
@@ -133,7 +123,7 @@ public class JeoTest {
 
         if (memory) {
             @SuppressWarnings("resource")
-            MemWorkspace mem = new MemWorkspace();
+            MemWorkspace mem = new MemWorkspace("");
 
             //mem.put("layer", data);
             try {
@@ -141,9 +131,9 @@ public class JeoTest {
                 Schema s = data.schema();
                 VectorQuery q = new VectorQuery();
 
-                MemVector memData = mem.create(s);
+                MemVectorDataset memData = mem.create(s);
 
-                for (Feature f : data.cursor(q)) {
+                for (Feature f : data.read(q)) {
                     memData.add(f);
                 }
 
@@ -160,14 +150,14 @@ public class JeoTest {
         GeomBuilder gb = new GeomBuilder(4326);
 
         @SuppressWarnings("resource")
-        MemWorkspace mem = new MemWorkspace();
+        MemWorkspace mem = new MemWorkspace("");
         Schema schema = new SchemaBuilder(layer)
                 .field("geometry", Geometry.class)
                 .field("id", Integer.class)
                 .field("name", String.class)
                 .field("cost", Double.class).schema();
 
-        MemVector data;
+        MemVectorDataset data;
         try {
             data = mem.create(schema);
         } catch (UnsupportedOperationException e) {
@@ -181,15 +171,16 @@ public class JeoTest {
         Geometry g = gb.point(0, 0).toPoint();
         //g.setSRID(4326);
 
-        data.add(Features.create(null, data.schema(),
+
+        data.add(new ListFeature(data.schema(),
                 g, 1, "anvil",
                 10.99));
 
-        data.add(Features.create(null, data.schema(),
+        data.add(new ListFeature(data.schema(),
                 gb.points(10, 10, 20, 20).toLineString(),
                 2, "bomb", 11.99));
 
-        data.add(Features.create(null, data.schema(),
+        data.add(new ListFeature(data.schema(),
                 gb.point(100, 10).toPoint().buffer(10),
                 3, "dynamite", 12.99));
 
diff --git a/vtm-jeo/src/org/oscim/theme/carto/BasicFeature.java b/vtm-jeo/src/org/oscim/theme/carto/BasicFeature.java
new file mode 100644
index 00000000..0a13ecf6
--- /dev/null
+++ b/vtm-jeo/src/org/oscim/theme/carto/BasicFeature.java
@@ -0,0 +1,452 @@
+/* Copyright 2013 The jeo project. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.oscim.theme.carto;
+
+import com.vividsolutions.jts.geom.Geometry;
+import io.jeo.util.Util;
+import io.jeo.vector.Feature;
+import io.jeo.vector.Field;
+import io.jeo.vector.Schema;
+import io.jeo.vector.SchemaBuilder;
+import org.osgeo.proj4j.CoordinateReferenceSystem;
+
+import java.util.*;
+
+/**
+ * Basic feature implementation.
+ *
+ * @author Justin Deoliveira, Boundless
+ * <p>
+ * Adapted by Jan Lippert to the changes made in https://github.com/jeo/jeo/commit/e28695ccc8530ae6d1a2dff1fbd1e11449ef949f
+ */
+public class BasicFeature implements Feature {
+
+    /**
+     * feature identifier
+     */
+    protected String id;
+
+    /**
+     * Underlying feature storage.
+     */
+    protected Storage storage;
+
+    /**
+     * Constructor taking a feature identifier.
+     *
+     * @param id The feature id, if <code>null</code> an identifier will be generated.
+     */
+    public BasicFeature(String id) {
+        this(id, (Schema) null);
+    }
+
+    /**
+     * Constructor taking a feature identifier and an explicit schema object.
+     *
+     * @param id     The feature id, if <code>null</code> an identifier will be generated.
+     * @param schema The feature schema, if <code>null</code> the schema will be always be derived
+     */
+    public BasicFeature(String id, Schema schema) {
+        this(id, (Storage)
+                (schema != null ? new ListStorage(null, schema) : new MapStorage(null, schema)));
+    }
+
+    /**
+     * Constructs a feature from an identifier and a list of values.
+     *
+     * @param id     The feature id, if <code>null</code> an identifier will be generated.
+     * @param values The feature values.
+     */
+    public BasicFeature(String id, List<Object> values) {
+        this(id, values, null);
+    }
+
+    /**
+     * Constructs a feature from an identifier, a list of values, and a schema.
+     *
+     * @param id     The feature id, if <code>null</code> an identifier will be generated.
+     * @param values The feature values.
+     * @param schema The feature schema, if <code>null</code> the schema will be always be derived
+     */
+    public BasicFeature(String id, List<Object> values, Schema schema) {
+        this(id, new ListStorage(values, schema));
+    }
+
+    /**
+     * Constructs a feature from an identifier and a map of values.
+     *
+     * @param id     The feature id, if <code>null</code> an identifier will be generated.
+     * @param values The feature values.
+     */
+    public BasicFeature(String id, Map<String, Object> values) {
+        this(id, values, null);
+    }
+
+    /**
+     * Constructs a feature from an identifier, a map of values, and a schema.
+     *
+     * @param id     The feature id, if <code>null</code> an identifier will be generated.
+     * @param values The feature values.
+     * @param schema The feature schema, if <code>null</code> the schema will be always be derived
+     */
+    public BasicFeature(String id, Map<String, Object> values, Schema schema) {
+        this(id, new MapStorage(values, schema));
+    }
+
+    /**
+     * Constructor taking an identifier and feature storage object directly.
+     * <p>
+     * This constructor is typically only used for subclasses that need to implement custom feature
+     * storage.
+     * </p>
+     */
+    protected BasicFeature(String id, Storage storage) {
+        this.id = id != null ? id : Util.uuid();
+        this.storage = storage;
+    }
+
+    @Override
+    public String id() {
+        return id;
+    }
+
+    /*@Override
+    public CoordinateReferenceSystem getCRS() {
+        return crs;
+    }*/
+
+    public BasicFeature crs(CoordinateReferenceSystem crs) {
+        storage.crs(crs);
+        return this;
+    }
+
+    @Override
+    public boolean has(String key) {
+        return storage.has(key);
+    }
+
+    @Override
+    public Object get(String key) {
+        return storage.get(key);
+    }
+
+    @Override
+    public BasicFeature put(String key, Object val) {
+        storage.put(key, val);
+        return this;
+    }
+
+    @Override
+    public BasicFeature put(Geometry g) {
+        //TODO:optimize before triggering schema creation
+        Field gf = storage.schema(true).geometry();
+        if (gf == null) {
+            throw new IllegalArgumentException("Feature schema has no geometry");
+        }
+
+        return put(gf.name(), g);
+    }
+
+
+    @Override
+    public Geometry geometry() {
+        return storage.geometry();
+    }
+
+    @Override
+    public Map<String, Object> map() {
+        return storage.map();
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder(id).append(map()).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((storage == null) ? 0 : storage.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        BasicFeature other = (BasicFeature) obj;
+        if (id == null) {
+            return other.id == null;
+        }
+
+        return id.equals(other.id);
+    }
+
+
+    protected static abstract class Storage {
+        Schema schema;
+        CoordinateReferenceSystem crs;
+
+        protected Storage(Schema schema) {
+            this.schema = schema;
+        }
+
+        protected Storage crs(CoordinateReferenceSystem crs) {
+            this.crs = crs;
+            return this;
+        }
+
+        protected Schema schema() {
+            return schema(true);
+        }
+
+        protected Schema schema(boolean derive) {
+            if (schema == null && derive) {
+                schema = buildSchema();
+
+                // hack to apply crs override
+                if (crs != null && schema.crs() == null) {
+                    schema = SchemaBuilder.crs(schema, crs);
+                }
+            }
+            return schema;
+        }
+
+        protected Geometry geometry() {
+            if (schema != null) {
+                Field f = schema.geometry();
+                if (f != null) {
+                    return (Geometry) get(f.name());
+                }
+            }
+
+            return findGeometry();
+        }
+
+        protected CoordinateReferenceSystem crs() {
+            if (crs != null) {
+                return crs;
+            }
+
+            if (schema != null) {
+                return schema.crs();
+            }
+            return null;
+        }
+
+        /**
+         * Method for subclasses to implement to build a schema for the feature from its underlying
+         * attributes.
+         */
+        protected abstract Schema buildSchema();
+
+        /**
+         * Method for subclasses to implement in order to find a geometry object when no schema
+         * information is available.
+         */
+        protected abstract Geometry findGeometry();
+
+        protected abstract Object get(String key);
+
+        protected abstract Object get(int index);
+
+        protected abstract void put(String key, Object value);
+
+        protected abstract void set(int index, Object value);
+
+        protected abstract List<Object> list();
+
+        protected abstract Map<String, Object> map();
+
+        protected abstract boolean has(String key);
+    }
+
+    static class ListStorage extends Storage {
+
+        List<Object> list;
+
+        ListStorage(List<Object> values, Schema schema) {
+            super(schema);
+            this.list = pad(values, schema);
+        }
+
+        List<Object> pad(List<Object> values, Schema schema) {
+            //copy list passed in
+            values = values != null ? new ArrayList<Object>(values) : new ArrayList<Object>();
+
+            //expand up to size of schema if necessary
+            if (schema != null) {
+                while (values.size() < schema.size()) {
+                    values.add(null);
+                }
+            }
+            return values;
+        }
+
+        @Override
+        protected Geometry findGeometry() {
+            for (Object o : list) {
+                if (o instanceof Geometry) {
+                    return (Geometry) o;
+                }
+            }
+
+            return null;
+        }
+
+        @Override
+        protected Schema buildSchema() {
+            List<Field> fields = new ArrayList<Field>();
+            int i = 0;
+            boolean g = false;
+            for (Object o : list) {
+                if (o instanceof Geometry && !g) {
+                    //first geometry
+                    fields.add(new Field("geometry", o.getClass()));
+                    g = true;
+                } else {
+                    //regular field
+                    fields.add(new Field(String.format(Locale.ROOT, "field%d", i++), o != null ? o.getClass() : null));
+                }
+            }
+            return new Schema("feature", fields);
+        }
+
+        @Override
+        protected boolean has(String key) {
+            return schema().indexOf(key) >= 0;
+        }
+
+        @Override
+        protected Object get(int i) {
+            return list.get(i);
+        }
+
+        @Override
+        protected void set(int i, Object value) {
+            list.set(i, value);
+        }
+
+        @Override
+        protected Object get(String key) {
+            int i = schema().indexOf(key);
+            return i != -1 ? get(i) : null;
+        }
+
+        @Override
+        protected void put(String key, Object val) {
+            int i = schema().indexOf(key);
+            if (i == -1) {
+                throw new IllegalArgumentException("No such key " + key);
+            }
+            set(i, val);
+        }
+
+        @Override
+        protected List<Object> list() {
+            return Collections.unmodifiableList(list);
+        }
+
+        @Override
+        protected Map<String, Object> map() {
+            LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
+            for (Field f : schema()) {
+                map.put(f.name(), get(f.name()));
+            }
+            return map;
+        }
+    }
+
+    static class MapStorage extends Storage {
+
+        Map<String, Object> map;
+
+        MapStorage(Map<String, Object> values, Schema schema) {
+            super(schema);
+            this.map = values != null ?
+                    new LinkedHashMap<String, Object>(values) : new LinkedHashMap<String, Object>();
+        }
+
+        @Override
+        protected Schema buildSchema() {
+            List<Field> fields = new ArrayList<Field>();
+            for (Map.Entry<String, Object> e : map.entrySet()) {
+                fields.add(new Field(e.getKey(), e.getValue() != null ? e.getValue().getClass() : null));
+            }
+
+            return new Schema("feature", fields);
+        }
+
+        @Override
+        protected Geometry findGeometry() {
+            for (Object obj : map.values()) {
+                if (obj instanceof Geometry) {
+                    return (Geometry) obj;
+                }
+            }
+
+            return null;
+        }
+
+        @Override
+        protected boolean has(String key) {
+            return map.containsKey(key);
+        }
+
+        @Override
+        protected Object get(String key) {
+            return map.get(key);
+        }
+
+        @Override
+        protected void put(String key, Object val) {
+            if (!map.containsKey(key)) {
+                //new field, clear cached schema
+                schema = null;
+            }
+            map.put(key, val);
+        }
+
+        @Override
+        protected Object get(int index) {
+            return Util.get(map, index);
+        }
+
+        @Override
+        protected void set(int index, Object value) {
+            Util.set(map, index, value);
+        }
+
+        @Override
+        protected List<Object> list() {
+            List<Object> list = new ArrayList<Object>();
+            for (Field f : schema()) {
+                list.add(get(f.name()));
+            }
+            return list;
+        }
+
+        @Override
+        protected Map<String, Object> map() {
+            return Collections.unmodifiableMap(map);
+        }
+    }
+}
diff --git a/vtm-jeo/src/org/oscim/theme/carto/MatcherFeature.java b/vtm-jeo/src/org/oscim/theme/carto/MatcherFeature.java
index 1c68832d..12af6aca 100644
--- a/vtm-jeo/src/org/oscim/theme/carto/MatcherFeature.java
+++ b/vtm-jeo/src/org/oscim/theme/carto/MatcherFeature.java
@@ -16,11 +16,9 @@
  */
 package org.oscim.theme.carto;
 
-import org.jeo.vector.BasicFeature;
 import org.oscim.core.Tag;
 import org.oscim.core.TagSet;
 
-import java.util.List;
 import java.util.Map;
 
 import static java.lang.System.out;
@@ -64,27 +62,10 @@ class MatcherFeature extends BasicFeature {
         return null;
     }
 
-    @Override
-    public List<Object> list() {
-        out.println("EEEK list()");
-        return null;
-    }
 
     @Override
     public Map<String, Object> map() {
         out.println("EEEK map()");
         return null;
     }
-
-    @Override
-    public Object get(int arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public BasicFeature set(int arg0, Object arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
 }
diff --git a/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java b/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
index 47424ce5..66c4d199 100644
--- a/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
+++ b/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
@@ -1,11 +1,7 @@
 package org.oscim.theme.carto;
 
-import org.jeo.carto.Carto;
-import org.jeo.map.CartoCSS;
-import org.jeo.map.RGB;
-import org.jeo.map.Rule;
-import org.jeo.map.RuleList;
-import org.jeo.map.Style;
+import io.jeo.carto.Carto;
+import io.jeo.map.*;
 import org.oscim.core.GeometryBuffer.GeometryType;
 import org.oscim.core.MapElement;
 import org.oscim.core.Tag;
@@ -19,9 +15,9 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
+import static io.jeo.map.CartoCSS.BACKGROUND_COLOR;
+import static io.jeo.map.CartoCSS.OPACITY;
 import static java.lang.System.out;
-import static org.jeo.map.CartoCSS.BACKGROUND_COLOR;
-import static org.jeo.map.CartoCSS.OPACITY;
 
 public class RenderTheme implements IRenderTheme {
 
diff --git a/vtm-playground/build.gradle b/vtm-playground/build.gradle
index 846d647b..22955daf 100644
--- a/vtm-playground/build.gradle
+++ b/vtm-playground/build.gradle
@@ -8,7 +8,7 @@ dependencies {
     implementation project(':vtm-extras')
     implementation project(':vtm-gdx-poi3d')
     implementation project(':vtm-http')
-    //implementation project(':vtm-jeo')
+    implementation project(':vtm-jeo')
     implementation project(':vtm-json')
     implementation project(':vtm-jts')
     implementation project(':vtm-models')
diff --git a/vtm-playground/src/org/oscim/test/jeo/LayerTest.java b/vtm-playground/src/org/oscim/test/jeo/LayerTest.java
index 03d66487..380b1532 100644
--- a/vtm-playground/src/org/oscim/test/jeo/LayerTest.java
+++ b/vtm-playground/src/org/oscim/test/jeo/LayerTest.java
@@ -1,92 +1,92 @@
-///*
-// * Copyright 2014 Hannes Janetzek
-// * Copyright 2016-2017 devemux86
-// *
-// * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
-// *
-// * 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 <http://www.gnu.org/licenses/>.
-// */
-//package org.oscim.test.jeo;
-//
-//import org.jeo.map.Style;
-//import org.jeo.vector.VectorDataset;
-//import org.oscim.backend.canvas.Color;
-//import org.oscim.gdx.GdxMapApp;
-//import org.oscim.layers.JeoVectorLayer;
-//import org.oscim.layers.OSMIndoorLayer;
-//import org.oscim.layers.tile.bitmap.BitmapTileLayer;
-//import org.oscim.test.JeoTest;
-//import org.oscim.theme.styles.TextStyle;
-//
-//import java.io.IOException;
-//import java.io.InputStream;
-//import java.net.URL;
-//import java.net.URLConnection;
-//
-//import static org.oscim.tiling.source.bitmap.DefaultSources.STAMEN_TONER;
-//
-//public class LayerTest extends GdxMapApp {
-//
-//    // from http://overpass-turbo.eu/s/2vp
-//    String PATH = "https://gist.githubusercontent.com/anonymous/09062103a66844a96048f25626078c8d/raw/1d3af6a5a55e9ea4adc9551fa633a051a44a5a9c/overpass.geojson";
-//
-//    private OSMIndoorLayer mIndoorLayer;
-//
-//    @Override
-//    public void createLayers() {
-//        mMap.setBaseMap(new BitmapTileLayer(mMap, STAMEN_TONER.build()));
-//
-//        mMap.addTask(new Runnable() {
-//            @Override
-//            public void run() {
-//                try {
-//                    URL url = new URL(PATH);
-//                    URLConnection conn = url.openConnection();
-//                    InputStream is = conn.getInputStream();
-//
-//                    VectorDataset data = JeoTest.readGeoJson(is);
-//                    Style style = JeoTest.getStyle();
-//                    TextStyle textStyle = TextStyle.builder()
-//                            .isCaption(true)
-//                            .fontSize(16).color(Color.BLACK)
-//                            .strokeWidth(2.2f).strokeColor(Color.WHITE)
-//                            .build();
-//                    mIndoorLayer = new OSMIndoorLayer(mMap, data, style, textStyle);
-//                    mIndoorLayer.activeLevels[0] = true;
-//                    mIndoorLayer.activeLevels[1] = true;
-//                    mIndoorLayer.activeLevels[2] = true;
-//                    mIndoorLayer.activeLevels[3] = true;
-//
-//                    mMap.layers().add(new JeoVectorLayer(mMap, data, style));
-//                    mMap.layers().add(mIndoorLayer);
-//
-//                    mMap.updateMap(true);
-//
-//                } catch (IOException e) {
-//                    e.printStackTrace();
-//                }
-//            }
-//        });
-//
-//        mMap.setMapPosition(53.5620092, 9.9866457, 1 << 16);
-//
-//        //VectorDataset data = (VectorDataset) JeoTest.getJsonData("states.json", true);
-//        //Style style = JeoTest.getStyle();
-//        //mMap.layers().add(new JeoVectorLayer(mMap, data, style));
-//
-//    }
-//
-//    public static void main(String[] args) {
-//        GdxMapApp.init();
-//        GdxMapApp.run(new LayerTest(), null, 256);
-//    }
-//}
+/*
+ * Copyright 2014 Hannes Janetzek
+ * Copyright 2016-2017 devemux86
+ *
+ * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.test.jeo;
+
+import io.jeo.map.Style;
+import io.jeo.vector.VectorDataset;
+import org.oscim.backend.canvas.Color;
+import org.oscim.gdx.GdxMapApp;
+import org.oscim.layers.JeoVectorLayer;
+import org.oscim.layers.OSMIndoorLayer;
+import org.oscim.layers.tile.bitmap.BitmapTileLayer;
+import org.oscim.test.JeoTest;
+import org.oscim.theme.styles.TextStyle;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import static org.oscim.tiling.source.bitmap.DefaultSources.STAMEN_TONER;
+
+public class LayerTest extends GdxMapApp {
+
+    // from http://overpass-turbo.eu/s/2vp
+    String PATH = "https://gist.githubusercontent.com/anonymous/09062103a66844a96048f25626078c8d/raw/1d3af6a5a55e9ea4adc9551fa633a051a44a5a9c/overpass.geojson";
+
+    private OSMIndoorLayer mIndoorLayer;
+
+    @Override
+    public void createLayers() {
+        mMap.setBaseMap(new BitmapTileLayer(mMap, STAMEN_TONER.build()));
+
+        mMap.addTask(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    URL url = new URL(PATH);
+                    URLConnection conn = url.openConnection();
+                    InputStream is = conn.getInputStream();
+
+                    VectorDataset data = JeoTest.readGeoJson(is);
+                    Style style = JeoTest.getStyle();
+                    TextStyle textStyle = TextStyle.builder()
+                            .isCaption(true)
+                            .fontSize(16).color(Color.BLACK)
+                            .strokeWidth(2.2f).strokeColor(Color.WHITE)
+                            .build();
+                    mIndoorLayer = new OSMIndoorLayer(mMap, data, style, textStyle);
+                    mIndoorLayer.activeLevels[0] = true;
+                    mIndoorLayer.activeLevels[1] = true;
+                    mIndoorLayer.activeLevels[2] = true;
+                    mIndoorLayer.activeLevels[3] = true;
+
+                    mMap.layers().add(new JeoVectorLayer(mMap, data, style));
+                    mMap.layers().add(mIndoorLayer);
+
+                    mMap.updateMap(true);
+
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        mMap.setMapPosition(53.5620092, 9.9866457, 1 << 16);
+
+        //VectorDataset data = (VectorDataset) JeoTest.getJsonData("states.json", true);
+        //Style style = JeoTest.getStyle();
+        //mMap.layers().add(new JeoVectorLayer(mMap, data, style));
+
+    }
+
+    public static void main(String[] args) {
+        GdxMapApp.init();
+        GdxMapApp.run(new LayerTest(), null, 256);
+    }
+}
diff --git a/vtm-playground/src/org/oscim/test/jeo/ThemeTest.java b/vtm-playground/src/org/oscim/test/jeo/ThemeTest.java
index 9036a623..7e40462a 100644
--- a/vtm-playground/src/org/oscim/test/jeo/ThemeTest.java
+++ b/vtm-playground/src/org/oscim/test/jeo/ThemeTest.java
@@ -1,50 +1,50 @@
-///*
-// * Copyright 2016-2017 devemux86
-// *
-// * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
-// *
-// * 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 <http://www.gnu.org/licenses/>.
-// */
-//package org.oscim.test.jeo;
-//
-//import org.oscim.gdx.GdxMapApp;
-//import org.oscim.layers.tile.vector.VectorTileLayer;
-//import org.oscim.renderer.MapRenderer;
-//import org.oscim.theme.carto.RenderTheme;
-//import org.oscim.tiling.source.OkHttpEngine;
-//import org.oscim.tiling.source.UrlTileSource;
-//import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
-//
-//public class ThemeTest extends GdxMapApp {
-//
-//    public static void main(String[] args) {
-//        GdxMapApp.init();
-//        GdxMapApp.run(new ThemeTest(), null, 256);
-//    }
-//
-//    @Override
-//    public void createLayers() {
-//        UrlTileSource ts = OSciMap4TileSource.builder()
-//                .httpFactory(new OkHttpEngine.OkHttpFactory())
-//                .build();
-//
-//        VectorTileLayer l = mMap.setBaseMap(ts);
-//
-//        l.setRenderTheme(new RenderTheme());
-//
-//        MapRenderer.setBackgroundColor(0xffcccccc);
-//
-//        // mMap.getLayers().add(new LabelLayer(mMap,
-//        // mMapLayer.getTileLayer()));
-//        // mMap.getLayers().add(new JeoMapLayer(mMap));
-//    }
-//}
+/*
+ * Copyright 2016-2017 devemux86
+ *
+ * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.test.jeo;
+
+import org.oscim.gdx.GdxMapApp;
+import org.oscim.layers.tile.vector.VectorTileLayer;
+import org.oscim.renderer.MapRenderer;
+import org.oscim.theme.carto.RenderTheme;
+import org.oscim.tiling.source.OkHttpEngine;
+import org.oscim.tiling.source.UrlTileSource;
+import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
+
+public class ThemeTest extends GdxMapApp {
+
+    public static void main(String[] args) {
+        GdxMapApp.init();
+        GdxMapApp.run(new ThemeTest(), null, 256);
+    }
+
+    @Override
+    public void createLayers() {
+        UrlTileSource ts = OSciMap4TileSource.builder()
+                .httpFactory(new OkHttpEngine.OkHttpFactory())
+                .build();
+
+        VectorTileLayer l = mMap.setBaseMap(ts);
+
+        l.setRenderTheme(new RenderTheme());
+
+        MapRenderer.setBackgroundColor(0xffcccccc);
+
+        // mMap.getLayers().add(new LabelLayer(mMap,
+        // mMapLayer.getTileLayer()));
+        // mMap.getLayers().add(new JeoMapLayer(mMap));
+    }
+}