diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
index 200a1dc69..ef1526c5b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
@@ -93,7 +93,7 @@ public final class Mapbox {
ThreadUtils.init(context);
ThreadUtils.checkThread(TAG);
if (INSTANCE == null) {
- Timber.plant(new Timber.DebugTree());
+ Timber.plant();
Context appContext = context.getApplicationContext();
FileSource.initializeFileDirsPaths(appContext);
INSTANCE = new Mapbox(appContext, apiKey);
@@ -281,4 +281,4 @@ public final class Mapbox {
private static AssetManager getAssetManager() {
return getApplicationContext().getResources().getAssets();
}
-}
\ No newline at end of file
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java
deleted file mode 100644
index d6be7a7c8..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.Keep;
-
-/**
- * Thrown when adding a source to a map twice
- */
-@Keep
-public class CannotAddSourceException extends RuntimeException {
-
- public CannotAddSourceException(String message) {
- super(message);
- }
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.kt
new file mode 100644
index 000000000..7d677ca96
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.kt
@@ -0,0 +1,9 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Keep
+
+/**
+ * Thrown when adding a source to a map twice
+ */
+@Keep
+class CannotAddSourceException(message: String?) : RuntimeException(message)
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
deleted file mode 100644
index 1bd53fd04..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.java
+++ /dev/null
@@ -1,379 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.Keep;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
-
-import com.mapbox.geojson.Feature;
-import com.mapbox.geojson.FeatureCollection;
-import com.mapbox.mapboxsdk.geometry.LatLngBounds;
-import com.mapbox.mapboxsdk.style.expressions.Expression;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Custom Vector Source, allows using FeatureCollections.
- *
- * CustomGeometrySource uses a coalescing model for frequent data updates targeting the same tile id,
- * which means, that the in-progress request as well as the last scheduled request are guaranteed to finish.
- * Any requests scheduled meanwhile can be canceled.
- */
-public class CustomGeometrySource extends Source {
- public static final String THREAD_PREFIX = "CustomGeom";
- public static final int THREAD_POOL_LIMIT = 4;
- private static final AtomicInteger poolCount = new AtomicInteger();
- private final Lock executorLock = new ReentrantLock();
- private ThreadPoolExecutor executor;
- private GeometryTileProvider provider;
- private final Map awaitingTasksMap = new HashMap<>();
-
- /**
- * A map containing in-progress requests targeting distinct tiles.
- * A request is considered in-progress when it's started by the ThreadPoolExecutor.
- * A request is marked as done when the data is passed from the JNI layer to the core, after the features conversion.
- */
- private final Map inProgressTasksMap = new HashMap<>();
-
- /**
- * Create a CustomGeometrySource
- *
- * @param id The source id.
- * @param provider The tile provider that returns geometry data for this source.
- */
- @UiThread
- public CustomGeometrySource(String id, GeometryTileProvider provider) {
- this(id, new CustomGeometrySourceOptions(), provider);
- }
-
- /**
- * Create a CustomGeometrySource with non-default {@link CustomGeometrySourceOptions}.
- *
- * @param id The source id.
- * @param options CustomGeometrySourceOptions.
- * @param provider The tile provider that returns geometry data for this source.
- */
- @UiThread
- public CustomGeometrySource(String id, CustomGeometrySourceOptions options,
- GeometryTileProvider provider) {
- super();
- this.provider = provider;
- 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 expression to filter the returned Features
- * @return the features
- */
- @NonNull
- public List querySourceFeatures(@Nullable Expression filter) {
- checkThread();
- Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
- return features != null ? Arrays.asList(features) : new ArrayList();
- }
-
- @Keep
- protected native void initialize(String sourceId, Object options);
-
- @NonNull
- @Keep
- private native Feature[] querySourceFeatures(Object[] filter);
-
- @Keep
- private native void nativeSetTileData(int z, int x, int y, FeatureCollection data);
-
- @Keep
- private native void nativeInvalidateTile(int z, int x, int y);
-
- @Keep
- private native void nativeInvalidateBounds(LatLngBounds bounds);
-
- @Override
- @Keep
- protected native void finalize() throws Throwable;
-
- private void setTileData(TileID tileId, FeatureCollection data) {
- nativeSetTileData(tileId.z, tileId.x, tileId.y, data);
- }
-
- /**
- * Tile data request can come from a number of different threads.
- * To remove race condition for requests targeting the same tile id we are first checking if there is a request
- * already enqueued, if yes, we are replacing it.
- * Otherwise, we are checking if there is an in-progress request, if yes,
- * we are creating or replacing an awaiting request.
- * If none of the above, we are enqueueing the request.
- */
- @WorkerThread
- @Keep
- private void fetchTile(int z, int x, int y) {
- AtomicBoolean cancelFlag = new AtomicBoolean(false);
- TileID tileID = new TileID(z, x, y);
- GeometryTileRequest request =
- new GeometryTileRequest(tileID, provider, awaitingTasksMap, inProgressTasksMap, this, cancelFlag);
-
- synchronized (awaitingTasksMap) {
- synchronized (inProgressTasksMap) {
- if (executor.getQueue().contains(request)) {
- executor.remove(request);
- executeRequest(request);
- } else if (inProgressTasksMap.containsKey(tileID)) {
- awaitingTasksMap.put(tileID, request);
- } else {
- executeRequest(request);
- }
- }
- }
- }
-
- private void executeRequest(@NonNull GeometryTileRequest request) {
- executorLock.lock();
- try {
- if (executor != null && !executor.isShutdown()) {
- executor.execute(request);
- }
- } finally {
- executorLock.unlock();
- }
- }
-
- /**
- * We want to cancel only the oldest request, therefore, we are first checking if it's in progress,
- * if not or if the currently in progress request has already been canceled,
- * we are searching for any request in the executor's queue.
- * Otherwise, we are removing an awaiting request targeting this tile id.
- *
- * {@link GeometryTileRequest#equals(Object)} is overridden to cover only the tile id,
- * therefore, we can use an empty request to search the executor's queue.
- */
- @WorkerThread
- @Keep
- private void cancelTile(int z, int x, int y) {
- TileID tileID = new TileID(z, x, y);
-
- synchronized (awaitingTasksMap) {
- synchronized (inProgressTasksMap) {
- AtomicBoolean cancelFlag = inProgressTasksMap.get(tileID);
- // check if there is an in progress task
- if (!(cancelFlag != null && cancelFlag.compareAndSet(false, true))) {
- // if there is no tasks in progress or the in progress task was already cancelled, check the executor's queue
- GeometryTileRequest emptyRequest =
- new GeometryTileRequest(tileID, null, null, null, null, null);
- if (!executor.getQueue().remove(emptyRequest)) {
- // if there was no tasks in queue, remove from the awaiting map
- awaitingTasksMap.remove(tileID);
- }
- }
- }
- }
- }
-
- @Keep
- private void startThreads() {
- executorLock.lock();
- try {
- if (executor != null && !executor.isShutdown()) {
- executor.shutdownNow();
- }
-
- executor = new ThreadPoolExecutor(THREAD_POOL_LIMIT, THREAD_POOL_LIMIT,
- 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),
- new ThreadFactory() {
- final AtomicInteger threadCount = new AtomicInteger();
- final int poolId = poolCount.getAndIncrement();
-
- @NonNull
- @Override
- public Thread newThread(@NonNull Runnable runnable) {
- return new Thread(
- runnable,
- String.format(Locale.US, "%s-%d-%d", THREAD_PREFIX, poolId, threadCount.getAndIncrement()));
- }
- });
- } finally {
- executorLock.unlock();
- }
- }
-
- @Keep
- private void releaseThreads() {
- executorLock.lock();
- try {
- executor.shutdownNow();
- } finally {
- executorLock.unlock();
- }
- }
-
- @Keep
- private boolean isCancelled(int z, int x, int y) {
- return inProgressTasksMap.get(new TileID(z, x, y)).get();
- }
-
- static class TileID {
- public int z;
- public int x;
- public int y;
-
- 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(@Nullable 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;
- }
- }
-
- static class GeometryTileRequest implements Runnable {
- private final TileID id;
- private final GeometryTileProvider provider;
- private final Map awaiting;
- private final Map inProgress;
- @NonNull
- private final WeakReference sourceRef;
- private final AtomicBoolean cancelled;
-
- GeometryTileRequest(TileID _id, GeometryTileProvider p,
- Map awaiting,
- Map m,
- CustomGeometrySource _source, AtomicBoolean _cancelled) {
- id = _id;
- provider = p;
- this.awaiting = awaiting;
- inProgress = m;
- sourceRef = new WeakReference<>(_source);
- cancelled = _cancelled;
- }
-
- public void run() {
- synchronized (awaiting) {
- synchronized (inProgress) {
- if (inProgress.containsKey(id)) {
- // request targeting this tile id is already being processed,
- // scenario that should occur only if the tile is being requested when
- // another request is switching threads to execute
- if (!awaiting.containsKey(id)) {
- awaiting.put(id, this);
- }
- return;
- } else {
- inProgress.put(id, cancelled);
- }
- }
- }
-
- if (!isCancelled()) {
- 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);
- }
- }
-
- synchronized (awaiting) {
- synchronized (inProgress) {
- inProgress.remove(id);
-
- // executing the next request targeting the same tile
- if (awaiting.containsKey(id)) {
- GeometryTileRequest queuedRequest = awaiting.get(id);
- CustomGeometrySource source = sourceRef.get();
- if (source != null && queuedRequest != null) {
- source.executor.execute(queuedRequest);
- }
-
- awaiting.remove(id);
- }
- }
- }
- }
-
- private Boolean isCancelled() {
- return cancelled.get();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- GeometryTileRequest request = (GeometryTileRequest) o;
- return id.equals(request.id);
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.kt
new file mode 100644
index 000000000..e5f2cbecb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySource.kt
@@ -0,0 +1,344 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Keep
+import androidx.annotation.UiThread
+import androidx.annotation.WorkerThread
+import com.mapbox.geojson.Feature
+import com.mapbox.geojson.FeatureCollection
+import com.mapbox.mapboxsdk.geometry.LatLngBounds
+import com.mapbox.mapboxsdk.geometry.LatLngBounds.Companion.from
+import com.mapbox.mapboxsdk.style.expressions.Expression
+import java.lang.ref.WeakReference
+import java.util.Arrays
+import java.util.Locale
+import java.util.concurrent.LinkedBlockingQueue
+import java.util.concurrent.ThreadFactory
+import java.util.concurrent.ThreadPoolExecutor
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicInteger
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.collections.ArrayList
+import kotlin.collections.HashMap
+
+/**
+ * Custom Vector Source, allows using FeatureCollections.
+ *
+ *
+ * CustomGeometrySource uses a coalescing model for frequent data updates targeting the same tile id,
+ * which means, that the in-progress request as well as the last scheduled request are guaranteed to finish.
+ * Any requests scheduled meanwhile can be canceled.
+ */
+class CustomGeometrySource @UiThread constructor(id: String?, options: CustomGeometrySourceOptions?, private val provider: GeometryTileProvider?) : Source() {
+ private val executorLock: Lock = ReentrantLock()
+ private var executor: ThreadPoolExecutor? = null
+ private val awaitingTasksMap: MutableMap = HashMap()
+
+ /**
+ * A map containing in-progress requests targeting distinct tiles.
+ * A request is considered in-progress when it's started by the ThreadPoolExecutor.
+ * A request is marked as done when the data is passed from the JNI layer to the core, after the features conversion.
+ */
+ private val inProgressTasksMap: MutableMap = HashMap()
+
+ /**
+ * Create a CustomGeometrySource
+ *
+ * @param id The source id.
+ * @param provider The tile provider that returns geometry data for this source.
+ */
+ @UiThread
+ constructor(id: String?, provider: GeometryTileProvider?) : this(id, CustomGeometrySourceOptions(), provider) {
+ }
+
+ /**
+ * Create a CustomGeometrySource with non-default [CustomGeometrySourceOptions].
+ *
+ * @param id The source id.
+ * @param options CustomGeometrySourceOptions.
+ */
+ init {
+ 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
+ */
+ fun invalidateRegion(bounds: LatLngBounds) {
+ 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.
+ */
+ fun invalidateTile(zoomLevel: Int, x: Int, y: Int) {
+ 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.
+ */
+ fun setTileData(zoomLevel: Int, x: Int, y: Int, data: FeatureCollection) {
+ nativeSetTileData(zoomLevel, x, y, data)
+ }
+
+ /**
+ * Queries the source for features.
+ *
+ * @param filter an optional filter expression to filter the returned Features
+ * @return the features
+ */
+ fun querySourceFeatures(filter: Expression?): List {
+ checkThread()
+ val features = querySourceFeatures(filter?.toArray())
+ return if (features != null) Arrays.asList(*features) else ArrayList()
+ }
+
+ @Keep
+ private external fun initialize(sourceId: String?, options: Any?)
+
+ @Keep
+ private external fun querySourceFeatures(filter: Array?): Array
+
+ @Keep
+ private external fun nativeSetTileData(z: Int, x: Int, y: Int, data: FeatureCollection)
+
+ @Keep
+ private external fun nativeInvalidateTile(z: Int, x: Int, y: Int)
+
+ @Keep
+ private external fun nativeInvalidateBounds(bounds: LatLngBounds)
+
+ @Keep
+ @Throws(Throwable::class)
+ protected external fun finalize()
+
+ private fun setTileData(tileId: TileID, data: FeatureCollection) {
+ nativeSetTileData(tileId.z, tileId.x, tileId.y, data)
+ }
+
+ /**
+ * Tile data request can come from a number of different threads.
+ * To remove race condition for requests targeting the same tile id we are first checking if there is a request
+ * already enqueued, if yes, we are replacing it.
+ * Otherwise, we are checking if there is an in-progress request, if yes,
+ * we are creating or replacing an awaiting request.
+ * If none of the above, we are enqueueing the request.
+ */
+ @WorkerThread
+ @Keep
+ private fun fetchTile(z: Int, x: Int, y: Int) {
+ val cancelFlag = AtomicBoolean(false)
+ val tileID = TileID(z, x, y)
+ val request = GeometryTileRequest(tileID, provider, awaitingTasksMap, inProgressTasksMap, this, cancelFlag)
+ synchronized(awaitingTasksMap) {
+ synchronized(inProgressTasksMap) {
+ if (executor!!.queue.contains(request)) {
+ executor!!.remove(request)
+ executeRequest(request)
+ } else if (inProgressTasksMap.containsKey(tileID)) {
+ awaitingTasksMap.put(tileID, request)
+ } else {
+ executeRequest(request)
+ }
+ }
+ }
+ }
+
+ private fun executeRequest(request: GeometryTileRequest) {
+ executorLock.lock()
+ try {
+ if (executor != null && !executor!!.isShutdown) {
+ executor!!.execute(request)
+ }
+ } finally {
+ executorLock.unlock()
+ }
+ }
+
+ /**
+ * We want to cancel only the oldest request, therefore, we are first checking if it's in progress,
+ * if not or if the currently in progress request has already been canceled,
+ * we are searching for any request in the executor's queue.
+ * Otherwise, we are removing an awaiting request targeting this tile id.
+ *
+ *
+ * [GeometryTileRequest.equals] is overridden to cover only the tile id,
+ * therefore, we can use an empty request to search the executor's queue.
+ */
+ @WorkerThread
+ @Keep
+ private fun cancelTile(z: Int, x: Int, y: Int) {
+ val tileID = TileID(z, x, y)
+ synchronized(awaitingTasksMap) {
+ synchronized(inProgressTasksMap) {
+ val cancelFlag = inProgressTasksMap[tileID]
+ // check if there is an in progress task
+ if (!(cancelFlag != null && cancelFlag.compareAndSet(false, true))) {
+ // if there is no tasks in progress or the in progress task was already cancelled, check the executor's queue
+ val emptyRequest = GeometryTileRequest(tileID, null, null, null, null, null)
+ if (!executor!!.queue.remove(emptyRequest)) {
+ // if there was no tasks in queue, remove from the awaiting map
+ awaitingTasksMap.remove(tileID)
+ }
+ }
+ }
+ }
+ }
+
+ @Keep
+ private fun startThreads() {
+ executorLock.lock()
+ executor = try {
+ if (executor != null && !executor!!.isShutdown) {
+ executor!!.shutdownNow()
+ }
+ ThreadPoolExecutor(
+ THREAD_POOL_LIMIT,
+ THREAD_POOL_LIMIT,
+ 0L,
+ TimeUnit.MILLISECONDS,
+ LinkedBlockingQueue(),
+ object : ThreadFactory {
+ val threadCount = AtomicInteger()
+ val poolId = poolCount.getAndIncrement()
+ override fun newThread(runnable: Runnable): Thread {
+ return Thread(runnable, String.format(Locale.US, "%s-%d-%d", THREAD_PREFIX, poolId, threadCount.getAndIncrement()))
+ }
+ }
+ )
+ } finally {
+ executorLock.unlock()
+ }
+ }
+
+ @Keep
+ private fun releaseThreads() {
+ executorLock.lock()
+ try {
+ executor!!.shutdownNow()
+ } finally {
+ executorLock.unlock()
+ }
+ }
+
+ @Keep
+ private fun isCancelled(z: Int, x: Int, y: Int): Boolean {
+ return inProgressTasksMap[TileID(z, x, y)]!!.get()
+ }
+
+ internal class TileID(var z: Int, var x: Int, var y: Int) {
+ override fun hashCode(): Int {
+ return Arrays.hashCode(intArrayOf(z, x, y))
+ }
+
+ override fun equals(`object`: Any?): Boolean {
+ if (`object` === this) {
+ return true
+ }
+ if (`object` == null || javaClass != `object`.javaClass) {
+ return false
+ }
+ if (`object` is TileID) {
+ val other = `object`
+ return z == other.z && x == other.x && y == other.y
+ }
+ return false
+ }
+ }
+
+ internal class GeometryTileRequest(
+ private val id: TileID,
+ private val provider: GeometryTileProvider?,
+ private val awaiting: MutableMap?,
+ private val inProgress: MutableMap?,
+ _source: CustomGeometrySource?,
+ _cancelled: AtomicBoolean?
+ ) : Runnable {
+ private val sourceRef: WeakReference
+ private val cancelled: AtomicBoolean?
+
+ init {
+ sourceRef = WeakReference(_source)
+ cancelled = _cancelled
+ }
+
+ override fun run() {
+ synchronized(awaiting!!) {
+ synchronized(inProgress!!) {
+ if (inProgress.containsKey(id)) {
+ // request targeting this tile id is already being processed,
+ // scenario that should occur only if the tile is being requested when
+ // another request is switching threads to execute
+ if (!awaiting.containsKey(id)) {
+ awaiting[id] = this
+ }
+ return
+ } else {
+ inProgress.put(id, cancelled)
+ }
+ }
+ }
+ if (!isCancelled()) {
+ val data = provider!!.getFeaturesForBounds(from(id.z, id.x, id.y), id.z)
+ val source = sourceRef.get()
+ if (!isCancelled() && source != null && data != null) {
+ source.setTileData(id, data)
+ }
+ }
+ synchronized(awaiting) {
+ synchronized(inProgress!!) {
+ inProgress.remove(id)
+
+ // executing the next request targeting the same tile
+ if (awaiting.containsKey(id)) {
+ val queuedRequest = awaiting[id]
+ val source = sourceRef.get()
+ if (source != null && queuedRequest != null) {
+ source.executor!!.execute(queuedRequest)
+ }
+ awaiting.remove(id)
+ }
+ }
+ }
+ }
+
+ private fun isCancelled(): Boolean {
+ return cancelled!!.get()
+ }
+
+ override fun equals(o: Any?): Boolean {
+ if (this === o) {
+ return true
+ }
+ if (o == null || javaClass != o.javaClass) {
+ return false
+ }
+ val request = o as GeometryTileRequest
+ return id == request.id
+ }
+ }
+
+ companion object {
+ const val THREAD_PREFIX = "CustomGeom"
+ const val THREAD_POOL_LIMIT = 4
+ private val poolCount = AtomicInteger()
+ }
+}
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
deleted file mode 100644
index dd5998b04..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.NonNull;
-
-import java.util.HashMap;
-
-/**
- * Builder class for composing CustomGeometrySource objects.
- */
-public class CustomGeometrySourceOptions extends HashMap {
-
- /**
- * If the data includes wrapped coordinates, setting this to true unwraps the coordinates.
- *
- * @param wrap defaults to false
- * @return the current instance for chaining
- */
- @NonNull
- 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
- */
- @NonNull
- public CustomGeometrySourceOptions withClip(boolean clip) {
- this.put("clip", clip);
- return this;
- }
-
- /**
- * Minimum zoom level at which to create vector tiles (lower means more field of view detail at low zoom levels).
- *
- * @param minZoom the minimum zoom - Defaults to 0.
- * @return the current instance for chaining
- */
- @NonNull
- public CustomGeometrySourceOptions 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 25.5
- * @return the current instance for chaining
- */
- @NonNull
- public CustomGeometrySourceOptions withMaxZoom(int maxZoom) {
- this.put("maxzoom", maxZoom);
- return this;
- }
-
- /**
- * Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile
- * edges but slower performance).
- *
- * @param buffer the buffer size - Defaults to 128.
- * @return the current instance for chaining
- */
- @NonNull
- public CustomGeometrySourceOptions withBuffer(int buffer) {
- this.put("buffer", buffer);
- return this;
- }
-
- /**
- * Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
- *
- * @param tolerance the tolerance - Defaults to 0.375
- * @return the current instance for chaining
- */
- @NonNull
- public CustomGeometrySourceOptions withTolerance(float tolerance) {
- this.put("tolerance", tolerance);
- return this;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.kt
new file mode 100644
index 000000000..494c2ca16
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomGeometrySourceOptions.kt
@@ -0,0 +1,74 @@
+package com.mapbox.mapboxsdk.style.sources
+
+/**
+ * Builder class for composing CustomGeometrySource objects.
+ */
+class CustomGeometrySourceOptions : HashMap() {
+ /**
+ * If the data includes wrapped coordinates, setting this to true unwraps the coordinates.
+ *
+ * @param wrap defaults to false
+ * @return the current instance for chaining
+ */
+ fun withWrap(wrap: Boolean): CustomGeometrySourceOptions {
+ this["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
+ */
+ fun withClip(clip: Boolean): CustomGeometrySourceOptions {
+ this["clip"] = clip
+ return this
+ }
+
+ /**
+ * Minimum zoom level at which to create vector tiles (lower means more field of view detail at low zoom levels).
+ *
+ * @param minZoom the minimum zoom - Defaults to 0.
+ * @return the current instance for chaining
+ */
+ fun withMinZoom(minZoom: Int): CustomGeometrySourceOptions {
+ this["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 25.5
+ * @return the current instance for chaining
+ */
+ fun withMaxZoom(maxZoom: Int): CustomGeometrySourceOptions {
+ this["maxzoom"] = maxZoom
+ return this
+ }
+
+ /**
+ * Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile
+ * edges but slower performance).
+ *
+ * @param buffer the buffer size - Defaults to 128.
+ * @return the current instance for chaining
+ */
+ fun withBuffer(buffer: Int): CustomGeometrySourceOptions {
+ this["buffer"] = buffer
+ return this
+ }
+
+ /**
+ * Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
+ *
+ * @param tolerance the tolerance - Defaults to 0.375
+ * @return the current instance for chaining
+ */
+ fun withTolerance(tolerance: Float): CustomGeometrySourceOptions {
+ this["tolerance"] = tolerance
+ 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
deleted file mode 100644
index ea34b0dc0..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.NonNull;
-
-import com.mapbox.mapboxsdk.style.expressions.Expression;
-
-import java.util.HashMap;
-
-import static com.mapbox.mapboxsdk.style.expressions.Expression.ExpressionLiteral;
-
-/**
- * Builder class for composing GeoJsonSource objects.
- *
- * @see GeoJsonSource
- * @see The online documentation
- */
-public class GeoJsonOptions extends HashMap {
-
- /**
- * Minimum zoom level at which to create vector tiles (lower means more field of view detail at low zoom levels).
- *
- * @param minZoom the minimum zoom - Defaults to 0.
- * @return the current instance for chaining
- */
- @NonNull
- 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 25.5
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withMaxZoom(int maxZoom) {
- this.put("maxzoom", maxZoom);
- return this;
- }
-
- /**
- * Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile
- * edges but slower performance).
- *
- * @param buffer the buffer size - Defaults to 128.
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withBuffer(int buffer) {
- this.put("buffer", buffer);
- return this;
- }
-
- /**
- * Initialises whether to calculate line distance metrics.
- *
- * @param lineMetrics true to calculate line distance metrics.
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withLineMetrics(boolean lineMetrics) {
- this.put("lineMetrics", lineMetrics);
- return this;
- }
-
- /**
- * Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
- *
- * @param tolerance the tolerance - Defaults to 0.375
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withTolerance(float tolerance) {
- this.put("tolerance", tolerance);
- return this;
- }
-
- /**
- * If the data is a collection of point features, setting this to true clusters the points by radius into groups.
- *
- * @param cluster cluster? - Defaults to false
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withCluster(boolean cluster) {
- this.put("cluster", cluster);
- return this;
- }
-
- /**
- * Max zoom to cluster points on.
- *
- * @param clusterMaxZoom clusterMaxZoom cluster maximum zoom - Defaults to one zoom less than maxzoom (so that last
- * zoom features are not clustered)
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withClusterMaxZoom(int clusterMaxZoom) {
- this.put("clusterMaxZoom", clusterMaxZoom);
- return this;
- }
-
- /**
- * Radius of each cluster when clustering points, measured in 1/512ths of a tile.
- *
- * @param clusterRadius cluster radius - Defaults to 50
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withClusterRadius(int clusterRadius) {
- this.put("clusterRadius", clusterRadius);
- return this;
- }
-
- /**
- * An object defining custom properties on the generated clusters if clustering is enabled,
- * aggregating values from clustered points. Has the form {"property_name": [operator, [map_expression]]} or
- * {"property_name": [[operator, accumulated, expression], [map_expression]]}
- *
- * @param propertyName name of the property
- * @param operatorExpr operatorExpr is any expression function that accepts at least 2 operands (e.g. "+" or "max").
- * It accumulates the property value from clusters/points the cluster contains. It can either be
- * a literal with single operator, or be a valid expression
- * @param mapExpr map expression produces the value of a single point, it shall be a valid expression
- * @return the current instance for chaining
- */
- @NonNull
- public GeoJsonOptions withClusterProperty(String propertyName, Expression operatorExpr, Expression mapExpr) {
- HashMap properties = containsKey("clusterProperties")
- ? (HashMap) get("clusterProperties") : new HashMap();
- Object operator = (operatorExpr instanceof ExpressionLiteral)
- ? ((ExpressionLiteral)operatorExpr).toValue() : operatorExpr.toArray();
- Object map = mapExpr.toArray();
- properties.put(propertyName, new Object[]{operator, map});
- this.put("clusterProperties", properties);
- return this;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.kt
new file mode 100644
index 000000000..db61665bb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.kt
@@ -0,0 +1,123 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import com.mapbox.mapboxsdk.style.expressions.Expression
+import com.mapbox.mapboxsdk.style.expressions.Expression.ExpressionLiteral
+/**
+ * Builder class for composing GeoJsonSource objects.
+ *
+ * @see GeoJsonSource
+ *
+ * @see [The online documentation](https://www.mapbox.com/mapbox-gl-style-spec/.sources-geojson)
+ */
+class GeoJsonOptions : HashMap() {
+ /**
+ * Minimum zoom level at which to create vector tiles (lower means more field of view detail at low zoom levels).
+ *
+ * @param minZoom the minimum zoom - Defaults to 0.
+ * @return the current instance for chaining
+ */
+ fun withMinZoom(minZoom: Int): GeoJsonOptions {
+ this["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 25.5
+ * @return the current instance for chaining
+ */
+ fun withMaxZoom(maxZoom: Int): GeoJsonOptions {
+ this["maxzoom"] = maxZoom
+ return this
+ }
+
+ /**
+ * Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile
+ * edges but slower performance).
+ *
+ * @param buffer the buffer size - Defaults to 128.
+ * @return the current instance for chaining
+ */
+ fun withBuffer(buffer: Int): GeoJsonOptions {
+ this["buffer"] = buffer
+ return this
+ }
+
+ /**
+ * Initialises whether to calculate line distance metrics.
+ *
+ * @param lineMetrics true to calculate line distance metrics.
+ * @return the current instance for chaining
+ */
+ fun withLineMetrics(lineMetrics: Boolean): GeoJsonOptions {
+ this["lineMetrics"] = lineMetrics
+ return this
+ }
+
+ /**
+ * Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
+ *
+ * @param tolerance the tolerance - Defaults to 0.375
+ * @return the current instance for chaining
+ */
+ fun withTolerance(tolerance: Float): GeoJsonOptions {
+ this["tolerance"] = tolerance
+ return this
+ }
+
+ /**
+ * If the data is a collection of point features, setting this to true clusters the points by radius into groups.
+ *
+ * @param cluster cluster? - Defaults to false
+ * @return the current instance for chaining
+ */
+ fun withCluster(cluster: Boolean): GeoJsonOptions {
+ this["cluster"] = cluster
+ return this
+ }
+
+ /**
+ * Max zoom to cluster points on.
+ *
+ * @param clusterMaxZoom clusterMaxZoom cluster maximum zoom - Defaults to one zoom less than maxzoom (so that last
+ * zoom features are not clustered)
+ * @return the current instance for chaining
+ */
+ fun withClusterMaxZoom(clusterMaxZoom: Int): GeoJsonOptions {
+ this["clusterMaxZoom"] = clusterMaxZoom
+ return this
+ }
+
+ /**
+ * Radius of each cluster when clustering points, measured in 1/512ths of a tile.
+ *
+ * @param clusterRadius cluster radius - Defaults to 50
+ * @return the current instance for chaining
+ */
+ fun withClusterRadius(clusterRadius: Int): GeoJsonOptions {
+ this["clusterRadius"] = clusterRadius
+ return this
+ }
+
+ /**
+ * An object defining custom properties on the generated clusters if clustering is enabled,
+ * aggregating values from clustered points. Has the form {"property_name": [operator, [map_expression]]} or
+ * {"property_name": [[operator, accumulated, expression], [map_expression]]}
+ *
+ * @param propertyName name of the property
+ * @param operatorExpr operatorExpr is any expression function that accepts at least 2 operands (e.g. "+" or "max").
+ * It accumulates the property value from clusters/points the cluster contains. It can either be
+ * a literal with single operator, or be a valid expression
+ * @param mapExpr map expression produces the value of a single point, it shall be a valid expression
+ * @return the current instance for chaining
+ */
+ fun withClusterProperty(propertyName: String, operatorExpr: Expression, mapExpr: Expression): GeoJsonOptions {
+ val properties = if (containsKey("clusterProperties")) get("clusterProperties") as HashMap>? else HashMap()
+ val operator = if (operatorExpr is ExpressionLiteral) operatorExpr.toValue() else operatorExpr.toArray()
+ val map: Any = mapExpr.toArray()
+ properties!![propertyName] = arrayOf(operator, map)
+ this["clusterProperties"] = properties
+ return this
+ }
+}
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
deleted file mode 100644
index 85216e931..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
+++ /dev/null
@@ -1,519 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.Keep;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
-import com.mapbox.geojson.Feature;
-import com.mapbox.geojson.FeatureCollection;
-import com.mapbox.geojson.Geometry;
-import com.mapbox.mapboxsdk.style.expressions.Expression;
-
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * GeoJson source, allows using FeatureCollections from Json.
- *
- * @see the style specification
- */
-@UiThread
-public class GeoJsonSource extends Source {
-
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- @Keep
- GeoJsonSource(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Create an empty GeoJsonSource
- *
- * @param id the source id
- */
- public GeoJsonSource(String id) {
- super();
- initialize(id, null);
- setGeoJson(FeatureCollection.fromFeatures(new ArrayList()));
- }
-
- /**
- * Create an empty GeoJsonSource with non-default GeoJsonOptions.
- *
- * @param id the source id
- * @param options options
- */
- public GeoJsonSource(String id, GeoJsonOptions options) {
- super();
- initialize(id, options);
- setGeoJson(FeatureCollection.fromFeatures(new ArrayList()));
- }
-
- /**
- * Create a GeoJsonSource from a raw json string
- *
- * @param id the source id
- * @param geoJson raw Json FeatureCollection
- */
- public GeoJsonSource(String id, @Nullable String geoJson) {
- super();
- if (geoJson == null || geoJson.startsWith("http")) {
- throw new IllegalArgumentException("Expected a raw json body");
- }
- initialize(id, null);
- setGeoJson(geoJson);
- }
-
- /**
- * Create a GeoJsonSource from a raw json string and non-default GeoJsonOptions
- *
- * @param id the source id
- * @param geoJson raw Json body
- * @param options options
- */
- public GeoJsonSource(String id, @Nullable String geoJson, GeoJsonOptions options) {
- super();
- if (geoJson == null || geoJson.startsWith("http") || geoJson.startsWith("asset") || geoJson.startsWith("file")) {
- throw new IllegalArgumentException("Expected a raw json body");
- }
- initialize(id, options);
- setGeoJson(geoJson);
- }
-
- /**
- * Create a GeoJsonSource from a remote geo json file
- *
- * @param id the source id
- * @param url remote json file
- * @deprecated use {@link #GeoJsonSource(String, URI)} instead
- */
- @Deprecated
- public GeoJsonSource(String id, URL url) {
- super();
- initialize(id, null);
- nativeSetUrl(url.toExternalForm());
- }
-
- /**
- * Create a GeoJsonSource from a remote geo json file and non-default GeoJsonOptions
- *
- * @param id the source id
- * @param url remote json file
- * @param options options
- * @deprecated use {@link #GeoJsonSource(String, URI, GeoJsonOptions)} instead
- */
- @Deprecated
- public GeoJsonSource(String id, URL url, GeoJsonOptions options) {
- super();
- initialize(id, options);
- nativeSetUrl(url.toExternalForm());
- }
-
- /**
- * Create a GeoJsonSource from a geo json URI
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri unique resource identifier
- */
- public GeoJsonSource(String id, URI uri) {
- super();
- initialize(id, null);
- nativeSetUrl(uri.toString());
- }
-
- /**
- * Create a GeoJsonSource from a geo json URI and non-default GeoJsonOptions
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri remote json file
- * @param options options
- */
- public GeoJsonSource(String id, URI uri, GeoJsonOptions options) {
- super();
- initialize(id, options);
- nativeSetUrl(uri.toString());
- }
-
- /**
- * Create a GeoJsonSource from a FeatureCollection.
- *
- * @param id the source id
- * @param features the features
- */
- public GeoJsonSource(String id, FeatureCollection features) {
- super();
- initialize(id, null);
- setGeoJson(features);
- }
-
- /**
- * Create a GeoJsonSource from a FeatureCollection and non-default GeoJsonOptions.
- *
- * @param id the source id
- * @param features the features
- * @param options options
- */
- public GeoJsonSource(String id, FeatureCollection features, GeoJsonOptions options) {
- super();
- initialize(id, options);
- setGeoJson(features);
- }
-
- /**
- * Create a GeoJsonSource from a {@link Feature}
- *
- * @param id the source id
- * @param feature the feature
- */
- public GeoJsonSource(String id, Feature feature) {
- super();
- initialize(id, null);
- setGeoJson(feature);
- }
-
- /**
- * Create a GeoJsonSource from a {@link Feature} and non-default {@link GeoJsonOptions}
- *
- * @param id the source id
- * @param feature the feature
- * @param options options
- */
- public GeoJsonSource(String id, Feature feature, GeoJsonOptions options) {
- super();
- initialize(id, options);
- setGeoJson(feature);
- }
-
- /**
- * Create a GeoJsonSource from a {@link Geometry}
- *
- * @param id the source id
- * @param geometry the geometry
- */
- public GeoJsonSource(String id, Geometry geometry) {
- super();
- initialize(id, null);
- setGeoJson(geometry);
- }
-
- /**
- * Create a GeoJsonSource from a {@link Geometry} and non-default {@link GeoJsonOptions}
- *
- * @param id the source id
- * @param geometry the geometry
- * @param options options
- */
- public GeoJsonSource(String id, Geometry geometry, GeoJsonOptions options) {
- super();
- initialize(id, options);
- setGeoJson(geometry);
- }
-
- /**
- * Updates the GeoJson with a single feature. The update is performed asynchronously,
- * so the data won't be immediately visible or available to query when this method returns.
- *
- * @param feature the GeoJSON {@link Feature} to set
- */
- public void setGeoJson(Feature feature) {
- if (detached) {
- return;
- }
- checkThread();
- nativeSetFeature(feature);
- }
-
- /**
- * Updates the GeoJson with a single geometry. The update is performed asynchronously,
- * so the data won't be immediately visible or available to query when this method returns.
- *
- * @param geometry the GeoJSON {@link Geometry} to set
- */
- public void setGeoJson(Geometry geometry) {
- if (detached) {
- return;
- }
- checkThread();
- nativeSetGeometry(geometry);
- }
-
- /**
- * Updates the GeoJson. The update is performed asynchronously,
- * so the data won't be immediately visible or available to query when this method returns.
- *
- * @param featureCollection the GeoJSON FeatureCollection
- */
- public void setGeoJson(@Nullable FeatureCollection featureCollection) {
- if (detached) {
- return;
- }
- checkThread();
-
- if (featureCollection != null && featureCollection.features() != null) {
- List features = featureCollection.features();
- List featuresCopy = new ArrayList<>(features);
- nativeSetFeatureCollection(FeatureCollection.fromFeatures(featuresCopy));
- } else {
- nativeSetFeatureCollection(featureCollection);
- }
- }
-
- /**
- * Updates the GeoJson. The update is performed asynchronously,
- * so the data won't be immediately visible or available to query when this method returns.
- *
- * @param json the raw GeoJson FeatureCollection string
- */
- public void setGeoJson(String json) {
- if (detached) {
- return;
- }
- checkThread();
- nativeSetGeoJsonString(json);
- }
-
- /**
- * Updates the url
- *
- * @param url the GeoJSON FeatureCollection url
- * @deprecated use {@link #setUri(URI)} instead
- */
- @Deprecated
- public void setUrl(@NonNull URL url) {
- checkThread();
- setUrl(url.toExternalForm());
- }
-
- /**
- * Updates the URI of the source.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param uri the GeoJSON FeatureCollection uri
- */
- public void setUri(@NonNull URI uri) {
- setUri(uri.toString());
- }
-
- /**
- * Updates the url
- *
- * @param url the GeoJSON FeatureCollection url
- * @deprecated use {@link #setUri(String)} instead
- */
- @Deprecated
- public void setUrl(String url) {
- checkThread();
- nativeSetUrl(url);
- }
-
- /**
- * Updates the URI of the source.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param uri the GeoJSON FeatureCollection uri
- */
- public void setUri(String uri) {
- checkThread();
- nativeSetUrl(uri);
- }
-
- /**
- * @return The url or null
- * @deprecated use {@link #getUri()} instead
- */
- @Nullable
- public String getUrl() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Get the URI of the source.
- *
- * @return The uri or null
- */
- @Nullable
- public String getUri() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Queries the source for features.
- *
- * @param filter an optional filter expression to filter the returned Features
- * @return the features
- */
- @NonNull
- public List querySourceFeatures(@Nullable Expression filter) {
- checkThread();
- Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
- return features != null ? Arrays.asList(features) : new ArrayList();
- }
-
- /**
- * Returns the children of a cluster (on the next zoom level) given its id (cluster_id value from feature properties).
- *
- * Requires configuring this source as a cluster by calling {@link GeoJsonOptions#withCluster(boolean)}.
- *
- *
- * @param cluster cluster from which to retrieve children from
- * @return a list of features for the underlying children
- */
- @NonNull
- public FeatureCollection getClusterChildren(@NonNull Feature cluster) {
- checkThread();
- return FeatureCollection.fromFeatures(nativeGetClusterChildren(cluster));
- }
-
- /**
- * Returns all the leaves of a cluster (given its cluster_id), with pagination support: limit is the number of leaves
- * to return (set to Infinity for all points), and offset is the amount of points to skip (for pagination).
- *
- * Requires configuring this source as a cluster by calling {@link GeoJsonOptions#withCluster(boolean)}.
- *
- *
- * @param cluster cluster from which to retrieve leaves from
- * @param limit limit is the number of points to return
- * @param offset offset is the amount of points to skip (for pagination)
- * @return a list of features for the underlying leaves
- */
- @NonNull
- public FeatureCollection getClusterLeaves(@NonNull Feature cluster, long limit, long offset) {
- checkThread();
- return FeatureCollection.fromFeatures(nativeGetClusterLeaves(cluster, limit, offset));
- }
-
- /**
- * Returns the zoom on which the cluster expands into several children (useful for "click to zoom" feature)
- * given the cluster's cluster_id (cluster_id value from feature properties).
- *
- * Requires configuring this source as a cluster by calling {@link GeoJsonOptions#withCluster(boolean)}.
- *
- *
- * @param cluster cluster from which to retrieve the expansion zoom from
- * @return the zoom on which the cluster expands into several children
- */
- public int getClusterExpansionZoom(@NonNull Feature cluster) {
- checkThread();
- return nativeGetClusterExpansionZoom(cluster);
- }
-
- @Keep
- protected native void initialize(String layerId, Object options);
-
- @Keep
- protected native void nativeSetUrl(String url);
-
- @NonNull
- @Keep
- protected native String nativeGetUrl();
-
- @Keep
- private native void nativeSetGeoJsonString(String geoJson);
-
- @Keep
- private native void nativeSetFeatureCollection(FeatureCollection geoJson);
-
- @Keep
- private native void nativeSetFeature(Feature feature);
-
- @Keep
- private native void nativeSetGeometry(Geometry geometry);
-
- @NonNull
- @Keep
- private native Feature[] querySourceFeatures(Object[] filter);
-
- @Keep
- private native Feature[] nativeGetClusterChildren(Feature feature);
-
- @Keep
- private native Feature[] nativeGetClusterLeaves(Feature feature, long limit, long offset);
-
- @Keep
- private native int nativeGetClusterExpansionZoom(Feature feature);
-
- @Override
- @Keep
- protected native void finalize() throws Throwable;
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.kt
new file mode 100644
index 000000000..87b3972b6
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.kt
@@ -0,0 +1,498 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Keep
+import androidx.annotation.UiThread
+import com.mapbox.geojson.Feature
+import com.mapbox.geojson.FeatureCollection
+import com.mapbox.geojson.Geometry
+import com.mapbox.mapboxsdk.style.expressions.Expression
+import java.net.URI
+import java.net.URL
+import java.util.*
+
+/**
+ * GeoJson source, allows using FeatureCollections from Json.
+ *
+ * @see [the style specification](https://www.mapbox.com/mapbox-gl-style-spec/.sources-geojson)
+ */
+@UiThread
+class GeoJsonSource : Source {
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ @Keep
+ internal constructor(nativePtr: Long) : super(nativePtr) {
+ }
+
+ /**
+ * Create an empty GeoJsonSource
+ *
+ * @param id the source id
+ */
+ constructor(id: String?) : super() {
+ initialize(id, null)
+ setGeoJson(FeatureCollection.fromFeatures(ArrayList()))
+ }
+
+ /**
+ * Create an empty GeoJsonSource with non-default GeoJsonOptions.
+ *
+ * @param id the source id
+ * @param options options
+ */
+ constructor(id: String?, options: GeoJsonOptions?) : super() {
+ initialize(id, options)
+ setGeoJson(FeatureCollection.fromFeatures(ArrayList()))
+ }
+
+ /**
+ * Create a GeoJsonSource from a raw json string
+ *
+ * @param id the source id
+ * @param geoJson raw Json FeatureCollection
+ */
+ constructor(id: String?, geoJson: String?) : super() {
+ require(!(geoJson == null || geoJson.startsWith("http"))) { "Expected a raw json body" }
+ initialize(id, null)
+ setGeoJson(geoJson)
+ }
+
+ /**
+ * Create a GeoJsonSource from a raw json string and non-default GeoJsonOptions
+ *
+ * @param id the source id
+ * @param geoJson raw Json body
+ * @param options options
+ */
+ constructor(id: String?, geoJson: String?, options: GeoJsonOptions?) : super() {
+ require(!(geoJson == null || geoJson.startsWith("http") || geoJson.startsWith("asset") || geoJson.startsWith("file"))) { "Expected a raw json body" }
+ initialize(id, options)
+ setGeoJson(geoJson)
+ }
+
+ /**
+ * Create a GeoJsonSource from a remote geo json file
+ *
+ * @param id the source id
+ * @param url remote json file
+ */
+ @Deprecated("use {@link #GeoJsonSource(String, URI)} instead")
+ constructor(id: String?, url: URL) : super() {
+ initialize(id, null)
+ nativeSetUrl(url.toExternalForm())
+ }
+
+ /**
+ * Create a GeoJsonSource from a remote geo json file and non-default GeoJsonOptions
+ *
+ * @param id the source id
+ * @param url remote json file
+ * @param options options
+ */
+ @Deprecated("use {@link #GeoJsonSource(String, URI, GeoJsonOptions)} instead")
+ constructor(id: String?, url: URL, options: GeoJsonOptions?) : super() {
+ initialize(id, options)
+ nativeSetUrl(url.toExternalForm())
+ }
+
+ /**
+ * Create a GeoJsonSource from a geo json URI
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri unique resource identifier
+ */
+ constructor(id: String?, uri: URI) : super() {
+ initialize(id, null)
+ nativeSetUrl(uri.toString())
+ }
+
+ /**
+ * Create a GeoJsonSource from a geo json URI and non-default GeoJsonOptions
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri remote json file
+ * @param options options
+ */
+ constructor(id: String?, uri: URI, options: GeoJsonOptions?) : super() {
+ initialize(id, options)
+ nativeSetUrl(uri.toString())
+ }
+
+ /**
+ * Create a GeoJsonSource from a FeatureCollection.
+ *
+ * @param id the source id
+ * @param features the features
+ */
+ constructor(id: String?, features: FeatureCollection?) : super() {
+ initialize(id, null)
+ setGeoJson(features)
+ }
+
+ /**
+ * Create a GeoJsonSource from a FeatureCollection and non-default GeoJsonOptions.
+ *
+ * @param id the source id
+ * @param features the features
+ * @param options options
+ */
+ constructor(id: String?, features: FeatureCollection?, options: GeoJsonOptions?) : super() {
+ initialize(id, options)
+ setGeoJson(features)
+ }
+
+ /**
+ * Create a GeoJsonSource from a [Feature]
+ *
+ * @param id the source id
+ * @param feature the feature
+ */
+ constructor(id: String?, feature: Feature?) : super() {
+ initialize(id, null)
+ setGeoJson(feature)
+ }
+
+ /**
+ * Create a GeoJsonSource from a [Feature] and non-default [GeoJsonOptions]
+ *
+ * @param id the source id
+ * @param feature the feature
+ * @param options options
+ */
+ constructor(id: String?, feature: Feature?, options: GeoJsonOptions?) : super() {
+ initialize(id, options)
+ setGeoJson(feature)
+ }
+
+ /**
+ * Create a GeoJsonSource from a [Geometry]
+ *
+ * @param id the source id
+ * @param geometry the geometry
+ */
+ constructor(id: String?, geometry: Geometry?) : super() {
+ initialize(id, null)
+ setGeoJson(geometry)
+ }
+
+ /**
+ * Create a GeoJsonSource from a [Geometry] and non-default [GeoJsonOptions]
+ *
+ * @param id the source id
+ * @param geometry the geometry
+ * @param options options
+ */
+ constructor(id: String?, geometry: Geometry?, options: GeoJsonOptions?) : super() {
+ initialize(id, options)
+ setGeoJson(geometry)
+ }
+
+ /**
+ * Updates the GeoJson with a single feature. The update is performed asynchronously,
+ * so the data won't be immediately visible or available to query when this method returns.
+ *
+ * @param feature the GeoJSON [Feature] to set
+ */
+ fun setGeoJson(feature: Feature?) {
+ if (detached) {
+ return
+ }
+ checkThread()
+ nativeSetFeature(feature)
+ }
+
+ /**
+ * Updates the GeoJson with a single geometry. The update is performed asynchronously,
+ * so the data won't be immediately visible or available to query when this method returns.
+ *
+ * @param geometry the GeoJSON [Geometry] to set
+ */
+ fun setGeoJson(geometry: Geometry?) {
+ if (detached) {
+ return
+ }
+ checkThread()
+ nativeSetGeometry(geometry)
+ }
+
+ /**
+ * Updates the GeoJson. The update is performed asynchronously,
+ * so the data won't be immediately visible or available to query when this method returns.
+ *
+ * @param featureCollection the GeoJSON FeatureCollection
+ */
+ fun setGeoJson(featureCollection: FeatureCollection?) {
+ if (detached) {
+ return
+ }
+ checkThread()
+ if (featureCollection != null && featureCollection.features() != null) {
+ val features = featureCollection.features()
+ val featuresCopy: List = ArrayList(features)
+ nativeSetFeatureCollection(FeatureCollection.fromFeatures(featuresCopy))
+ } else {
+ nativeSetFeatureCollection(featureCollection)
+ }
+ }
+
+ /**
+ * Updates the GeoJson. The update is performed asynchronously,
+ * so the data won't be immediately visible or available to query when this method returns.
+ *
+ * @param json the raw GeoJson FeatureCollection string
+ */
+ fun setGeoJson(json: String) {
+ if (detached) {
+ return
+ }
+ checkThread()
+ nativeSetGeoJsonString(json)
+ }
+
+ /**
+ * Updates the url
+ *
+ * @param url the GeoJSON FeatureCollection url
+ */
+ @Deprecated("use {@link #setUri(URI)} instead")
+ fun setUrl(url: URL) {
+ checkThread()
+ this.url = url.toExternalForm()
+ }
+
+ /**
+ * Updates the URI of the source.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param uri the GeoJSON FeatureCollection uri
+ */
+ fun setUri(uri: URI) {
+ setUri(uri.toString())
+ }
+
+ /**
+ * Updates the URI of the source.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param uri the GeoJSON FeatureCollection uri
+ */
+ fun setUri(uri: String?) {
+ checkThread()
+ nativeSetUrl(uri)
+ }
+
+ private fun setUrlInternal(url: String?) {
+ checkThread()
+ nativeSetUrl(url)
+ }
+
+ private fun getUrlInternal(): String? {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ var url: String?
+
+ /**
+ * @return The url or null
+ */
+ @get:Deprecated("use {@link #getUri()} instead")
+ get() {
+ return getUrlInternal()
+ }
+
+ /**
+ * Updates the url
+ *
+ * @param url the GeoJSON FeatureCollection url
+ */
+ @Deprecated("use {@link #setUri(String)} instead")
+ set(value) {
+ setUrlInternal(value)
+ }
+
+ /**
+ * Get the URI of the source.
+ *
+ * @return The uri or null
+ */
+ val uri: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ /**
+ * Queries the source for features.
+ *
+ * @param filter an optional filter expression to filter the returned Features
+ * @return the features
+ */
+ fun querySourceFeatures(filter: Expression?): List {
+ checkThread()
+ val features = querySourceFeatures(filter?.toArray())
+ return if (features != null) Arrays.asList(*features) else ArrayList()
+ }
+
+ /**
+ * Returns the children of a cluster (on the next zoom level) given its id (cluster_id value from feature properties).
+ *
+ *
+ * Requires configuring this source as a cluster by calling [GeoJsonOptions.withCluster].
+ *
+ *
+ * @param cluster cluster from which to retrieve children from
+ * @return a list of features for the underlying children
+ */
+ fun getClusterChildren(cluster: Feature): FeatureCollection {
+ checkThread()
+ return FeatureCollection.fromFeatures(nativeGetClusterChildren(cluster)!!)
+ }
+
+ /**
+ * Returns all the leaves of a cluster (given its cluster_id), with pagination support: limit is the number of leaves
+ * to return (set to Infinity for all points), and offset is the amount of points to skip (for pagination).
+ *
+ *
+ * Requires configuring this source as a cluster by calling [GeoJsonOptions.withCluster].
+ *
+ *
+ * @param cluster cluster from which to retrieve leaves from
+ * @param limit limit is the number of points to return
+ * @param offset offset is the amount of points to skip (for pagination)
+ * @return a list of features for the underlying leaves
+ */
+ fun getClusterLeaves(cluster: Feature, limit: Long, offset: Long): FeatureCollection {
+ checkThread()
+ return FeatureCollection.fromFeatures(nativeGetClusterLeaves(cluster, limit, offset)!!)
+ }
+
+ /**
+ * Returns the zoom on which the cluster expands into several children (useful for "click to zoom" feature)
+ * given the cluster's cluster_id (cluster_id value from feature properties).
+ *
+ *
+ * Requires configuring this source as a cluster by calling [GeoJsonOptions.withCluster].
+ *
+ *
+ * @param cluster cluster from which to retrieve the expansion zoom from
+ * @return the zoom on which the cluster expands into several children
+ */
+ fun getClusterExpansionZoom(cluster: Feature): Int {
+ checkThread()
+ return nativeGetClusterExpansionZoom(cluster)
+ }
+
+ @Keep
+ protected external fun initialize(layerId: String?, options: Any?)
+
+ @Keep
+ protected external fun nativeSetUrl(url: String?)
+
+ @Keep
+ protected external fun nativeGetUrl(): String?
+
+ @Keep
+ private external fun nativeSetGeoJsonString(geoJson: String)
+
+ @Keep
+ private external fun nativeSetFeatureCollection(geoJson: FeatureCollection?)
+
+ @Keep
+ private external fun nativeSetFeature(feature: Feature?)
+
+ @Keep
+ private external fun nativeSetGeometry(geometry: Geometry?)
+
+ @Keep
+ private external fun querySourceFeatures(filter: Array?): Array
+
+ @Keep
+ private external fun nativeGetClusterChildren(feature: Feature): Array?
+
+ @Keep
+ private external fun nativeGetClusterLeaves(feature: Feature, limit: Long, offset: Long): Array?
+
+ @Keep
+ private external fun nativeGetClusterExpansionZoom(feature: Feature): Int
+
+ @Keep
+ @Throws(Throwable::class)
+ protected external fun finalize()
+}
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
deleted file mode 100644
index 1ca67011a..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeometryTileProvider.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.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/GeometryTileProvider.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeometryTileProvider.kt
new file mode 100644
index 000000000..4ad98095f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeometryTileProvider.kt
@@ -0,0 +1,20 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.WorkerThread
+import com.mapbox.geojson.FeatureCollection
+import com.mapbox.mapboxsdk.geometry.LatLngBounds
+
+/**
+ * Interface that defines methods for working with [CustomGeometrySource].
+ */
+interface GeometryTileProvider {
+ /***
+ * Interface method called by [CustomGeometrySource] to request features for a tile.
+ *
+ * @param bounds [LatLngBounds] of the tile.
+ * @param zoomLevel Tile zoom level.
+ * @return Return a @{link FeatureCollection} to be displayed in the requested tile.
+ */
+ @WorkerThread
+ fun getFeaturesForBounds(bounds: LatLngBounds, zoomLevel: Int): FeatureCollection
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java
deleted file mode 100644
index 0fc393fae..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java
+++ /dev/null
@@ -1,273 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.Keep;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
-import com.mapbox.mapboxsdk.Mapbox;
-import com.mapbox.mapboxsdk.geometry.LatLngQuad;
-import com.mapbox.mapboxsdk.utils.BitmapUtils;
-
-import java.net.URI;
-import java.net.URL;
-
-
-/**
- * Image source, allows a georeferenced raster image to be shown on the map.
- *
- * The georeferenced image scales and rotates as the user zooms and rotates the map.
- * The geographic location of the raster image content, supplied with `LatLngQuad`,
- * can be non-axis aligned.
- *
- * * @see the style specification
- */
-@UiThread
-public class ImageSource extends Source {
-
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- @Keep
- ImageSource(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Create an ImageSource from coordinates and an image URL
- *
- * @param id The source id
- * @param coordinates The Latitude and Longitude of the four corners of the image
- * @param url remote json file
- * @deprecated use {@link ImageSource#ImageSource(String, LatLngQuad, URI)} instead
- */
- @Deprecated
- public ImageSource(String id, LatLngQuad coordinates, @NonNull URL url) {
- super();
- initialize(id, coordinates);
- setUrl(url);
- }
-
- /**
- * Create an ImageSource from coordinates and an image URI
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id The source id
- * @param coordinates The Latitude and Longitude of the four corners of the image
- * @param uri json file uri
- */
- public ImageSource(String id, LatLngQuad coordinates, @NonNull URI uri) {
- super();
- initialize(id, coordinates);
- setUri(uri);
- }
-
- /**
- * Create an ImageSource from coordinates and a bitmap image
- *
- * @param id The source id
- * @param coordinates The Latitude and Longitude of the four corners of the image
- * @param bitmap A Bitmap image
- */
- public ImageSource(String id, LatLngQuad coordinates, @NonNull Bitmap bitmap) {
- super();
- initialize(id, coordinates);
- setImage(bitmap);
- }
-
- /**
- * Create an ImageSource from coordinates and a bitmap image resource
- *
- * @param id The source id
- * @param coordinates The Latitude and Longitude of the four corners of the image
- * @param resourceId The resource ID of a Bitmap image
- */
- public ImageSource(String id, LatLngQuad coordinates, @DrawableRes int resourceId) {
- super();
- initialize(id, coordinates);
- setImage(resourceId);
- }
-
- /**
- * Updates the source image url
- *
- * @param url An Image url
- * @deprecated use {@link #setUri(URI)} instead
- */
- @Deprecated
- public void setUrl(@NonNull URL url) {
- setUrl(url.toExternalForm());
- }
-
- /**
- * Updates the source image url
- *
- * @param url An image url
- * @deprecated use {@link #setUri(String)} instead
- */
- @Deprecated
- public void setUrl(String url) {
- checkThread();
- nativeSetUrl(url);
- }
-
- /**
- * Updates the source image URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param uri An Image uri
- */
- public void setUri(@NonNull URI uri) {
- checkThread();
- nativeSetUrl(uri.toString());
- }
-
- /**
- * Updates the source image URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param uri An image uri
- */
- public void setUri(String uri) {
- checkThread();
- nativeSetUrl(uri);
- }
-
- /**
- * Updates the source image to a bitmap
- *
- * @param bitmap A Bitmap image
- */
- public void setImage(@NonNull android.graphics.Bitmap bitmap) {
- checkThread();
- nativeSetImage(bitmap);
- }
-
- /**
- * Updates the source image to a bitmap image resource
- *
- * @param resourceId The resource ID of a Bitmap image
- */
- public void setImage(@DrawableRes int resourceId) throws IllegalArgumentException {
- checkThread();
- Context context = Mapbox.getApplicationContext();
- Drawable drawable = BitmapUtils.getDrawableFromRes(context, resourceId);
- if (drawable instanceof BitmapDrawable) {
- BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
- nativeSetImage(bitmapDrawable.getBitmap());
- } else {
- throw new IllegalArgumentException("Failed to decode image. The resource provided must be a Bitmap.");
- }
- }
-
- /**
- * @return The url or null
- * @deprecated use {@link #getUri()} instead
- */
- @Deprecated
- @Nullable
- public String getUrl() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Get the source URI.
- *
- * @return The uri or null
- */
- @Nullable
- public String getUri() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Updates the latitude and longitude of the four corners of the image
- *
- * @param latLngQuad latitude and longitude of the four corners of the image
- */
- public void setCoordinates(LatLngQuad latLngQuad) {
- checkThread();
- nativeSetCoordinates(latLngQuad);
- }
-
- @Keep
- protected native void initialize(String layerId, LatLngQuad payload);
-
- @Keep
- protected native void nativeSetUrl(String url);
-
- @NonNull
- @Keep
- protected native String nativeGetUrl();
-
- @Keep
- protected native void nativeSetImage(Bitmap bitmap);
-
- @Keep
- protected native void nativeSetCoordinates(LatLngQuad latLngQuad);
-
- @Override
- @Keep
- protected native void finalize() throws Throwable;
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.kt
new file mode 100644
index 000000000..00551c51c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.kt
@@ -0,0 +1,257 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import android.graphics.Bitmap
+import android.graphics.drawable.BitmapDrawable
+import androidx.annotation.DrawableRes
+import androidx.annotation.Keep
+import androidx.annotation.UiThread
+import com.mapbox.mapboxsdk.Mapbox
+import com.mapbox.mapboxsdk.geometry.LatLngQuad
+import com.mapbox.mapboxsdk.utils.BitmapUtils
+import java.net.URI
+import java.net.URL
+/**
+ * Image source, allows a georeferenced raster image to be shown on the map.
+ *
+ *
+ * The georeferenced image scales and rotates as the user zooms and rotates the map.
+ * The geographic location of the raster image content, supplied with `LatLngQuad`,
+ * can be non-axis aligned.
+ *
+ * * @see [the style specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-image)
+ */
+@UiThread
+class ImageSource : Source {
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ @Keep
+ internal constructor(nativePtr: Long) : super(nativePtr) {
+ }
+
+ /**
+ * Create an ImageSource from coordinates and an image URL
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param url remote json file
+ */
+ @Deprecated("use {@link ImageSource#ImageSource(String, LatLngQuad, URI)} instead")
+ constructor(id: String?, coordinates: LatLngQuad?, url: URL) : super() {
+ initialize(id, coordinates)
+ setUrl(url)
+ }
+
+ /**
+ * Create an ImageSource from coordinates and an image URI
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param uri json file uri
+ */
+ constructor(id: String?, coordinates: LatLngQuad?, uri: URI) : super() {
+ initialize(id, coordinates)
+ setUri(uri)
+ }
+
+ /**
+ * Create an ImageSource from coordinates and a bitmap image
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param bitmap A Bitmap image
+ */
+ constructor(id: String?, coordinates: LatLngQuad?, bitmap: Bitmap) : super() {
+ initialize(id, coordinates)
+ setImage(bitmap)
+ }
+
+ /**
+ * Create an ImageSource from coordinates and a bitmap image resource
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param resourceId The resource ID of a Bitmap image
+ */
+ constructor(id: String?, coordinates: LatLngQuad?, @DrawableRes resourceId: Int) : super() {
+ initialize(id, coordinates)
+ setImage(resourceId)
+ }
+
+ /**
+ * Updates the source image url
+ *
+ * @param url An Image url
+ */
+ @Deprecated("use {@link #setUri(URI)} instead")
+ fun setUrl(url: URL) {
+ setUrl(url.toExternalForm())
+ }
+
+ /**
+ * Updates the source image url
+ *
+ * @param url An image url
+ */
+ @Deprecated("use {@link #setUri(String)} instead")
+ fun setUrl(url: String?) {
+ checkThread()
+ nativeSetUrl(url)
+ }
+
+ /**
+ * Updates the source image URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param uri An Image uri
+ */
+ fun setUri(uri: URI) {
+ checkThread()
+ nativeSetUrl(uri.toString())
+ }
+
+ /**
+ * Updates the source image URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param uri An image uri
+ */
+ fun setUri(uri: String?) {
+ checkThread()
+ nativeSetUrl(uri)
+ }
+
+ /**
+ * Updates the source image to a bitmap
+ *
+ * @param bitmap A Bitmap image
+ */
+ fun setImage(bitmap: Bitmap) {
+ checkThread()
+ nativeSetImage(bitmap)
+ }
+
+ /**
+ * Updates the source image to a bitmap image resource
+ *
+ * @param resourceId The resource ID of a Bitmap image
+ */
+ @Throws(IllegalArgumentException::class)
+ fun setImage(@DrawableRes resourceId: Int) {
+ checkThread()
+ val context = Mapbox.getApplicationContext()
+ val drawable = BitmapUtils.getDrawableFromRes(context, resourceId)
+ if (drawable is BitmapDrawable) {
+ nativeSetImage(drawable.bitmap)
+ } else {
+ throw IllegalArgumentException("Failed to decode image. The resource provided must be a Bitmap.")
+ }
+ }
+
+ /**
+ * @return The url or null
+ */
+ @get:Deprecated("use {@link #getUri()} instead")
+ val url: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ /**
+ * Get the source URI.
+ *
+ * @return The uri or null
+ */
+ val uri: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ /**
+ * Updates the latitude and longitude of the four corners of the image
+ *
+ * @param latLngQuad latitude and longitude of the four corners of the image
+ */
+ fun setCoordinates(latLngQuad: LatLngQuad?) {
+ checkThread()
+ nativeSetCoordinates(latLngQuad)
+ }
+
+ @Keep
+ protected external fun initialize(layerId: String?, payload: LatLngQuad?)
+
+ @Keep
+ protected external fun nativeSetUrl(url: String?)
+
+ @Keep
+ protected external fun nativeGetUrl(): String
+
+ @Keep
+ protected external fun nativeSetImage(bitmap: Bitmap?)
+
+ @Keep
+ protected external fun nativeSetCoordinates(latLngQuad: LatLngQuad?)
+
+ @Keep
+ @Throws(Throwable::class)
+ protected external fun finalize()
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/PackageInfo.kt
similarity index 61%
rename from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/package-info.java
rename to platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/PackageInfo.kt
index c7c325ee5..211fe62f1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/package-info.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/PackageInfo.kt
@@ -1,4 +1,4 @@
/**
* Contains the Mapbox Maps Android Style Sources API classes.
*/
-package com.mapbox.mapboxsdk.style.sources;
+package com.mapbox.mapboxsdk.style.sources
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
deleted file mode 100644
index 39cf4b327..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.Keep;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
-import java.net.URI;
-import java.net.URL;
-
-/**
- * A raster DEM source.
- *
- * @see The style specification
- */
-@UiThread
-public class RasterDemSource extends Source {
- public static final int DEFAULT_TILE_SIZE = 512;
-
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- @Keep
- RasterDemSource(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Create the raster dem source from an URL
- *
- * @param id the source id
- * @param url the source url
- * @deprecated use {@link #RasterDemSource(String, URI)} instead
- */
- @Deprecated
- public RasterDemSource(String id, URL url) {
- this(id, url.toExternalForm());
- }
-
- /**
- * Create the raster dem source from an URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the source uri
- */
- public RasterDemSource(String id, URI uri) {
- this(id, uri.toString());
- }
-
- /**
- * Create the raster dem source from an URI
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the source uri
- */
- public RasterDemSource(String id, String uri) {
- super();
- initialize(id, uri, DEFAULT_TILE_SIZE);
- }
-
- /**
- * Create the raster source from an URL with a specific tile size
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the source url
- * @param tileSize the tile size
- */
- public RasterDemSource(String id, String uri, int tileSize) {
- super();
- initialize(id, uri, 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) {
- super();
- 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) {
- super();
- initialize(id, tileSet.toValueObject(), tileSize);
- }
-
- /**
- * @return The url or null
- * @deprecated use {@link #getUri()} instead
- */
- @Deprecated
- @Nullable
- public String getUrl() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Get the source URI.
- *
- * @return The uri or null
- */
- @Nullable
- public String getUri() {
- checkThread();
- return nativeGetUrl();
- }
-
- @Keep
- protected native void initialize(String layerId, Object payload, int tileSize);
-
- @Override
- @Keep
- protected native void finalize() throws Throwable;
-
- @NonNull
- @Keep
- protected native String nativeGetUrl();
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.kt
new file mode 100644
index 000000000..fc50f2579
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterDemSource.kt
@@ -0,0 +1,176 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Keep
+import androidx.annotation.UiThread
+import java.net.URI
+import java.net.URL
+
+/**
+ * A raster DEM source.
+ *
+ * @see [The style specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/.sources-raster-dem)
+ */
+
+@UiThread
+class RasterDemSource : Source {
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ @Keep
+ internal constructor(nativePtr: Long) : super(nativePtr) {
+ }
+
+ /**
+ * Create the raster dem source from an URL
+ *
+ * @param id the source id
+ * @param url the source url
+ */
+ @Deprecated("use {@link #RasterDemSource(String, URI)} instead")
+ constructor(id: String?, url: URL) : this(id, url.toExternalForm()) {
+ }
+
+ /**
+ * Create the raster dem source from an URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the source uri
+ */
+ constructor(id: String?, uri: URI) : this(id, uri.toString()) {}
+
+ /**
+ * Create the raster dem source from an URI
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the source uri
+ */
+ constructor(id: String?, uri: String?) : super() {
+ initialize(id, uri, DEFAULT_TILE_SIZE)
+ }
+
+ /**
+ * Create the raster source from an URL with a specific tile size
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the source url
+ * @param tileSize the tile size
+ */
+ constructor(id: String?, uri: String?, tileSize: Int) : super() {
+ initialize(id, uri, tileSize)
+ }
+
+ /**
+ * Create the raster dem source from a [TileSet]
+ *
+ * @param id the source id
+ * @param tileSet the [TileSet]
+ */
+ constructor(id: String?, tileSet: TileSet) : super() {
+ initialize(id, tileSet.toValueObject(), DEFAULT_TILE_SIZE)
+ }
+
+ /**
+ * Create the raster source from a [TileSet] with a specific tile size
+ *
+ * @param id the source id
+ * @param tileSet the [TileSet]
+ * @param tileSize tje tile size
+ */
+ constructor(id: String?, tileSet: TileSet, tileSize: Int) : super() {
+ initialize(id, tileSet.toValueObject(), tileSize)
+ }
+
+ /**
+ * @return The url or null
+ */
+ @get:Deprecated("use {@link #getUri()} instead")
+ val url: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ /**
+ * Get the source URI.
+ *
+ * @return The uri or null
+ */
+ val uri: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ @Keep
+ protected external fun initialize(layerId: String?, payload: Any?, tileSize: Int)
+
+ @Keep
+ @Throws(Throwable::class)
+ protected external fun finalize()
+
+ @Keep
+ private external fun nativeGetUrl(): String
+
+ companion object {
+ const val DEFAULT_TILE_SIZE = 512
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java
deleted file mode 100644
index 9eb9f575c..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.Keep;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.net.URI;
-import java.net.URL;
-
-/**
- * Raster source, allows using raster tiles as source.
- *
- * @see The style specification
- */
-public class RasterSource extends Source {
- public static final int DEFAULT_TILE_SIZE = 512;
-
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- @Keep
- RasterSource(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Create the raster source from an URL
- *
- * @param id the source id
- * @param url the source url
- * @deprecated use {@link #RasterSource(String, URI)} instead
- */
- public RasterSource(String id, URL url) {
- this(id, url.toExternalForm());
- }
-
- /**
- * Create the raster source from an URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the source uri
- */
- public RasterSource(String id, URI uri) {
- this(id, uri.toString());
- }
-
- /**
- * Create the raster source from an URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the source uri
- */
- public RasterSource(String id, String uri) {
- super();
- initialize(id, uri, DEFAULT_TILE_SIZE);
- }
-
- /**
- * Create the raster source from an URI with a specific tile size.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the source uri
- * @param tileSize the tile size
- */
- public RasterSource(String id, String uri, int tileSize) {
- super();
- initialize(id, uri, tileSize);
- }
-
- /**
- * Create the raster source from a {@link TileSet}
- *
- * @param id the source id
- * @param tileSet the {@link TileSet}
- */
- public RasterSource(String id, TileSet tileSet) {
- super();
- 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 RasterSource(String id, TileSet tileSet, int tileSize) {
- super();
- initialize(id, tileSet.toValueObject(), tileSize);
- }
-
- /**
- * @return The url or null
- * @deprecated use {@link #getUri()} instead
- */
- @Nullable
- @Deprecated
- public String getUrl() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Get the source URI.
- *
- * @return The uri or null
- */
- @Nullable
- public String getUri() {
- checkThread();
- return nativeGetUrl();
- }
-
- @Keep
- protected native void initialize(String layerId, Object payload, int tileSize);
-
- @Override
- @Keep
- protected native void finalize() throws Throwable;
-
- @NonNull
- @Keep
- protected native String nativeGetUrl();
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.kt
new file mode 100644
index 000000000..a6a821574
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.kt
@@ -0,0 +1,173 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Keep
+import java.net.URI
+import java.net.URL
+
+/**
+ * Raster source, allows using raster tiles as source.
+ *
+ * @see [The style specification](https://www.mapbox.com/mapbox-gl-style-spec/.sources-raster)
+ */
+class RasterSource : Source {
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ @Keep
+ internal constructor(nativePtr: Long) : super(nativePtr) {
+ }
+
+ /**
+ * Create the raster source from an URL
+ *
+ * @param id the source id
+ * @param url the source url
+ */
+ @Deprecated("use {@link #RasterSource(String, URI)} instead")
+ constructor(id: String?, url: URL) : this(id, url.toExternalForm()) {
+ }
+
+ /**
+ * Create the raster source from an URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the source uri
+ */
+ constructor(id: String?, uri: URI) : this(id, uri.toString()) {}
+
+ /**
+ * Create the raster source from an URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the source uri
+ */
+ constructor(id: String?, uri: String?) : super() {
+ initialize(id, uri, DEFAULT_TILE_SIZE)
+ }
+
+ /**
+ * Create the raster source from an URI with a specific tile size.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the source uri
+ * @param tileSize the tile size
+ */
+ constructor(id: String?, uri: String?, tileSize: Int) : super() {
+ initialize(id, uri, tileSize)
+ }
+
+ /**
+ * Create the raster source from a [TileSet]
+ *
+ * @param id the source id
+ * @param tileSet the [TileSet]
+ */
+ constructor(id: String?, tileSet: TileSet) : super() {
+ initialize(id, tileSet.toValueObject(), DEFAULT_TILE_SIZE)
+ }
+
+ /**
+ * Create the raster source from a [TileSet] with a specific tile size
+ *
+ * @param id the source id
+ * @param tileSet the [TileSet]
+ * @param tileSize tje tile size
+ */
+ constructor(id: String?, tileSet: TileSet, tileSize: Int) : super() {
+ initialize(id, tileSet.toValueObject(), tileSize)
+ }
+
+ /**
+ * @return The url or null
+ */
+ @get:Deprecated("use {@link #getUri()} instead")
+ val url: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ /**
+ * Get the source URI.
+ *
+ * @return The uri or null
+ */
+ val uri: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ @Keep
+ protected external fun initialize(layerId: String?, payload: Any?, tileSize: Int)
+
+ @Keep
+ @Throws(Throwable::class)
+ protected external fun finalize()
+
+ @Keep
+ protected external fun nativeGetUrl(): String
+
+ companion object {
+ const val DEFAULT_TILE_SIZE = 512
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java
index a0ef6b985..42dd4f288 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java
@@ -174,13 +174,11 @@ public abstract class Source {
@Keep
protected native Integer nativeGetPrefetchZoomDelta();
- @NonNull
@Keep
- protected native void nativeSetPrefetchZoomDelta(Integer delta);
+ protected native void nativeSetPrefetchZoomDelta(@Nullable Integer delta);
- @NonNull
@Keep
- protected native void nativeSetMaxOverscaleFactorForParentTiles(Integer maxOverscaleFactor);
+ protected native void nativeSetMaxOverscaleFactorForParentTiles(@Nullable Integer maxOverscaleFactor);
@NonNull
@Keep
@@ -190,13 +188,11 @@ public abstract class Source {
@Keep
protected native Boolean nativeIsVolatile();
- @NonNull
@Keep
- protected native void nativeSetVolatile(Boolean value);
+ protected native void nativeSetVolatile(@NonNull Boolean value);
- @NonNull
@Keep
- protected native void nativeSetMinimumTileUpdateInterval(Long interval);
+ protected native void nativeSetMinimumTileUpdateInterval(@NonNull Long interval);
@NonNull
@Keep
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java
deleted file mode 100644
index 5e8db3839..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java
+++ /dev/null
@@ -1,341 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Size;
-
-import com.mapbox.mapboxsdk.geometry.LatLng;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tile set, allows using TileJson specification as source.
- * Note that `encoding` is only relevant to `raster-dem` sources, and is not supported in the TileJson spec.
- *
- * @see The tileset specification
- */
-public class TileSet {
- private final String tilejson;
- private String name;
- private String description;
- private String version;
- private String attribution;
- private String template;
- private String legend;
- private String scheme;
- private final String[] tiles;
- private String[] grids;
- private String[] data;
- private Float minZoom;
- private Float maxZoom;
- private Float[] bounds;
- private Float[] center;
- private String encoding;
-
- /**
- * @param tilejson A semver.org style version number. Describes the version of the TileJSON spec that is implemented
- * by this JSON object.
- * @param tiles An array of tile endpoints. {z}, {x} and {y}, if present, are replaced with the corresponding
- * integers.
- * If multiple endpoints are specified, clients may use any combination of endpoints. All endpoints
- * MUST return the same
- * content for the same URL. The array MUST contain at least one endpoint.
- * Example: "http:localhost:8888/admin/1.0.0/world-light,broadband/{z}/{x}/{y}.png"
- */
- public TileSet(String tilejson, String... tiles) {
- this.tilejson = tilejson;
- this.tiles = tiles;
- }
-
- public String getTilejson() {
- return tilejson;
- }
-
- public String getName() {
- return name;
- }
-
- /**
- * A name describing the tileset. The name can
- * contain any legal character. Implementations SHOULD NOT interpret the
- * name as HTML.
- * "name": "compositing",
- *
- * @param name the name to be set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- /**
- * A text description of the tileset. The
- * description can contain any legal character.
- * Implementations SHOULD NOT
- * interpret the description as HTML.
- * "description": "A simple, light grey world."
- *
- * @param description the description to set
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
- public String getAttribution() {
- return attribution;
- }
-
- /**
- * Default: null. Contains an attribution to be displayed
- * when the map is shown to a user. Implementations MAY decide to treat this
- * as HTML or literal text. For security reasons, make absolutely sure that
- * this field can't be abused as a vector for XSS or beacon tracking.
- * "attribution": "OSM contributors",
- *
- * @param attribution the attribution to set
- */
- public void setAttribution(String attribution) {
- this.attribution = attribution;
- }
-
- public String getTemplate() {
- return template;
- }
-
- /**
- * Contains a mustache template to be used to
- * format data from grids for interaction.
- * See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
- * for the interactivity specification.
- * "template": "{{#__teaser__}}{{NAME}}{{/__teaser__}}"
- *
- * @param template the template to set
- */
- public void setTemplate(String template) {
- this.template = template;
- }
-
- public String getLegend() {
- return legend;
- }
-
- /**
- * Contains a legend to be displayed with the map.
- * Implementations MAY decide to treat this as HTML or literal text.
- * For security reasons, make absolutely sure that this field can't be
- * abused as a vector for XSS or beacon tracking.
- * "legend": "Dangerous zones are red, safe zones are green"
- *
- * @param legend the legend to set
- */
- public void setLegend(String legend) {
- this.legend = legend;
- }
-
- public String getScheme() {
- return scheme;
- }
-
- /**
- * Default: "xyz". Either "xyz" or "tms". Influences the y
- * direction of the tile coordinates.
- * The global-mercator (aka Spherical Mercator) profile is assumed.
- * "scheme": "xyz"
- *
- * @param scheme the scheme to set
- */
- public void setScheme(String scheme) {
- this.scheme = scheme;
- }
-
- public String[] getTiles() {
- return tiles;
- }
-
- public String[] getGrids() {
- return grids;
- }
-
- /**
- * An array of interactivity endpoints. {z}, {x}
- * and {y}, if present, are replaced with the corresponding integers. If multiple
- * endpoints are specified, clients may use any combination of endpoints.
- * All endpoints MUST return the same content for the same URL.
- * If the array doesn't contain any entries, interactivity is not supported
- * for this tileset. See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
- * for the interactivity specification.
- *
- * Example: "http:localhost:8888/admin/1.0.0/broadband/{z}/{x}/{y}.grid.json"
- *
- *
- * @param grids the grids to set
- */
- public void setGrids(String... grids) {
- this.grids = grids;
- }
-
- public String[] getData() {
- return data;
- }
-
- /**
- * An array of data files in GeoJSON format.
- * {z}, {x} and {y}, if present,
- * are replaced with the corresponding integers. If multiple
- * endpoints are specified, clients may use any combination of endpoints.
- * All endpoints MUST return the same content for the same URL.
- * If the array doesn't contain any entries, then no data is present in
- * the map.
- *
- * "http:localhost:8888/admin/data.geojson"
- *
- *
- * @param data the data array to set
- */
- public void setData(String... data) {
- this.data = data;
- }
-
- public float getMinZoom() {
- return minZoom;
- }
-
- /**
- * 0. >= 0, < 22. An integer specifying the minimum zoom level.
- *
- * @param minZoom the minZoom level to set
- */
- public void setMinZoom(float minZoom) {
- this.minZoom = minZoom;
- }
-
- public float getMaxZoom() {
- return maxZoom;
- }
-
- /**
- * 0. >= 0, <= 22. An integer specifying the maximum zoom level.
- *
- * @param maxZoom the maxZoom level to set
- */
- public void setMaxZoom(float maxZoom) {
- this.maxZoom = maxZoom;
- }
-
- public Float[] getBounds() {
- return bounds;
- }
-
- /**
- * Default: [-180, -90, 180, 90]. The maximum extent of available map tiles. Bounds MUST define an area
- * covered by all zoom levels. The bounds are represented in WGS:84
- * latitude and longitude values, in the order left, bottom, right, top.
- * Values may be integers or floating point numbers.
- *
- * @param bounds the Float array to set
- */
- public void setBounds(@Size(value = 4) Float... bounds) {
- this.bounds = bounds;
- }
-
- public String getEncoding() {
- return encoding;
- }
-
- /**
- * Default: "mapbox". The encoding formula for a raster-dem tileset.
- * Supported values are "mapbox" and "terrarium".
- *
- * @param encoding the String encoding formula to set
- */
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
-
- public Float[] getCenter() {
- return center;
- }
-
- /**
- * The first value is the longitude, the second is latitude (both in
- * WGS:84 values), the third value is the zoom level as an integer.
- * Longitude and latitude MUST be within the specified bounds.
- * The zoom level MUST be between minzoom and maxzoom.
- * Implementations can use this value to set the default location. If the
- * value is null, implementations may use their own algorithm for
- * determining a default location.
- *
- * @param center the Float array to set
- */
- public void setCenter(@Size(value = 2) Float... center) {
- this.center = center;
- }
-
- public void setCenter(@NonNull LatLng center) {
- this.center = new Float[] {(float) center.getLongitude(), (float) center.getLatitude()};
- }
-
- @NonNull
- Map toValueObject() {
- Map result = new HashMap<>();
- result.put("tilejson", tilejson);
- result.put("tiles", tiles);
-
- if (name != null) {
- result.put("name", name);
- }
- if (description != null) {
- result.put("description", description);
- }
- if (version != null) {
- result.put("version", version);
- }
- if (attribution != null) {
- result.put("attribution", attribution);
- }
- if (template != null) {
- result.put("template", template);
- }
- if (legend != null) {
- result.put("legend", legend);
- }
- if (scheme != null) {
- result.put("scheme", scheme);
- }
- if (grids != null) {
- result.put("grids", grids);
- }
- if (data != null) {
- result.put("data", data);
- }
- if (minZoom != null) {
- result.put("minzoom", minZoom);
- }
- if (maxZoom != null) {
- result.put("maxzoom", maxZoom);
- }
- if (bounds != null) {
- result.put("bounds", bounds);
- }
- if (center != null) {
- result.put("center", center);
- }
- if (encoding != null) {
- result.put("encoding", encoding);
- }
-
-
- return result;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.kt
new file mode 100644
index 000000000..1221a1585
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.kt
@@ -0,0 +1,259 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Size
+import com.mapbox.mapboxsdk.geometry.LatLng
+/**
+ * Tile set, allows using TileJson specification as source.
+ * Note that `encoding` is only relevant to `raster-dem` sources, and is not supported in the TileJson spec.
+ *
+ * @see [The tileset specification](https://github.com/mapbox/tilejson-spec/tree/master/2.1.0)
+ */
+class TileSet(val tilejson: String, vararg tiles: String) {
+
+ /**
+ * A name describing the tileset. The name can
+ * contain any legal character. Implementations SHOULD NOT interpret the
+ * name as HTML.
+ * "name": "compositing",
+ *
+ * @param name the name to be set
+ */
+ var name: String? = null
+
+ /**
+ * A text description of the tileset. The
+ * description can contain any legal character.
+ * Implementations SHOULD NOT
+ * interpret the description as HTML.
+ * "description": "A simple, light grey world."
+ *
+ * @param description the description to set
+ */
+ var description: String? = null
+ var version: String? = null
+
+ /**
+ * Default: null. Contains an attribution to be displayed
+ * when the map is shown to a user. Implementations MAY decide to treat this
+ * as HTML or literal text. For security reasons, make absolutely sure that
+ * this field can't be abused as a vector for XSS or beacon tracking.
+ * "attribution": "[OSM contributors](http:openstreetmap.org)",
+ *
+ * @param attribution the attribution to set
+ */
+ var attribution: String? = null
+
+ /**
+ * Contains a mustache template to be used to
+ * format data from grids for interaction.
+ * See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
+ * for the interactivity specification.
+ * "template": "{{#__teaser__}}{{NAME}}{{/__teaser__}}"
+ *
+ * @param template the template to set
+ */
+ var template: String? = null
+
+ /**
+ * Contains a legend to be displayed with the map.
+ * Implementations MAY decide to treat this as HTML or literal text.
+ * For security reasons, make absolutely sure that this field can't be
+ * abused as a vector for XSS or beacon tracking.
+ * "legend": "Dangerous zones are red, safe zones are green"
+ *
+ * @param legend the legend to set
+ */
+ var legend: String? = null
+
+ /**
+ * Default: "xyz". Either "xyz" or "tms". Influences the y
+ * direction of the tile coordinates.
+ * The global-mercator (aka Spherical Mercator) profile is assumed.
+ * "scheme": "xyz"
+ *
+ * @param scheme the scheme to set
+ */
+ var scheme: String? = null
+ val tiles: Array
+ var grids: Array? = null
+ private set
+ var data: Array? = null
+ private set
+
+ @JvmField
+ var minZoom: Float? = null
+
+ @JvmField
+ var maxZoom: Float? = null
+
+ var bounds: FloatArray? = null
+ private set
+ var center: FloatArray? = null
+ private set
+
+ /**
+ * Default: "mapbox". The encoding formula for a raster-dem tileset.
+ * Supported values are "mapbox" and "terrarium".
+ *
+ * @param encoding the String encoding formula to set
+ */
+ var encoding: String? = null
+
+ /**
+ * @param tilejson A semver.org style version number. Describes the version of the TileJSON spec that is implemented
+ * by this JSON object.
+ * @param tiles An array of tile endpoints. {z}, {x} and {y}, if present, are replaced with the corresponding
+ * integers.
+ * If multiple endpoints are specified, clients may use any combination of endpoints. All endpoints
+ * MUST return the same
+ * content for the same URL. The array MUST contain at least one endpoint.
+ * Example: "http:localhost:8888/admin/1.0.0/world-light,broadband/{z}/{x}/{y}.png"
+ */
+ init {
+ this.tiles = arrayOf(*tiles)
+ }
+
+ /**
+ * An array of interactivity endpoints. {z}, {x}
+ * and {y}, if present, are replaced with the corresponding integers. If multiple
+ * endpoints are specified, clients may use any combination of endpoints.
+ * All endpoints MUST return the same content for the same URL.
+ * If the array doesn't contain any entries, interactivity is not supported
+ * for this tileset. See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
+ * for the interactivity specification.
+ *
+ *
+ * Example: "http:localhost:8888/admin/1.0.0/broadband/{z}/{x}/{y}.grid.json"
+ *
+ *
+ * @param grids the grids to set
+ */
+ fun setGrids(vararg grids: String) {
+ this.grids = arrayOf(*grids)
+ }
+
+ /**
+ * An array of data files in GeoJSON format.
+ * {z}, {x} and {y}, if present,
+ * are replaced with the corresponding integers. If multiple
+ * endpoints are specified, clients may use any combination of endpoints.
+ * All endpoints MUST return the same content for the same URL.
+ * If the array doesn't contain any entries, then no data is present in
+ * the map.
+ *
+ *
+ * "http:localhost:8888/admin/data.geojson"
+ *
+ *
+ * @param data the data array to set
+ */
+ fun setData(vararg data: String) {
+ this.data = arrayOf(*data)
+ }
+
+ fun getMinZoom(): Float {
+ return minZoom!!
+ }
+
+ /**
+ * 0. >= 0, < 22. An integer specifying the minimum zoom level.
+ *
+ * @param minZoom the minZoom level to set
+ */
+ fun setMinZoom(minZoom: Float) {
+ this.minZoom = minZoom
+ }
+
+ fun getMaxZoom(): Float {
+ return maxZoom!!
+ }
+
+ /**
+ * 0. >= 0, <= 22. An integer specifying the maximum zoom level.
+ *
+ * @param maxZoom the maxZoom level to set
+ */
+ fun setMaxZoom(maxZoom: Float) {
+ this.maxZoom = maxZoom
+ }
+
+ /**
+ * Default: [-180, -90, 180, 90]. The maximum extent of available map tiles. Bounds MUST define an area
+ * covered by all zoom levels. The bounds are represented in WGS:84
+ * latitude and longitude values, in the order left, bottom, right, top.
+ * Values may be integers or floating point numbers.
+ *
+ * @param bounds the Float array to set
+ */
+ fun setBounds(@Size(value = 4) vararg bounds: Float) {
+ this.bounds = bounds
+ }
+
+ /**
+ * The first value is the longitude, the second is latitude (both in
+ * WGS:84 values), the third value is the zoom level as an integer.
+ * Longitude and latitude MUST be within the specified bounds.
+ * The zoom level MUST be between minzoom and maxzoom.
+ * Implementations can use this value to set the default location. If the
+ * value is null, implementations may use their own algorithm for
+ * determining a default location.
+ *
+ * @param center the Float array to set
+ */
+ fun setCenter(@Size(value = 2) vararg center: Float) {
+ this.center = center
+ }
+
+ fun setCenter(center: LatLng) {
+ this.center = floatArrayOf(center.longitude.toFloat(), center.latitude.toFloat())
+ }
+
+ fun toValueObject(): Map {
+ val result: MutableMap = HashMap()
+ result["tilejson"] = tilejson
+ result["tiles"] = tiles
+ if (name != null) {
+ result["name"] = name!!
+ }
+ if (description != null) {
+ result["description"] = description!!
+ }
+ if (version != null) {
+ result["version"] = version!!
+ }
+ if (attribution != null) {
+ result["attribution"] = attribution!!
+ }
+ if (template != null) {
+ result["template"] = template!!
+ }
+ if (legend != null) {
+ result["legend"] = legend!!
+ }
+ if (scheme != null) {
+ result["scheme"] = scheme!!
+ }
+ if (grids != null) {
+ result["grids"] = grids!!
+ }
+ if (data != null) {
+ result["data"] = data!!
+ }
+ if (minZoom != null) {
+ result["minzoom"] = minZoom!!
+ }
+ if (maxZoom != null) {
+ result["maxzoom"] = maxZoom!!
+ }
+ if (bounds != null) {
+ result["bounds"] = bounds!!
+ }
+ if (center != null) {
+ result["center"] = center!!
+ }
+ if (encoding != null) {
+ result["encoding"] = encoding!!
+ }
+ return result
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.java
deleted file mode 100644
index 1fc3878f9..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import androidx.annotation.Keep;
-import androidx.annotation.UiThread;
-
-/**
- * An unknown type of source
- */
-@UiThread
-@Keep
-public class UnknownSource extends Source {
-
- /**
- * Creates a UnknownSource.
- *
- * @param nativePtr pointer used by core
- */
- UnknownSource(long nativePtr) {
- super(nativePtr);
- }
-
- protected native void initialize();
-
- @Override
- protected native void finalize() throws Throwable;
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.kt
new file mode 100644
index 000000000..3b3b5206e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.kt
@@ -0,0 +1,21 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import androidx.annotation.Keep
+import androidx.annotation.UiThread
+/**
+ * An unknown type of source
+ */
+@UiThread
+@Keep
+class UnknownSource
+/**
+ * Creates a UnknownSource.
+ *
+ * @param nativePtr pointer used by core
+ */
+internal constructor(nativePtr: Long) : Source(nativePtr) {
+ protected external fun initialize()
+
+ @Throws(Throwable::class)
+ protected external fun finalize()
+}
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
deleted file mode 100644
index 6c48715c0..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.mapbox.mapboxsdk.style.sources;
-
-import android.net.Uri;
-
-import androidx.annotation.Keep;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.Size;
-import androidx.annotation.UiThread;
-
-import com.mapbox.geojson.Feature;
-import com.mapbox.mapboxsdk.style.expressions.Expression;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Vector source, allows the use of vector tiles.
- *
- * @see the style specification
- */
-@UiThread
-public class VectorSource extends Source {
-
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- @Keep
- VectorSource(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Create a vector source from a remote url pointing to a TileJSON resource
- *
- * @param id the source id
- * @param url the TileJSON resource url
- * @deprecated use {@link #VectorSource(String, Uri)} instead
- */
- @Deprecated
- public VectorSource(String id, URL url) {
- this(id, url.toExternalForm());
- }
-
- /**
- * Create a vector source from an URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the TileJSON resource uri
- */
- public VectorSource(String id, Uri uri) {
- this(id, uri.toString());
- }
-
- /**
- * Create a vector source from an URI.
- *
- * An URI is a combination of a protocol and a resource path.
- * The following URI protocol schemes are supported:
- *
- *
- * - http://
- *
- * - load resources using HyperText Transfer Protocol
- *
- * - file://
- *
- * - load resources from the Android file system
- *
- * - asset://
- *
- * - load resources from the binary packaged assets folder
- *
- *
- *
- * @param id the source id
- * @param uri the uri
- */
- public VectorSource(String id, String uri) {
- super();
- initialize(id, uri);
- }
-
- /**
- * Create a vector source from a tileset
- *
- * @param id the source id
- * @param tileSet the tileset
- */
- public VectorSource(String id, TileSet tileSet) {
- super();
- initialize(id, tileSet.toValueObject());
- }
-
- /**
- * Queries the source for features.
- *
- * @param sourceLayerIds the source layer identifiers. At least one must be specified.
- * @param filter an optional filter expression to filter the returned Features
- * @return the features
- */
- @NonNull
- public List querySourceFeatures(@Size(min = 1) String[] sourceLayerIds,
- @Nullable Expression filter) {
- checkThread();
- Feature[] features = querySourceFeatures(
- sourceLayerIds,
- filter != null ? filter.toArray() : null);
- return features != null ? Arrays.asList(features) : new ArrayList();
- }
-
- /**
- * @return The url or null
- * @deprecated use {@link #getUri()} instead
- */
- @Nullable
- @Deprecated
- public String getUrl() {
- checkThread();
- return nativeGetUrl();
- }
-
- /**
- * Get the source URI.
- *
- * @return The uri or null
- */
- @Nullable
- public String getUri() {
- checkThread();
- return nativeGetUrl();
- }
-
- @Keep
- protected native void initialize(String layerId, Object payload);
-
- @Override
- @Keep
- protected native void finalize() throws Throwable;
-
- @NonNull
- @Keep
- protected native String nativeGetUrl();
-
- @NonNull
- @Keep
- private native Feature[] querySourceFeatures(String[] sourceLayerId,
- Object[] filter);
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.kt
new file mode 100644
index 000000000..8f9155eef
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.kt
@@ -0,0 +1,151 @@
+package com.mapbox.mapboxsdk.style.sources
+
+import android.net.Uri
+import androidx.annotation.Keep
+import androidx.annotation.Size
+import androidx.annotation.UiThread
+import com.mapbox.geojson.Feature
+import com.mapbox.mapboxsdk.style.expressions.Expression
+import java.net.URL
+import java.util.*
+import kotlin.collections.ArrayList
+
+/**
+ * Vector source, allows the use of vector tiles.
+ *
+ * @see [the style specification](https://www.mapbox.com/mapbox-gl-style-spec/.sources-vector)
+ */
+@UiThread
+class VectorSource : Source {
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ @Keep
+ internal constructor(nativePtr: Long) : super(nativePtr) {
+ }
+
+ /**
+ * Create a vector source from a remote url pointing to a TileJSON resource
+ *
+ * @param id the source id
+ * @param url the TileJSON resource url
+ */
+ @Deprecated("use {@link #VectorSource(String, Uri)} instead")
+ constructor(id: String?, url: URL) : this(id, url.toExternalForm()) {
+ }
+
+ /**
+ * Create a vector source from an URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the TileJSON resource uri
+ */
+ constructor(id: String?, uri: Uri) : this(id, uri.toString()) {}
+
+ /**
+ * Create a vector source from an URI.
+ *
+ *
+ * An URI is a combination of a protocol and a resource path.
+ * The following URI protocol schemes are supported:
+ *
+ *
+ * * http://
+ *
+ * * load resources using HyperText Transfer Protocol
+ *
+ * * file://
+ *
+ * * load resources from the Android file system
+ *
+ * * asset://
+ *
+ * * load resources from the binary packaged assets folder
+ *
+ *
+ *
+ * @param id the source id
+ * @param uri the uri
+ */
+ constructor(id: String?, uri: String?) : super() {
+ initialize(id, uri)
+ }
+
+ /**
+ * Create a vector source from a tileset
+ *
+ * @param id the source id
+ * @param tileSet the tileset
+ */
+ constructor(id: String?, tileSet: TileSet) : super() {
+ initialize(id, tileSet.toValueObject())
+ }
+
+ /**
+ * Queries the source for features.
+ *
+ * @param sourceLayerIds the source layer identifiers. At least one must be specified.
+ * @param filter an optional filter expression to filter the returned Features
+ * @return the features
+ */
+ fun querySourceFeatures(@Size(min = 1) sourceLayerIds: Array, filter: Expression?): List {
+ checkThread()
+ val features = querySourceFeatures(sourceLayerIds, filter?.toArray())
+ return if (features != null) Arrays.asList(*features) else ArrayList()
+ }
+
+ /**
+ * @return The url or null
+ */
+ @get:Deprecated("use {@link #getUri()} instead")
+ val url: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ /**
+ * Get the source URI.
+ *
+ * @return The uri or null
+ */
+ val uri: String?
+ get() {
+ checkThread()
+ return nativeGetUrl()
+ }
+
+ @Keep
+ protected external fun initialize(layerId: String?, payload: Any?)
+
+ @Keep
+ @Throws(Throwable::class)
+ protected external fun finalize()
+
+ @Keep
+ protected external fun nativeGetUrl(): String?
+
+ @Keep
+ private external fun querySourceFeatures(sourceLayerId: Array, filter: Array?): Array
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java
deleted file mode 100644
index a8a5739e5..000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.mapbox.mapboxsdk.style.types;
-
-import androidx.annotation.Keep;
-import androidx.annotation.Nullable;
-
-import java.util.Arrays;
-
-/**
- * Represents a string broken into sections annotated with separate formatting options.
- *
- * @see Style specification
- */
-@Keep
-public class Formatted {
- private final FormattedSection[] formattedSections;
-
- /**
- * Create a new formatted text.
- *
- * @param formattedSections sections with formatting options
- */
- public Formatted(FormattedSection... formattedSections) {
- this.formattedSections = formattedSections;
- }
-
- /**
- * Returns sections with separate formatting options that are a part of this formatted text.
- *
- * @return formatted sections
- */
- public FormattedSection[] getFormattedSections() {
- return formattedSections;
- }
-
- public Object[] toArray() {
- Object[] sections = new Object[formattedSections.length];
- for (int i = 0; i < formattedSections.length; i++) {
- sections[i] = formattedSections[i].toArray();
- }
- return sections;
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- Formatted formatted = (Formatted) o;
-
- return Arrays.equals(formattedSections, formatted.formattedSections);
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(formattedSections);
- }
-
- @Override
- public String toString() {
- return "Formatted{"
- + "formattedSections="
- + Arrays.toString(formattedSections)
- + '}';
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.kt b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.kt
new file mode 100644
index 000000000..5263a1b88
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/Formatted.kt
@@ -0,0 +1,55 @@
+package com.mapbox.mapboxsdk.style.types
+
+import androidx.annotation.Keep
+import java.util.*
+
+/**
+ * Represents a string broken into sections annotated with separate formatting options.
+ *
+ * @see [Style specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/.types-formatted)
+ */
+@Keep
+class Formatted(vararg formattedSections: FormattedSection) {
+ /**
+ * Returns sections with separate formatting options that are a part of this formatted text.
+ *
+ * @return formatted sections
+ */
+ val formattedSections: Array
+
+ /**
+ * Create a new formatted text.
+ *
+ * @param formattedSections sections with formatting options
+ */
+ init {
+ this.formattedSections = formattedSections
+ }
+
+ fun toArray(): Array {
+ val sections = arrayOfNulls(formattedSections.size)
+ for (i in formattedSections.indices) {
+ sections[i] = formattedSections[i].toArray()
+ }
+ return sections
+ }
+
+ override fun equals(o: Any?): Boolean {
+ if (this === o) {
+ return true
+ }
+ if (o == null || javaClass != o.javaClass) {
+ return false
+ }
+ val formatted = o as Formatted
+ return Arrays.equals(formattedSections, formatted.formattedSections)
+ }
+
+ override fun hashCode(): Int {
+ return Arrays.hashCode(formattedSections)
+ }
+
+ override fun toString(): String {
+ return ("Formatted{" + "formattedSections=" + Arrays.toString(formattedSections) + '}')
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/PackageInfo.kt
similarity index 67%
rename from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/package-info.java
rename to platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/PackageInfo.kt
index 084ba9019..74f3ebea5 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/package-info.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/types/PackageInfo.kt
@@ -1,4 +1,4 @@
/**
* Contains the Mapbox Maps Android Formatted Expression Types API classes.
*/
-package com.mapbox.mapboxsdk.style.types;
\ No newline at end of file
+package com.mapbox.mapboxsdk.style.types
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.kt
index 6fe1ead9d..ae66dfade 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.kt
@@ -531,7 +531,7 @@ class DataDrivenStyleActivity : AppCompatActivity() {
// Add a fill layer
mapboxMap.style!!
.addLayer(
- FillLayer(AMSTERDAM_PARKS_LAYER, source.getId())
+ FillLayer(AMSTERDAM_PARKS_LAYER, source.id)
.withProperties(
PropertyFactory.fillColor(Expression.color(Color.GREEN)),
PropertyFactory.fillOutlineColor(Expression.rgb(0, 0, 255)),
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GridSourceActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GridSourceActivity.kt
index bd333bb0a..e4a753cc5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GridSourceActivity.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GridSourceActivity.kt
@@ -33,26 +33,25 @@ class GridSourceActivity : AppCompatActivity(), OnMapReadyCallback {
* grid.
*/
internal class GridProvider : GeometryTileProvider {
- override fun getFeaturesForBounds(bounds: LatLngBounds, zoom: Int): FeatureCollection {
+ override fun getFeaturesForBounds(bounds: LatLngBounds, zoomLevel: Int): FeatureCollection {
val features: MutableList = ArrayList()
- val gridSpacing: Double
- gridSpacing = if (zoom >= 13) {
+ val gridSpacing = if (zoomLevel >= 13) {
0.01
- } else if (zoom >= 11) {
+ } else if (zoomLevel >= 11) {
0.05
- } else if (zoom == 10) {
+ } else if (zoomLevel == 10) {
.1
- } else if (zoom == 9) {
+ } else if (zoomLevel == 9) {
0.25
- } else if (zoom == 8) {
+ } else if (zoomLevel == 8) {
0.5
- } else if (zoom >= 6) {
+ } else if (zoomLevel >= 6) {
1.0
- } else if (zoom == 5) {
+ } else if (zoomLevel == 5) {
2.0
- } else if (zoom >= 4) {
+ } else if (zoomLevel >= 4) {
5.0
- } else if (zoom == 2) {
+ } else if (zoomLevel == 2) {
10.0
} else {
20.0
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.kt
index fd6ceb572..42eacb53e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.kt
@@ -93,11 +93,8 @@ class RealTimeGeoJsonActivity : AppCompatActivity(), OnMapReadyCallback {
private val handler: Handler
) : Runnable {
override fun run() {
- (
- mapboxMap.style!!
- .getSource(ID_GEOJSON_SOURCE) as GeoJsonSource?
- )!!.url =
- URL_GEOJSON_SOURCE
+ val geoJsonSource = mapboxMap.style!!.getSource(ID_GEOJSON_SOURCE) as GeoJsonSource
+ geoJsonSource.url = URL_GEOJSON_SOURCE
handler.postDelayed(this, 2000)
}
}