Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[android] Runtime Styling API: mutable GeoJsonSource #6054

Merged
merged 1 commit into from
Sep 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,31 @@ public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,12 @@ public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
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 {
Expand Down Expand Up @@ -712,7 +716,9 @@ private native void nativeSetVisibleCoordinateBounds(long nativeMapViewPtr, LatL

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;

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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;

/**
Expand All @@ -12,8 +13,34 @@
* @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
Expand All @@ -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);
}

/**
Expand All @@ -36,8 +78,20 @@ public GeoJsonSource(String id, String geoJson) {
* @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());
}

/**
Expand All @@ -47,30 +101,57 @@ public GeoJsonSource(String id, URL url) {
* @param features the features
*/
public GeoJsonSource(String id, FeatureCollection features) {
super(id, TYPE);
setRawJson(features.toJson());
initialize(id, null);
setGeoJson(features);
}

/**
* 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 void setGeoJson(FeatureCollection features) {
checkValidity();
setGeoJson(features.toJson());
}

public GeoJsonSource withCluster(boolean cluster) {
this.put("cluster", cluster);
return this;
public void setGeoJson(String json) {
checkValidity();
setRawJson(json);
}

public GeoJsonSource withClusterMaxZoom(float zoom) {
this.put("clusterMaxZoom", zoom);
return this;
public void setUrl(URL url) {
checkValidity();
setUrl(url.toExternalForm());
}

public GeoJsonSource withClusterRadius(float radius) {
this.put("clusterRadius", radius);
return this;
public void setUrl(String url) {
checkValidity();
nativeSetUrl(url);
}

private void setRawJson(String geoJson) {
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;

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,37 @@
* @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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,38 @@

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