diff --git a/.github/workflows/flutter_ci.yml b/.github/workflows/flutter_ci.yml index 3cef5f9e2..b6707163e 100644 --- a/.github/workflows/flutter_ci.yml +++ b/.github/workflows/flutter_ci.yml @@ -39,7 +39,20 @@ jobs: - run: chmod +x swiftformat_linux - name: Check Swift formatting run: ./swiftformat_linux --swiftversion 4.2 --maxwidth 100 --lint ios + + check-java-formatting: + name: "Check Java formatting" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: get google-java-format + run: wget https://github.com/google/google-java-format/releases/download/v1.13.0/google-java-format-1.13.0-all-deps.jar + - run: java --version + - name: Check Java formatting + run: java -jar google-java-format-1.13.0-all-deps.jar --set-exit-if-changed -n $(find . -type f -name "*.java") + + build-android: environment: ANDROID_CI_DOWNLOADS_TOKEN name: "Build Android apk" diff --git a/android/src/main/java/com/mapbox/mapboxgl/Convert.java b/android/src/main/java/com/mapbox/mapboxgl/Convert.java index 745833380..f22b9d068 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/Convert.java +++ b/android/src/main/java/com/mapbox/mapboxgl/Convert.java @@ -7,29 +7,23 @@ import android.content.Context; import android.graphics.Point; import android.util.DisplayMetrics; - import com.mapbox.geojson.Polygon; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; -import com.mapbox.mapboxsdk.log.Logger; import com.mapbox.mapboxsdk.maps.MapboxMap; - import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -/** - * Conversions between JSON-like values and MapboxMaps data types. - */ +/** Conversions between JSON-like values and MapboxMaps data types. */ class Convert { - private final static String TAG = "Convert"; + private static final String TAG = "Convert"; static boolean toBoolean(Object o) { return (Boolean) o; @@ -57,15 +51,17 @@ static CameraUpdate toCameraUpdate(Object o, MapboxMap mapboxMap, float density) case "newLatLng": return CameraUpdateFactory.newLatLng(toLatLng(data.get(1))); case "newLatLngBounds": - return CameraUpdateFactory.newLatLngBounds(toLatLngBounds(data.get(1)), toPixels(data.get(2), density), - toPixels(data.get(3), density), toPixels(data.get(4), density), toPixels(data.get(5), density)); + return CameraUpdateFactory.newLatLngBounds( + toLatLngBounds(data.get(1)), + toPixels(data.get(2), density), + toPixels(data.get(3), density), + toPixels(data.get(4), density), + toPixels(data.get(5), density)); case "newLatLngZoom": return CameraUpdateFactory.newLatLngZoom(toLatLng(data.get(1)), toFloat(data.get(2))); case "scrollBy": mapboxMap.scrollBy( - toFractionalPixels(data.get(1), density), - toFractionalPixels(data.get(2), density) - ); + toFractionalPixels(data.get(1), density), toFractionalPixels(data.get(2), density)); return null; case "zoomBy": if (data.size() == 2) { @@ -143,12 +139,11 @@ static List toLatLngList(Object o, boolean flippedOrder) { } final List data = toList(o); List latLngList = new ArrayList<>(); - for (int i=0; i coords = toList(data.get(i)); - if(flippedOrder){ + if (flippedOrder) { latLngList.add(new LatLng(toDouble(coords.get(1)), toDouble(coords.get(0)))); - } - else{ + } else { latLngList.add(new LatLng(toDouble(coords.get(0)), toDouble(coords.get(1)))); } } @@ -173,7 +168,8 @@ static Polygon interpretListLatLng(List> geometry) { for (List innerGeometry : geometry) { List innerPoints = new ArrayList<>(innerGeometry.size()); for (LatLng latLng : innerGeometry) { - innerPoints.add(com.mapbox.geojson.Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); + innerPoints.add( + com.mapbox.geojson.Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())); } points.add(innerPoints); } @@ -229,8 +225,8 @@ static void interpretMapboxMapOptions(Object o, MapboxMapOptionsSink sink, Conte if (minMaxZoomPreference != null) { final List zoomPreferenceData = toList(minMaxZoomPreference); sink.setMinMaxZoomPreference( // - toFloatWrapper(zoomPreferenceData.get(0)), // - toFloatWrapper(zoomPreferenceData.get(1))); + toFloatWrapper(zoomPreferenceData.get(0)), // + toFloatWrapper(zoomPreferenceData.get(1))); } final Object rotateGesturesEnabled = data.get("rotateGesturesEnabled"); if (rotateGesturesEnabled != null) { @@ -265,30 +261,30 @@ static void interpretMapboxMapOptions(Object o, MapboxMapOptionsSink sink, Conte sink.setMyLocationRenderMode(toInt(myLocationRenderMode)); } final Object logoViewMargins = data.get("logoViewMargins"); - if(logoViewMargins != null){ + if (logoViewMargins != null) { final List logoViewMarginsData = toList(logoViewMargins); final Point point = toPoint(logoViewMarginsData, metrics.density); sink.setLogoViewMargins(point.x, point.y); } final Object compassGravity = data.get("compassViewPosition"); - if(compassGravity != null){ + if (compassGravity != null) { sink.setCompassGravity(toInt(compassGravity)); } final Object compassViewMargins = data.get("compassViewMargins"); - if(compassViewMargins != null){ + if (compassViewMargins != null) { final List compassViewMarginsData = toList(compassViewMargins); final Point point = toPoint(compassViewMarginsData, metrics.density); sink.setCompassViewMargins(point.x, point.y); } final Object attributionButtonGravity = data.get("attributionButtonPosition"); - if(attributionButtonGravity != null){ + if (attributionButtonGravity != null) { sink.setAttributionButtonGravity(toInt(attributionButtonGravity)); } final Object attributionButtonMargins = data.get("attributionButtonMargins"); - if(attributionButtonMargins != null){ + if (attributionButtonMargins != null) { final List attributionButtonMarginsData = toList(attributionButtonMargins); final Point point = toPoint(attributionButtonMarginsData, metrics.density); sink.setAttributionButtonMargins(point.x, point.y); } } -} \ No newline at end of file +} diff --git a/android/src/main/java/com/mapbox/mapboxgl/GlobalMethodHandler.java b/android/src/main/java/com/mapbox/mapboxgl/GlobalMethodHandler.java index 1b95f47f5..0d2a1db94 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/GlobalMethodHandler.java +++ b/android/src/main/java/com/mapbox/mapboxgl/GlobalMethodHandler.java @@ -2,14 +2,14 @@ import android.content.Context; import android.util.Log; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.mapbox.mapboxsdk.net.ConnectivityReceiver; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - +import com.mapbox.mapboxsdk.net.ConnectivityReceiver; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.PluginRegistry; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -20,139 +20,133 @@ import java.io.OutputStream; import java.util.Map; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.PluginRegistry; - class GlobalMethodHandler implements MethodChannel.MethodCallHandler { - private static final String TAG = GlobalMethodHandler.class.getSimpleName(); - private static final String DATABASE_NAME = "mbgl-offline.db"; - private static final int BUFFER_SIZE = 1024 * 2; - - @Nullable - private PluginRegistry.Registrar registrar; - @Nullable - private FlutterPlugin.FlutterAssets flutterAssets; - @NonNull - private final Context context; - @NonNull - private final BinaryMessenger messenger; - - GlobalMethodHandler(@NonNull PluginRegistry.Registrar registrar) { - this.registrar = registrar; - this.context = registrar.activeContext(); - this.messenger = registrar.messenger(); - - } - - GlobalMethodHandler(@NonNull FlutterPlugin.FlutterPluginBinding binding) { - this.context = binding.getApplicationContext(); - this.flutterAssets = binding.getFlutterAssets(); - this.messenger = binding.getBinaryMessenger(); - } - - @Override - public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { - String accessToken = methodCall.argument("accessToken"); - MapBoxUtils.getMapbox(context, accessToken); - - switch (methodCall.method) { - case "installOfflineMapTiles": - String tilesDb = methodCall.argument("tilesdb"); - installOfflineMapTiles(tilesDb); - result.success(null); - break; - case "setOffline": - boolean offline = methodCall.argument("offline"); - ConnectivityReceiver.instance(context).setConnected(offline ? false : null); - result.success(null); - break; - case "mergeOfflineRegions": - OfflineManagerUtils.mergeRegions(result, context, methodCall.argument("path")); - break; - case "setOfflineTileCountLimit": - OfflineManagerUtils.setOfflineTileCountLimit(result, context, methodCall.argument("limit").longValue()); - break; - case "downloadOfflineRegion": - // Get args from caller - Map definitionMap = (Map) methodCall.argument("definition"); - Map metadataMap = (Map) methodCall.argument("metadata"); - String channelName = methodCall.argument("channelName"); - - // Prepare args - OfflineChannelHandlerImpl channelHandler = new OfflineChannelHandlerImpl(messenger, channelName); - - // Start downloading - OfflineManagerUtils.downloadRegion(result, context, definitionMap, metadataMap, channelHandler); - break; - case "getListOfRegions": - OfflineManagerUtils.regionsList(result, context); - break; - case "updateOfflineRegionMetadata": - // Get download region arguments from caller - Map metadata = (Map) methodCall.argument("metadata"); - OfflineManagerUtils.updateRegionMetadata(result, context, methodCall.argument("id").longValue(), metadata); - break; - case "deleteOfflineRegion": - OfflineManagerUtils.deleteRegion(result, context, methodCall.argument("id").longValue()); - break; - default: - result.notImplemented(); - break; - } + private static final String TAG = GlobalMethodHandler.class.getSimpleName(); + private static final String DATABASE_NAME = "mbgl-offline.db"; + private static final int BUFFER_SIZE = 1024 * 2; + + @Nullable private PluginRegistry.Registrar registrar; + @Nullable private FlutterPlugin.FlutterAssets flutterAssets; + @NonNull private final Context context; + @NonNull private final BinaryMessenger messenger; + + GlobalMethodHandler(@NonNull PluginRegistry.Registrar registrar) { + this.registrar = registrar; + this.context = registrar.activeContext(); + this.messenger = registrar.messenger(); + } + + GlobalMethodHandler(@NonNull FlutterPlugin.FlutterPluginBinding binding) { + this.context = binding.getApplicationContext(); + this.flutterAssets = binding.getFlutterAssets(); + this.messenger = binding.getBinaryMessenger(); + } + + @Override + public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { + String accessToken = methodCall.argument("accessToken"); + MapBoxUtils.getMapbox(context, accessToken); + + switch (methodCall.method) { + case "installOfflineMapTiles": + String tilesDb = methodCall.argument("tilesdb"); + installOfflineMapTiles(tilesDb); + result.success(null); + break; + case "setOffline": + boolean offline = methodCall.argument("offline"); + ConnectivityReceiver.instance(context).setConnected(offline ? false : null); + result.success(null); + break; + case "mergeOfflineRegions": + OfflineManagerUtils.mergeRegions(result, context, methodCall.argument("path")); + break; + case "setOfflineTileCountLimit": + OfflineManagerUtils.setOfflineTileCountLimit( + result, context, methodCall.argument("limit").longValue()); + break; + case "downloadOfflineRegion": + // Get args from caller + Map definitionMap = (Map) methodCall.argument("definition"); + Map metadataMap = (Map) methodCall.argument("metadata"); + String channelName = methodCall.argument("channelName"); + + // Prepare args + OfflineChannelHandlerImpl channelHandler = + new OfflineChannelHandlerImpl(messenger, channelName); + + // Start downloading + OfflineManagerUtils.downloadRegion( + result, context, definitionMap, metadataMap, channelHandler); + break; + case "getListOfRegions": + OfflineManagerUtils.regionsList(result, context); + break; + case "updateOfflineRegionMetadata": + // Get download region arguments from caller + Map metadata = (Map) methodCall.argument("metadata"); + OfflineManagerUtils.updateRegionMetadata( + result, context, methodCall.argument("id").longValue(), metadata); + break; + case "deleteOfflineRegion": + OfflineManagerUtils.deleteRegion( + result, context, methodCall.argument("id").longValue()); + break; + default: + result.notImplemented(); + break; } - - private void installOfflineMapTiles(String tilesDb) { - final File dest = new File(context.getFilesDir(), DATABASE_NAME); - try (InputStream input = openTilesDbFile(tilesDb); - OutputStream output = new FileOutputStream(dest)) { - copy(input, output); - } catch (IOException e) { - e.printStackTrace(); - } + } + + private void installOfflineMapTiles(String tilesDb) { + final File dest = new File(context.getFilesDir(), DATABASE_NAME); + try (InputStream input = openTilesDbFile(tilesDb); + OutputStream output = new FileOutputStream(dest)) { + copy(input, output); + } catch (IOException e) { + e.printStackTrace(); } - - private InputStream openTilesDbFile(String tilesDb) throws IOException { - if (tilesDb.startsWith("/")) { // Absolute path. - return new FileInputStream(new File(tilesDb)); - } else { - String assetKey; - if (registrar != null) { - assetKey = registrar.lookupKeyForAsset(tilesDb); - } else if(flutterAssets != null) { - assetKey = flutterAssets.getAssetFilePathByName(tilesDb); - } else { - throw new IllegalStateException(); - } - return context.getAssets().open(assetKey); - } + } + + private InputStream openTilesDbFile(String tilesDb) throws IOException { + if (tilesDb.startsWith("/")) { // Absolute path. + return new FileInputStream(new File(tilesDb)); + } else { + String assetKey; + if (registrar != null) { + assetKey = registrar.lookupKeyForAsset(tilesDb); + } else if (flutterAssets != null) { + assetKey = flutterAssets.getAssetFilePathByName(tilesDb); + } else { + throw new IllegalStateException(); + } + return context.getAssets().open(assetKey); } - - private static void copy(InputStream input, OutputStream output) throws IOException { - final byte[] buffer = new byte[BUFFER_SIZE]; - final BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE); - final BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE); - int count = 0; - int n = 0; - try { - while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) { - out.write(buffer, 0, n); - count += n; - } - out.flush(); - } finally { - try { - out.close(); - } catch (IOException e) { - Log.e(TAG, e.getMessage(), e); - } - try { - in.close(); - } catch (IOException e) { - Log.e(TAG, e.getMessage(), e); - } - } + } + + private static void copy(InputStream input, OutputStream output) throws IOException { + final byte[] buffer = new byte[BUFFER_SIZE]; + final BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE); + final BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE); + int count = 0; + int n = 0; + try { + while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) { + out.write(buffer, 0, n); + count += n; + } + out.flush(); + } finally { + try { + out.close(); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); + } + try { + in.close(); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); + } } + } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/LayerPropertyConverter.java b/android/src/main/java/com/mapbox/mapboxgl/LayerPropertyConverter.java index 9e6a98056..4dcb9b034 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/LayerPropertyConverter.java +++ b/android/src/main/java/com/mapbox/mapboxgl/LayerPropertyConverter.java @@ -3,21 +3,17 @@ package com.mapbox.mapboxgl; +import static com.mapbox.mapboxgl.Convert.toMap; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; import com.mapbox.mapboxsdk.style.expressions.Expression; import com.mapbox.mapboxsdk.style.layers.PropertyFactory; import com.mapbox.mapboxsdk.style.layers.PropertyValue; - import java.util.LinkedList; import java.util.List; import java.util.Map; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; - - -import static com.mapbox.mapboxgl.Convert.toMap; - class LayerPropertyConverter { static PropertyValue[] interpretSymbolLayerProperties(Object o) { final Map data = (Map) toMap(o); @@ -107,9 +103,9 @@ static PropertyValue[] interpretSymbolLayerProperties(Object o) { properties.add(PropertyFactory.iconTextFitPadding(expression)); break; case "icon-image": - if(jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()){ + if (jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()) { properties.add(PropertyFactory.iconImage(jsonElement.getAsString())); - }else{ + } else { properties.add(PropertyFactory.iconImage(expression)); } break; @@ -457,5 +453,4 @@ static PropertyValue[] interpretHillshadeLayerProperties(Object o) { return properties.toArray(new PropertyValue[properties.size()]); } - -} \ No newline at end of file +} diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapBoxUtils.java b/android/src/main/java/com/mapbox/mapboxgl/MapBoxUtils.java index 2319da949..1bd491801 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapBoxUtils.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapBoxUtils.java @@ -5,33 +5,37 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.util.Log; - import androidx.annotation.NonNull; - import com.mapbox.mapboxsdk.Mapbox; abstract class MapBoxUtils { - private static final String TAG = "MapboxMapController"; + private static final String TAG = "MapboxMapController"; - static Mapbox getMapbox(Context context, String accessToken) { - return Mapbox.getInstance(context, accessToken == null ? getAccessToken(context) : accessToken); - } + static Mapbox getMapbox(Context context, String accessToken) { + return Mapbox.getInstance(context, accessToken == null ? getAccessToken(context) : accessToken); + } - private static String getAccessToken(@NonNull Context context) { - try { - ApplicationInfo ai = context.getPackageManager() - .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); - Bundle bundle = ai.metaData; - String token = bundle.getString("com.mapbox.token"); - if (token == null || token.isEmpty()) { - throw new NullPointerException(); - } - return token; - } catch (Exception e) { - Log.e(TAG, "Failed to find an Access Token in the Application meta-data. Maps may not load correctly. " + - "Please refer to the installation guide at https://github.com/tobrun/flutter-mapbox-gl#mapbox-access-token " + - "for troubleshooting advice." + e.getMessage()); - } - return null; + private static String getAccessToken(@NonNull Context context) { + try { + ApplicationInfo ai = + context + .getPackageManager() + .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); + Bundle bundle = ai.metaData; + String token = bundle.getString("com.mapbox.token"); + if (token == null || token.isEmpty()) { + throw new NullPointerException(); + } + return token; + } catch (Exception e) { + Log.e( + TAG, + "Failed to find an Access Token in the Application meta-data. Maps may not load" + + " correctly. Please refer to the installation guide at" + + " https://github.com/tobrun/flutter-mapbox-gl#mapbox-access-token for" + + " troubleshooting advice." + + e.getMessage()); } + return null; + } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapBuilder.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapBuilder.java index 0d5786287..a7a27e866 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapBuilder.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapBuilder.java @@ -5,26 +5,16 @@ package com.mapbox.mapboxgl; import android.content.Context; -import android.util.Log; import android.view.Gravity; - import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; import com.mapbox.mapboxsdk.maps.Style; - import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.PluginRegistry; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.List; -import java.util.ArrayList; - class MapboxMapBuilder implements MapboxMapOptionsSink { public final String TAG = getClass().getSimpleName(); - private final MapboxMapOptions options = new MapboxMapOptions() - .attributionEnabled(true); + private final MapboxMapOptions options = new MapboxMapOptions().attributionEnabled(true); private boolean trackCameraPosition = false; private boolean myLocationEnabled = false; private boolean dragEnabled = true; @@ -34,9 +24,21 @@ class MapboxMapBuilder implements MapboxMapOptionsSink { private LatLngBounds bounds = null; MapboxMapController build( - int id, Context context, BinaryMessenger messenger, MapboxMapsPlugin.LifecycleProvider lifecycleProvider, String accessToken) { + int id, + Context context, + BinaryMessenger messenger, + MapboxMapsPlugin.LifecycleProvider lifecycleProvider, + String accessToken) { final MapboxMapController controller = - new MapboxMapController(id, context, messenger, lifecycleProvider, options, accessToken, styleString, dragEnabled); + new MapboxMapController( + id, + context, + messenger, + lifecycleProvider, + options, + accessToken, + styleString, + dragEnabled); controller.init(); controller.setMyLocationEnabled(myLocationEnabled); controller.setMyLocationTrackingMode(myLocationTrackingMode); @@ -67,7 +69,7 @@ public void setCameraTargetBounds(LatLngBounds bounds) { @Override public void setStyleString(String styleString) { this.styleString = styleString; - //options. styleString(styleString); + // options. styleString(styleString); } @Override @@ -121,17 +123,18 @@ public void setMyLocationRenderMode(int myLocationRenderMode) { } public void setLogoViewMargins(int x, int y) { - options.logoMargins(new int[] { - (int) x, //left - (int) 0, //top - (int) 0, //right - (int) y, //bottom - }); + options.logoMargins( + new int[] { + (int) x, // left + (int) 0, // top + (int) 0, // right + (int) y, // bottom + }); } @Override public void setCompassGravity(int gravity) { - switch(gravity){ + switch (gravity) { case 0: options.compassGravity(Gravity.TOP | Gravity.START); break; @@ -149,13 +152,12 @@ public void setCompassGravity(int gravity) { @Override public void setCompassViewMargins(int x, int y) { - switch(options.getCompassGravity()) - { + switch (options.getCompassGravity()) { case Gravity.TOP | Gravity.START: options.compassMargins(new int[] {(int) x, (int) y, 0, 0}); break; - // If the application code has not specified gravity, assume the platform - // default for the compass which is top-right + // If the application code has not specified gravity, assume the platform + // default for the compass which is top-right default: case Gravity.TOP | Gravity.END: options.compassMargins(new int[] {0, (int) y, (int) x, 0}); @@ -171,7 +173,7 @@ public void setCompassViewMargins(int x, int y) { @Override public void setAttributionButtonGravity(int gravity) { - switch(gravity){ + switch (gravity) { case 0: options.attributionGravity(Gravity.TOP | Gravity.START); break; @@ -189,16 +191,15 @@ public void setAttributionButtonGravity(int gravity) { @Override public void setAttributionButtonMargins(int x, int y) { - switch(options.getAttributionGravity()) - { + switch (options.getAttributionGravity()) { case Gravity.TOP | Gravity.START: options.attributionMargins(new int[] {(int) x, (int) y, 0, 0}); break; case Gravity.TOP | Gravity.END: options.attributionMargins(new int[] {0, (int) y, (int) x, 0}); break; - // If the application code has not specified gravity, assume the platform - // default for the attribution button which is bottom left + // If the application code has not specified gravity, assume the platform + // default for the attribution button which is bottom left default: case Gravity.BOTTOM | Gravity.START: options.attributionMargins(new int[] {(int) x, 0, 0, (int) y}); @@ -209,7 +210,7 @@ public void setAttributionButtonMargins(int x, int y) { } } - public void setDragEnabled(boolean enabled){ - this.dragEnabled = enabled; + public void setDragEnabled(boolean enabled) { + this.dragEnabled = enabled; } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index eac17f712..8f72fa48a 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -18,16 +18,12 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; -import android.view.View; import android.view.MotionEvent; - - +import android.view.View; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; - import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -35,8 +31,8 @@ import com.mapbox.android.core.location.LocationEngineCallback; import com.mapbox.android.core.location.LocationEngineProvider; import com.mapbox.android.core.location.LocationEngineResult; -import com.mapbox.android.gestures.MoveGestureDetector; import com.mapbox.android.gestures.AndroidGesturesManager; +import com.mapbox.android.gestures.MoveGestureDetector; import com.mapbox.android.telemetry.TelemetryEnabler; import com.mapbox.geojson.Feature; import com.mapbox.geojson.FeatureCollection; @@ -61,60 +57,46 @@ import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.mapboxsdk.plugins.localization.LocalizationPlugin; import com.mapbox.mapboxsdk.style.expressions.Expression; -import com.mapbox.mapboxsdk.style.layers.Layer; -import com.mapbox.mapboxsdk.style.sources.ImageSource; - -import com.mapbox.mapboxsdk.style.layers.LineLayer; import com.mapbox.mapboxsdk.style.layers.CircleLayer; import com.mapbox.mapboxsdk.style.layers.FillLayer; -import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.layers.HillshadeLayer; -import com.mapbox.mapboxsdk.style.layers.RasterLayer; - -import com.mapbox.mapboxsdk.style.layers.Property; -import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.layers.LineLayer; import com.mapbox.mapboxsdk.style.layers.PropertyValue; +import com.mapbox.mapboxsdk.style.layers.RasterLayer; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; - - +import com.mapbox.mapboxsdk.style.sources.ImageSource; +import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.platform.PlatformView; - import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Set; import java.util.List; -import java.util.ArrayList; import java.util.Map; -import java.util.Collections; - -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.platform.PlatformView; +import java.util.Set; -/** - * Controller of a single MapboxMaps MapView instance. - */ +/** Controller of a single MapboxMaps MapView instance. */ @SuppressLint("MissingPermission") final class MapboxMapController - implements DefaultLifecycleObserver, - MapboxMap.OnCameraIdleListener, - MapboxMap.OnCameraMoveListener, - MapboxMap.OnCameraMoveStartedListener, - MapView.OnDidBecomeIdleListener, - MapboxMap.OnMapClickListener, - MapboxMap.OnMapLongClickListener, - MapboxMapOptionsSink, - MethodChannel.MethodCallHandler, - OnMapReadyCallback, - OnCameraTrackingChangedListener, - PlatformView { + implements DefaultLifecycleObserver, + MapboxMap.OnCameraIdleListener, + MapboxMap.OnCameraMoveListener, + MapboxMap.OnCameraMoveStartedListener, + MapView.OnDidBecomeIdleListener, + MapboxMap.OnMapClickListener, + MapboxMap.OnMapLongClickListener, + MapboxMapOptionsSink, + MethodChannel.MethodCallHandler, + OnMapReadyCallback, + OnCameraTrackingChangedListener, + PlatformView { private static final String TAG = "MapboxMapController"; private final int id; private final MethodChannel methodChannel; @@ -148,14 +130,14 @@ final class MapboxMapController private LatLngBounds bounds = null; MapboxMapController( - int id, - Context context, - BinaryMessenger messenger, - MapboxMapsPlugin.LifecycleProvider lifecycleProvider, - MapboxMapOptions options, - String accessToken, - String styleStringInitial, - boolean dragEnabled) { + int id, + Context context, + BinaryMessenger messenger, + MapboxMapsPlugin.LifecycleProvider lifecycleProvider, + MapboxMapOptions options, + String accessToken, + String styleStringInitial, + boolean dragEnabled) { MapBoxUtils.getMapbox(context, accessToken); this.id = id; this.context = context; @@ -166,7 +148,7 @@ final class MapboxMapController this.addedFeaturesByLayer = new HashMap(); this.density = context.getResources().getDisplayMetrics().density; this.lifecycleProvider = lifecycleProvider; - if(dragEnabled){ + if (dragEnabled) { this.androidGesturesManager = new AndroidGesturesManager(this.mapView.getContext(), false); } @@ -207,25 +189,27 @@ public void onMapReady(MapboxMap mapboxMap) { mapboxMap.addOnCameraMoveListener(this); mapboxMap.addOnCameraIdleListener(this); - if(androidGesturesManager != null){ + if (androidGesturesManager != null) { androidGesturesManager.setMoveGestureListener(new MoveGestureListener()); - mapView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - androidGesturesManager.onTouchEvent(event); + mapView.setOnTouchListener( + new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + androidGesturesManager.onTouchEvent(event); - return draggedFeature != null; - } - }); + return draggedFeature != null; + } + }); } - mapView.addOnStyleImageMissingListener((id) -> { - DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - final Bitmap bitmap = getScaledImage(id, displayMetrics.density); - if (bitmap != null) { - mapboxMap.getStyle().addImage(id, bitmap); - } - }); + mapView.addOnStyleImageMissingListener( + (id) -> { + DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); + final Bitmap bitmap = getScaledImage(id, displayMetrics.density); + if (bitmap != null) { + mapboxMap.getStyle().addImage(id, bitmap); + } + }); mapView.addOnDidBecomeIdleListener(this); @@ -242,11 +226,11 @@ public void setStyleString(String styleString) { mapboxMap.setStyle(new Style.Builder().fromJson(styleString), onStyleLoadedCallback); } else if (styleString.startsWith("/")) { // Absolute path - mapboxMap.setStyle(new Style.Builder().fromUri("file://" + styleString), onStyleLoadedCallback); - } else if ( - !styleString.startsWith("http://") && - !styleString.startsWith("https://")&& - !styleString.startsWith("mapbox://")) { + mapboxMap.setStyle( + new Style.Builder().fromUri("file://" + styleString), onStyleLoadedCallback); + } else if (!styleString.startsWith("http://") + && !styleString.startsWith("https://") + && !styleString.startsWith("mapbox://")) { // We are assuming that the style will be loaded from an asset here. String key = MapboxMapsPlugin.flutterAssets.getAssetFilePathByName(styleString); mapboxMap.setStyle(new Style.Builder().fromUri("asset://" + key), onStyleLoadedCallback); @@ -255,34 +239,34 @@ public void setStyleString(String styleString) { } } - Style.OnStyleLoaded onStyleLoadedCallback = new Style.OnStyleLoaded() { - @Override - public void onStyleLoaded(@NonNull Style style) { - MapboxMapController.this.style = style; + Style.OnStyleLoaded onStyleLoadedCallback = + new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + MapboxMapController.this.style = style; - if (myLocationEnabled) { - enableLocationComponent(style); - } + if (myLocationEnabled) { + enableLocationComponent(style); + } - if (null != bounds) { - mapboxMap.setLatLngBoundsForCameraTarget(bounds); - } - - mapboxMap.addOnMapClickListener(MapboxMapController.this); - mapboxMap.addOnMapLongClickListener(MapboxMapController.this); - localizationPlugin = new LocalizationPlugin(mapView, mapboxMap, style); + if (null != bounds) { + mapboxMap.setLatLngBoundsForCameraTarget(bounds); + } - methodChannel.invokeMethod("map#onStyleLoaded", null); - } - }; + mapboxMap.addOnMapClickListener(MapboxMapController.this); + mapboxMap.addOnMapLongClickListener(MapboxMapController.this); + localizationPlugin = new LocalizationPlugin(mapView, mapboxMap, style); - @SuppressWarnings( {"MissingPermission"}) + methodChannel.invokeMethod("map#onStyleLoaded", null); + } + }; + + @SuppressWarnings({"MissingPermission"}) private void enableLocationComponent(@NonNull Style style) { if (hasLocationPermission()) { locationEngine = LocationEngineProvider.getBestLocationEngine(context); - LocationComponentOptions locationComponentOptions = LocationComponentOptions.builder(context) - .trackingGesturesManagement(true) - .build(); + LocationComponentOptions locationComponentOptions = + LocationComponentOptions.builder(context).trackingGesturesManagement(true).build(); locationComponent = mapboxMap.getLocationComponent(); locationComponent.activateLocationComponent(context, style, locationComponentOptions); locationComponent.setLocationComponentEnabled(true); @@ -299,19 +283,23 @@ private void enableLocationComponent(@NonNull Style style) { } } - private void onUserLocationUpdate(Location location){ - if(location==null){ + private void onUserLocationUpdate(Location location) { + if (location == null) { return; } final Map userLocation = new HashMap<>(6); - userLocation.put("position", new double[]{location.getLatitude(), location.getLongitude()}); + userLocation.put("position", new double[] {location.getLatitude(), location.getLongitude()}); userLocation.put("speed", location.getSpeed()); userLocation.put("altitude", location.getAltitude()); userLocation.put("bearing", location.getBearing()); userLocation.put("horizontalAccuracy", location.getAccuracy()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - userLocation.put("verticalAccuracy", (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? location.getVerticalAccuracyMeters() : null); + userLocation.put( + "verticalAccuracy", + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + ? location.getVerticalAccuracyMeters() + : null); } userLocation.put("timestamp", location.getTime()); @@ -319,7 +307,7 @@ private void onUserLocationUpdate(Location location){ arguments.put("userLocation", userLocation); methodChannel.invokeMethod("map#onUserLocationUpdated", arguments); } - + private void addGeoJsonSource(String sourceName, String source) { FeatureCollection featureCollection = FeatureCollection.fromJson(source); GeoJsonSource geoJsonSource = new GeoJsonSource(sourceName, featureCollection); @@ -340,11 +328,11 @@ private void setGeoJsonFeature(String sourceName, String geojsonFeature) { Feature feature = Feature.fromJson(geojsonFeature); FeatureCollection featureCollection = addedFeaturesByLayer.get(sourceName); GeoJsonSource geoJsonSource = style.getSourceAs(sourceName); - if(featureCollection != null && geoJsonSource != null){ + if (featureCollection != null && geoJsonSource != null) { final List features = featureCollection.features(); for (int i = 0; i < features.size(); i++) { final String id = features.get(i).id(); - if(id.equals(feature.id())){ + if (id.equals(feature.id())) { features.set(i, feature); break; } @@ -354,160 +342,154 @@ private void setGeoJsonFeature(String sourceName, String geojsonFeature) { } } - private void addSymbolLayer(String layerName, - String sourceName, - String belowLayerId, - String sourceLayer, - PropertyValue[] properties, - boolean enableInteraction, - Expression filter) { + private void addSymbolLayer( + String layerName, + String sourceName, + String belowLayerId, + String sourceLayer, + PropertyValue[] properties, + boolean enableInteraction, + Expression filter) { SymbolLayer symbolLayer = new SymbolLayer(layerName, sourceName); symbolLayer.setProperties(properties); - if(sourceLayer != null){ + if (sourceLayer != null) { symbolLayer.setSourceLayer(sourceLayer); } - if(belowLayerId != null){ + if (belowLayerId != null) { style.addLayerBelow(symbolLayer, belowLayerId); - } - else - { + } else { style.addLayer(symbolLayer); } - if(enableInteraction){ + if (enableInteraction) { interactiveFeatureLayerIds.add(layerName); } } - private void addLineLayer(String layerName, - String sourceName, - String belowLayerId, - String sourceLayer, - PropertyValue[] properties, - boolean enableInteraction, - Expression filter) { + private void addLineLayer( + String layerName, + String sourceName, + String belowLayerId, + String sourceLayer, + PropertyValue[] properties, + boolean enableInteraction, + Expression filter) { LineLayer lineLayer = new LineLayer(layerName, sourceName); lineLayer.setProperties(properties); - if(sourceLayer != null){ + if (sourceLayer != null) { lineLayer.setSourceLayer(sourceLayer); } - if(belowLayerId != null){ + if (belowLayerId != null) { style.addLayerBelow(lineLayer, belowLayerId); - } - else - { + } else { style.addLayer(lineLayer); } - if(enableInteraction){ + if (enableInteraction) { interactiveFeatureLayerIds.add(layerName); } } - private void addFillLayer(String layerName, - String sourceName, - String belowLayerId, - String sourceLayer, - PropertyValue[] properties, - boolean enableInteraction, - Expression filter) { + private void addFillLayer( + String layerName, + String sourceName, + String belowLayerId, + String sourceLayer, + PropertyValue[] properties, + boolean enableInteraction, + Expression filter) { FillLayer fillLayer = new FillLayer(layerName, sourceName); fillLayer.setProperties(properties); - if(sourceLayer != null){ + if (sourceLayer != null) { fillLayer.setSourceLayer(sourceLayer); } - if(belowLayerId != null){ + if (belowLayerId != null) { style.addLayerBelow(fillLayer, belowLayerId); - } - else - { + } else { style.addLayer(fillLayer); } - if(enableInteraction){ + if (enableInteraction) { interactiveFeatureLayerIds.add(layerName); } } - private void addCircleLayer(String layerName, - String sourceName, - String belowLayerId, - String sourceLayer, - PropertyValue[] properties, - boolean enableInteraction, - Expression filter) { + private void addCircleLayer( + String layerName, + String sourceName, + String belowLayerId, + String sourceLayer, + PropertyValue[] properties, + boolean enableInteraction, + Expression filter) { CircleLayer circleLayer = new CircleLayer(layerName, sourceName); circleLayer.setProperties(properties); - if(sourceLayer != null){ + if (sourceLayer != null) { circleLayer.setSourceLayer(sourceLayer); } - if(belowLayerId != null){ + if (belowLayerId != null) { style.addLayerBelow(circleLayer, belowLayerId); - } - else - { + } else { style.addLayer(circleLayer); } - if(enableInteraction){ + if (enableInteraction) { interactiveFeatureLayerIds.add(layerName); - }; - } - - private void addRasterLayer(String layerName, - String sourceName, - String belowLayerId, - PropertyValue[] properties, - Expression filter) { + } + ; + } + + private void addRasterLayer( + String layerName, + String sourceName, + String belowLayerId, + PropertyValue[] properties, + Expression filter) { RasterLayer layer = new RasterLayer(layerName, sourceName); layer.setProperties(properties); - if(belowLayerId != null){ + if (belowLayerId != null) { style.addLayerBelow(layer, belowLayerId); - } - else - { + } else { style.addLayer(layer); } } - private void addHillshadeLayer(String layerName, - String sourceName, - String belowLayerId, - PropertyValue[] properties, - Expression filter) { + private void addHillshadeLayer( + String layerName, + String sourceName, + String belowLayerId, + PropertyValue[] properties, + Expression filter) { HillshadeLayer layer = new HillshadeLayer(layerName, sourceName); layer.setProperties(properties); - if(belowLayerId != null){ + if (belowLayerId != null) { style.addLayerBelow(layer, belowLayerId); - } - else - { + } else { style.addLayer(layer); } } private Feature firstFeatureOnLayers(RectF in) { - if(style != null){ + if (style != null) { final List layers = style.getLayers(); final List layersInOrder = new ArrayList(); - for (Layer layer : layers){ + for (Layer layer : layers) { String id = layer.getId(); - if(interactiveFeatureLayerIds.contains(id)) - layersInOrder.add(id); + if (interactiveFeatureLayerIds.contains(id)) layersInOrder.add(id); } Collections.reverse(layersInOrder); - for(String id: layersInOrder){ + for (String id : layersInOrder) { List features = mapboxMap.queryRenderedFeatures(in, id); - if(!features.isEmpty()){ + if (!features.isEmpty()) { return features.get(0); } } } return null; - } + } @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { @@ -520,364 +502,470 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { } mapReadyResult = result; break; - case "map#update": { - Convert.interpretMapboxMapOptions(call.argument("options"), this, context); - result.success(Convert.toJson(getCameraPosition())); - break; - } - case "map#updateMyLocationTrackingMode": { - int myLocationTrackingMode = call.argument("mode"); - setMyLocationTrackingMode(myLocationTrackingMode); - result.success(null); - break; - } - case "map#matchMapLanguageWithDeviceDefault": { - try { - localizationPlugin.matchMapLanguageWithDeviceDefault(); - result.success(null); - } catch (RuntimeException exception) { - Log.d(TAG, exception.toString()); - result.error("MAPBOX LOCALIZATION PLUGIN ERROR", exception.toString(), null); - } - break; - } - case "map#setMapLanguage": { - final String language = call.argument("language"); - try { - localizationPlugin.setMapLanguage(language); - result.success(null); - } catch (RuntimeException exception) { - Log.d(TAG, exception.toString()); - result.error("MAPBOX LOCALIZATION PLUGIN ERROR", exception.toString(), null); - } - break; - } - case "map#getVisibleRegion": { - Map reply = new HashMap<>(); - VisibleRegion visibleRegion = mapboxMap.getProjection().getVisibleRegion(); - reply.put("sw", Arrays.asList(visibleRegion.nearLeft.getLatitude(), visibleRegion.nearLeft.getLongitude())); - reply.put("ne", Arrays.asList(visibleRegion.farRight.getLatitude(), visibleRegion.farRight.getLongitude())); - result.success(reply); - break; - } - case "map#toScreenLocation": { - Map reply = new HashMap<>(); - PointF pointf = mapboxMap.getProjection().toScreenLocation(new LatLng(call.argument("latitude"),call.argument("longitude"))); - reply.put("x", pointf.x); - reply.put("y", pointf.y); - result.success(reply); - break; - } - case "map#toScreenLocationBatch": { - double[] param = (double[])call.argument("coordinates"); - double[] reply = new double[param.length]; - - for (int i = 0; i < param.length; i += 2) { - PointF pointf = mapboxMap.getProjection().toScreenLocation(new LatLng(param[i], param[i + 1])); - reply[i] = pointf.x; - reply[i + 1] = pointf.y; + case "map#update": + { + Convert.interpretMapboxMapOptions(call.argument("options"), this, context); + result.success(Convert.toJson(getCameraPosition())); + break; } - - result.success(reply); - break; - } - case "map#toLatLng": { - Map reply = new HashMap<>(); - LatLng latlng = mapboxMap.getProjection().fromScreenLocation(new PointF( ((Double) call.argument("x")).floatValue(), ((Double) call.argument("y")).floatValue())); - reply.put("latitude", latlng.getLatitude()); - reply.put("longitude", latlng.getLongitude()); - result.success(reply); - break; - } - case "map#getMetersPerPixelAtLatitude": { - Map reply = new HashMap<>(); - Double retVal = mapboxMap.getProjection().getMetersPerPixelAtLatitude((Double)call.argument("latitude")); - reply.put("metersperpixel", retVal); - result.success(reply); - break; - } - case "camera#move": { - final CameraUpdate cameraUpdate = Convert.toCameraUpdate(call.argument("cameraUpdate"), mapboxMap, density); - if (cameraUpdate != null) { - // camera transformation not handled yet - mapboxMap.moveCamera(cameraUpdate, new OnCameraMoveFinishedListener(){ - @Override - public void onFinish() { - super.onFinish(); - result.success(true); - } - - @Override - public void onCancel() { - super.onCancel(); - result.success(false); - } - }); - - // moveCamera(cameraUpdate); - }else { - result.success(false); + case "map#updateMyLocationTrackingMode": + { + int myLocationTrackingMode = call.argument("mode"); + setMyLocationTrackingMode(myLocationTrackingMode); + result.success(null); + break; } - break; - } - case "camera#animate": { - final CameraUpdate cameraUpdate = Convert.toCameraUpdate(call.argument("cameraUpdate"), mapboxMap, density); - final Integer duration = call.argument("duration"); - - final OnCameraMoveFinishedListener onCameraMoveFinishedListener = new OnCameraMoveFinishedListener(){ - @Override - public void onFinish() { - super.onFinish(); - result.success(true); + case "map#matchMapLanguageWithDeviceDefault": + { + try { + localizationPlugin.matchMapLanguageWithDeviceDefault(); + result.success(null); + } catch (RuntimeException exception) { + Log.d(TAG, exception.toString()); + result.error("MAPBOX LOCALIZATION PLUGIN ERROR", exception.toString(), null); } - - @Override - public void onCancel() { - super.onCancel(); - result.success(false); + break; + } + case "map#setMapLanguage": + { + final String language = call.argument("language"); + try { + localizationPlugin.setMapLanguage(language); + result.success(null); + } catch (RuntimeException exception) { + Log.d(TAG, exception.toString()); + result.error("MAPBOX LOCALIZATION PLUGIN ERROR", exception.toString(), null); } - }; - if (cameraUpdate != null && duration != null) { - // camera transformation not handled yet - mapboxMap.animateCamera(cameraUpdate, duration, onCameraMoveFinishedListener); - } else if (cameraUpdate != null) { - // camera transformation not handled yet - mapboxMap.animateCamera(cameraUpdate, onCameraMoveFinishedListener); - } else { - result.success(false); + break; } - break; - } - case "map#queryRenderedFeatures": { - Map reply = new HashMap<>(); - List features; - - String[] layerIds = ((List) call.argument("layerIds")).toArray(new String[0]); + case "map#getVisibleRegion": + { + Map reply = new HashMap<>(); + VisibleRegion visibleRegion = mapboxMap.getProjection().getVisibleRegion(); + reply.put( + "sw", + Arrays.asList( + visibleRegion.nearLeft.getLatitude(), visibleRegion.nearLeft.getLongitude())); + reply.put( + "ne", + Arrays.asList( + visibleRegion.farRight.getLatitude(), visibleRegion.farRight.getLongitude())); + result.success(reply); + break; + } + case "map#toScreenLocation": + { + Map reply = new HashMap<>(); + PointF pointf = + mapboxMap + .getProjection() + .toScreenLocation( + new LatLng(call.argument("latitude"), call.argument("longitude"))); + reply.put("x", pointf.x); + reply.put("y", pointf.y); + result.success(reply); + break; + } + case "map#toScreenLocationBatch": + { + double[] param = (double[]) call.argument("coordinates"); + double[] reply = new double[param.length]; + + for (int i = 0; i < param.length; i += 2) { + PointF pointf = + mapboxMap.getProjection().toScreenLocation(new LatLng(param[i], param[i + 1])); + reply[i] = pointf.x; + reply[i + 1] = pointf.y; + } - List filter = call.argument("filter"); - JsonElement jsonElement = filter == null ? null : new Gson().toJsonTree(filter); - JsonArray jsonArray = null; - if (jsonElement != null && jsonElement.isJsonArray()) { - jsonArray = jsonElement.getAsJsonArray(); + result.success(reply); + break; } - Expression filterExpression = jsonArray == null ? null : Expression.Converter.convert(jsonArray); - if (call.hasArgument("x")) { - Double x = call.argument("x"); - Double y = call.argument("y"); - PointF pixel = new PointF(x.floatValue(), y.floatValue()); - features = mapboxMap.queryRenderedFeatures(pixel, filterExpression, layerIds); - } else { - Double left = call.argument("left"); - Double top = call.argument("top"); - Double right = call.argument("right"); - Double bottom = call.argument("bottom"); - RectF rectF = new RectF(left.floatValue(), top.floatValue(), right.floatValue(), bottom.floatValue()); - features = mapboxMap.queryRenderedFeatures(rectF, filterExpression, layerIds); + case "map#toLatLng": + { + Map reply = new HashMap<>(); + LatLng latlng = + mapboxMap + .getProjection() + .fromScreenLocation( + new PointF( + ((Double) call.argument("x")).floatValue(), + ((Double) call.argument("y")).floatValue())); + reply.put("latitude", latlng.getLatitude()); + reply.put("longitude", latlng.getLongitude()); + result.success(reply); + break; } - List featuresJson = new ArrayList<>(); - for (Feature feature : features) { - featuresJson.add(feature.toJson()); + case "map#getMetersPerPixelAtLatitude": + { + Map reply = new HashMap<>(); + Double retVal = + mapboxMap + .getProjection() + .getMetersPerPixelAtLatitude((Double) call.argument("latitude")); + reply.put("metersperpixel", retVal); + result.success(reply); + break; } - reply.put("features", featuresJson); - result.success(reply); - break; - } - case "map#setTelemetryEnabled": { - final boolean enabled = call.argument("enabled"); - Mapbox.getTelemetry().setUserTelemetryRequestState(enabled); - result.success(null); - break; - } - case "map#getTelemetryEnabled": { - final TelemetryEnabler.State telemetryState = TelemetryEnabler.retrieveTelemetryStateFromPreferences(); - result.success(telemetryState == TelemetryEnabler.State.ENABLED); - break; - } - case "map#invalidateAmbientCache": { - OfflineManager fileSource = OfflineManager.getInstance(context); - - fileSource.invalidateAmbientCache(new OfflineManager.FileSourceCallback() { - @Override - public void onSuccess() { - result.success(null); + case "camera#move": + { + final CameraUpdate cameraUpdate = + Convert.toCameraUpdate(call.argument("cameraUpdate"), mapboxMap, density); + if (cameraUpdate != null) { + // camera transformation not handled yet + mapboxMap.moveCamera( + cameraUpdate, + new OnCameraMoveFinishedListener() { + @Override + public void onFinish() { + super.onFinish(); + result.success(true); + } + + @Override + public void onCancel() { + super.onCancel(); + result.success(false); + } + }); + + // moveCamera(cameraUpdate); + } else { + result.success(false); } - - @Override - public void onError(@NonNull String message) { - result.error("MAPBOX CACHE ERROR", message, null); + break; + } + case "camera#animate": + { + final CameraUpdate cameraUpdate = + Convert.toCameraUpdate(call.argument("cameraUpdate"), mapboxMap, density); + final Integer duration = call.argument("duration"); + + final OnCameraMoveFinishedListener onCameraMoveFinishedListener = + new OnCameraMoveFinishedListener() { + @Override + public void onFinish() { + super.onFinish(); + result.success(true); + } + + @Override + public void onCancel() { + super.onCancel(); + result.success(false); + } + }; + if (cameraUpdate != null && duration != null) { + // camera transformation not handled yet + mapboxMap.animateCamera(cameraUpdate, duration, onCameraMoveFinishedListener); + } else if (cameraUpdate != null) { + // camera transformation not handled yet + mapboxMap.animateCamera(cameraUpdate, onCameraMoveFinishedListener); + } else { + result.success(false); } - }); - break; - } - case "source#addGeoJson": { - final String sourceId = call.argument("sourceId"); - final String geojson = call.argument("geojson"); - addGeoJsonSource(sourceId, geojson); - result.success(null); - break; - } - case "source#setGeoJson": { - final String sourceId = call.argument("sourceId"); - final String geojson = call.argument("geojson"); - setGeoJsonSource(sourceId, geojson); - result.success(null); - break; - } - case "source#setFeature":{ - final String sourceId = call.argument("sourceId"); - final String geojsonFeature = call.argument("geojsonFeature"); - setGeoJsonFeature(sourceId, geojsonFeature); - result.success(null); - break; - } - case "symbolLayer#add": { - final String sourceId = call.argument("sourceId"); - final String layerId = call.argument("layerId"); - final String belowLayerId = call.argument("belowLayerId"); - final String sourceLayer = call.argument("sourceLayer"); - final boolean enableInteraction = call.argument("enableInteraction"); - final PropertyValue[] properties = LayerPropertyConverter.interpretSymbolLayerProperties(call.argument("properties")); - addSymbolLayer(layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); - result.success(null); - break; - } - case "lineLayer#add": { - final String sourceId = call.argument("sourceId"); - final String layerId = call.argument("layerId"); - final String belowLayerId = call.argument("belowLayerId"); - final String sourceLayer = call.argument("sourceLayer"); - final boolean enableInteraction = call.argument("enableInteraction"); - final PropertyValue[] properties = LayerPropertyConverter.interpretLineLayerProperties(call.argument("properties")); - addLineLayer(layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); - result.success(null); - break; - } - case "fillLayer#add": { - final String sourceId = call.argument("sourceId"); - final String layerId = call.argument("layerId"); - final String belowLayerId = call.argument("belowLayerId"); - final String sourceLayer = call.argument("sourceLayer"); - final boolean enableInteraction = call.argument("enableInteraction"); - final PropertyValue[] properties = LayerPropertyConverter.interpretFillLayerProperties(call.argument("properties")); - addFillLayer(layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); - result.success(null); - break; - } - case "circleLayer#add": { - final String sourceId = call.argument("sourceId"); - final String layerId = call.argument("layerId"); - final String belowLayerId = call.argument("belowLayerId"); - final String sourceLayer = call.argument("sourceLayer"); - final boolean enableInteraction = call.argument("enableInteraction"); - final PropertyValue[] properties = LayerPropertyConverter.interpretCircleLayerProperties(call.argument("properties")); - addCircleLayer(layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); - result.success(null); - break; - } - case "rasterLayer#add": { - final String sourceId = call.argument("sourceId"); - final String layerId = call.argument("layerId"); - final String belowLayerId = call.argument("belowLayerId"); - final PropertyValue[] properties = LayerPropertyConverter.interpretRasterLayerProperties(call.argument("properties")); - addRasterLayer(layerId, sourceId, belowLayerId, properties, null); - result.success(null); - break; - } - case "hillshadeLayer#add": { - final String sourceId = call.argument("sourceId"); - final String layerId = call.argument("layerId"); - final String belowLayerId = call.argument("belowLayerId"); - final PropertyValue[] properties = LayerPropertyConverter.interpretHillshadeLayerProperties(call.argument("properties")); - addHillshadeLayer(layerId, sourceId, belowLayerId, properties, null); - result.success(null); - break; - } - case "locationComponent#getLastLocation": { - Log.e(TAG, "location component: getLastLocation"); - if (this.myLocationEnabled && locationComponent != null && locationEngine != null) { + break; + } + case "map#queryRenderedFeatures": + { Map reply = new HashMap<>(); - locationEngine.getLastLocation(new LocationEngineCallback() { - @Override - public void onSuccess(LocationEngineResult locationEngineResult) { - Location lastLocation = locationEngineResult.getLastLocation(); - if (lastLocation != null) { - reply.put("latitude", lastLocation.getLatitude()); - reply.put("longitude", lastLocation.getLongitude()); - reply.put("altitude", lastLocation.getAltitude()); - result.success(reply); - } else { - result.error("", "", null); // ??? - } - } + List features; - @Override - public void onFailure(@NonNull Exception exception) { - result.error("", "", null); // ??? - } - }); + String[] layerIds = ((List) call.argument("layerIds")).toArray(new String[0]); + + List filter = call.argument("filter"); + JsonElement jsonElement = filter == null ? null : new Gson().toJsonTree(filter); + JsonArray jsonArray = null; + if (jsonElement != null && jsonElement.isJsonArray()) { + jsonArray = jsonElement.getAsJsonArray(); + } + Expression filterExpression = + jsonArray == null ? null : Expression.Converter.convert(jsonArray); + if (call.hasArgument("x")) { + Double x = call.argument("x"); + Double y = call.argument("y"); + PointF pixel = new PointF(x.floatValue(), y.floatValue()); + features = mapboxMap.queryRenderedFeatures(pixel, filterExpression, layerIds); + } else { + Double left = call.argument("left"); + Double top = call.argument("top"); + Double right = call.argument("right"); + Double bottom = call.argument("bottom"); + RectF rectF = + new RectF( + left.floatValue(), top.floatValue(), right.floatValue(), bottom.floatValue()); + features = mapboxMap.queryRenderedFeatures(rectF, filterExpression, layerIds); + } + List featuresJson = new ArrayList<>(); + for (Feature feature : features) { + featuresJson.add(feature.toJson()); + } + reply.put("features", featuresJson); + result.success(reply); + break; } - break; - } - case "style#addImage": { - if(style==null) { - result.error("STYLE IS NULL", "The style is null. Has onStyleLoaded() already been invoked?", null); + case "map#setTelemetryEnabled": + { + final boolean enabled = call.argument("enabled"); + Mapbox.getTelemetry().setUserTelemetryRequestState(enabled); + result.success(null); + break; } - style.addImage(call.argument("name"), BitmapFactory.decodeByteArray(call.argument("bytes"),0,call.argument("length")), call.argument("sdf")); - result.success(null); - break; - } - case "style#addImageSource": { - if (style == null) { - result.error("STYLE IS NULL", "The style is null. Has onStyleLoaded() already been invoked?", null); + case "map#getTelemetryEnabled": + { + final TelemetryEnabler.State telemetryState = + TelemetryEnabler.retrieveTelemetryStateFromPreferences(); + result.success(telemetryState == TelemetryEnabler.State.ENABLED); + break; } - List coordinates = Convert.toLatLngList(call.argument("coordinates"), false); - style.addSource(new ImageSource(call.argument("imageSourceId"), new LatLngQuad(coordinates.get(0), coordinates.get(1), coordinates.get(2), coordinates.get(3)), BitmapFactory.decodeByteArray(call.argument("bytes"), 0, call.argument("length")))); - result.success(null); - break; - } - case "style#addSource":{ - final String id = Convert.toString(call.argument("sourceId")); - final Map properties = (Map) call.argument("properties"); - SourcePropertyConverter.addSource(id, properties, style); - result.success(null); - break; - } - - case "style#removeSource": { - if (style == null) { - result.error("STYLE IS NULL", "The style is null. Has onStyleLoaded() already been invoked?", null); + case "map#invalidateAmbientCache": + { + OfflineManager fileSource = OfflineManager.getInstance(context); + + fileSource.invalidateAmbientCache( + new OfflineManager.FileSourceCallback() { + @Override + public void onSuccess() { + result.success(null); + } + + @Override + public void onError(@NonNull String message) { + result.error("MAPBOX CACHE ERROR", message, null); + } + }); + break; } - style.removeSource((String) call.argument("sourceId")); - result.success(null); - break; - } - case "style#addLayer": { - if (style == null) { - result.error("STYLE IS NULL", "The style is null. Has onStyleLoaded() already been invoked?", null); + case "source#addGeoJson": + { + final String sourceId = call.argument("sourceId"); + final String geojson = call.argument("geojson"); + addGeoJsonSource(sourceId, geojson); + result.success(null); + break; } - style.addLayer(new RasterLayer(call.argument("imageLayerId"), call.argument("imageSourceId"))); - result.success(null); - break; - } - case "style#addLayerBelow": { - if (style == null) { - result.error("STYLE IS NULL", "The style is null. Has onStyleLoaded() already been invoked?", null); + case "source#setGeoJson": + { + final String sourceId = call.argument("sourceId"); + final String geojson = call.argument("geojson"); + setGeoJsonSource(sourceId, geojson); + result.success(null); + break; } - style.addLayerBelow(new RasterLayer(call.argument("imageLayerId"), call.argument("imageSourceId")), call.argument("belowLayerId")); - result.success(null); - break; - } - case "style#removeLayer": { - if (style == null) { - result.error("STYLE IS NULL", "The style is null. Has onStyleLoaded() already been invoked?", null); + case "source#setFeature": + { + final String sourceId = call.argument("sourceId"); + final String geojsonFeature = call.argument("geojsonFeature"); + setGeoJsonFeature(sourceId, geojsonFeature); + result.success(null); + break; + } + case "symbolLayer#add": + { + final String sourceId = call.argument("sourceId"); + final String layerId = call.argument("layerId"); + final String belowLayerId = call.argument("belowLayerId"); + final String sourceLayer = call.argument("sourceLayer"); + final boolean enableInteraction = call.argument("enableInteraction"); + final PropertyValue[] properties = + LayerPropertyConverter.interpretSymbolLayerProperties(call.argument("properties")); + addSymbolLayer( + layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); + result.success(null); + break; + } + case "lineLayer#add": + { + final String sourceId = call.argument("sourceId"); + final String layerId = call.argument("layerId"); + final String belowLayerId = call.argument("belowLayerId"); + final String sourceLayer = call.argument("sourceLayer"); + final boolean enableInteraction = call.argument("enableInteraction"); + final PropertyValue[] properties = + LayerPropertyConverter.interpretLineLayerProperties(call.argument("properties")); + addLineLayer( + layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); + result.success(null); + break; + } + case "fillLayer#add": + { + final String sourceId = call.argument("sourceId"); + final String layerId = call.argument("layerId"); + final String belowLayerId = call.argument("belowLayerId"); + final String sourceLayer = call.argument("sourceLayer"); + final boolean enableInteraction = call.argument("enableInteraction"); + final PropertyValue[] properties = + LayerPropertyConverter.interpretFillLayerProperties(call.argument("properties")); + addFillLayer( + layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); + result.success(null); + break; + } + case "circleLayer#add": + { + final String sourceId = call.argument("sourceId"); + final String layerId = call.argument("layerId"); + final String belowLayerId = call.argument("belowLayerId"); + final String sourceLayer = call.argument("sourceLayer"); + final boolean enableInteraction = call.argument("enableInteraction"); + final PropertyValue[] properties = + LayerPropertyConverter.interpretCircleLayerProperties(call.argument("properties")); + addCircleLayer( + layerId, sourceId, belowLayerId, sourceLayer, properties, enableInteraction, null); + result.success(null); + break; + } + case "rasterLayer#add": + { + final String sourceId = call.argument("sourceId"); + final String layerId = call.argument("layerId"); + final String belowLayerId = call.argument("belowLayerId"); + final PropertyValue[] properties = + LayerPropertyConverter.interpretRasterLayerProperties(call.argument("properties")); + addRasterLayer(layerId, sourceId, belowLayerId, properties, null); + result.success(null); + break; + } + case "hillshadeLayer#add": + { + final String sourceId = call.argument("sourceId"); + final String layerId = call.argument("layerId"); + final String belowLayerId = call.argument("belowLayerId"); + final PropertyValue[] properties = + LayerPropertyConverter.interpretHillshadeLayerProperties(call.argument("properties")); + addHillshadeLayer(layerId, sourceId, belowLayerId, properties, null); + result.success(null); + break; + } + case "locationComponent#getLastLocation": + { + Log.e(TAG, "location component: getLastLocation"); + if (this.myLocationEnabled && locationComponent != null && locationEngine != null) { + Map reply = new HashMap<>(); + locationEngine.getLastLocation( + new LocationEngineCallback() { + @Override + public void onSuccess(LocationEngineResult locationEngineResult) { + Location lastLocation = locationEngineResult.getLastLocation(); + if (lastLocation != null) { + reply.put("latitude", lastLocation.getLatitude()); + reply.put("longitude", lastLocation.getLongitude()); + reply.put("altitude", lastLocation.getAltitude()); + result.success(reply); + } else { + result.error("", "", null); // ??? + } + } + + @Override + public void onFailure(@NonNull Exception exception) { + result.error("", "", null); // ??? + } + }); + } + break; + } + case "style#addImage": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + style.addImage( + call.argument("name"), + BitmapFactory.decodeByteArray(call.argument("bytes"), 0, call.argument("length")), + call.argument("sdf")); + result.success(null); + break; + } + case "style#addImageSource": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + List coordinates = Convert.toLatLngList(call.argument("coordinates"), false); + style.addSource( + new ImageSource( + call.argument("imageSourceId"), + new LatLngQuad( + coordinates.get(0), + coordinates.get(1), + coordinates.get(2), + coordinates.get(3)), + BitmapFactory.decodeByteArray( + call.argument("bytes"), 0, call.argument("length")))); + result.success(null); + break; + } + case "style#addSource": + { + final String id = Convert.toString(call.argument("sourceId")); + final Map properties = (Map) call.argument("properties"); + SourcePropertyConverter.addSource(id, properties, style); + result.success(null); + break; } - String layerId = call.argument("layerId"); - style.removeLayer(layerId); - interactiveFeatureLayerIds.remove(layerId); - result.success(null); - break; - } + case "style#removeSource": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + style.removeSource((String) call.argument("sourceId")); + result.success(null); + break; + } + case "style#addLayer": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + style.addLayer( + new RasterLayer(call.argument("imageLayerId"), call.argument("imageSourceId"))); + result.success(null); + break; + } + case "style#addLayerBelow": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + style.addLayerBelow( + new RasterLayer(call.argument("imageLayerId"), call.argument("imageSourceId")), + call.argument("belowLayerId")); + result.success(null); + break; + } + case "style#removeLayer": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + String layerId = call.argument("layerId"); + style.removeLayer(layerId); + interactiveFeatureLayerIds.remove(layerId); + + result.success(null); + break; + } default: result.notImplemented(); } @@ -931,22 +1019,17 @@ public void onDidBecomeIdle() { @Override public boolean onMapClick(@NonNull LatLng point) { PointF pointf = mapboxMap.getProjection().toScreenLocation(point); - RectF rectF = new RectF( - pointf.x - 10, - pointf.y - 10, - pointf.x + 10, - pointf.y + 10 - ); + RectF rectF = new RectF(pointf.x - 10, pointf.y - 10, pointf.x + 10, pointf.y + 10); Feature feature = firstFeatureOnLayers(rectF); final Map arguments = new HashMap<>(); arguments.put("x", pointf.x); arguments.put("y", pointf.y); arguments.put("lng", point.getLongitude()); arguments.put("lat", point.getLatitude()); - if(feature != null){ + if (feature != null) { arguments.put("id", feature.id()); methodChannel.invokeMethod("feature#onTap", arguments); - } else { + } else { methodChannel.invokeMethod("map#onMapClick", arguments); } return true; @@ -1014,7 +1097,7 @@ public void onResume(@NonNull LifecycleOwner owner) { return; } mapView.onResume(); - if(myLocationEnabled){ + if (myLocationEnabled) { startListeningForLocationUpdates(); } } @@ -1126,7 +1209,7 @@ public void setLogoViewMargins(int x, int y) { @Override public void setCompassGravity(int gravity) { - switch(gravity) { + switch (gravity) { case 0: mapboxMap.getUiSettings().setCompassGravity(Gravity.TOP | Gravity.START); break; @@ -1145,8 +1228,7 @@ public void setCompassGravity(int gravity) { @Override public void setCompassViewMargins(int x, int y) { - switch(mapboxMap.getUiSettings().getCompassGravity()) - { + switch (mapboxMap.getUiSettings().getCompassGravity()) { case Gravity.TOP | Gravity.START: mapboxMap.getUiSettings().setCompassMargins(x, y, 0, 0); break; @@ -1165,7 +1247,7 @@ public void setCompassViewMargins(int x, int y) { @Override public void setAttributionButtonGravity(int gravity) { - switch(gravity) { + switch (gravity) { case 0: mapboxMap.getUiSettings().setAttributionGravity(Gravity.TOP | Gravity.START); break; @@ -1184,8 +1266,7 @@ public void setAttributionButtonGravity(int gravity) { @Override public void setAttributionButtonMargins(int x, int y) { - switch(mapboxMap.getUiSettings().getAttributionGravity()) - { + switch (mapboxMap.getUiSettings().getAttributionGravity()) { case Gravity.TOP | Gravity.START: mapboxMap.getUiSettings().setAttributionMargins(x, y, 0, 0); break; @@ -1203,44 +1284,54 @@ public void setAttributionButtonMargins(int x, int y) { } private void updateMyLocationEnabled() { - if(this.locationComponent == null && myLocationEnabled){ + if (this.locationComponent == null && myLocationEnabled) { enableLocationComponent(mapboxMap.getStyle()); } - if(myLocationEnabled){ + if (myLocationEnabled) { startListeningForLocationUpdates(); - }else { + } else { stopListeningForLocationUpdates(); } locationComponent.setLocationComponentEnabled(myLocationEnabled); } - private void startListeningForLocationUpdates(){ - if(locationEngineCallback == null && locationComponent!=null && locationComponent.getLocationEngine()!=null){ - locationEngineCallback = new LocationEngineCallback() { - @Override - public void onSuccess(LocationEngineResult result) { - onUserLocationUpdate(result.getLastLocation()); - } + private void startListeningForLocationUpdates() { + if (locationEngineCallback == null + && locationComponent != null + && locationComponent.getLocationEngine() != null) { + locationEngineCallback = + new LocationEngineCallback() { + @Override + public void onSuccess(LocationEngineResult result) { + onUserLocationUpdate(result.getLastLocation()); + } - @Override - public void onFailure(@NonNull Exception exception) { - } - }; - locationComponent.getLocationEngine().requestLocationUpdates(locationComponent.getLocationEngineRequest(), locationEngineCallback , null); + @Override + public void onFailure(@NonNull Exception exception) {} + }; + locationComponent + .getLocationEngine() + .requestLocationUpdates( + locationComponent.getLocationEngineRequest(), locationEngineCallback, null); } } - private void stopListeningForLocationUpdates(){ - if(locationEngineCallback != null && locationComponent!=null && locationComponent.getLocationEngine()!=null){ + private void stopListeningForLocationUpdates() { + if (locationEngineCallback != null + && locationComponent != null + && locationComponent.getLocationEngine() != null) { locationComponent.getLocationEngine().removeLocationUpdates(locationEngineCallback); locationEngineCallback = null; } } private void updateMyLocationTrackingMode() { - int[] mapboxTrackingModes = new int[] {CameraMode.NONE, CameraMode.TRACKING, CameraMode.TRACKING_COMPASS, CameraMode.TRACKING_GPS}; + int[] mapboxTrackingModes = + new int[] { + CameraMode.NONE, CameraMode.TRACKING, CameraMode.TRACKING_COMPASS, CameraMode.TRACKING_GPS + }; locationComponent.setCameraMode(mapboxTrackingModes[this.myLocationTrackingMode]); } @@ -1251,9 +1342,9 @@ private void updateMyLocationRenderMode() { private boolean hasLocationPermission() { return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED - || checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) - == PackageManager.PERMISSION_GRANTED; + == PackageManager.PERMISSION_GRANTED + || checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) + == PackageManager.PERMISSION_GRANTED; } private int checkSelfPermission(String permission) { @@ -1261,11 +1352,12 @@ private int checkSelfPermission(String permission) { throw new IllegalArgumentException("permission is null"); } return context.checkPermission( - permission, android.os.Process.myPid(), android.os.Process.myUid()); + permission, android.os.Process.myPid(), android.os.Process.myUid()); } /** * Tries to find highest scale image for display type + * * @param imageId * @param density * @return @@ -1296,7 +1388,7 @@ private Bitmap getScaledImage(String imageId, float density) { } stringBuilder.append(((float) i) + "x"); stringBuilder.append("/"); - stringBuilder.append(imagePathList.get(imagePathList.size()-1)); + stringBuilder.append(imagePathList.get(imagePathList.size() - 1)); assetPath = MapboxMapsPlugin.flutterAssets.getAssetFilePathByName(stringBuilder.toString()); } // Build up a list of resolution aware asset paths. @@ -1320,31 +1412,25 @@ private Bitmap getScaledImage(String imageId, float density) { return bitmap; } - /** - * Simple Listener to listen for the status of camera movements. - */ - public class OnCameraMoveFinishedListener implements MapboxMap.CancelableCallback{ + /** Simple Listener to listen for the status of camera movements. */ + public class OnCameraMoveFinishedListener implements MapboxMap.CancelableCallback { @Override - public void onFinish() { - } + public void onFinish() {} @Override - public void onCancel() { - } + public void onCancel() {} } - boolean onMoveBegin(MoveGestureDetector detector) { - // onMoveBegin gets called even during a move - move end is also not called unless this function returns - // true at least once. To avoid redundant queries only check for feature if the previous event was ACTION_DOWN - if (detector.getPreviousEvent().getActionMasked() == MotionEvent.ACTION_DOWN && detector.getPointersCount() == 1) { + boolean onMoveBegin(MoveGestureDetector detector) { + // onMoveBegin gets called even during a move - move end is also not called unless this function + // returns + // true at least once. To avoid redundant queries only check for feature if the previous event + // was ACTION_DOWN + if (detector.getPreviousEvent().getActionMasked() == MotionEvent.ACTION_DOWN + && detector.getPointersCount() == 1) { PointF pointf = detector.getFocalPoint(); LatLng origin = mapboxMap.getProjection().fromScreenLocation(pointf); - RectF rectF = new RectF( - pointf.x - 10, - pointf.y - 10, - pointf.x + 10, - pointf.y + 10 - ); + RectF rectF = new RectF(pointf.x - 10, pointf.y - 10, pointf.x + 10, pointf.y + 10); Feature feature = firstFeatureOnLayers(rectF); if (feature != null && startDragging(feature, origin)) { return true; @@ -1353,14 +1439,13 @@ boolean onMoveBegin(MoveGestureDetector detector) { return false; } - boolean onMove(MoveGestureDetector detector) { if (draggedFeature != null) { if (detector.getPointersCount() > 1) { stopDragging(); return true; } - + PointF pointf = detector.getFocalPoint(); LatLng current = mapboxMap.getProjection().fromScreenLocation(pointf); @@ -1388,8 +1473,10 @@ void onMoveEnd() { } boolean startDragging(@NonNull Feature feature, @NonNull LatLng origin) { - final boolean draggable = feature.hasNonNullValueForProperty("draggable") ? - feature.getBooleanProperty("draggable") : false; + final boolean draggable = + feature.hasNonNullValueForProperty("draggable") + ? feature.getBooleanProperty("draggable") + : false; if (draggable) { draggedFeature = feature; dragPrevious = origin; @@ -1399,15 +1486,12 @@ boolean startDragging(@NonNull Feature feature, @NonNull LatLng origin) { return false; } - void stopDragging() { draggedFeature = null; dragOrigin = null; dragPrevious = null; } - - private class MoveGestureListener implements MoveGestureDetector.OnMoveGestureListener { @Override @@ -1417,7 +1501,7 @@ public boolean onMoveBegin(MoveGestureDetector detector) { @Override public boolean onMove(MoveGestureDetector detector, float distanceX, float distanceY) { - return MapboxMapController.this.onMove(detector); + return MapboxMapController.this.onMove(detector); } @Override diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapFactory.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapFactory.java index 6e322098c..625caf9a8 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapFactory.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapFactory.java @@ -1,25 +1,20 @@ package com.mapbox.mapboxgl; import android.content.Context; - import com.mapbox.mapboxsdk.camera.CameraPosition; - import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.StandardMessageCodec; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; - import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.List; -import java.util.ArrayList; public class MapboxMapFactory extends PlatformViewFactory { private final BinaryMessenger messenger; private final MapboxMapsPlugin.LifecycleProvider lifecycleProvider; - public MapboxMapFactory(BinaryMessenger messenger, MapboxMapsPlugin.LifecycleProvider lifecycleProvider) { + public MapboxMapFactory( + BinaryMessenger messenger, MapboxMapsPlugin.LifecycleProvider lifecycleProvider) { super(StandardMessageCodec.INSTANCE); this.messenger = messenger; this.lifecycleProvider = lifecycleProvider; @@ -40,6 +35,7 @@ public PlatformView create(Context context, int id, Object args) { builder.setDragEnabled(dragEnabled); } - return builder.build(id, context, messenger, lifecycleProvider, (String) params.get("accessToken")); + return builder.build( + id, context, messenger, lifecycleProvider, (String) params.get("accessToken")); } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapOptionsSink.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapOptionsSink.java index 35e811cf4..bcc8e6b48 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapOptionsSink.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapOptionsSink.java @@ -6,11 +6,10 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds; -/** - * Receiver of MapboxMap configuration options. - */ +/** Receiver of MapboxMap configuration options. */ interface MapboxMapOptionsSink { - void setCameraTargetBounds(LatLngBounds bounds); //todo: dddd replace with CameraPosition.Builder target + void setCameraTargetBounds( + LatLngBounds bounds); // todo: dddd replace with CameraPosition.Builder target void setCompassEnabled(boolean compassEnabled); diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapsPlugin.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapsPlugin.java index 7014b1e41..3f25d26a6 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapsPlugin.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapsPlugin.java @@ -7,13 +7,11 @@ import android.app.Activity; import android.app.Application; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; - import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; @@ -44,19 +42,23 @@ public MapboxMapsPlugin() { public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { flutterAssets = binding.getFlutterAssets(); - MethodChannel methodChannel = new MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/mapbox_gl"); + MethodChannel methodChannel = + new MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/mapbox_gl"); methodChannel.setMethodCallHandler(new GlobalMethodHandler(binding)); binding - .getPlatformViewRegistry() - .registerViewFactory( - "plugins.flutter.io/mapbox_gl", new MapboxMapFactory(binding.getBinaryMessenger(), new LifecycleProvider() { - @Nullable - @Override - public Lifecycle getLifecycle() { - return lifecycle; - } - })); + .getPlatformViewRegistry() + .registerViewFactory( + "plugins.flutter.io/mapbox_gl", + new MapboxMapFactory( + binding.getBinaryMessenger(), + new LifecycleProvider() { + @Nullable + @Override + public Lifecycle getLifecycle() { + return lifecycle; + } + })); } @Override @@ -95,34 +97,32 @@ public static void registerWith(Registrar registrar) { } if (activity instanceof LifecycleOwner) { registrar - .platformViewRegistry() - .registerViewFactory( - VIEW_TYPE, - new MapboxMapFactory( - registrar.messenger(), - new LifecycleProvider() { - @Override - public Lifecycle getLifecycle() { - return ((LifecycleOwner) activity).getLifecycle(); - } - })); + .platformViewRegistry() + .registerViewFactory( + VIEW_TYPE, + new MapboxMapFactory( + registrar.messenger(), + new LifecycleProvider() { + @Override + public Lifecycle getLifecycle() { + return ((LifecycleOwner) activity).getLifecycle(); + } + })); } else { registrar - .platformViewRegistry() - .registerViewFactory( - VIEW_TYPE, - new MapboxMapFactory(registrar.messenger(), new ProxyLifecycleProvider(activity))); + .platformViewRegistry() + .registerViewFactory( + VIEW_TYPE, + new MapboxMapFactory(registrar.messenger(), new ProxyLifecycleProvider(activity))); } - MethodChannel methodChannel = new MethodChannel( - registrar.messenger(), - "plugins.flutter.io/mapbox_gl" - ); + MethodChannel methodChannel = + new MethodChannel(registrar.messenger(), "plugins.flutter.io/mapbox_gl"); methodChannel.setMethodCallHandler(new GlobalMethodHandler(registrar)); } private static final class ProxyLifecycleProvider - implements Application.ActivityLifecycleCallbacks, LifecycleOwner, LifecycleProvider { + implements Application.ActivityLifecycleCallbacks, LifecycleOwner, LifecycleProvider { private final LifecycleRegistry lifecycle = new LifecycleRegistry(this); private final int registrarActivityHashCode; @@ -207,9 +207,9 @@ public static class FlutterLifecycleAdapter { */ @NonNull public static Lifecycle getActivityLifecycle( - @NonNull ActivityPluginBinding activityPluginBinding) { + @NonNull ActivityPluginBinding activityPluginBinding) { HiddenLifecycleReference reference = - (HiddenLifecycleReference) activityPluginBinding.getLifecycle(); + (HiddenLifecycleReference) activityPluginBinding.getLifecycle(); return reference.getLifecycle(); } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/OfflineChannelHandlerImpl.java b/android/src/main/java/com/mapbox/mapboxgl/OfflineChannelHandlerImpl.java index 322376c3a..64164f792 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/OfflineChannelHandlerImpl.java +++ b/android/src/main/java/com/mapbox/mapboxgl/OfflineChannelHandlerImpl.java @@ -1,58 +1,55 @@ package com.mapbox.mapboxgl; import androidx.annotation.Nullable; - import com.google.gson.Gson; - -import java.util.HashMap; -import java.util.Map; - import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.EventChannel; +import java.util.HashMap; +import java.util.Map; public class OfflineChannelHandlerImpl implements EventChannel.StreamHandler { - private EventChannel.EventSink sink; - private Gson gson = new Gson(); - - OfflineChannelHandlerImpl(BinaryMessenger messenger, String channelName) { - EventChannel eventChannel = new EventChannel(messenger, channelName); - eventChannel.setStreamHandler(this); - } - - @Override - public void onListen(Object arguments, EventChannel.EventSink events) { - sink = events; - } - - @Override - public void onCancel(Object arguments) { - sink = null; - } - - void onError(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - if (sink == null) return; - sink.error(errorCode, errorMessage, errorDetails); - } - - void onSuccess() { - if (sink == null) return; - Map body = new HashMap<>(); - body.put("status", "success"); - sink.success(gson.toJson(body)); - } - - void onStart() { - if (sink == null) return; - Map body = new HashMap<>(); - body.put("status", "start"); - sink.success(gson.toJson(body)); - } - - void onProgress(double progress) { - if (sink == null) return; - Map body = new HashMap<>(); - body.put("status", "progress"); - body.put("progress", progress); - sink.success(gson.toJson(body)); - } + private EventChannel.EventSink sink; + private Gson gson = new Gson(); + + OfflineChannelHandlerImpl(BinaryMessenger messenger, String channelName) { + EventChannel eventChannel = new EventChannel(messenger, channelName); + eventChannel.setStreamHandler(this); + } + + @Override + public void onListen(Object arguments, EventChannel.EventSink events) { + sink = events; + } + + @Override + public void onCancel(Object arguments) { + sink = null; + } + + void onError(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + if (sink == null) return; + sink.error(errorCode, errorMessage, errorDetails); + } + + void onSuccess() { + if (sink == null) return; + Map body = new HashMap<>(); + body.put("status", "success"); + sink.success(gson.toJson(body)); + } + + void onStart() { + if (sink == null) return; + Map body = new HashMap<>(); + body.put("status", "start"); + sink.success(gson.toJson(body)); + } + + void onProgress(double progress) { + if (sink == null) return; + Map body = new HashMap<>(); + body.put("status", "progress"); + body.put("progress", progress); + sink.success(gson.toJson(body)); + } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/OfflineManagerUtils.java b/android/src/main/java/com/mapbox/mapboxgl/OfflineManagerUtils.java index e451e7022..d82de30f1 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/OfflineManagerUtils.java +++ b/android/src/main/java/com/mapbox/mapboxgl/OfflineManagerUtils.java @@ -2,293 +2,321 @@ import android.content.Context; import android.util.Log; - import com.google.gson.Gson; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.mapboxsdk.offline.OfflineRegion; import com.mapbox.mapboxsdk.offline.OfflineRegionDefinition; -import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineRegionError; import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; - -import java.util.Arrays; +import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition; +import io.flutter.plugin.common.MethodChannel; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import io.flutter.plugin.common.MethodChannel; - abstract class OfflineManagerUtils { - private static final String TAG = "OfflineManagerUtils"; - - static void mergeRegions(MethodChannel.Result result, Context context, String path) { - OfflineManager.getInstance(context).mergeOfflineRegions(path, new OfflineManager.MergeOfflineRegionsCallback() { - public void onMerge(OfflineRegion[] offlineRegions) { + private static final String TAG = "OfflineManagerUtils"; + + static void mergeRegions(MethodChannel.Result result, Context context, String path) { + OfflineManager.getInstance(context) + .mergeOfflineRegions( + path, + new OfflineManager.MergeOfflineRegionsCallback() { + public void onMerge(OfflineRegion[] offlineRegions) { if (result == null) return; List> regionsArgs = new ArrayList<>(); for (OfflineRegion offlineRegion : offlineRegions) { - regionsArgs.add(offlineRegionToMap(offlineRegion)); + regionsArgs.add(offlineRegionToMap(offlineRegion)); } String json = new Gson().toJson(regionsArgs); result.success(json); - } + } - public void onError(String error) { + public void onError(String error) { if (result == null) return; result.error("mergeOfflineRegions Error", error, null); - } - }); - } - - static void setOfflineTileCountLimit(MethodChannel.Result result, Context context, long limit){ - OfflineManager.getInstance(context).setOfflineMapboxTileCountLimit(limit); - result.success(null); + } + }); + } + + static void setOfflineTileCountLimit(MethodChannel.Result result, Context context, long limit) { + OfflineManager.getInstance(context).setOfflineMapboxTileCountLimit(limit); + result.success(null); + } + + static void downloadRegion( + MethodChannel.Result result, + Context context, + Map definitionMap, + Map metadataMap, + OfflineChannelHandlerImpl channelHandler) { + float pixelDensity = context.getResources().getDisplayMetrics().density; + OfflineRegionDefinition definition = mapToRegionDefinition(definitionMap, pixelDensity); + String metadata = "{}"; + if (metadataMap != null) { + metadata = new Gson().toJson(metadataMap); } - - static void downloadRegion( - MethodChannel.Result result, - Context context, - Map definitionMap, - Map metadataMap, - OfflineChannelHandlerImpl channelHandler - ) { - float pixelDensity = context.getResources().getDisplayMetrics().density; - OfflineRegionDefinition definition = mapToRegionDefinition(definitionMap, pixelDensity); - String metadata = "{}"; - if (metadataMap != null) { - metadata = new Gson().toJson(metadataMap); - } - AtomicBoolean isComplete = new AtomicBoolean(false); - //Download region - OfflineManager.getInstance(context).createOfflineRegion(definition, metadata.getBytes(), new OfflineManager.CreateOfflineRegionCallback() { - private OfflineRegion _offlineRegion; - - @Override - public void onCreate(OfflineRegion offlineRegion) { + AtomicBoolean isComplete = new AtomicBoolean(false); + // Download region + OfflineManager.getInstance(context) + .createOfflineRegion( + definition, + metadata.getBytes(), + new OfflineManager.CreateOfflineRegionCallback() { + private OfflineRegion _offlineRegion; + + @Override + public void onCreate(OfflineRegion offlineRegion) { Map regionData = offlineRegionToMap(offlineRegion); result.success(new Gson().toJson(regionData)); _offlineRegion = offlineRegion; - //Start downloading region + // Start downloading region _offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE); channelHandler.onStart(); - //Observe downloading state - OfflineRegion.OfflineRegionObserver observer = new OfflineRegion.OfflineRegionObserver() { - @Override - public void onStatusChanged(OfflineRegionStatus status) { - //Calculate progress of downloading - double progress = calculateDownloadingProgress(status.getRequiredResourceCount(), status.getCompletedResourceCount()); - //Check if downloading is complete + // Observe downloading state + OfflineRegion.OfflineRegionObserver observer = + new OfflineRegion.OfflineRegionObserver() { + @Override + public void onStatusChanged(OfflineRegionStatus status) { + // Calculate progress of downloading + double progress = + calculateDownloadingProgress( + status.getRequiredResourceCount(), + status.getCompletedResourceCount()); + // Check if downloading is complete if (status.isComplete()) { - Log.i(TAG, "Region downloaded successfully."); - //Reset downloading state - _offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE); - //This can be called multiple times, and result can be called only once, so there is need to prevent it - if (isComplete.get()) return; - isComplete.set(true); - channelHandler.onSuccess(); + Log.i(TAG, "Region downloaded successfully."); + // Reset downloading state + _offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE); + // This can be called multiple times, and result can be called only once, + // so there is need to prevent it + if (isComplete.get()) return; + isComplete.set(true); + channelHandler.onSuccess(); } else { - Log.i(TAG, "Region download progress = " + progress); - channelHandler.onProgress(progress); + Log.i(TAG, "Region download progress = " + progress); + channelHandler.onProgress(progress); } - } + } - @Override - public void onError(OfflineRegionError error) { + @Override + public void onError(OfflineRegionError error) { Log.e(TAG, "onError reason: " + error.getReason()); Log.e(TAG, "onError message: " + error.getMessage()); - //Reset downloading state + // Reset downloading state _offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE); isComplete.set(true); - channelHandler.onError("Downloading error", error.getMessage(), error.getReason()); - } + channelHandler.onError( + "Downloading error", error.getMessage(), error.getReason()); + } - @Override - public void mapboxTileCountLimitExceeded(long limit) { + @Override + public void mapboxTileCountLimitExceeded(long limit) { Log.e(TAG, "Mapbox tile count limit exceeded: " + limit); - //Reset downloading state + // Reset downloading state _offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE); isComplete.set(true); - channelHandler.onError("mapboxTileCountLimitExceeded", "Mapbox tile count limit exceeded: " + limit, null); - //Mapbox even after crash and not downloading fully region still keeps part of it in database, so we have to remove it + channelHandler.onError( + "mapboxTileCountLimitExceeded", + "Mapbox tile count limit exceeded: " + limit, + null); + // Mapbox even after crash and not downloading fully region still keeps part + // of it in database, so we have to remove it deleteRegion(null, context, _offlineRegion.getID()); - } - }; + } + }; _offlineRegion.setObserver(observer); - } - - /** - * This will be call if given region definition is invalid - * @param error - **/ - @Override - public void onError(String error) { + } + + /** + * This will be call if given region definition is invalid + * + * @param error + */ + @Override + public void onError(String error) { Log.e(TAG, "Error: " + error); - //Reset downloading state + // Reset downloading state _offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE); channelHandler.onError("mapboxInvalidRegionDefinition", error, null); result.error("mapboxInvalidRegionDefinition", error, null); - } - }); - } - - static void regionsList(MethodChannel.Result result, Context context) { - OfflineManager.getInstance(context).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() { - @Override - public void onList(OfflineRegion[] offlineRegions) { + } + }); + } + + static void regionsList(MethodChannel.Result result, Context context) { + OfflineManager.getInstance(context) + .listOfflineRegions( + new OfflineManager.ListOfflineRegionsCallback() { + @Override + public void onList(OfflineRegion[] offlineRegions) { List> regionsArgs = new ArrayList<>(); for (OfflineRegion offlineRegion : offlineRegions) { - regionsArgs.add(offlineRegionToMap(offlineRegion)); + regionsArgs.add(offlineRegionToMap(offlineRegion)); } result.success(new Gson().toJson(regionsArgs)); - } + } - @Override - public void onError(String error) { + @Override + public void onError(String error) { result.error("RegionListError", error, null); - } - }); - } - - static void updateRegionMetadata(MethodChannel.Result result, Context context, long id, Map metadataMap) { - OfflineManager.getInstance(context).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() { - @Override - public void onList(OfflineRegion[] offlineRegions) { + } + }); + } + + static void updateRegionMetadata( + MethodChannel.Result result, Context context, long id, Map metadataMap) { + OfflineManager.getInstance(context) + .listOfflineRegions( + new OfflineManager.ListOfflineRegionsCallback() { + @Override + public void onList(OfflineRegion[] offlineRegions) { for (OfflineRegion offlineRegion : offlineRegions) { - if (offlineRegion.getID() != id) continue; - - String metadata = "{}"; - if (metadataMap != null) { - metadata = new Gson().toJson(metadataMap); - } - offlineRegion.updateMetadata(metadata.getBytes(), new OfflineRegion.OfflineRegionUpdateMetadataCallback() { + if (offlineRegion.getID() != id) continue; + + String metadata = "{}"; + if (metadataMap != null) { + metadata = new Gson().toJson(metadataMap); + } + offlineRegion.updateMetadata( + metadata.getBytes(), + new OfflineRegion.OfflineRegionUpdateMetadataCallback() { @Override public void onUpdate(byte[] metadataBytes) { - Map regionData = offlineRegionToMap(offlineRegion); - regionData.put("metadata", metadataBytesToMap(metadataBytes)); + Map regionData = offlineRegionToMap(offlineRegion); + regionData.put("metadata", metadataBytesToMap(metadataBytes)); - if (result == null) return; - result.success(new Gson().toJson(regionData)); + if (result == null) return; + result.success(new Gson().toJson(regionData)); } @Override public void onError(String error) { - if (result == null) return; - result.error("UpdateMetadataError", error, null); + if (result == null) return; + result.error("UpdateMetadataError", error, null); } - }); - return; + }); + return; } if (result == null) return; - result.error("UpdateMetadataError", "There is no region with given id to update.", null); - } + result.error( + "UpdateMetadataError", "There is no region with given id to update.", null); + } - @Override - public void onError(String error) { + @Override + public void onError(String error) { if (result == null) return; result.error("RegionListError", error, null); - } - }); - } - - static void deleteRegion(MethodChannel.Result result, Context context, long id) { - OfflineManager.getInstance(context).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() { - @Override - public void onList(OfflineRegion[] offlineRegions) { + } + }); + } + + static void deleteRegion(MethodChannel.Result result, Context context, long id) { + OfflineManager.getInstance(context) + .listOfflineRegions( + new OfflineManager.ListOfflineRegionsCallback() { + @Override + public void onList(OfflineRegion[] offlineRegions) { for (OfflineRegion offlineRegion : offlineRegions) { - if (offlineRegion.getID() != id) continue; + if (offlineRegion.getID() != id) continue; - offlineRegion.delete(new OfflineRegion.OfflineRegionDeleteCallback() { + offlineRegion.delete( + new OfflineRegion.OfflineRegionDeleteCallback() { @Override public void onDelete() { - if (result == null) return; - result.success(null); + if (result == null) return; + result.success(null); } @Override public void onError(String error) { - if (result == null) return; - result.error("DeleteRegionError", error, null); + if (result == null) return; + result.error("DeleteRegionError", error, null); } - }); - return; + }); + return; } if (result == null) return; - result.error("DeleteRegionError", "There is no region with given id to delete.", null); - } + result.error( + "DeleteRegionError", "There is no region with given id to delete.", null); + } - @Override - public void onError(String error) { + @Override + public void onError(String error) { if (result == null) return; result.error("RegionListError", error, null); - } - }); + } + }); + } + + private static double calculateDownloadingProgress( + long requiredResourceCount, long completedResourceCount) { + return requiredResourceCount > 0 + ? (100.0 * completedResourceCount / requiredResourceCount) + : 0.0; + } + + private static OfflineRegionDefinition mapToRegionDefinition( + Map map, float pixelDensity) { + for (Map.Entry entry : map.entrySet()) { + Log.d(TAG, entry.getKey()); + Log.d(TAG, entry.getValue().toString()); } - - private static double calculateDownloadingProgress(long requiredResourceCount, long completedResourceCount) { - return requiredResourceCount > 0 - ? (100.0 * completedResourceCount / requiredResourceCount) : - 0.0; - } - - private static OfflineRegionDefinition mapToRegionDefinition(Map map, float pixelDensity) { - for (Map.Entry entry : map.entrySet()) { - Log.d(TAG, entry.getKey()); - Log.d(TAG, entry.getValue().toString()); - } - // Create a bounding box for the offline region - return new OfflineTilePyramidRegionDefinition( - (String) map.get("mapStyleUrl"), - listToBounds((List>) map.get("bounds")), - ((Number) map.get("minZoom")).doubleValue(), - ((Number) map.get("maxZoom")).doubleValue(), - pixelDensity, - (Boolean) map.get("includeIdeographs") - ); - } - - private static LatLngBounds listToBounds(List> bounds) { - return new LatLngBounds.Builder() - .include(new LatLng(bounds.get(1).get(0), bounds.get(1).get(1))) //Northeast - .include(new LatLng(bounds.get(0).get(0), bounds.get(0).get(1))) //Southwest - .build(); - } - - private static Map offlineRegionToMap(OfflineRegion region) { - Map result = new HashMap(); - result.put("id", region.getID()); - result.put("definition", offlineRegionDefinitionToMap(region.getDefinition())); - result.put("metadata", metadataBytesToMap(region.getMetadata())); - return result; - } - - private static Map offlineRegionDefinitionToMap(OfflineRegionDefinition definition) { - Map result = new HashMap(); - result.put("mapStyleUrl", definition.getStyleURL()); - result.put("bounds", boundsToList(definition.getBounds())); - result.put("minZoom", definition.getMinZoom()); - result.put("maxZoom", definition.getMaxZoom()); - result.put("includeIdeographs", definition.getIncludeIdeographs()); - return result; - } - - private static List> boundsToList(LatLngBounds bounds) { - List> boundsList = new ArrayList<>(); - List northeast = Arrays.asList(bounds.getLatNorth(), bounds.getLonEast()); - List southwest = Arrays.asList(bounds.getLatSouth(), bounds.getLonWest()); - boundsList.add(southwest); - boundsList.add(northeast); - return boundsList; - } - - private static Map metadataBytesToMap(byte[] metadataBytes) { - if (metadataBytes != null) { - return new Gson().fromJson(new String(metadataBytes), HashMap.class); - } - return new HashMap(); + // Create a bounding box for the offline region + return new OfflineTilePyramidRegionDefinition( + (String) map.get("mapStyleUrl"), + listToBounds((List>) map.get("bounds")), + ((Number) map.get("minZoom")).doubleValue(), + ((Number) map.get("maxZoom")).doubleValue(), + pixelDensity, + (Boolean) map.get("includeIdeographs")); + } + + private static LatLngBounds listToBounds(List> bounds) { + return new LatLngBounds.Builder() + .include(new LatLng(bounds.get(1).get(0), bounds.get(1).get(1))) // Northeast + .include(new LatLng(bounds.get(0).get(0), bounds.get(0).get(1))) // Southwest + .build(); + } + + private static Map offlineRegionToMap(OfflineRegion region) { + Map result = new HashMap(); + result.put("id", region.getID()); + result.put("definition", offlineRegionDefinitionToMap(region.getDefinition())); + result.put("metadata", metadataBytesToMap(region.getMetadata())); + return result; + } + + private static Map offlineRegionDefinitionToMap( + OfflineRegionDefinition definition) { + Map result = new HashMap(); + result.put("mapStyleUrl", definition.getStyleURL()); + result.put("bounds", boundsToList(definition.getBounds())); + result.put("minZoom", definition.getMinZoom()); + result.put("maxZoom", definition.getMaxZoom()); + result.put("includeIdeographs", definition.getIncludeIdeographs()); + return result; + } + + private static List> boundsToList(LatLngBounds bounds) { + List> boundsList = new ArrayList<>(); + List northeast = Arrays.asList(bounds.getLatNorth(), bounds.getLonEast()); + List southwest = Arrays.asList(bounds.getLatSouth(), bounds.getLonWest()); + boundsList.add(southwest); + boundsList.add(northeast); + return boundsList; + } + + private static Map metadataBytesToMap(byte[] metadataBytes) { + if (metadataBytes != null) { + return new Gson().fromJson(new String(metadataBytes), HashMap.class); } + return new HashMap(); + } } diff --git a/android/src/main/java/com/mapbox/mapboxgl/SourcePropertyConverter.java b/android/src/main/java/com/mapbox/mapboxgl/SourcePropertyConverter.java index faf7f3adc..308ffab01 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/SourcePropertyConverter.java +++ b/android/src/main/java/com/mapbox/mapboxgl/SourcePropertyConverter.java @@ -1,227 +1,220 @@ package com.mapbox.mapboxgl; -import java.net.URI; -import java.net.URISyntaxException; - -import com.google.gson.Gson; - import android.net.Uri; -import android.util.Log; - +import com.google.gson.Gson; import com.mapbox.geojson.FeatureCollection; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.geometry.LatLngQuad; import com.mapbox.mapboxsdk.maps.Style; -import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; -import com.mapbox.mapboxsdk.style.sources.RasterSource; -import com.mapbox.mapboxsdk.style.sources.RasterDemSource; import com.mapbox.mapboxsdk.style.sources.ImageSource; -import com.mapbox.mapboxsdk.style.sources.VectorSource; +import com.mapbox.mapboxsdk.style.sources.RasterDemSource; +import com.mapbox.mapboxsdk.style.sources.RasterSource; +import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.style.sources.TileSet; -import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions; - -import java.util.Map; -import java.util.List; +import com.mapbox.mapboxsdk.style.sources.VectorSource; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.List; +import java.util.Map; +class SourcePropertyConverter { + private static final String TAG = "SourcePropertyConverter"; + static TileSet buildTileset(Map data) { + final Object tiles = data.get("tiles"); -class SourcePropertyConverter{ - private final static String TAG = "SourcePropertyConverter"; - - static TileSet buildTileset(Map data) { - final Object tiles = data.get("tiles"); - - //options are only valid with tiles - if(tiles == null){ - return null; - } - - final TileSet tileSet = new TileSet("2.1.0", (String[]) Convert.toList(tiles).toArray(new String[0])); - - final Object bounds = data.get("bounds"); - if (bounds != null) { - List boundsFloat = new ArrayList(); - for (Object item : Convert.toList(bounds)) { - boundsFloat.add(Convert.toFloat(item)); - } - tileSet.setBounds(boundsFloat.toArray(new Float[0])); - } - - final Object scheme = data.get("scheme"); - if (scheme != null) { - tileSet.setScheme(Convert.toString(scheme)); - } - - final Object minzoom = data.get("minzoom"); - if (minzoom != null) { - tileSet.setMinZoom(Convert.toFloat(minzoom)); - } + // options are only valid with tiles + if (tiles == null) { + return null; + } - final Object maxzoom = data.get("maxzoom"); - if (maxzoom != null) { - tileSet.setMaxZoom(Convert.toFloat(maxzoom)); - } + final TileSet tileSet = + new TileSet("2.1.0", (String[]) Convert.toList(tiles).toArray(new String[0])); - final Object attribution = data.get("attribution"); - if (attribution != null) { - tileSet.setAttribution(Convert.toString(attribution)); - } - return tileSet; + final Object bounds = data.get("bounds"); + if (bounds != null) { + List boundsFloat = new ArrayList(); + for (Object item : Convert.toList(bounds)) { + boundsFloat.add(Convert.toFloat(item)); + } + tileSet.setBounds(boundsFloat.toArray(new Float[0])); } + final Object scheme = data.get("scheme"); + if (scheme != null) { + tileSet.setScheme(Convert.toString(scheme)); + } - static GeoJsonOptions buildGeojsonOptions(Map data) { - GeoJsonOptions options = new GeoJsonOptions(); - + final Object minzoom = data.get("minzoom"); + if (minzoom != null) { + tileSet.setMinZoom(Convert.toFloat(minzoom)); + } - final Object buffer = data.get("buffer"); - if (buffer != null) { - options = options.withBuffer(Convert.toInt(buffer)); - } + final Object maxzoom = data.get("maxzoom"); + if (maxzoom != null) { + tileSet.setMaxZoom(Convert.toFloat(maxzoom)); + } - final Object cluster = data.get("cluster"); - if (cluster != null) { - options = options.withCluster(Convert.toBoolean(cluster)); - } + final Object attribution = data.get("attribution"); + if (attribution != null) { + tileSet.setAttribution(Convert.toString(attribution)); + } + return tileSet; + } - final Object clusterMaxZoom = data.get("clusterMaxZoom"); - if (clusterMaxZoom != null) { - options = options.withClusterMaxZoom(Convert.toInt(clusterMaxZoom)); - } + static GeoJsonOptions buildGeojsonOptions(Map data) { + GeoJsonOptions options = new GeoJsonOptions(); - final Object clusterRadius = data.get("clusterRadius"); - if (clusterRadius != null) { - options = options.withClusterRadius(Convert.toInt(clusterRadius)); - } + final Object buffer = data.get("buffer"); + if (buffer != null) { + options = options.withBuffer(Convert.toInt(buffer)); + } - final Object lineMetrics = data.get("lineMetrics"); - if (lineMetrics != null) { - options = options.withLineMetrics(Convert.toBoolean(lineMetrics)); - } + final Object cluster = data.get("cluster"); + if (cluster != null) { + options = options.withCluster(Convert.toBoolean(cluster)); + } - final Object maxZoom = data.get("maxZoom"); - if (maxZoom != null) { - options = options.withMaxZoom(Convert.toInt(maxZoom)); - } + final Object clusterMaxZoom = data.get("clusterMaxZoom"); + if (clusterMaxZoom != null) { + options = options.withClusterMaxZoom(Convert.toInt(clusterMaxZoom)); + } - final Object minZoom = data.get("minZoom"); - if (minZoom != null) { - options = options.withMinZoom(Convert.toInt(minZoom)); - } + final Object clusterRadius = data.get("clusterRadius"); + if (clusterRadius != null) { + options = options.withClusterRadius(Convert.toInt(clusterRadius)); + } - final Object tolerance = data.get("tolerance"); - if (tolerance != null) { - options = options.withTolerance(Convert.toFloat(tolerance)); - } - return options; - } - - static GeoJsonSource buildGeojsonSource(String id, Map properties){ - final Object data = properties.get("data"); - final GeoJsonOptions options = buildGeojsonOptions(properties); - if(data != null){ - if(data instanceof String){ - try{ - final URI uri = new URI(Convert.toString(data)); - return new GeoJsonSource(id, uri, options); - }catch (URISyntaxException e){} - }else{ - Gson gson = new Gson(); - String geojson = gson.toJson(data); - final FeatureCollection featureCollection = FeatureCollection.fromJson(geojson); - return new GeoJsonSource(id, featureCollection, options); - } - } - return null; + final Object lineMetrics = data.get("lineMetrics"); + if (lineMetrics != null) { + options = options.withLineMetrics(Convert.toBoolean(lineMetrics)); } - static ImageSource buildImageSource(String id, Map properties){ - final Object url = properties.get("url"); - List coordinates = Convert.toLatLngList(properties.get("coordinates"), true); - final LatLngQuad quad = new LatLngQuad(coordinates.get(0), coordinates.get(1), coordinates.get(2), coordinates.get(3)); - try{ - final URI uri = new URI(Convert.toString(url)); - return new ImageSource(id, quad, uri); - }catch (URISyntaxException e){ - } - return null; - } - - static VectorSource buildVectorSource(String id, Map properties){ - final Object url = properties.get("url"); - if(url != null) - { - final Uri uri = Uri.parse(Convert.toString(url)); - - if(uri != null){ - return new VectorSource(id, uri); - } - return null; - } + final Object maxZoom = data.get("maxZoom"); + if (maxZoom != null) { + options = options.withMaxZoom(Convert.toInt(maxZoom)); + } - final TileSet tileSet = buildTileset(properties); - return tileSet != null ? new VectorSource(id, tileSet) : null; + final Object minZoom = data.get("minZoom"); + if (minZoom != null) { + options = options.withMinZoom(Convert.toInt(minZoom)); } - static RasterSource buildRasterSource(String id, Map properties){ - final Object url = properties.get("url"); - if(url != null) - { - try { - final URI uri = new URI(Convert.toString(url)); - return new RasterSource(id, uri); - } catch (URISyntaxException e){} - } + final Object tolerance = data.get("tolerance"); + if (tolerance != null) { + options = options.withTolerance(Convert.toFloat(tolerance)); + } + return options; + } + + static GeoJsonSource buildGeojsonSource(String id, Map properties) { + final Object data = properties.get("data"); + final GeoJsonOptions options = buildGeojsonOptions(properties); + if (data != null) { + if (data instanceof String) { + try { + final URI uri = new URI(Convert.toString(data)); + return new GeoJsonSource(id, uri, options); + } catch (URISyntaxException e) { + } + } else { + Gson gson = new Gson(); + String geojson = gson.toJson(data); + final FeatureCollection featureCollection = FeatureCollection.fromJson(geojson); + return new GeoJsonSource(id, featureCollection, options); + } + } + return null; + } + + static ImageSource buildImageSource(String id, Map properties) { + final Object url = properties.get("url"); + List coordinates = Convert.toLatLngList(properties.get("coordinates"), true); + final LatLngQuad quad = + new LatLngQuad( + coordinates.get(0), coordinates.get(1), coordinates.get(2), coordinates.get(3)); + try { + final URI uri = new URI(Convert.toString(url)); + return new ImageSource(id, quad, uri); + } catch (URISyntaxException e) { + } + return null; + } + + static VectorSource buildVectorSource(String id, Map properties) { + final Object url = properties.get("url"); + if (url != null) { + final Uri uri = Uri.parse(Convert.toString(url)); + + if (uri != null) { + return new VectorSource(id, uri); + } + return null; + } - final TileSet tileSet = buildTileset(properties); - return tileSet != null ? new RasterSource(id, tileSet) : null; + final TileSet tileSet = buildTileset(properties); + return tileSet != null ? new VectorSource(id, tileSet) : null; + } + + static RasterSource buildRasterSource(String id, Map properties) { + final Object url = properties.get("url"); + if (url != null) { + try { + final URI uri = new URI(Convert.toString(url)); + return new RasterSource(id, uri); + } catch (URISyntaxException e) { + } } - static RasterDemSource buildRasterDemSource(String id, Map properties){ - final Object url = properties.get("url"); - if(url != null) - { - try { - final URI uri = new URI(Convert.toString(url)); - return new RasterDemSource(id, uri); - } catch (URISyntaxException e){} - } + final TileSet tileSet = buildTileset(properties); + return tileSet != null ? new RasterSource(id, tileSet) : null; + } + + static RasterDemSource buildRasterDemSource(String id, Map properties) { + final Object url = properties.get("url"); + if (url != null) { + try { + final URI uri = new URI(Convert.toString(url)); + return new RasterDemSource(id, uri); + } catch (URISyntaxException e) { + } + } - final TileSet tileSet = buildTileset(properties); - return tileSet != null ? new RasterDemSource(id, tileSet) : null; - } - - static void addSource(String id, Map properties, Style style) { - final Object type = properties.get("type"); - Source source = null; - - if(type != null){ - switch (Convert.toString(type)) { - case "vector": - source = buildVectorSource(id, properties); - break; - case "raster": - source = buildRasterSource(id, properties); - break; - case "raster-dem": - source = buildRasterDemSource(id, properties); - break; - case "image": - source = buildImageSource(id, properties); - break; - case "geojson": - source = buildGeojsonSource(id, properties); - break; - default: - // unsupported source type - } - } + final TileSet tileSet = buildTileset(properties); + return tileSet != null ? new RasterDemSource(id, tileSet) : null; + } + + static void addSource(String id, Map properties, Style style) { + final Object type = properties.get("type"); + Source source = null; + + if (type != null) { + switch (Convert.toString(type)) { + case "vector": + source = buildVectorSource(id, properties); + break; + case "raster": + source = buildRasterSource(id, properties); + break; + case "raster-dem": + source = buildRasterDemSource(id, properties); + break; + case "image": + source = buildImageSource(id, properties); + break; + case "geojson": + source = buildGeojsonSource(id, properties); + break; + default: + // unsupported source type + } + } - if (source != null) { - style.addSource(source); - } + if (source != null) { + style.addSource(source); } -} \ No newline at end of file + } +} diff --git a/example/android/app/src/main/java/com/mapbox/mapboxglexample/MainActivity.java b/example/android/app/src/main/java/com/mapbox/mapboxglexample/MainActivity.java index 4e2c0d6ec..39570e461 100644 --- a/example/android/app/src/main/java/com/mapbox/mapboxglexample/MainActivity.java +++ b/example/android/app/src/main/java/com/mapbox/mapboxglexample/MainActivity.java @@ -2,6 +2,4 @@ import io.flutter.embedding.android.FlutterActivity; -public class MainActivity extends FlutterActivity { - -} +public class MainActivity extends FlutterActivity {}