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; }