diff --git a/docs/Changelog.md b/docs/Changelog.md
index 40faae8d..56eb4515 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -10,6 +10,8 @@
- POT textures [#334](https://github.com/mapsforge/vtm/issues/334)
- OkHttp external cache [#135](https://github.com/mapsforge/vtm/issues/135)
- Texture atlas improvements [#301](https://github.com/mapsforge/vtm/pull/301) [#304](https://github.com/mapsforge/vtm/pull/304)
+- vtm-json module [#367](https://github.com/mapsforge/vtm/issues/367)
+- Mapzen GeoJSON vector tiles [#55](https://github.com/mapsforge/vtm/issues/55)
- vtm-ios-example module [#326](https://github.com/mapsforge/vtm/issues/326)
- Handle layers enabled state [#342](https://github.com/mapsforge/vtm/issues/342)
- Fix coord scale short overflow [#343](https://github.com/mapsforge/vtm/issues/343)
diff --git a/settings.gradle b/settings.gradle
index d5bf8d5a..1556c9ed 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,20 +1,21 @@
rootProject.name = 'vtm-parent'
include ':vtm'
-include ':vtm-http'
-include ':vtm-jts'
-include ':vtm-tests'
-include ':vtm-extras'
include ':vtm-android'
include ':vtm-android-example'
-include ':vtm-themes'
-include ':vtm-gdx'
-include ':vtm-desktop'
include ':vtm-android-gdx'
+include ':vtm-app'
+include ':vtm-desktop'
+include ':vtm-extras'
+include ':vtm-gdx'
+include ':vtm-http'
+include ':vtm-ios'
+include ':vtm-ios-example'
+include ':vtm-jeo'
+include ':vtm-json'
+include ':vtm-jts'
+include ':vtm-playground'
+include ':vtm-tests'
+include ':vtm-themes'
include ':vtm-web'
include ':vtm-web-app'
//include ':vtm-web-js'
-include ':vtm-jeo'
-include ':vtm-playground'
-include ':vtm-ios'
-include ':vtm-ios-example'
-include ':vtm-app'
diff --git a/vtm-android-example/AndroidManifest.xml b/vtm-android-example/AndroidManifest.xml
index 1e075dd3..158fffbc 100644
--- a/vtm-android-example/AndroidManifest.xml
+++ b/vtm-android-example/AndroidManifest.xml
@@ -68,6 +68,9 @@
+
diff --git a/vtm-android-example/build.gradle b/vtm-android-example/build.gradle
index add94d25..c3dc39c4 100644
--- a/vtm-android-example/build.gradle
+++ b/vtm-android-example/build.gradle
@@ -7,6 +7,7 @@ dependencies {
compile(project(':vtm-jeo')) {
exclude group: 'com.vividsolutions', module: 'jts'
}
+ compile project(':vtm-json')
compile project(':vtm-jts')
compile project(':vtm-themes')
compile 'com.noveogroup.android:android-logger:1.3.6'
diff --git a/vtm-android-example/src/org/oscim/android/test/MapzenGeojsonMapActivity.java b/vtm-android-example/src/org/oscim/android/test/MapzenGeojsonMapActivity.java
new file mode 100644
index 00000000..3a83f0a8
--- /dev/null
+++ b/vtm-android-example/src/org/oscim/android/test/MapzenGeojsonMapActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 devemux86
+ *
+ * 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.android.test;
+
+import android.os.Bundle;
+
+import org.oscim.android.cache.TileCache;
+import org.oscim.layers.TileGridLayer;
+import org.oscim.layers.tile.buildings.BuildingLayer;
+import org.oscim.layers.tile.vector.VectorTileLayer;
+import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.theme.VtmThemes;
+import org.oscim.tiling.source.OkHttpEngine;
+import org.oscim.tiling.source.UrlTileSource;
+import org.oscim.tiling.source.geojson.MapzenGeojsonTileSource;
+
+public class MapzenGeojsonMapActivity extends MapActivity {
+
+ private static final boolean USE_CACHE = false;
+
+ private TileCache mCache;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ UrlTileSource tileSource = MapzenGeojsonTileSource.builder()
+ .apiKey("mapzen-xxxxxxx") // Put a proper API key
+ .httpFactory(new OkHttpEngine.OkHttpFactory())
+ //.locale("en")
+ .build();
+
+ if (USE_CACHE) {
+ // Cache the tiles into a local SQLite database
+ mCache = new TileCache(this, null, "tile.db");
+ mCache.setCacheSize(512 * (1 << 10));
+ tileSource.setCache(mCache);
+ }
+
+ VectorTileLayer l = mMap.setBaseMap(tileSource);
+ mMap.setTheme(VtmThemes.MAPZEN);
+
+ mMap.layers().add(new BuildingLayer(mMap, l));
+ mMap.layers().add(new LabelLayer(mMap, l));
+
+ mMap.layers().add(new TileGridLayer(mMap, getResources().getDisplayMetrics().density));
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+
+ if (mCache != null)
+ mCache.dispose();
+ }
+}
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 bc60a58e..0ae3b52e 100644
--- a/vtm-android-example/src/org/oscim/android/test/Samples.java
+++ b/vtm-android-example/src/org/oscim/android/test/Samples.java
@@ -44,6 +44,7 @@ public class Samples extends Activity {
linearLayout.addView(createButton(SimpleMapActivity.class));
linearLayout.addView(createButton(MapsforgeMapActivity.class));
linearLayout.addView(createButton(MapzenMvtMapActivity.class));
+ linearLayout.addView(createButton(MapzenGeojsonMapActivity.class));
linearLayout.addView(createLabel("Vector Features"));
linearLayout.addView(createButton(MapsforgeStyleActivity.class));
diff --git a/vtm-json/build.gradle b/vtm-json/build.gradle
new file mode 100644
index 00000000..497b93ec
--- /dev/null
+++ b/vtm-json/build.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'java'
+apply plugin: 'maven'
+
+dependencies {
+ compile project(':vtm')
+ compile 'com.fasterxml.jackson.core:jackson-core:2.8.4'
+}
+
+sourceSets {
+ main.java.srcDirs = ['src']
+}
+
+if (project.hasProperty("SONATYPE_USERNAME")) {
+ afterEvaluate {
+ project.apply from: "${rootProject.projectDir}/deploy.gradle"
+ }
+}
diff --git a/vtm-json/src/org/oscim/tiling/source/geojson/GeojsonTileSource.java b/vtm-json/src/org/oscim/tiling/source/geojson/GeojsonTileSource.java
new file mode 100644
index 00000000..b979d46c
--- /dev/null
+++ b/vtm-json/src/org/oscim/tiling/source/geojson/GeojsonTileSource.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014 Hannes Janetzek
+ * Copyright 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 .
+ */
+package org.oscim.tiling.source.geojson;
+
+import org.oscim.core.MapElement;
+import org.oscim.core.Tag;
+import org.oscim.tiling.ITileDataSource;
+import org.oscim.tiling.source.UrlTileDataSource;
+import org.oscim.tiling.source.UrlTileSource;
+
+import java.util.Map;
+
+public abstract class GeojsonTileSource extends UrlTileSource {
+
+ protected GeojsonTileSource(Builder> builder) {
+ super(builder);
+ }
+
+ protected GeojsonTileSource(String urlString, String tilePath) {
+ super(urlString, tilePath);
+ }
+
+ protected GeojsonTileSource(String urlString, String tilePath, int zoomMin, int zoomMax) {
+ super(urlString, tilePath, zoomMin, zoomMax);
+ }
+
+ @Override
+ public ITileDataSource getDataSource() {
+ return new UrlTileDataSource(this, new TileDecoder(this), getHttpEngine());
+ }
+
+ public Tag getFeatureTag() {
+ return null;
+ }
+
+ /**
+ * allow overriding tag handling
+ */
+ public abstract void decodeTags(MapElement mapElement, Map properties);
+
+ public Tag rewriteTag(String key, Object value) {
+ if (value == null)
+ return null;
+
+ String val = (value instanceof String) ? (String) value : String.valueOf(value);
+
+ return new Tag(key, val);
+ }
+
+ /**
+ * modify mapElement before process()
+ */
+ public void postGeomHook(MapElement mapElement) {
+ }
+}
diff --git a/vtm-json/src/org/oscim/tiling/source/geojson/MapzenGeojsonTileSource.java b/vtm-json/src/org/oscim/tiling/source/geojson/MapzenGeojsonTileSource.java
new file mode 100644
index 00000000..2f0b3d42
--- /dev/null
+++ b/vtm-json/src/org/oscim/tiling/source/geojson/MapzenGeojsonTileSource.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017 devemux86
+ *
+ * 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.tiling.source.geojson;
+
+import org.oscim.core.MapElement;
+import org.oscim.core.Tag;
+import org.oscim.tiling.source.UrlTileSource;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class MapzenGeojsonTileSource extends GeojsonTileSource {
+
+ private final static String DEFAULT_URL = "https://tile.mapzen.com/mapzen/vector/v1/all";
+ private final static String DEFAULT_PATH = "/{Z}/{X}/{Y}.json";
+
+ public static class Builder> extends UrlTileSource.Builder {
+ private String locale = "";
+
+ public Builder() {
+ super(DEFAULT_URL, DEFAULT_PATH, 1, 17);
+ }
+
+ public T locale(String locale) {
+ this.locale = locale;
+ return self();
+ }
+
+ public MapzenGeojsonTileSource build() {
+ return new MapzenGeojsonTileSource(this);
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static Builder> builder() {
+ return new Builder();
+ }
+
+ private static Map mappings = new LinkedHashMap<>();
+
+ private static Tag addMapping(String key, String val) {
+ Tag tag = new Tag(key, val);
+ mappings.put(key + "=" + val, tag);
+ return tag;
+ }
+
+ private final String locale;
+
+ public MapzenGeojsonTileSource(Builder> builder) {
+ super(builder);
+ this.locale = builder.locale;
+ }
+
+ public MapzenGeojsonTileSource() {
+ this(builder());
+ }
+
+ public MapzenGeojsonTileSource(String urlString) {
+ this(builder().url(urlString));
+ }
+
+ @Override
+ public void decodeTags(MapElement mapElement, Map properties) {
+ boolean hasName = false;
+ String fallbackName = null;
+
+ for (Map.Entry entry : properties.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ String val = (value instanceof String) ? (String) value : String.valueOf(value);
+
+ if (key.startsWith(Tag.KEY_NAME)) {
+ int len = key.length();
+ if (len == 4) {
+ fallbackName = val;
+ continue;
+ }
+ if (len < 7)
+ continue;
+ if (locale.equals(key.substring(5))) {
+ hasName = true;
+ mapElement.tags.add(new Tag(Tag.KEY_NAME, val, false));
+ }
+ continue;
+ }
+
+ Tag tag = mappings.get(key + "=" + val);
+ if (tag == null)
+ tag = addMapping(key, val);
+ mapElement.tags.add(tag);
+ }
+
+ if (!hasName && fallbackName != null)
+ mapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false));
+ }
+}
diff --git a/vtm-json/src/org/oscim/tiling/source/geojson/TileDecoder.java b/vtm-json/src/org/oscim/tiling/source/geojson/TileDecoder.java
new file mode 100644
index 00000000..667418f9
--- /dev/null
+++ b/vtm-json/src/org/oscim/tiling/source/geojson/TileDecoder.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2014 Hannes Janetzek
+ * Copyright 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 .
+ */
+package org.oscim.tiling.source.geojson;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+
+import org.oscim.core.GeometryBuffer.GeometryType;
+import org.oscim.core.MapElement;
+import org.oscim.core.Tag;
+import org.oscim.core.Tile;
+import org.oscim.tiling.ITileDataSink;
+import org.oscim.tiling.source.ITileDecoder;
+import org.oscim.utils.ArrayUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedHashMap;
+
+import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
+import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
+import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;
+import static com.fasterxml.jackson.core.JsonToken.START_ARRAY;
+import static com.fasterxml.jackson.core.JsonToken.START_OBJECT;
+import static com.fasterxml.jackson.core.JsonToken.VALUE_NUMBER_FLOAT;
+import static com.fasterxml.jackson.core.JsonToken.VALUE_NUMBER_INT;
+import static com.fasterxml.jackson.core.JsonToken.VALUE_STRING;
+import static org.oscim.core.MercatorProjection.latitudeToY;
+import static org.oscim.core.MercatorProjection.longitudeToX;
+
+public class TileDecoder implements ITileDecoder {
+
+ private final MapElement mMapElement;
+ private final GeojsonTileSource mTileSource;
+ private final LinkedHashMap mTagMap;
+ private final JsonFactory mJsonFactory;
+
+ private final static char[] FIELD_FEATURES = "features".toCharArray();
+ private final static char[] FIELD_GEOMETRY = "geometry".toCharArray();
+ private final static char[] FIELD_PROPERTIES = "properties".toCharArray();
+ private final static char[] FIELD_COORDINATES = "coordinates".toCharArray();
+ private final static char[] FIELD_TYPE = "type".toCharArray();
+
+ private final static char[] LINETRING = "LineString".toCharArray();
+ private final static char[] POLYGON = "Polygon".toCharArray();
+ private final static char[] POINT = "Point".toCharArray();
+ private final static char[] MULTI_LINESTRING = "MultiLineString".toCharArray();
+ private final static char[] MULTI_POLYGON = "MultiPolygon".toCharArray();
+ private final static char[] MULTI_POINT = "MultiPoint".toCharArray();
+
+ private ITileDataSink mTileDataSink;
+
+ private double mTileY, mTileX, mTileScale;
+
+ public TileDecoder(GeojsonTileSource tileSource) {
+ mTileSource = tileSource;
+ mTagMap = new LinkedHashMap<>();
+ mJsonFactory = new JsonFactory();
+
+ mMapElement = new MapElement();
+ mMapElement.layer = 5;
+ }
+
+ @Override
+ public boolean decode(Tile tile, ITileDataSink sink, InputStream is) throws IOException {
+ mTileDataSink = sink;
+ mTileScale = 1 << tile.zoomLevel;
+ mTileX = tile.tileX / mTileScale;
+ mTileY = tile.tileY / mTileScale;
+ mTileScale *= Tile.SIZE;
+
+ JsonParser jp = mJsonFactory.createParser(new InputStreamReader(is));
+
+ Tag layerTag = null;
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == FIELD_NAME) {
+ if (!match(jp, FIELD_FEATURES) && !match(jp, FIELD_TYPE))
+ layerTag = new Tag("layer", jp.getCurrentName());
+ if (match(jp, FIELD_FEATURES)) {
+ if (jp.nextToken() != START_ARRAY)
+ continue;
+
+ while ((t = jp.nextToken()) != null) {
+ if (t == START_OBJECT)
+ parseFeature(jp, layerTag);
+
+ if (t == END_ARRAY)
+ break;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ private void parseFeature(JsonParser jp, Tag layerTag) throws IOException {
+
+ mMapElement.clear();
+ mMapElement.tags.clear();
+ if (layerTag != null)
+ mMapElement.tags.add(layerTag);
+ mTagMap.clear();
+
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == FIELD_NAME) {
+ if (match(jp, FIELD_GEOMETRY)) {
+ if (jp.nextToken() == START_OBJECT)
+ parseGeometry(jp);
+ }
+
+ if (match(jp, FIELD_PROPERTIES)) {
+ if (jp.nextToken() == START_OBJECT)
+ parseProperties(jp);
+ }
+ continue;
+ }
+ if (t == END_OBJECT)
+ break;
+ }
+
+ //add tag information
+ mTileSource.decodeTags(mMapElement, mTagMap);
+ if (mMapElement.tags.numTags == 0)
+ return;
+
+ mTileSource.postGeomHook(mMapElement);
+
+ if (mMapElement.type == GeometryType.NONE)
+ return;
+
+ //process this element
+ mTileDataSink.process(mMapElement);
+ }
+
+ private void parseProperties(JsonParser jp) throws IOException {
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == FIELD_NAME) {
+ String text = jp.getCurrentName();
+
+ t = jp.nextToken();
+ if (t == VALUE_STRING) {
+ mTagMap.put(text, jp.getText());
+ } else if (t == VALUE_NUMBER_INT) {
+ mTagMap.put(text, jp.getNumberValue());
+ }
+ continue;
+ }
+ if (t == END_OBJECT)
+ break;
+ }
+ }
+
+ private void parseGeometry(JsonParser jp) throws IOException {
+
+ boolean multi = false;
+ GeometryType type = GeometryType.NONE;
+
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == FIELD_NAME) {
+ if (match(jp, FIELD_COORDINATES)) {
+ if (jp.nextToken() != START_ARRAY)
+ continue;
+ if (multi) {
+ parseMulti(jp, type);
+ } else {
+ if (type == GeometryType.POLY)
+ parsePolygon(jp);
+
+ if (type == GeometryType.LINE)
+ parseLineString(jp);
+
+ if (type == GeometryType.POINT)
+ parseCoordinate(jp);
+
+ }
+ } else if (match(jp, FIELD_TYPE)) {
+ multi = false;
+
+ jp.nextToken();
+
+ if (match(jp, LINETRING))
+ type = GeometryType.LINE;
+ else if (match(jp, POLYGON))
+ type = GeometryType.POLY;
+ else if (match(jp, POINT))
+ type = GeometryType.POINT;
+ else if (match(jp, MULTI_LINESTRING)) {
+ type = GeometryType.LINE;
+ multi = true;
+ } else if (match(jp, MULTI_POLYGON)) {
+ type = GeometryType.POLY;
+ multi = true;
+ } else if (match(jp, MULTI_POINT)) {
+ type = GeometryType.POINT;
+ multi = true;
+ }
+
+ if (type == GeometryType.POINT)
+ mMapElement.startPoints();
+ }
+ continue;
+ }
+ if (t == END_OBJECT)
+ break;
+ }
+ }
+
+ private void parseMulti(JsonParser jp, GeometryType type) throws IOException {
+
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == END_ARRAY)
+ break;
+
+ if (t == START_ARRAY) {
+ if (type == GeometryType.POLY)
+ parsePolygon(jp);
+
+ else if (type == GeometryType.LINE)
+ parseLineString(jp);
+
+ else if (type == GeometryType.POINT)
+ parseCoordinate(jp);
+
+ } else {
+ //....
+ }
+ }
+ }
+
+ private void parsePolygon(JsonParser jp) throws IOException {
+ int ring = 0;
+
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == START_ARRAY) {
+ if (ring == 0)
+ mMapElement.startPolygon();
+ else
+ mMapElement.startHole();
+
+ ring++;
+ parseCoordSequence(jp);
+ removeLastPoint();
+ continue;
+ }
+
+ if (t == END_ARRAY)
+ break;
+ }
+ }
+
+ private void removeLastPoint() {
+ mMapElement.pointPos -= 2;
+ mMapElement.index[mMapElement.indexPos] -= 2;
+ }
+
+ private void parseLineString(JsonParser jp) throws IOException {
+ mMapElement.startLine();
+ parseCoordSequence(jp);
+ }
+
+ private void parseCoordSequence(JsonParser jp) throws IOException {
+
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+
+ if (t == START_ARRAY) {
+ parseCoordinate(jp);
+ continue;
+ }
+
+ if (t == END_ARRAY)
+ break;
+
+ }
+ }
+
+ private void parseCoordinate(JsonParser jp) throws IOException {
+ int pos = 0;
+ double x = 0, y = 0; //, z = 0;
+
+ for (JsonToken t; (t = jp.nextToken()) != null; ) {
+ if (t == VALUE_NUMBER_FLOAT || t == VALUE_NUMBER_INT) {
+
+ // avoid String allocation (by getDouble...)
+ char[] val = jp.getTextCharacters();
+ int offset = jp.getTextOffset();
+ int length = jp.getTextLength();
+ double c = ArrayUtils.parseNumber(val, offset, offset + length);
+
+ if (pos == 0)
+ x = c;
+ if (pos == 1)
+ y = c;
+ //if (pos == 2)
+ //z = c;
+
+ pos++;
+ continue;
+ }
+
+ if (t == END_ARRAY)
+ break;
+ }
+
+ mMapElement.addPoint((float) ((longitudeToX(x) - mTileX) * mTileScale),
+ (float) ((latitudeToY(y) - mTileY) * mTileScale));
+
+ }
+
+ private static boolean match(JsonParser jp, char[] fieldName) throws IOException {
+
+ int length = jp.getTextLength();
+ if (length != fieldName.length)
+ return false;
+
+ char[] val = jp.getTextCharacters();
+ int offset = jp.getTextOffset();
+
+ for (int i = 0; i < length; i++) {
+ if (fieldName[i] != val[i + offset])
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/vtm-playground/build.gradle b/vtm-playground/build.gradle
index c10074b2..52f2d203 100644
--- a/vtm-playground/build.gradle
+++ b/vtm-playground/build.gradle
@@ -5,6 +5,7 @@ dependencies {
compile project(':vtm-extras')
compile project(':vtm-http')
compile project(':vtm-jeo')
+ compile project(':vtm-json')
compile project(':vtm-jts')
compile "org.slf4j:slf4j-simple:$slf4jVersion"
}
diff --git a/vtm-playground/src/org/oscim/test/MapzenGeojsonTest.java b/vtm-playground/src/org/oscim/test/MapzenGeojsonTest.java
new file mode 100644
index 00000000..062cbf2d
--- /dev/null
+++ b/vtm-playground/src/org/oscim/test/MapzenGeojsonTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017 devemux86
+ *
+ * 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.test;
+
+import org.oscim.gdx.GdxMapApp;
+import org.oscim.layers.tile.buildings.BuildingLayer;
+import org.oscim.layers.tile.vector.VectorTileLayer;
+import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.theme.VtmThemes;
+import org.oscim.tiling.source.OkHttpEngine;
+import org.oscim.tiling.source.UrlTileSource;
+import org.oscim.tiling.source.geojson.MapzenGeojsonTileSource;
+
+import java.io.File;
+import java.util.UUID;
+
+import okhttp3.Cache;
+import okhttp3.OkHttpClient;
+
+public class MapzenGeojsonTest extends GdxMapApp {
+
+ private static final boolean USE_CACHE = false;
+
+ @Override
+ public void createLayers() {
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ if (USE_CACHE) {
+ // Cache the tiles into file system
+ File cacheDirectory = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
+ int cacheSize = 10 * 1024 * 1024; // 10 MB
+ Cache cache = new Cache(cacheDirectory, cacheSize);
+ builder.cache(cache);
+ }
+ OkHttpEngine.OkHttpFactory factory = new OkHttpEngine.OkHttpFactory(builder);
+
+ UrlTileSource tileSource = MapzenGeojsonTileSource.builder()
+ .apiKey("mapzen-xxxxxxx") // Put a proper API key
+ .httpFactory(factory)
+ //.locale("en")
+ .build();
+
+ VectorTileLayer l = mMap.setBaseMap(tileSource);
+ mMap.setTheme(VtmThemes.MAPZEN);
+
+ mMap.layers().add(new BuildingLayer(mMap, l));
+ mMap.layers().add(new LabelLayer(mMap, l));
+ }
+
+ public static void main(String[] args) {
+ GdxMapApp.init();
+ GdxMapApp.run(new MapzenGeojsonTest());
+ }
+}
diff --git a/vtm/src/org/oscim/tiling/source/mvt/MapzenMvtTileSource.java b/vtm/src/org/oscim/tiling/source/mvt/MapzenMvtTileSource.java
index f350692b..2ed1030b 100644
--- a/vtm/src/org/oscim/tiling/source/mvt/MapzenMvtTileSource.java
+++ b/vtm/src/org/oscim/tiling/source/mvt/MapzenMvtTileSource.java
@@ -50,7 +50,7 @@ public class MapzenMvtTileSource extends UrlTileSource {
private final String locale;
- protected MapzenMvtTileSource(Builder> builder) {
+ public MapzenMvtTileSource(Builder> builder) {
super(builder);
this.locale = builder.locale;
}