[android] Sources: peer model, mutability (#6054)

This commit is contained in:
Ivo van Dongen
2016-09-21 11:04:32 +02:00
committed by GitHub
parent 3b546b9646
commit eb97dbe383
24 changed files with 886 additions and 87 deletions

View File

@@ -152,6 +152,31 @@ public class MapboxMap {
getMapView().getNativeMapView().removeLayer(layerId);
}
@Nullable
@UiThread
public Source getSource(@NonNull String sourceId) {
return getMapView().getNativeMapView().getSource(sourceId);
}
/**
* Tries to cast the Source to T, returns null if it's another type.
*
* @param sourceId the id used to look up a layer
* @param <T> the generic type of a Source
* @return the casted Source, null if another type
*/
@Nullable
@UiThread
public <T extends Source> T getSourceAs(@NonNull String sourceId) {
try {
//noinspection unchecked
return (T) getMapView().getNativeMapView().getSource(sourceId);
} catch (ClassCastException e) {
Log.e(TAG, String.format("Source: %s is a different type: %s", sourceId, e.getMessage()));
return null;
}
}
@UiThread
public void addSource(@NonNull Source source) {
getMapView().getNativeMapView().addSource(source);

View File

@@ -494,8 +494,12 @@ final class NativeMapView {
nativeRemoveLayer(nativeMapViewPtr, layerId);
}
public Source getSource(@NonNull String sourceId) {
return nativeGetSource(nativeMapViewPtr, sourceId);
}
public void addSource(@NonNull Source source) {
nativeAddSource(nativeMapViewPtr, source.getId(), source);
nativeAddSource(nativeMapViewPtr, source.getNativePtr());
}
public void removeSource(@NonNull String sourceId) throws NoSuchSourceException {
@@ -712,7 +716,9 @@ final class NativeMapView {
private native void nativeRemoveLayer(long nativeMapViewPtr, String layerId) throws NoSuchLayerException;
private native void nativeAddSource(long nativeMapViewPtr, String id, Source source);
private native Source nativeGetSource(long nativeMapViewPtr, String sourceId);
private native void nativeAddSource(long nativeMapViewPtr, long nativeSourcePtr);
private native void nativeRemoveSource(long nativeMapViewPtr, String sourceId) throws NoSuchSourceException;

View File

@@ -0,0 +1,63 @@
package com.mapbox.mapboxsdk.style.sources;
import java.util.HashMap;
/**
* Options for the <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">GeoJsonSource</a>
*/
public class GeoJsonOptions extends HashMap<String, Object> {
/**
* Defaults to 18.
* Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels).
*/
public GeoJsonOptions withMaxZoom(int maxZoom) {
this.put("maxzoom", maxZoom);
return this;
}
/**
* Defaults to 128.
* Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile edges but slower performance).
*/
public GeoJsonOptions withBuffer(int buffer) {
this.put("buffer", buffer);
return this;
}
/**
* Defaults to 0.375.
* Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
*/
public GeoJsonOptions withTolerance(float tolerance) {
this.put("tolerance", tolerance);
return this;
}
/**
* Defaults to false.
* If the data is a collection of point features, setting this to true clusters the points by radius into groups.
*/
public GeoJsonOptions withCluster(boolean cluster) {
this.put("cluster", cluster);
return this;
}
/**
* Defaults to 50.
* Radius of each cluster when clustering points, measured in 1/512ths of a tile.
*/
public GeoJsonOptions withClusterMaxZoom(int clusterMaxZoom) {
this.put("clusterMaxZoom", clusterMaxZoom);
return this;
}
/**
* Max zoom to cluster points on. Defaults to one zoom less than maxzoom (so that last zoom features are not clustered).
*/
public GeoJsonOptions withClusterRadius(int clusterRadius) {
this.put("clusterRadius", clusterRadius);
return this;
}
}

View File

@@ -1,9 +1,10 @@
package com.mapbox.mapboxsdk.style.sources;
import com.google.gson.Gson;
import com.mapbox.services.commons.geojson.Feature;
import com.mapbox.services.commons.geojson.FeatureCollection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
/**
@@ -12,8 +13,34 @@ import java.util.HashMap;
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">the style specification</a>
*/
public class GeoJsonSource extends Source {
public static final String TYPE = "geojson";
private static final String DATA_KEY = "data";
/**
* Internal use
*/
public GeoJsonSource(long nativePtr) {
super(nativePtr);
}
/**
* Create an empty GeoJsonSource
*
* @param id the source id
*/
public GeoJsonSource(String id) {
initialize(id, null);
setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
}
/**
* Create an empty GeoJsonSource
*
* @param id the source id
* @param options options
*/
public GeoJsonSource(String id, GeoJsonOptions options) {
initialize(id, options);
setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
}
/**
* Create a GeoJsonSource from a raw json string
@@ -22,11 +49,26 @@ public class GeoJsonSource extends Source {
* @param geoJson raw Json body
*/
public GeoJsonSource(String id, String geoJson) {
super(id, TYPE);
if (geoJson == null || geoJson.startsWith("http")) {
throw new IllegalArgumentException("Expected a raw json body");
}
setRawJson(geoJson);
initialize(id, null);
setGeoJson(geoJson);
}
/**
* Create a GeoJsonSource from a raw json string
*
* @param id the source id
* @param geoJson raw Json body
* @param options options
*/
public GeoJsonSource(String id, String geoJson, GeoJsonOptions options) {
if (geoJson == null || geoJson.startsWith("http")) {
throw new IllegalArgumentException("Expected a raw json body");
}
initialize(id, options);
setGeoJson(geoJson);
}
/**
@@ -36,8 +78,20 @@ public class GeoJsonSource extends Source {
* @param url remote json file
*/
public GeoJsonSource(String id, URL url) {
super(id, TYPE);
this.put(DATA_KEY, url.toExternalForm());
initialize(id, null);
nativeSetUrl(url.toExternalForm());
}
/**
* Create a GeoJsonSource from a remote geo json file
*
* @param id the source id
* @param url remote json file
* @param options options
*/
public GeoJsonSource(String id, URL url, GeoJsonOptions options) {
initialize(id, options);
nativeSetUrl(url.toExternalForm());
}
/**
@@ -47,30 +101,57 @@ public class GeoJsonSource extends Source {
* @param features the features
*/
public GeoJsonSource(String id, FeatureCollection features) {
super(id, TYPE);
setRawJson(features.toJson());
initialize(id, null);
setGeoJson(features);
}
public GeoJsonSource withCluster(boolean cluster) {
this.put("cluster", cluster);
return this;
/**
* Create a GeoJsonSource from a FeatureCollection
*
* @param id the source id
* @param features the features
* @param options options
*/
public GeoJsonSource(String id, FeatureCollection features, GeoJsonOptions options) {
initialize(id, options);
setGeoJson(features);
}
public GeoJsonSource withClusterMaxZoom(float zoom) {
this.put("clusterMaxZoom", zoom);
return this;
public void setGeoJson(FeatureCollection features) {
checkValidity();
setGeoJson(features.toJson());
}
public GeoJsonSource withClusterRadius(float radius) {
this.put("clusterRadius", radius);
return this;
public void setGeoJson(String json) {
checkValidity();
setRawJson(json);
}
private void setRawJson(String geoJson) {
public void setUrl(URL url) {
checkValidity();
setUrl(url.toExternalForm());
}
public void setUrl(String url) {
checkValidity();
nativeSetUrl(url);
}
protected void setRawJson(String geoJson) {
//Wrap the String in a map as an Object is expected by the
//style conversion template
HashMap<String, String> wrapper = new HashMap<>();
wrapper.put(DATA_KEY, geoJson);
this.put(DATA_KEY, wrapper);
wrapper.put("data", geoJson);
nativeSetGeoJson(wrapper);
}
protected native void initialize(String layerId, Object options);
protected native void nativeSetUrl(String url);
private native void nativeSetGeoJson(Object geoJson);
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -8,26 +8,37 @@ import java.net.URL;
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-raster">The style specificition</a>
*/
public class RasterSource extends Source {
public static final String TYPE = "raster";
private static final String URL_KEY = "url";
private static final String TILE_SIZE_KEY = "tileSize";
public static final int DEFAULT_TILE_SIZE = 512;
/**
* Internal use
*/
public RasterSource(long nativePtr) {
super(nativePtr);
}
public RasterSource(String id, URL url) {
this(id, url.toExternalForm());
}
public RasterSource(String id, String url) {
super(id, TYPE);
this.put(URL_KEY, url);
initialize(id, url, DEFAULT_TILE_SIZE);
}
public RasterSource(String id, String url, int tileSize) {
initialize(id, url, tileSize);
}
public RasterSource(String id, TileSet tileSet) {
super(id, TYPE);
this.putAll(tileSet.toValueObject());
initialize(id, tileSet.toValueObject(), DEFAULT_TILE_SIZE);
}
public RasterSource withTileSize(int tileSize) {
this.put(TILE_SIZE_KEY, (float) tileSize);
return this;
public RasterSource(String id, TileSet tileSet, int tileSize) {
initialize(id, tileSet.toValueObject(), tileSize);
}
protected native void initialize(String layerId, Object payload, int tileSize);
@Override
protected native void finalize() throws Throwable;
}

View File

@@ -2,15 +2,38 @@ package com.mapbox.mapboxsdk.style.sources;
import java.util.HashMap;
public abstract class Source extends HashMap<String, Object> {
private final String id;
/**
* Base Peer class for sources. see source.hpp for the other half of the peer.
*/
public abstract class Source {
private long nativePtr;
private boolean invalidated;
protected Source(String id, String type) {
this.put("type", type);
this.id = id;
public Source(long nativePtr) {
this.nativePtr = nativePtr;
}
public Source() {
}
public String getId() {
return id;
checkValidity();
return nativeGetId();
}
public long getNativePtr() {
return nativePtr;
}
protected native String nativeGetId();
protected void checkValidity() {
if (invalidated) {
throw new RuntimeException("Layer has been invalidated. Request a new reference after adding");
}
}
public final void invalidate() {
this.invalidated = true;
}
}

View File

@@ -8,8 +8,13 @@ import java.net.URL;
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-vector">the style specification</a>
*/
public class VectorSource extends Source {
public static final String TYPE = "vector";
private static final String URL_KEY = "url";
/**
* Internal use
*/
public VectorSource(long nativePtr) {
super(nativePtr);
}
/**
* Create a vector source from a remote url
@@ -28,8 +33,7 @@ public class VectorSource extends Source {
* @param url the url
*/
public VectorSource(String id, String url) {
super(id, TYPE);
this.put(URL_KEY, url);
initialize(id, url);
}
/**
@@ -39,7 +43,11 @@ public class VectorSource extends Source {
* @param tileSet the tileset
*/
public VectorSource(String id, TileSet tileSet) {
super(id, TYPE);
this.putAll(tileSet.toValueObject());
initialize(id, tileSet.toValueObject());
}
protected native void initialize(String layerId, Object payload);
@Override
protected native void finalize() throws Throwable;
}