summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortobrun <tobrun.van.nuland@gmail.com>2018-08-23 15:41:58 +0200
committertobrun <tobrun.van.nuland@gmail.com>2018-08-23 16:04:02 +0200
commitffa2d54d371942b914588167eec6747bfcc47438 (patch)
treef742fb75110554edf7429fc5d35b2b9ee1723ab6
parent461cceb7ebbbcd6d2dda734ae845b1221254e28e (diff)
downloadqtlocation-mapboxgl-upstream/tvn-next-gen-cluster-droid.tar.gz
[android] - integrate supercluster api 0.3.0upstream/tvn-next-gen-cluster-droid
-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.java57
-rw-r--r--platform/android/src/style/sources/geojson_source.cpp25
-rw-r--r--platform/android/src/style/sources/geojson_source.hpp6
4 files changed, 106 insertions, 12 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 2d9b1c985a..996e4007d7 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
@@ -297,6 +316,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..54cd4ba91a 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
@@ -5,6 +5,7 @@ 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,6 +21,7 @@ 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;
@@ -36,7 +38,9 @@ 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;
@@ -52,6 +56,7 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
private MapView mapView;
private MapboxMap mapboxMap;
+ private GeoJsonSource source;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -59,10 +64,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 +135,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 +158,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 +171,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 +208,40 @@ public class GeoJsonClusteringActivity extends AppCompatActivity {
mapboxMap.addLayer(count);
+ mapboxMap.addOnMapClickListener(point -> {
+ List<Feature> features = mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(point), layerIds);
+ if (!features.isEmpty()) {
+ moveCameraToClusterExpansion(features.get(0), point);
+ 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=%s (id=%s) with %s points, cluster will expand at zoom %s", cluster, 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 e526231763..4f52c2812a 100644
--- a/platform/android/src/style/sources/geojson_source.cpp
+++ b/platform/android/src/style/sources/geojson_source.cpp
@@ -103,6 +103,26 @@ namespace android {
return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, features);
}
+ 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 *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, features);
+ }
+
+ 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 *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, features);
+ }
+
+ jni::jdouble GeoJSONSource::getClusterExpansionZoom(jni::JNIEnv&, jni::jlong clusterId) {
+ return source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::getClusterExpansionZoom(clusterId);
+ }
+
jni::Class<GeoJSONSource> GeoJSONSource::javaClass;
jni::Object<Source> GeoJSONSource::createJavaPeer(jni::JNIEnv& env) {
@@ -172,7 +192,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 b9c360c67c..513d1fc09a 100644
--- a/platform/android/src/style/sources/geojson_source.hpp
+++ b/platform/android/src/style/sources/geojson_source.hpp
@@ -58,6 +58,12 @@ public:
jni::Array<jni::Object<geojson::Feature>> querySourceFeatures(jni::JNIEnv&,
jni::Array<jni::Object<>> jfilter);
+ jni::Array<jni::Object<geojson::Feature>> getChildren(jni::JNIEnv&, jni::jlong);
+
+ jni::Array<jni::Object<geojson::Feature>> getLeaves(jni::JNIEnv&, jni::jlong, jni::jlong, jni::jlong);
+
+ jni::jdouble getClusterExpansionZoom(jni::JNIEnv&, jni::jlong);
+
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
std::unique_ptr<Update> awaitingUpdate;