summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortobrun <tobrun.van.nuland@gmail.com>2018-08-23 15:41:58 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2018-10-18 10:46:55 +0300
commita1eb283c35bfeb1747030874c6666a29d1af0473 (patch)
treed949053de2859a30837eb42d7b089e03a154c61b
parent39e4de06eccd1ac9fd25ec621a1cb41e42644e03 (diff)
downloadqtlocation-mapboxgl-a1eb283c35bfeb1747030874c6666a29d1af0473.tar.gz
[android] - integrate supercluster api 0.3.0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java30
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java63
-rw-r--r--platform/android/src/style/sources/geojson_source.cpp25
-rw-r--r--platform/android/src/style/sources/geojson_source.hpp7
4 files changed, 111 insertions, 14 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
index a9eb43f968..1d54545b92 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
@@ -270,7 +270,26 @@ public class GeoJsonSource extends Source {
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>();
+ return features != null ? Arrays.asList(features) : new ArrayList<>();
+ }
+
+ @NonNull
+ public List<Feature> getChildren(long clusterId) {
+ checkThread();
+ Feature[] features = nativeGetChildren(clusterId);
+ return features != null ? Arrays.asList(features) : new ArrayList<>();
+ }
+
+ @NonNull
+ public List<Feature> getLeaves(long clusterId, long limit, long offset) {
+ checkThread();
+ Feature[] features = nativeGetLeaves(clusterId, limit, offset);
+ return features != null ? Arrays.asList(features) : new ArrayList<>();
+ }
+
+ public double getClusterExpansionZoom(long clusterId) {
+ checkThread();
+ return nativeGetClusterExpansionZoom(clusterId);
}
@Keep
@@ -299,6 +318,15 @@ public class GeoJsonSource extends Source {
@Keep
private native Feature[] querySourceFeatures(Object[] filter);
+ @Keep
+ private native Feature[] nativeGetChildren(long clusterId);
+
+ @Keep
+ private native Feature[] nativeGetLeaves(long clusterId, long limit, long offset);
+
+ @Keep
+ private native double nativeGetClusterExpansionZoom(long clusterId);
+
@Override
@Keep
protected native void finalize() throws Throwable;
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 a14a2b9589..d857d0a798 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,12 @@
package com.mapbox.mapboxsdk.testapp.activity.style;
import android.graphics.Color;
+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 com.mapbox.geojson.Feature;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -20,9 +22,9 @@ import timber.log.Timber;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.List;
import static com.mapbox.mapboxsdk.style.expressions.Expression.all;
-import static com.mapbox.mapboxsdk.style.expressions.Expression.division;
import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential;
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.gt;
@@ -36,9 +38,10 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.stop;
import static com.mapbox.mapboxsdk.style.expressions.Expression.toNumber;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
@@ -52,6 +55,7 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
private MapView mapView;
private MapboxMap mapboxMap;
+ private GeoJsonSource source;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -59,10 +63,8 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
setContentView(R.layout.activity_geojson_clustering);
// Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- // noinspection ConstantConditions
+ mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
-
mapView.getMapAsync(map -> {
mapboxMap = map;
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.7749, 122.4194), 0));
@@ -132,7 +134,7 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
private void addClusteredGeoJsonSource() {
// Add a clustered source
try {
- mapboxMap.addSource(
+ mapboxMap.addSource(source =
new GeoJsonSource("earthquakes",
new URL("https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"),
new GeoJsonOptions()
@@ -155,11 +157,8 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
SymbolLayer unclustered = new SymbolLayer("unclustered-points", "earthquakes");
unclustered.setProperties(
iconImage("icon-id"),
- iconSize(
- division(
- get("mag"), literal(4.0f)
- )
- ),
+ iconAllowOverlap(true),
+ iconIgnorePlacement(true),
iconColor(
interpolate(exponential(1), get("mag"),
stop(2.0, rgb(0, 255, 0)),
@@ -171,9 +170,13 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
mapboxMap.addLayer(unclustered);
+
+ String[] layerIds = new String[layers.length];
+
for (int i = 0; i < layers.length; i++) {
// Add some nice circles
- CircleLayer circles = new CircleLayer("cluster-" + i, "earthquakes");
+ layerIds[i] = "cluster-" + i;
+ CircleLayer circles = new CircleLayer(layerIds[i], "earthquakes");
circles.setProperties(
circleColor(layers[i][1]),
circleRadius(18f)
@@ -204,7 +207,43 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
mapboxMap.addLayer(count);
+ mapboxMap.addOnMapClickListener(latLng -> {
+ PointF point = mapboxMap.getProjection().toScreenLocation(latLng);
+ List<Feature> features = mapboxMap.queryRenderedFeatures(point, layerIds);
+ if (!features.isEmpty()) {
+ moveCameraToClusterExpansion(features.get(0), latLng);
+ recursiveLoopClusterFeatures(features);
+ }
+ });
+
// Zoom out to start
mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1));
}
+
+ private void moveCameraToClusterExpansion(Feature feature, LatLng latLng) {
+ if (feature.hasProperty("cluster") && feature.getBooleanProperty("cluster")) {
+ double newZoom = source.getClusterExpansionZoom((long) feature.getNumberProperty("cluster_id"));
+ mapboxMap.animateCamera(
+ CameraUpdateFactory.newLatLngZoom(latLng, newZoom + 0.01), 750
+ );
+ }
+ }
+
+ private void recursiveLoopClusterFeatures(List<Feature> features) {
+ for (Feature feature : features) {
+ boolean cluster = feature.hasProperty("cluster") && feature.getBooleanProperty("cluster");
+ if (cluster) {
+ long pointCount = (long) feature.getNumberProperty("point_count");
+ long clusterId = (long) feature.getNumberProperty("cluster_id");
+ double expansionZoom = source.getClusterExpansionZoom(clusterId);
+ Timber.e(
+ "Cluster= (id=%s) with %s points, cluster will expand at zoom %s",
+ clusterId, pointCount, expansionZoom
+ );
+ recursiveLoopClusterFeatures(source.getLeaves(clusterId, 10, 0));
+ } else {
+ Timber.e("Point data: %s", feature.toJson());
+ }
+ }
+ }
}
diff --git a/platform/android/src/style/sources/geojson_source.cpp b/platform/android/src/style/sources/geojson_source.cpp
index d0ad5fb699..605b0c6e62 100644
--- a/platform/android/src/style/sources/geojson_source.cpp
+++ b/platform/android/src/style/sources/geojson_source.cpp
@@ -108,6 +108,26 @@ namespace android {
return Feature::convert(env, features);
}
+ jni::Local<jni::Array<jni::Object<geojson::Feature>>> GeoJSONSource::getChildren(jni::JNIEnv& env, jni::jlong clusterId) {
+ using namespace mbgl::android::conversion;
+ using namespace mbgl::android::geojson;
+
+ std::vector<mbgl::Feature> features = source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::getChildren(clusterId);
+ return Feature::convert(env, features);
+ }
+
+ jni::Local<jni::Array<jni::Object<geojson::Feature>>> GeoJSONSource::getLeaves(jni::JNIEnv& env, jni::jlong clusterId, jni::jlong limit, jni::jlong offset) {
+ using namespace mbgl::android::conversion;
+ using namespace mbgl::android::geojson;
+
+ std::vector<mbgl::Feature> features = source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::getLeaves(clusterId, limit, offset);
+ return Feature::convert(env, features);
+ }
+
+ jni::jdouble GeoJSONSource::getClusterExpansionZoom(jni::JNIEnv&, jni::jlong clusterId) {
+ return source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::getClusterExpansionZoom(clusterId);
+ }
+
jni::Local<jni::Object<Source>> GeoJSONSource::createJavaPeer(jni::JNIEnv& env) {
static auto& javaClass = jni::Class<GeoJSONSource>::Singleton(env);
static auto constructor = javaClass.GetConstructor<jni::jlong>(env);
@@ -176,7 +196,10 @@ namespace android {
METHOD(&GeoJSONSource::setGeometry, "nativeSetGeometry"),
METHOD(&GeoJSONSource::setURL, "nativeSetUrl"),
METHOD(&GeoJSONSource::getURL, "nativeGetUrl"),
- METHOD(&GeoJSONSource::querySourceFeatures, "querySourceFeatures")
+ METHOD(&GeoJSONSource::querySourceFeatures, "querySourceFeatures"),
+ METHOD(&GeoJSONSource::getLeaves, "nativeGetLeaves"),
+ METHOD(&GeoJSONSource::getChildren, "nativeGetChildren"),
+ METHOD(&GeoJSONSource::getClusterExpansionZoom, "nativeGetClusterExpansionZoom")
);
}
diff --git a/platform/android/src/style/sources/geojson_source.hpp b/platform/android/src/style/sources/geojson_source.hpp
index 20e8b6873b..9f7729ff7f 100644
--- a/platform/android/src/style/sources/geojson_source.hpp
+++ b/platform/android/src/style/sources/geojson_source.hpp
@@ -51,7 +51,14 @@ private:
jni::Local<jni::String> getURL(jni::JNIEnv&);
+ jni::Local<jni::Array<jni::Object<geojson::Feature>>> getChildren(jni::JNIEnv&, jni::jlong);
+
+ jni::Local<jni::Array<jni::Object<geojson::Feature>>> getLeaves(jni::JNIEnv&, jni::jlong, jni::jlong, jni::jlong);
+
+ jni::jdouble getClusterExpansionZoom(jni::JNIEnv&, jni::jlong);
+
jni::Local<jni::Object<Source>> createJavaPeer(jni::JNIEnv&);
+
std::unique_ptr<Update> awaitingUpdate;
std::unique_ptr<Update> update;
std::shared_ptr<ThreadPool> threadPool;