summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java')
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java230
1 files changed, 144 insertions, 86 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
index 2e1d255a44..dfc478eed0 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
@@ -1,10 +1,15 @@
package com.mapbox.mapboxsdk.testapp.activity.style;
import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.PointF;
import android.os.Bundle;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
+import android.widget.Toast;
+import com.mapbox.geojson.Feature;
+import com.mapbox.geojson.FeatureCollection;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -16,11 +21,13 @@ import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
import timber.log.Timber;
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
import static com.mapbox.mapboxsdk.style.expressions.Expression.all;
import static com.mapbox.mapboxsdk.style.expressions.Expression.division;
@@ -54,6 +61,9 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
private MapView mapView;
private MapboxMap mapboxMap;
+ private GeoJsonSource clusterSource;
+ private int clickOptionCounter;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -68,19 +78,119 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
mapboxMap = map;
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.7749, 122.4194), 0));
- mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
- @Override
- public void onStyleLoaded(Style style) {
- style.addImage(
- "icon-id",
- BitmapUtils.getBitmapFromDrawable(getResources().getDrawable(R.drawable.ic_hearing_black_24dp)),
- true
- );
- // Add a clustered source with some layers
- addClusteredGeoJsonSource(style);
+ final int[][] clusterLayers = new int[][] {
+ new int[] {150, ResourcesCompat.getColor(getResources(), R.color.redAccent, getTheme())},
+ new int[] {20, ResourcesCompat.getColor(getResources(), R.color.greenAccent, getTheme())},
+ new int[] {0, ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme())}
+ };
+
+ try {
+ mapboxMap.setStyle(new Style.Builder()
+ .fromUrl(Style.LIGHT)
+ .withSource(clusterSource = createClusterSource())
+ .withLayer(createSymbolLayer())
+ .withLayer(createClusterLevelLayer(0, clusterLayers))
+ .withLayer(createClusterLevelLayer(1, clusterLayers))
+ .withLayer(createClusterLevelLayer(2, clusterLayers))
+ .withLayer(createClusterTextLayer())
+ .withImage("icon-id", Objects.requireNonNull(
+ BitmapUtils.getBitmapFromDrawable(getResources().getDrawable(R.drawable.ic_hearing_black_24dp))), true
+ )
+ );
+ } catch (IOException exception) {
+ Timber.e(exception);
+ }
+
+ mapboxMap.addOnMapClickListener(latLng -> {
+ PointF point = mapboxMap.getProjection().toScreenLocation(latLng);
+ List<Feature> features = mapboxMap.queryRenderedFeatures(point, "cluster-0", "cluster-1", "cluster-2");
+ if (!features.isEmpty()) {
+ onClusterClick(features.get(0), new Point((int) point.x, (int) point.y));
}
+ return true;
});
});
+
+ findViewById(R.id.fab).setOnClickListener(v -> {
+ updateClickOptionCounter();
+ notifyClickOptionUpdate();
+ });
+ }
+
+ private void onClusterClick(Feature cluster, Point clickPoint) {
+ if (clickOptionCounter == 0) {
+ double nextZoomLevel = clusterSource.getClusterExpansionZoom(cluster);
+ double zoomDelta = nextZoomLevel - mapboxMap.getCameraPosition().zoom;
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomBy(zoomDelta, clickPoint));
+ Toast.makeText(this, "Zooming to " + nextZoomLevel, Toast.LENGTH_SHORT).show();
+ } else if (clickOptionCounter == 1) {
+ FeatureCollection collection = clusterSource.getClusterChildren(cluster);
+ Toast.makeText(this, "Children: " + collection.toJson(), Toast.LENGTH_SHORT).show();
+ } else {
+ FeatureCollection collection = clusterSource.getClusterLeaves(cluster, 2, 1);
+ Toast.makeText(this, "Leaves: " + collection.toJson(), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private GeoJsonSource createClusterSource() throws IOException {
+ String earthQuakes = GeoParseUtil.loadStringFromAssets(this, "earthquakes.geojson");
+ FeatureCollection featureCollection = FeatureCollection.fromJson(earthQuakes);
+ return new GeoJsonSource("earthquakes", featureCollection, new GeoJsonOptions()
+ .withCluster(true)
+ .withClusterMaxZoom(14)
+ .withClusterRadius(50)
+ );
+ }
+
+ private SymbolLayer createSymbolLayer() {
+ return new SymbolLayer("unclustered-points", "earthquakes")
+ .withProperties(
+ iconImage("icon-id"),
+ iconSize(
+ division(
+ get("mag"), literal(4.0f)
+ )
+ ),
+ iconColor(
+ interpolate(exponential(1), get("mag"),
+ stop(2.0, rgb(0, 255, 0)),
+ stop(4.5, rgb(0, 0, 255)),
+ stop(7.0, rgb(255, 0, 0))
+ )
+ )
+ )
+ .withFilter(has("mag"));
+ }
+
+ private CircleLayer createClusterLevelLayer(int level, int[][] layerColors) {
+ CircleLayer circles = new CircleLayer("cluster-" + level, "earthquakes");
+ circles.setProperties(
+ circleColor(layerColors[level][1]),
+ circleRadius(18f)
+ );
+
+ Expression pointCount = toNumber(get("point_count"));
+ circles.setFilter(
+ level == 0
+ ? all(has("point_count"),
+ gte(pointCount, literal(layerColors[level][0]))
+ ) : all(has("point_count"),
+ gt(pointCount, literal(layerColors[level][0])),
+ lt(pointCount, literal(layerColors[level - 1][0]))
+ )
+ );
+ return circles;
+ }
+
+ private SymbolLayer createClusterTextLayer() {
+ return new SymbolLayer("count", "earthquakes")
+ .withProperties(
+ textField(Expression.toString(get("point_count"))),
+ textSize(12f),
+ textColor(Color.WHITE),
+ textIgnorePlacement(true),
+ textAllowOverlap(true)
+ );
}
@Override
@@ -136,82 +246,30 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
}
}
- private void addClusteredGeoJsonSource(Style style) {
- // Add a clustered source
- try {
- style.addSource(
- new GeoJsonSource("earthquakes",
- new URL("https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"),
- new GeoJsonOptions()
- .withCluster(true)
- .withClusterMaxZoom(14)
- .withClusterRadius(50)
- )
- );
- } catch (MalformedURLException malformedUrlException) {
- Timber.e(malformedUrlException, "That's not an url... ");
+ private void updateClickOptionCounter() {
+ if (clickOptionCounter == 2) {
+ clickOptionCounter = 0;
+ } else {
+ clickOptionCounter++;
}
+ }
- // Add unclustered layer
- int[][] layers = new int[][] {
- new int[] {150, ResourcesCompat.getColor(getResources(), R.color.redAccent, getTheme())},
- new int[] {20, ResourcesCompat.getColor(getResources(), R.color.greenAccent, getTheme())},
- new int[] {0, ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme())}
- };
-
- SymbolLayer unclustered = new SymbolLayer("unclustered-points", "earthquakes");
- unclustered.setProperties(
- iconImage("icon-id"),
- iconSize(
- division(
- get("mag"), literal(4.0f)
- )
- ),
- iconColor(
- interpolate(exponential(1), get("mag"),
- stop(2.0, rgb(0, 255, 0)),
- stop(4.5, rgb(0, 0, 255)),
- stop(7.0, rgb(255, 0, 0))
- )
- )
- );
- unclustered.setFilter(has("mag"));
- style.addLayer(unclustered);
-
- for (int i = 0; i < layers.length; i++) {
- // Add some nice circles
- CircleLayer circles = new CircleLayer("cluster-" + i, "earthquakes");
- circles.setProperties(
- circleColor(layers[i][1]),
- circleRadius(18f)
- );
-
- Expression pointCount = toNumber(get("point_count"));
- circles.setFilter(
- i == 0
- ? all(has("point_count"),
- gte(pointCount, literal(layers[i][0]))
- ) : all(has("point_count"),
- gt(pointCount, literal(layers[i][0])),
- lt(pointCount, literal(layers[i - 1][0]))
- )
- );
- style.addLayer(circles);
+ private void notifyClickOptionUpdate() {
+ if (clickOptionCounter == 0) {
+ Toast.makeText(
+ GeoJsonClusteringActivity.this,
+ "Clicking a cluster will zoom to the level where it dissolves",
+ Toast.LENGTH_SHORT).show();
+ } else if (clickOptionCounter == 1) {
+ Toast.makeText(
+ GeoJsonClusteringActivity.this,
+ "Clicking a cluster will show the details of the cluster children",
+ Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(
+ GeoJsonClusteringActivity.this,
+ "Clicking a cluster will show the details of the cluster leaves with an offset and limit",
+ Toast.LENGTH_SHORT).show();
}
-
- // Add the count labels
- SymbolLayer count = new SymbolLayer("count", "earthquakes");
- count.setProperties(
- textField(Expression.toString(get("point_count"))),
- textSize(12f),
- textColor(Color.WHITE),
- textIgnorePlacement(true),
- textAllowOverlap(true)
- );
- style.addLayer(count);
-
-
- // Zoom out to start
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1));
}
}