More namespaces updated to Kotlin (#692)

This commit is contained in:
Artak Kalantarian
2023-01-14 06:35:51 -08:00
committed by GitHub
parent 39df4fc2f6
commit f561031010
33 changed files with 2181 additions and 2438 deletions

View File

@@ -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();
}
}
}

View File

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

View File

@@ -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)

View File

@@ -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.
* <p>
* 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<TileID, GeometryTileRequest> 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<TileID, AtomicBoolean> 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<Feature> querySourceFeatures(@Nullable Expression filter) {
checkThread();
Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
}
@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.
* <p>
* {@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<Runnable>(),
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<TileID, GeometryTileRequest> awaiting;
private final Map<TileID, AtomicBoolean> inProgress;
@NonNull
private final WeakReference<CustomGeometrySource> sourceRef;
private final AtomicBoolean cancelled;
GeometryTileRequest(TileID _id, GeometryTileProvider p,
Map<TileID, GeometryTileRequest> awaiting,
Map<TileID, AtomicBoolean> 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);
}
}
}

View File

@@ -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<TileID, GeometryTileRequest> = 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<TileID, AtomicBoolean?> = 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<Feature> {
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<Any>?): Array<Feature>
@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<TileID, GeometryTileRequest>?,
private val inProgress: MutableMap<TileID, AtomicBoolean?>?,
_source: CustomGeometrySource?,
_cancelled: AtomicBoolean?
) : Runnable {
private val sourceRef: WeakReference<CustomGeometrySource?>
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()
}
}

View File

@@ -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<String, Object> {
/**
* 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;
}
}

View File

@@ -0,0 +1,74 @@
package com.mapbox.mapboxsdk.style.sources
/**
* Builder class for composing CustomGeometrySource objects.
*/
class CustomGeometrySourceOptions : HashMap<String?, Any?>() {
/**
* 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
}
}

View File

@@ -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 <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">The online documentation</a>
*/
public class GeoJsonOptions extends HashMap<String, Object> {
/**
* 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<String, Object[]> properties = containsKey("clusterProperties")
? (HashMap<String, Object[]>) get("clusterProperties") : new HashMap<String, Object[]>();
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;
}
}

View File

@@ -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<String?, Any?>() {
/**
* 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<String, Array<Any>>? 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
}
}

View File

@@ -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 <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">the style specification</a>
*/
@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<Feature>()));
}
/**
* 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<Feature>()));
}
/**
* 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
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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<Feature> features = featureCollection.features();
List<Feature> 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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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<Feature> querySourceFeatures(@Nullable Expression filter) {
checkThread();
Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
}
/**
* Returns the children of a cluster (on the next zoom level) given its id (cluster_id value from feature properties).
* <p>
* Requires configuring this source as a cluster by calling {@link GeoJsonOptions#withCluster(boolean)}.
* </p>
*
* @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).
* <p>
* Requires configuring this source as a cluster by calling {@link GeoJsonOptions#withCluster(boolean)}.
* </p>
*
* @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).
* <p>
* Requires configuring this source as a cluster by calling {@link GeoJsonOptions#withCluster(boolean)}.
* </p>
*
* @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;
}

View File

@@ -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<Feature> = 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<Feature> {
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<Any>?): Array<Feature>
@Keep
private external fun nativeGetClusterChildren(feature: Feature): Array<Feature?>?
@Keep
private external fun nativeGetClusterLeaves(feature: Feature, limit: Long, offset: Long): Array<Feature?>?
@Keep
private external fun nativeGetClusterExpansionZoom(feature: Feature): Int
@Keep
@Throws(Throwable::class)
protected external fun finalize()
}

View File

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

View File

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

View File

@@ -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.
* <p>
* 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.
* </p>
* * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-image">the style specification</a>
*/
@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
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @param uri An Image uri
*/
public void setUri(@NonNull URI uri) {
checkThread();
nativeSetUrl(uri.toString());
}
/**
* Updates the source image URI.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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;
}

View File

@@ -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()
}

View File

@@ -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

View File

@@ -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 <a href="https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources-raster-dem">The style specification</a>
*/
@UiThread
public class RasterDemSource extends Source {
public static final int DEFAULT_TILE_SIZE = 512;
/**
* Internal use
*
* @param nativePtr - pointer to native peer
*/
@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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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();
}

View File

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

View File

@@ -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 <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-raster">The style specification</a>
*/
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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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();
}

View File

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

View File

@@ -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

View File

@@ -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 <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">The tileset specification</a>
*/
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": "<a href='http:openstreetmap.org'>OSM contributors</a>",
*
* @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.
* <p>
* Example: "http:localhost:8888/admin/1.0.0/broadband/{z}/{x}/{y}.grid.json"
* </p>
*
* @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.
* <p>
* "http:localhost:8888/admin/data.geojson"
* </p>
*
* @param data the data array to set
*/
public void setData(String... data) {
this.data = data;
}
public float getMinZoom() {
return minZoom;
}
/**
* 0. &gt;= 0, &lt; 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. &gt;= 0, &lt;= 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<String, Object> toValueObject() {
Map<String, Object> 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;
}
}

View File

@@ -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<String>
var grids: Array<String>? = null
private set
var data: Array<String>? = 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. &gt;= 0, &lt; 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. &gt;= 0, &lt;= 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<String, Any> {
val result: MutableMap<String, Any> = 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
}
}

View File

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

View File

@@ -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()
}

View File

@@ -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 <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-vector">the style specification</a>
*/
@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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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.
* <p>
* An URI is a combination of a protocol and a resource path.
* The following URI protocol schemes are supported:
* </p>
* <ul>
* <li>http://</li>
* <ul>
* <li>load resources using HyperText Transfer Protocol</li>
* </ul>
* <li>file://</li>
* <ul>
* <li>load resources from the Android file system</li>
* </ul>
* <li>asset://</li>
* <ul>
* <li>load resources from the binary packaged assets folder</li>
* </ul>
* </ul>
*
* @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<Feature> 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<Feature>();
}
/**
* @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);
}

View File

@@ -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<String>, filter: Expression?): List<Feature> {
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<String>, filter: Array<Any>?): Array<Feature>
}

View File

@@ -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 <a href="https://maplibre.org/maplibre-gl-js-docs/style-spec/#types-formatted">Style specification</a>
*/
@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)
+ '}';
}
}

View File

@@ -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<out FormattedSection>
/**
* Create a new formatted text.
*
* @param formattedSections sections with formatting options
*/
init {
this.formattedSections = formattedSections
}
fun toArray(): Array<Any?> {
val sections = arrayOfNulls<Any>(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) + '}')
}
}

View File

@@ -1,4 +1,4 @@
/**
* Contains the Mapbox Maps Android Formatted Expression Types API classes.
*/
package com.mapbox.mapboxsdk.style.types;
package com.mapbox.mapboxsdk.style.types

View File

@@ -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)),

View File

@@ -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<Feature> = 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

View File

@@ -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)
}
}