diff options
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK')
5 files changed, 194 insertions, 0 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java index 4fcb91033c..c1ea669418 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java @@ -11,6 +11,8 @@ import com.mapbox.services.android.telemetry.constants.GeoConstants; import java.util.ArrayList; import java.util.List; +import static android.R.attr.id; + /** * A geographical area representing a latitude/longitude aligned rectangle. * <p> @@ -231,6 +233,22 @@ public class LatLngBounds implements Parcelable { return new LatLngBounds(latNorth, lonEast, latSouth, lonWest); } + private static double lat_(int z, int y) { + double n = Math.PI - 2.0 * Math.PI * y / Math.pow(2.0, z); + return Math.toDegrees(Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); + } + + private static double lon_(int z, int x) { + return x / Math.pow(2.0, z) * 360.0 - GeoConstants.MAX_LONGITUDE; + } + + /** + * Constructs a LatLngBounds from a Tile identifier. + */ + public static LatLngBounds from(int z, int x, int y) { + return new LatLngBounds(lat_(z, y), lon_(z, x + 1), lat_(z, y + 1), lon_(z, x)); + } + /** * Constructs a LatLngBounds from current bounds with an additional latitude-longitude pair. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomVectorSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomVectorSource.java new file mode 100644 index 0000000000..11ed3111b7 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomVectorSource.java @@ -0,0 +1,134 @@ +package com.mapbox.mapboxsdk.style.sources; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.UiThread; +import android.support.annotation.WorkerThread; + +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.style.layers.Filter; +import com.mapbox.services.commons.geojson.Feature; +import com.mapbox.services.commons.geojson.FeatureCollection; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +class TileID { + public int z; + public int x; + public int y; + public TileID(int _z, int _x, int _y) { + z = _z; + x = _x; + y = _y; + } +} + +class TileRequest implements Runnable { + private TileID id; + private TileProvider provider; + private WeakReference<CustomVectorSource> sourceRef; + public TileRequest(TileID _id, TileProvider p, CustomVectorSource _source) { + id = _id; + provider = p; + sourceRef = new WeakReference<>(_source); + } + + public void run() { + FeatureCollection data = provider.getFeaturesForBounds(LatLngBounds.from(id.z, id.x, id.y), id.z); + CustomVectorSource source = sourceRef.get(); + if(source != null) { + source.setTileData(id, data); + } + } +} + +/** + * Custom Vector Source, allows using FeatureCollections. + * + */ +@UiThread +public class CustomVectorSource extends Source { + private BlockingQueue requestQueue; + private ThreadPoolExecutor executor; + private TileProvider provider; + + /** + * Internal use + * + * @param nativePtr - pointer to native peer + */ + public CustomVectorSource(long nativePtr) { + super(nativePtr); + } + + /** + * Create a CustomVectorSource + * + * @param id the source id + */ + public CustomVectorSource(String id, TileProvider provider_) { + requestQueue = new ArrayBlockingQueue(80); + executor = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, requestQueue); + + provider = provider_; + initialize(this, id, new GeoJsonOptions()); + } + + /** + * Create a CustomVectorSource with non-default GeoJsonOptions. + * + * @param id the source id + * @param options options + */ + public CustomVectorSource(String id, TileProvider provider_, GeoJsonOptions options) { + provider = provider_; + initialize(this, id, options); + } + + public void setTileData(TileID tileId, FeatureCollection data) { + setTileData(tileId.z, tileId.x, tileId.y, data); + } + + /** + * Queries the source for features. + * + * @param filter an optional filter statement to filter the returned Features + * @return the features + */ + @NonNull + public List<Feature> querySourceFeatures(@Nullable Filter.Statement filter) { + Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null); + return features != null ? Arrays.asList(features) : new ArrayList<Feature>(); + } + + protected native void initialize(CustomVectorSource self, String sourceId, Object options); + + private native Feature[] querySourceFeatures(Object[] filter); + + private native void setTileData(int z, int x, int y, FeatureCollection data); + + @WorkerThread + public void fetchTile(int z, int x, int y) { + TileRequest request = new TileRequest(new TileID(z, x, y), provider, this); + long active = executor.getActiveCount(); + long complete = executor.getCompletedTaskCount(); + executor.execute(request); +// setTileData(z, x, y, data); + System.out.println("Active=" + active); + System.out.println("Completed=" + complete); + } + + @WorkerThread + public void cancelTile(int z, int x, int y) { + } + + @Override + protected native void finalize() throws Throwable; +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java index 1a1711e547..81f7255b86 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java @@ -16,6 +16,17 @@ public class GeoJsonOptions extends HashMap<String, Object> { * @param maxZoom the maximum zoom - Defaults to 18. * @return the current instance for chaining */ + public GeoJsonOptions withMinZoom(int minZoom) { + this.put("minzoom", minZoom); + return this; + } + + /** + * Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels). + * + * @param maxZoom the maximum zoom - Defaults to 18. + * @return the current instance for chaining + */ public GeoJsonOptions withMaxZoom(int maxZoom) { this.put("maxzoom", maxZoom); return this; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileProvider.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileProvider.java new file mode 100644 index 0000000000..7e3befbc43 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileProvider.java @@ -0,0 +1,12 @@ +package com.mapbox.mapboxsdk.style.sources; + +import android.support.annotation.WorkerThread; + +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.services.commons.geojson.FeatureCollection; +import com.mapbox.services.commons.geojson.GeoJSON; + +public interface TileProvider { + @WorkerThread + FeatureCollection getFeaturesForBounds(LatLngBounds bounds, int zoomLevel); +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java index 8d9a360714..ac52b631ed 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java @@ -4,6 +4,7 @@ import android.os.Parcelable; import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; import com.mapbox.mapboxsdk.utils.MockParcel; +import com.mapbox.services.android.telemetry.constants.GeoConstants; import org.junit.Before; import org.junit.Test; @@ -281,4 +282,22 @@ public class LatLngBoundsTest { Parcelable parcel = MockParcel.obtain(latLngBounds); assertEquals("Parcel should match original object", parcel, latLngBounds); } + + @Test + public void fromTileID() { + //GeoConstants.MAX_LATITUDE is not defined to a high enough precision + double MAX_LATITUDE = 85.05112877980659; + LatLngBounds bounds = LatLngBounds.from(0, 0, 0); + assertEquals(-GeoConstants.MAX_LONGITUDE, bounds.getLonWest(), DELTA); + assertEquals(-MAX_LATITUDE, bounds.getLatSouth(), DELTA); + assertEquals(GeoConstants.MAX_LONGITUDE, bounds.getLonEast(), DELTA); + assertEquals(MAX_LATITUDE, bounds.getLatNorth(), DELTA); + + bounds = LatLngBounds.from(10, 288, 385); + assertEquals(-78.75, bounds.getLonWest(), DELTA); + assertEquals(40.446947059600497, bounds.getLatSouth(), DELTA); + assertEquals(-78.3984375, bounds.getLonEast(), DELTA); + assertEquals(40.713955826286039, bounds.getLatNorth(), DELTA); + + } } |