diff options
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources')
7 files changed, 364 insertions, 4 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.java new file mode 100644 index 0000000000..1b0999ae2e --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.java @@ -0,0 +1,203 @@ +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.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.style.layers.Filter; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Custom Vector Source, allows using FeatureCollections. + * + */ +@UiThread +public class CustomGeometrySource extends Source { + private ExecutorService executor; + private GeometryTileProvider provider; + private final Map<TileID, AtomicBoolean> cancelledTileRequests = new ConcurrentHashMap<>(); + + /** + * Create a CustomGeometrySource + * + * @param id The source id. + * @param provider The tile provider that returns geometry data for this source. + */ + public CustomGeometrySource(String id, GeometryTileProvider provider) { + this(id, provider, new CustomGeometrySourceOptions()); + } + + /** + * Create a CustomGeometrySource with non-default CustomGeometrySourceOptions. + * <p>Supported options are minZoom, maxZoom, buffer, and tolerance.</p> + * + * @param id The source id. + * @param provider The tile provider that returns geometry data for this source. + * @param options CustomGeometrySourceOptions. + */ + public CustomGeometrySource(String id, GeometryTileProvider provider, CustomGeometrySourceOptions options) { + this.provider = provider; + executor = Executors.newFixedThreadPool(4); + initialize(id, options); + } + + /** + * Invalidate previously provided features within a given bounds at all zoom levels. + * Invoking this method will result in new requests to `GeometryTileProvider` for regions + * that contain, include, or intersect with the provided bounds. + * + * @param bounds The region in which features should be invalidated at all zoom levels + */ + public void invalidateRegion(LatLngBounds bounds) { + nativeInvalidateBounds(bounds); + } + + /** + * Invalidate the geometry contents of a specific tile. Invoking this method will result + * in new requests to `GeometryTileProvider` for visible tiles. + * + * @param zoomLevel Tile zoom level. + * @param x Tile X coordinate. + * @param y Tile Y coordinate. + */ + public void invalidateTile(int zoomLevel, int x, int y) { + nativeInvalidateTile(zoomLevel, x, y); + } + + /** + * Set or update geometry contents of a specific tile. Use this method to update tiles + * for which `GeometryTileProvider` was previously invoked. This method can be called from + * background threads. + * + * @param zoomLevel Tile zoom level. + * @param x Tile X coordinate. + * @param y Tile Y coordinate. + * @param data Feature collection for the tile. + */ + public void setTileData(int zoomLevel, int x, int y, FeatureCollection data) { + nativeSetTileData(zoomLevel, x, 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(String sourceId, Object options); + + private native Feature[] querySourceFeatures(Object[] filter); + + private native void nativeSetTileData(int z, int x, int y, FeatureCollection data); + + private native void nativeInvalidateTile(int z, int x, int y); + + private native void nativeInvalidateBounds(LatLngBounds bounds); + + @Override + protected native void finalize() throws Throwable; + + private void setTileData(TileID tileId, FeatureCollection data) { + cancelledTileRequests.remove(tileId); + nativeSetTileData(tileId.z, tileId.x, tileId.y, data); + } + + @WorkerThread + private void fetchTile(int z, int x, int y) { + AtomicBoolean cancelFlag = new AtomicBoolean(false); + TileID tileID = new TileID(z, x, y); + cancelledTileRequests.put(tileID, cancelFlag); + GeometryTileRequest request = new GeometryTileRequest(tileID, provider, this, cancelFlag); + executor.execute(request); + } + + @WorkerThread + private void cancelTile(int z, int x, int y) { + AtomicBoolean cancelFlag = cancelledTileRequests.get(new TileID(z, x, y)); + if (cancelFlag != null) { + cancelFlag.compareAndSet(false, true); + } + } + + private static 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; + } + + public int hashCode() { + return Arrays.hashCode(new int[]{z, x, y}); + } + + public boolean equals(Object object) { + if (object == this) { + return true; + } + + if (object == null || getClass() != object.getClass()) { + return false; + } + + if (object instanceof TileID) { + TileID other = (TileID)object; + return this.z == other.z && this.x == other.x && this.y == other.y; + } + return false; + } + } + + private static class GeometryTileRequest implements Runnable { + private TileID id; + private GeometryTileProvider provider; + private WeakReference<CustomGeometrySource> sourceRef; + private AtomicBoolean cancelled; + + public GeometryTileRequest(TileID _id, GeometryTileProvider p, + CustomGeometrySource _source, AtomicBoolean _cancelled) { + id = _id; + provider = p; + sourceRef = new WeakReference<>(_source); + cancelled = _cancelled; + } + + public void run() { + if (isCancelled()) { + return; + } + + FeatureCollection data = provider.getFeaturesForBounds(LatLngBounds.from(id.z, id.x, id.y), id.z); + CustomGeometrySource source = sourceRef.get(); + if (!isCancelled() && source != null && data != null) { + source.setTileData(id, data); + } + } + + private Boolean isCancelled() { + return cancelled.get(); + } + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.java new file mode 100644 index 0000000000..4ada38c238 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.java @@ -0,0 +1,31 @@ +package com.mapbox.mapboxsdk.style.sources; + +/** + * Builder class for composing CustomGeometrySource objects. + */ +public class CustomGeometrySourceOptions extends GeoJsonOptions { + + /** + * If the data includes wrapped coordinates, setting this to true unwraps the coordinates. + * + * @param wrap defaults to false + * @return the current instance for chaining + */ + public CustomGeometrySourceOptions withWrap(boolean wrap) { + this.put("wrap", wrap); + return this; + } + + /** + * If the data includes geometry outside the tile boundaries, setting this to true clips the geometry + * to the tile boundaries. + * + * @param clip defaults to false + * @return the current instance for chaining + */ + public CustomGeometrySourceOptions withClip(boolean clip) { + this.put("clip", clip); + return this; + } + +} 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..79cde7429c 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 @@ -13,6 +13,17 @@ public class GeoJsonOptions extends HashMap<String, Object> { /** * Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels). * + * @param minZoom 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 */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java index 10ecb945ad..5c740554cd 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java @@ -4,10 +4,10 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Geometry; import com.mapbox.mapboxsdk.style.layers.Filter; -import com.mapbox.services.commons.geojson.Feature; -import com.mapbox.services.commons.geojson.FeatureCollection; -import com.mapbox.services.commons.geojson.Geometry; import java.net.URL; import java.util.ArrayList; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeometryTileProvider.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeometryTileProvider.java new file mode 100644 index 0000000000..17e7f0f5e4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeometryTileProvider.java @@ -0,0 +1,22 @@ +package com.mapbox.mapboxsdk.style.sources; + +import android.support.annotation.WorkerThread; + +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; + +/** + * Interface that defines methods for working with {@link CustomGeometrySource}. + */ +public interface GeometryTileProvider { + + /*** + * Interface method called by {@link CustomGeometrySource} to request features for a tile. + * + * @param bounds {@link LatLngBounds} of the tile. + * @param zoomLevel Tile zoom level. + * @return Return a @{link FeatureCollection} to be displayed in the requested tile. + */ + @WorkerThread + FeatureCollection getFeaturesForBounds(LatLngBounds bounds, int zoomLevel); +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.java new file mode 100644 index 0000000000..ee6fc5d7b7 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.java @@ -0,0 +1,93 @@ +package com.mapbox.mapboxsdk.style.sources; + +import android.support.annotation.Nullable; +import android.support.annotation.UiThread; + +import java.net.URL; + +/** + * A raster DEM source. Currently only supports Mapbox Terrain RGB (mapbox://mapbox.terrain-rgb) + * + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-raster-dem">The style specification</a> + */ +@UiThread +public class RasterDemSource extends Source { + public static final int DEFAULT_TILE_SIZE = 512; + + /** + * Internal use + * + * @param nativePtr - pointer to native peer + */ + private RasterDemSource(long nativePtr) { + super(nativePtr); + } + + /** + * Create the raster dem source from an URL + * + * @param id the source id + * @param url the source url + */ + public RasterDemSource(String id, URL url) { + this(id, url.toExternalForm()); + } + + /** + * Create the raster dem source from an URL + * + * @param id the source id + * @param url the source url + */ + public RasterDemSource(String id, String url) { + initialize(id, url, DEFAULT_TILE_SIZE); + } + + /** + * Create the raster source from an URL with a specific tile size + * + * @param id the source id + * @param url the source url + * @param tileSize the tile size + */ + public RasterDemSource(String id, String url, int tileSize) { + initialize(id, url, tileSize); + } + + /** + * Create the raster dem source from a {@link TileSet} + * + * @param id the source id + * @param tileSet the {@link TileSet} + */ + public RasterDemSource(String id, TileSet tileSet) { + initialize(id, tileSet.toValueObject(), DEFAULT_TILE_SIZE); + } + + /** + * Create the raster source from a {@link TileSet} with a specific tile size + * + * @param id the source id + * @param tileSet the {@link TileSet} + * @param tileSize tje tile size + */ + public RasterDemSource(String id, TileSet tileSet, int tileSize) { + initialize(id, tileSet.toValueObject(), tileSize); + } + + /** + * @return The url or null + */ + @Nullable + public String getUrl() { + return nativeGetUrl(); + } + + protected native void initialize(String layerId, Object payload, int tileSize); + + @Override + protected native void finalize() throws Throwable; + + protected native String nativeGetUrl(); + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java index 9b59cf8967..62b08a90ed 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java @@ -5,8 +5,8 @@ import android.support.annotation.Nullable; import android.support.annotation.Size; import android.support.annotation.UiThread; +import com.mapbox.geojson.Feature; import com.mapbox.mapboxsdk.style.layers.Filter; -import com.mapbox.services.commons.geojson.Feature; import java.net.URL; import java.util.ArrayList; |