init project
This commit is contained in:
3
android/src/main/AndroidManifest.xml
Normal file
3
android/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.amap.flutter.amap_map">
|
||||
</manifest>
|
@ -0,0 +1,117 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
||||
/**
|
||||
* AmapFlutterMapPlugin
|
||||
*/
|
||||
public class AMapFlutterMapPlugin implements
|
||||
FlutterPlugin,
|
||||
ActivityAware {
|
||||
private static final String CLASS_NAME = "AMapFlutterMapPlugin";
|
||||
private FlutterPluginBinding pluginBinding;
|
||||
private Lifecycle lifecycle;
|
||||
|
||||
private static final String VIEW_TYPE = "com.amap.flutter.map";
|
||||
|
||||
public static void registerWith(PluginRegistry.Registrar registrar) {
|
||||
LogUtil.i(CLASS_NAME, "registerWith=====>");
|
||||
|
||||
final Activity activity = registrar.activity();
|
||||
if (activity == null) {
|
||||
LogUtil.w(CLASS_NAME, "activity is null!!!");
|
||||
return;
|
||||
}
|
||||
if (activity instanceof LifecycleOwner) {
|
||||
registrar
|
||||
.platformViewRegistry()
|
||||
.registerViewFactory(
|
||||
VIEW_TYPE,
|
||||
new AMapPlatformViewFactory(
|
||||
registrar.messenger(),
|
||||
new LifecycleProvider() {
|
||||
@Override
|
||||
public Lifecycle getLifecycle() {
|
||||
return ((LifecycleOwner) activity).getLifecycle();
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
registrar
|
||||
.platformViewRegistry()
|
||||
.registerViewFactory(
|
||||
VIEW_TYPE,
|
||||
new AMapPlatformViewFactory(registrar.messenger(), new ProxyLifecycleProvider(activity)));
|
||||
}
|
||||
}
|
||||
|
||||
public AMapFlutterMapPlugin() {
|
||||
}
|
||||
|
||||
// FlutterPlugin
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
||||
LogUtil.i(CLASS_NAME, "onAttachedToEngine==>");
|
||||
pluginBinding = binding;
|
||||
binding
|
||||
.getPlatformViewRegistry()
|
||||
.registerViewFactory(
|
||||
VIEW_TYPE,
|
||||
new AMapPlatformViewFactory(
|
||||
binding.getBinaryMessenger(),
|
||||
new LifecycleProvider() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Lifecycle getLifecycle() {
|
||||
return lifecycle;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
LogUtil.i(CLASS_NAME, "onDetachedFromEngine==>");
|
||||
pluginBinding = null;
|
||||
}
|
||||
|
||||
|
||||
// ActivityAware
|
||||
|
||||
@Override
|
||||
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
|
||||
LogUtil.i(CLASS_NAME, "onAttachedToActivity==>");
|
||||
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivity() {
|
||||
LogUtil.i(CLASS_NAME, "onDetachedFromActivity==>");
|
||||
lifecycle = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
|
||||
LogUtil.i(CLASS_NAME, "onReattachedToActivityForConfigChanges==>");
|
||||
onAttachedToActivity(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivityForConfigChanges() {
|
||||
LogUtil.i(CLASS_NAME, "onDetachedFromActivityForConfigChanges==>");
|
||||
this.onDetachedFromActivity();
|
||||
}
|
||||
}
|
@ -0,0 +1,215 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
|
||||
import com.amap.api.maps.AMapOptions;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
import com.amap.api.maps.model.LatLngBounds;
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
import com.amap.flutter.map.core.AMapOptionsSink;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/10/29 10:13 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class AMapOptionsBuilder implements AMapOptionsSink {
|
||||
private static final String CLASS_NAME = "AMapOptionsBuilder";
|
||||
private final AMapOptions options = new AMapOptions();
|
||||
private CustomMapStyleOptions customMapStyleOptions;
|
||||
private MyLocationStyle myLocationStyle;
|
||||
|
||||
private float minZoomLevel = 3;
|
||||
private float maxZoomLevel = 20;
|
||||
private LatLngBounds latLngBounds;
|
||||
private boolean trafficEnabled = true;
|
||||
private boolean touchPoiEnabled = true;
|
||||
private boolean buildingsEnabled = true;
|
||||
private boolean labelsEnabled = true;
|
||||
|
||||
private float anchorX = 2.0F;
|
||||
private float anchorY = 2.0F;
|
||||
|
||||
private Object initialMarkers;
|
||||
|
||||
private Object initialPolylines;
|
||||
|
||||
private Object initialPolygons;
|
||||
|
||||
AMapPlatformView build(int id,
|
||||
Context context,
|
||||
BinaryMessenger binaryMessenger,
|
||||
LifecycleProvider lifecycleProvider) {
|
||||
try {
|
||||
//iOS端没有放大缩小UI, Android端强制隐藏
|
||||
options.zoomControlsEnabled(false);
|
||||
final AMapPlatformView aMapPlatformView = new AMapPlatformView(id, context, binaryMessenger, lifecycleProvider, options);
|
||||
|
||||
|
||||
if (null != customMapStyleOptions) {
|
||||
aMapPlatformView.getMapController().setCustomMapStyleOptions(customMapStyleOptions);
|
||||
}
|
||||
|
||||
if (null != myLocationStyle) {
|
||||
aMapPlatformView.getMapController().setMyLocationStyle(myLocationStyle);
|
||||
}
|
||||
if (anchorX >= 0
|
||||
&& anchorX <= 1.0
|
||||
&& anchorY <= 1.0
|
||||
&& anchorY >= 0) {
|
||||
|
||||
aMapPlatformView.getMapController().setScreenAnchor( anchorX, anchorY);
|
||||
}
|
||||
|
||||
aMapPlatformView.getMapController().setMinZoomLevel(minZoomLevel);
|
||||
aMapPlatformView.getMapController().setMaxZoomLevel(maxZoomLevel);
|
||||
|
||||
if (null != latLngBounds) {
|
||||
aMapPlatformView.getMapController().setLatLngBounds(latLngBounds);
|
||||
}
|
||||
|
||||
aMapPlatformView.getMapController().setTrafficEnabled(trafficEnabled);
|
||||
aMapPlatformView.getMapController().setTouchPoiEnabled(touchPoiEnabled);
|
||||
aMapPlatformView.getMapController().setBuildingsEnabled(buildingsEnabled);
|
||||
aMapPlatformView.getMapController().setLabelsEnabled(labelsEnabled);
|
||||
|
||||
|
||||
if (null != initialMarkers) {
|
||||
List<Object> markerList = (List<Object>) initialMarkers;
|
||||
aMapPlatformView.getMarkersController().addByList(markerList);
|
||||
}
|
||||
|
||||
if (null != initialPolylines) {
|
||||
List<Object> markerList = (List<Object>) initialPolylines;
|
||||
aMapPlatformView.getPolylinesController().addByList(markerList);
|
||||
}
|
||||
|
||||
if (null != initialPolygons) {
|
||||
List<Object> polygonList = (List<Object>) initialPolygons;
|
||||
aMapPlatformView.getPolygonsController().addByList(polygonList);
|
||||
}
|
||||
return aMapPlatformView;
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "build", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCamera(CameraPosition camera) {
|
||||
options.camera(camera);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMapType(int mapType) {
|
||||
options.mapType(mapType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomMapStyleOptions(CustomMapStyleOptions customMapStyleOptions) {
|
||||
this.customMapStyleOptions = customMapStyleOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMyLocationStyle(MyLocationStyle myLocationStyle) {
|
||||
this.myLocationStyle = myLocationStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScreenAnchor(float x, float y) {
|
||||
anchorX = x;
|
||||
anchorY = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinZoomLevel(float minZoomLevel) {
|
||||
this.minZoomLevel = minZoomLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxZoomLevel(float maxZoomLevel) {
|
||||
this.maxZoomLevel = maxZoomLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLatLngBounds(LatLngBounds latLngBounds) {
|
||||
this.latLngBounds = latLngBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrafficEnabled(boolean trafficEnabled) {
|
||||
this.trafficEnabled = trafficEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTouchPoiEnabled(boolean touchPoiEnabled) {
|
||||
this.touchPoiEnabled = touchPoiEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBuildingsEnabled(boolean buildingsEnabled) {
|
||||
this.buildingsEnabled = buildingsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabelsEnabled(boolean labelsEnabled) {
|
||||
this.labelsEnabled = labelsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompassEnabled(boolean compassEnabled) {
|
||||
options.compassEnabled(compassEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) {
|
||||
options.zoomGesturesEnabled(zoomGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) {
|
||||
options.scrollGesturesEnabled(scrollGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) {
|
||||
options.rotateGesturesEnabled(rotateGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) {
|
||||
options.tiltGesturesEnabled(tiltGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleEnabled(boolean scaleEnabled) {
|
||||
options.scaleControlsEnabled(scaleEnabled);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setInitialMarkers(Object markersObject) {
|
||||
this.initialMarkers = markersObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitialPolylines(Object polylinesObject) {
|
||||
this.initialPolylines = polylinesObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitialPolygons(Object polygonsObject) {
|
||||
this.initialPolygons = polygonsObject;
|
||||
}
|
||||
|
||||
|
||||
}
|
264
android/src/main/java/com/amap/flutter/map/AMapPlatformView.java
Normal file
264
android/src/main/java/com/amap/flutter/map/AMapPlatformView.java
Normal file
@ -0,0 +1,264 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.AMapOptions;
|
||||
import com.amap.api.maps.TextureMapView;
|
||||
import com.amap.flutter.map.core.MapController;
|
||||
import com.amap.flutter.map.overlays.marker.MarkersController;
|
||||
import com.amap.flutter.map.overlays.polygon.PolygonsController;
|
||||
import com.amap.flutter.map.overlays.polyline.PolylinesController;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.platform.PlatformView;
|
||||
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/10/27 5:49 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class AMapPlatformView
|
||||
implements
|
||||
DefaultLifecycleObserver,
|
||||
ActivityPluginBinding.OnSaveInstanceStateListener,
|
||||
MethodChannel.MethodCallHandler,
|
||||
PlatformView {
|
||||
private static final String CLASS_NAME = "AMapPlatformView";
|
||||
private final MethodChannel methodChannel;
|
||||
|
||||
private MapController mapController;
|
||||
private MarkersController markersController;
|
||||
private PolylinesController polylinesController;
|
||||
private PolygonsController polygonsController;
|
||||
|
||||
private TextureMapView mapView;
|
||||
|
||||
private boolean disposed = false;
|
||||
|
||||
private final Map<String, MyMethodCallHandler> myMethodCallHandlerMap;
|
||||
|
||||
AMapPlatformView(int id,
|
||||
Context context,
|
||||
BinaryMessenger binaryMessenger,
|
||||
LifecycleProvider lifecycleProvider,
|
||||
AMapOptions options) {
|
||||
|
||||
methodChannel = new MethodChannel(binaryMessenger, "amap_map_" + id);
|
||||
methodChannel.setMethodCallHandler(this);
|
||||
myMethodCallHandlerMap = new HashMap<String, MyMethodCallHandler>(8);
|
||||
|
||||
try {
|
||||
mapView = new TextureMapView(context, options);
|
||||
AMap amap = mapView.getMap();
|
||||
mapController = new MapController(methodChannel, mapView);
|
||||
markersController = new MarkersController(methodChannel, amap);
|
||||
polylinesController = new PolylinesController(methodChannel, amap);
|
||||
polygonsController = new PolygonsController(methodChannel, amap);
|
||||
initMyMethodCallHandlerMap();
|
||||
lifecycleProvider.getLifecycle().addObserver(this);
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "<init>", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initMyMethodCallHandlerMap() {
|
||||
String[] methodIdArray = mapController.getRegisterMethodIdArray();
|
||||
if (null != methodIdArray && methodIdArray.length > 0) {
|
||||
for (String methodId : methodIdArray) {
|
||||
myMethodCallHandlerMap.put(methodId, mapController);
|
||||
}
|
||||
}
|
||||
|
||||
methodIdArray = markersController.getRegisterMethodIdArray();
|
||||
if (null != methodIdArray && methodIdArray.length > 0) {
|
||||
for (String methodId : methodIdArray) {
|
||||
myMethodCallHandlerMap.put(methodId, markersController);
|
||||
}
|
||||
}
|
||||
|
||||
methodIdArray = polylinesController.getRegisterMethodIdArray();
|
||||
if (null != methodIdArray && methodIdArray.length > 0) {
|
||||
for (String methodId : methodIdArray) {
|
||||
myMethodCallHandlerMap.put(methodId, polylinesController);
|
||||
}
|
||||
}
|
||||
|
||||
methodIdArray = polygonsController.getRegisterMethodIdArray();
|
||||
if (null != methodIdArray && methodIdArray.length > 0) {
|
||||
for (String methodId : methodIdArray) {
|
||||
myMethodCallHandlerMap.put(methodId, polygonsController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public MapController getMapController() {
|
||||
return mapController;
|
||||
}
|
||||
|
||||
public MarkersController getMarkersController() {
|
||||
return markersController;
|
||||
}
|
||||
|
||||
public PolylinesController getPolylinesController() {
|
||||
return polylinesController;
|
||||
}
|
||||
|
||||
public PolygonsController getPolygonsController() {
|
||||
return polygonsController;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
LogUtil.i(CLASS_NAME, "onMethodCall==>" + call.method + ", arguments==> " + call.arguments);
|
||||
String methodId = call.method;
|
||||
if (myMethodCallHandlerMap.containsKey(methodId)) {
|
||||
myMethodCallHandlerMap.get(methodId).doMethodCall(call, result);
|
||||
} else {
|
||||
LogUtil.w(CLASS_NAME, "onMethodCall, the methodId: " + call.method + ", not implemented");
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull LifecycleOwner owner) {
|
||||
LogUtil.i(CLASS_NAME, "onCreate==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
if (null != mapView) {
|
||||
mapView.onCreate(null);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onCreate", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(@NonNull LifecycleOwner owner) {
|
||||
LogUtil.i(CLASS_NAME, "onStart==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(@NonNull LifecycleOwner owner) {
|
||||
LogUtil.i(CLASS_NAME, "onResume==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
if (null != mapView) {
|
||||
mapView.onResume();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onResume", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(@NonNull LifecycleOwner owner) {
|
||||
LogUtil.i(CLASS_NAME, "onPause==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
mapView.onPause();
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onPause", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(@NonNull LifecycleOwner owner) {
|
||||
LogUtil.i(CLASS_NAME, "onStop==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(@NonNull LifecycleOwner owner) {
|
||||
LogUtil.i(CLASS_NAME, "onDestroy==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
destroyMapViewIfNecessary();
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onDestroy", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle bundle) {
|
||||
LogUtil.i(CLASS_NAME, "onDestroy==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
mapView.onSaveInstanceState(bundle);
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onSaveInstanceState", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(@Nullable Bundle bundle) {
|
||||
LogUtil.i(CLASS_NAME, "onDestroy==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
mapView.onCreate(bundle);
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onRestoreInstanceState", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
LogUtil.i(CLASS_NAME, "getView==>");
|
||||
return mapView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
LogUtil.i(CLASS_NAME, "dispose==>");
|
||||
try {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
methodChannel.setMethodCallHandler(null);
|
||||
destroyMapViewIfNecessary();
|
||||
disposed = true;
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "dispose", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyMapViewIfNecessary() {
|
||||
if (mapView == null) {
|
||||
return;
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.StandardMessageCodec;
|
||||
import io.flutter.plugin.platform.PlatformView;
|
||||
import io.flutter.plugin.platform.PlatformViewFactory;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/10/27 4:08 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class AMapPlatformViewFactory extends PlatformViewFactory {
|
||||
private static final String CLASS_NAME = "AMapPlatformViewFactory";
|
||||
private final BinaryMessenger binaryMessenger;
|
||||
private final LifecycleProvider lifecycleProvider;
|
||||
AMapPlatformViewFactory(BinaryMessenger binaryMessenger,
|
||||
LifecycleProvider lifecycleProvider) {
|
||||
super(StandardMessageCodec.INSTANCE);
|
||||
this.binaryMessenger = binaryMessenger;
|
||||
this.lifecycleProvider = lifecycleProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformView create(Context context, int viewId, Object args) {
|
||||
final AMapOptionsBuilder builder = new AMapOptionsBuilder();
|
||||
Map<String, Object> params = null;
|
||||
try {
|
||||
ConvertUtil.density = context.getResources().getDisplayMetrics().density;
|
||||
params = (Map<String, Object>) args;
|
||||
LogUtil.i(CLASS_NAME,"create params==>" + params);
|
||||
if (params.containsKey("privacyStatement")) {
|
||||
ConvertUtil.setPrivacyStatement(context, params.get("privacyStatement"));
|
||||
}
|
||||
|
||||
Object options = ((Map<String, Object>) args).get("options");
|
||||
if(null != options) {
|
||||
ConvertUtil.interpretAMapOptions(options, builder);
|
||||
}
|
||||
|
||||
if (params.containsKey("initialCameraPosition")) {
|
||||
CameraPosition cameraPosition = ConvertUtil.toCameraPosition(params.get("initialCameraPosition"));
|
||||
builder.setCamera(cameraPosition);
|
||||
}
|
||||
|
||||
if (params.containsKey("markersToAdd")) {
|
||||
builder.setInitialMarkers(params.get("markersToAdd"));
|
||||
}
|
||||
if (params.containsKey("polylinesToAdd")) {
|
||||
builder.setInitialPolylines(params.get("polylinesToAdd"));
|
||||
}
|
||||
|
||||
if (params.containsKey("polygonsToAdd")) {
|
||||
builder.setInitialPolygons(params.get("polygonsToAdd"));
|
||||
}
|
||||
|
||||
|
||||
if (params.containsKey("apiKey")) {
|
||||
ConvertUtil.checkApiKey(params.get("apiKey"));
|
||||
}
|
||||
|
||||
if (params.containsKey("debugMode")) {
|
||||
LogUtil.isDebugMode = ConvertUtil.toBoolean(params.get("debugMode"));
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "create", e);
|
||||
}
|
||||
return builder.build(viewId, context, binaryMessenger, lifecycleProvider);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/8 6:17 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public interface LifecycleProvider {
|
||||
Lifecycle getLifecycle();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 9:47 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public interface MyMethodCallHandler {
|
||||
|
||||
public void doMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result);
|
||||
/**
|
||||
* 获取注册的{@link io.flutter.plugin.common.MethodCall#method}
|
||||
* @return
|
||||
*/
|
||||
public abstract String[] getRegisterMethodIdArray();
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package com.amap.flutter.map;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LifecycleRegistry;
|
||||
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
/**
|
||||
* This class provides a {@link LifecycleOwner} for the activity driven by {@link
|
||||
* Application.ActivityLifecycleCallbacks}.
|
||||
*
|
||||
* <p>This is used in the case where a direct Lifecycle/Owner is not available.
|
||||
*/
|
||||
public class ProxyLifecycleProvider
|
||||
implements
|
||||
Application.ActivityLifecycleCallbacks,
|
||||
LifecycleOwner,
|
||||
LifecycleProvider {
|
||||
private static final String CLASS_NAME = "ProxyLifecycleProvider";
|
||||
private final LifecycleRegistry lifecycle = new LifecycleRegistry(this);
|
||||
private final int registrarActivityHashCode;
|
||||
|
||||
public ProxyLifecycleProvider(Activity activity) {
|
||||
this.registrarActivityHashCode = activity.hashCode();
|
||||
activity.getApplication().registerActivityLifecycleCallbacks(this);
|
||||
LogUtil.i(CLASS_NAME, "<init>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
if (activity.hashCode() != registrarActivityHashCode) {
|
||||
return;
|
||||
}
|
||||
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
|
||||
LogUtil.i(CLASS_NAME, "onActivityCreated==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
if (activity.hashCode() != registrarActivityHashCode) {
|
||||
return;
|
||||
}
|
||||
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START);
|
||||
LogUtil.i(CLASS_NAME, "onActivityStarted==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
if (activity.hashCode() != registrarActivityHashCode) {
|
||||
return;
|
||||
}
|
||||
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
|
||||
LogUtil.i(CLASS_NAME, "onActivityResumed==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
if (activity.hashCode() != registrarActivityHashCode) {
|
||||
return;
|
||||
}
|
||||
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
|
||||
LogUtil.i(CLASS_NAME, "onActivityPaused==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
if (activity.hashCode() != registrarActivityHashCode) {
|
||||
return;
|
||||
}
|
||||
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
|
||||
LogUtil.i(CLASS_NAME, "onActivityStopped==>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
if (activity.hashCode() != registrarActivityHashCode) {
|
||||
return;
|
||||
}
|
||||
activity.getApplication().unregisterActivityLifecycleCallbacks(this);
|
||||
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
|
||||
LogUtil.i(CLASS_NAME, "onActivityDestroyed==>");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Lifecycle getLifecycle() {
|
||||
return lifecycle;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.amap.flutter.map.core;
|
||||
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
import com.amap.api.maps.model.LatLngBounds;
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
import com.amap.api.maps.model.MyTrafficStyle;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/10/29 9:56 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public interface AMapOptionsSink {
|
||||
|
||||
public void setCamera(CameraPosition camera);
|
||||
|
||||
public void setMapType(int mapType);
|
||||
|
||||
public void setCustomMapStyleOptions(CustomMapStyleOptions customMapStyleOptions);
|
||||
|
||||
public void setMyLocationStyle(MyLocationStyle myLocationStyle);
|
||||
|
||||
public void setScreenAnchor(float x, float y);
|
||||
|
||||
public void setMinZoomLevel(float minZoomLevel);
|
||||
|
||||
public void setMaxZoomLevel(float maxZoomLevel);
|
||||
|
||||
public void setLatLngBounds(LatLngBounds latLngBounds);
|
||||
|
||||
public void setTrafficEnabled(boolean trafficEnabled);
|
||||
|
||||
public void setTouchPoiEnabled(boolean touchPoiEnabled);
|
||||
|
||||
public void setBuildingsEnabled(boolean buildingsEnabled);
|
||||
|
||||
public void setLabelsEnabled(boolean labelsEnabled);
|
||||
|
||||
public void setCompassEnabled(boolean compassEnabled);
|
||||
|
||||
public void setScaleEnabled(boolean scaleEnabled);
|
||||
|
||||
|
||||
public void setZoomGesturesEnabled(boolean zoomGesturesEnabled);
|
||||
|
||||
public void setScrollGesturesEnabled(boolean scrollGesturesEnabled);
|
||||
|
||||
public void setRotateGesturesEnabled(boolean rotateGesturesEnabled);
|
||||
|
||||
public void setTiltGesturesEnabled(boolean tiltGesturesEnabled);
|
||||
|
||||
public void setInitialMarkers(Object initialMarkers);
|
||||
|
||||
public void setInitialPolylines(Object initialPolylines);
|
||||
|
||||
public void setInitialPolygons(Object initialPolygons);
|
||||
}
|
@ -0,0 +1,373 @@
|
||||
package com.amap.flutter.map.core;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.location.Location;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.CameraUpdate;
|
||||
import com.amap.api.maps.CameraUpdateFactory;
|
||||
import com.amap.api.maps.TextureMapView;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.LatLngBounds;
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
import com.amap.api.maps.model.Poi;
|
||||
import com.amap.flutter.map.MyMethodCallHandler;
|
||||
import com.amap.flutter.map.utils.Const;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/11 7:00 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class MapController
|
||||
implements MyMethodCallHandler,
|
||||
AMapOptionsSink,
|
||||
AMap.OnMapLoadedListener,
|
||||
AMap.OnMyLocationChangeListener,
|
||||
AMap.OnCameraChangeListener,
|
||||
AMap.OnMapClickListener,
|
||||
AMap.OnMapLongClickListener,
|
||||
AMap.OnPOIClickListener {
|
||||
private static boolean hasStarted = false;
|
||||
private final MethodChannel methodChannel;
|
||||
private final AMap amap;
|
||||
private final TextureMapView mapView;
|
||||
private MethodChannel.Result mapReadyResult;
|
||||
protected int[] myArray = {};
|
||||
|
||||
private static final String CLASS_NAME = "MapController";
|
||||
|
||||
private boolean mapLoaded = false;
|
||||
|
||||
public MapController(MethodChannel methodChannel, TextureMapView mapView) {
|
||||
this.methodChannel = methodChannel;
|
||||
this.mapView = mapView;
|
||||
amap = mapView.getMap();
|
||||
|
||||
amap.addOnMapLoadedListener(this);
|
||||
amap.addOnMyLocationChangeListener(this);
|
||||
amap.addOnCameraChangeListener(this);
|
||||
amap.addOnMapLongClickListener(this);
|
||||
amap.addOnMapClickListener(this);
|
||||
amap.addOnPOIClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getRegisterMethodIdArray() {
|
||||
return Const.METHOD_ID_LIST_FOR_MAP;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
LogUtil.i(CLASS_NAME, "doMethodCall===>" + call.method);
|
||||
if (null == amap) {
|
||||
LogUtil.w(CLASS_NAME, "onMethodCall amap is null!!!");
|
||||
return;
|
||||
}
|
||||
switch (call.method) {
|
||||
case Const.METHOD_MAP_WAIT_FOR_MAP:
|
||||
if (mapLoaded) {
|
||||
result.success(null);
|
||||
return;
|
||||
}
|
||||
mapReadyResult = result;
|
||||
break;
|
||||
case Const.METHOD_MAP_SATELLITE_IMAGE_APPROVAL_NUMBER:
|
||||
if (null != amap) {
|
||||
result.success(amap.getSatelliteImageApprovalNumber());
|
||||
}
|
||||
break;
|
||||
case Const.METHOD_MAP_CONTENT_APPROVAL_NUMBER:
|
||||
if (null != amap) {
|
||||
result.success(amap.getMapContentApprovalNumber());
|
||||
}
|
||||
break;
|
||||
case Const.METHOD_MAP_UPDATE:
|
||||
if (amap != null) {
|
||||
ConvertUtil.interpretAMapOptions(call.argument("options"), this);
|
||||
result.success(ConvertUtil.cameraPositionToMap(getCameraPosition()));
|
||||
}
|
||||
break;
|
||||
case Const.METHOD_MAP_MOVE_CAMERA:
|
||||
if (null != amap) {
|
||||
final CameraUpdate cameraUpdate = ConvertUtil.toCameraUpdate(call.argument("cameraUpdate"));
|
||||
final Object animatedObject = call.argument("animated");
|
||||
final Object durationObject = call.argument("duration");
|
||||
|
||||
moveCamera(cameraUpdate, animatedObject, durationObject);
|
||||
}
|
||||
break;
|
||||
case Const.METHOD_MAP_SET_RENDER_FPS:
|
||||
if (null != amap) {
|
||||
amap.setRenderFps((Integer) call.argument("fps"));
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case Const.METHOD_MAP_TAKE_SNAPSHOT:
|
||||
if (amap != null) {
|
||||
final MethodChannel.Result _result = result;
|
||||
amap.getMapScreenShot(new AMap.OnMapScreenShotListener() {
|
||||
@Override
|
||||
public void onMapScreenShot(Bitmap bitmap) {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
byte[] byteArray = stream.toByteArray();
|
||||
bitmap.recycle();
|
||||
_result.success(byteArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapScreenShot(Bitmap bitmap, int i) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case Const.METHOD_MAP_CLEAR_DISK:
|
||||
if (null != amap) {
|
||||
amap.removecache();
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LogUtil.w(CLASS_NAME, "onMethodCall not find methodId:" + call.method);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapLoaded() {
|
||||
LogUtil.i(CLASS_NAME, "onMapLoaded==>");
|
||||
try {
|
||||
mapLoaded = true;
|
||||
if (null != mapReadyResult) {
|
||||
mapReadyResult.success(null);
|
||||
mapReadyResult = null;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "onMapLoaded", e);
|
||||
}
|
||||
if (LogUtil.isDebugMode && !hasStarted) {
|
||||
hasStarted = true;
|
||||
int index = myArray[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCamera(CameraPosition camera) {
|
||||
amap.moveCamera(CameraUpdateFactory.newCameraPosition(camera));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMapType(int mapType) {
|
||||
amap.setMapType(mapType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomMapStyleOptions(CustomMapStyleOptions customMapStyleOptions) {
|
||||
if (null != amap) {
|
||||
amap.setCustomMapStyle(customMapStyleOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean myLocationShowing = false;
|
||||
|
||||
@Override
|
||||
public void setMyLocationStyle(MyLocationStyle myLocationStyle) {
|
||||
if (null != amap) {
|
||||
myLocationShowing = myLocationStyle.isMyLocationShowing();
|
||||
amap.setMyLocationEnabled(myLocationShowing);
|
||||
amap.setMyLocationStyle(myLocationStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScreenAnchor(float x, float y) {
|
||||
amap.setPointToCenter(Float.valueOf(mapView.getWidth() * x).intValue(), Float.valueOf(mapView.getHeight() * y).intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinZoomLevel(float minZoomLevel) {
|
||||
amap.setMinZoomLevel(minZoomLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxZoomLevel(float maxZoomLevel) {
|
||||
amap.setMaxZoomLevel(maxZoomLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLatLngBounds(LatLngBounds latLngBounds) {
|
||||
amap.setMapStatusLimits(latLngBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrafficEnabled(boolean trafficEnabled) {
|
||||
amap.setTrafficEnabled(trafficEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTouchPoiEnabled(boolean touchPoiEnabled) {
|
||||
amap.setTouchPoiEnable(touchPoiEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBuildingsEnabled(boolean buildingsEnabled) {
|
||||
amap.showBuildings(buildingsEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabelsEnabled(boolean labelsEnabled) {
|
||||
amap.showMapText(labelsEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompassEnabled(boolean compassEnabled) {
|
||||
amap.getUiSettings().setCompassEnabled(compassEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleEnabled(boolean scaleEnabled) {
|
||||
amap.getUiSettings().setScaleControlsEnabled(scaleEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) {
|
||||
amap.getUiSettings().setZoomGesturesEnabled(zoomGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) {
|
||||
amap.getUiSettings().setScrollGesturesEnabled(scrollGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) {
|
||||
amap.getUiSettings().setRotateGesturesEnabled(rotateGesturesEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) {
|
||||
amap.getUiSettings().setTiltGesturesEnabled(tiltGesturesEnabled);
|
||||
}
|
||||
|
||||
private CameraPosition getCameraPosition() {
|
||||
if (null != amap) {
|
||||
return amap.getCameraPosition();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMyLocationChange(Location location) {
|
||||
if (null != methodChannel && myLocationShowing) {
|
||||
final Map<String, Object> arguments = new HashMap<String, Object>(2);
|
||||
arguments.put("location", ConvertUtil.location2Map(location));
|
||||
methodChannel.invokeMethod("location#changed", arguments);
|
||||
LogUtil.i(CLASS_NAME, "onMyLocationChange===>" + arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChange(CameraPosition cameraPosition) {
|
||||
if (null != methodChannel) {
|
||||
final Map<String, Object> arguments = new HashMap<String, Object>(2);
|
||||
arguments.put("position", ConvertUtil.cameraPositionToMap(cameraPosition));
|
||||
methodChannel.invokeMethod("camera#onMove", arguments);
|
||||
LogUtil.i(CLASS_NAME, "onCameraChange===>" + arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChangeFinish(CameraPosition cameraPosition) {
|
||||
if (null != methodChannel) {
|
||||
final Map<String, Object> arguments = new HashMap<String, Object>(2);
|
||||
arguments.put("position", ConvertUtil.cameraPositionToMap(cameraPosition));
|
||||
methodChannel.invokeMethod("camera#onMoveEnd", arguments);
|
||||
LogUtil.i(CLASS_NAME, "onCameraChangeFinish===>" + arguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMapClick(LatLng latLng) {
|
||||
if (null != methodChannel) {
|
||||
final Map<String, Object> arguments = new HashMap<String, Object>(2);
|
||||
arguments.put("latLng", ConvertUtil.latLngToList(latLng));
|
||||
methodChannel.invokeMethod("map#onTap", arguments);
|
||||
LogUtil.i(CLASS_NAME, "onMapClick===>" + arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapLongClick(LatLng latLng) {
|
||||
if (null != methodChannel) {
|
||||
final Map<String, Object> arguments = new HashMap<String, Object>(2);
|
||||
arguments.put("latLng", ConvertUtil.latLngToList(latLng));
|
||||
methodChannel.invokeMethod("map#onLongPress", arguments);
|
||||
LogUtil.i(CLASS_NAME, "onMapLongClick===>" + arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPOIClick(Poi poi) {
|
||||
if (null != methodChannel) {
|
||||
final Map<String, Object> arguments = new HashMap<String, Object>(2);
|
||||
arguments.put("poi", ConvertUtil.poiToMap(poi));
|
||||
methodChannel.invokeMethod("map#onPoiTouched", arguments);
|
||||
LogUtil.i(CLASS_NAME, "onPOIClick===>" + arguments);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveCamera(CameraUpdate cameraUpdate, Object animatedObject, Object durationObject) {
|
||||
boolean animated = false;
|
||||
long duration = 250;
|
||||
if (null != animatedObject) {
|
||||
animated = (Boolean) animatedObject;
|
||||
}
|
||||
if (null != durationObject) {
|
||||
duration = ((Number) durationObject).intValue();
|
||||
}
|
||||
if (null != amap) {
|
||||
if (animated) {
|
||||
amap.animateCamera(cameraUpdate, duration, null);
|
||||
} else {
|
||||
amap.moveCamera(cameraUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitialMarkers(Object initialMarkers) {
|
||||
//不实现
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitialPolylines(Object initialPolylines) {
|
||||
//不实现
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInitialPolygons(Object polygonsObject) {
|
||||
//不实现
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.amap.flutter.map.overlays;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.TextureMapView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 7:42 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public abstract class AbstractOverlayController<T> {
|
||||
protected final Map<String, T> controllerMapByDartId;
|
||||
protected final Map<String, String> idMapByOverlyId;
|
||||
protected final MethodChannel methodChannel;
|
||||
protected final AMap amap;
|
||||
public AbstractOverlayController(MethodChannel methodChannel, AMap amap){
|
||||
this.methodChannel = methodChannel;
|
||||
this.amap = amap;
|
||||
controllerMapByDartId = new HashMap<String, T>(12);
|
||||
idMapByOverlyId = new HashMap<String, String>(12);
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.amap.flutter.map.overlays.marker;
|
||||
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.Marker;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/6 6:18 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class MarkerController implements MarkerOptionsSink {
|
||||
private final Marker marker;
|
||||
private final String markerId;
|
||||
|
||||
MarkerController(Marker marker) {
|
||||
this.marker = marker;
|
||||
markerId = marker.getId();
|
||||
}
|
||||
|
||||
public String getMarkerId() {
|
||||
return markerId;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (null != marker) {
|
||||
marker.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public LatLng getPosition() {
|
||||
if(null != marker) {
|
||||
return marker.getPosition();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(float alpha) {
|
||||
marker.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnchor(float u, float v) {
|
||||
marker.setAnchor(u, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDraggable(boolean draggable) {
|
||||
marker.setDraggable(draggable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlat(boolean flat) {
|
||||
marker.setFlat(flat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(BitmapDescriptor bitmapDescriptor) {
|
||||
marker.setIcon(bitmapDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
marker.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSnippet(String snippet) {
|
||||
marker.setSnippet(snippet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(LatLng position) {
|
||||
marker.setPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotation(float rotation) {
|
||||
marker.setRotateAngle(rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
marker.setVisible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZIndex(float zIndex) {
|
||||
marker.setZIndex(zIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInfoWindowEnable(boolean enable) {
|
||||
marker.setInfoWindowEnable(enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClickable(boolean clickable) {
|
||||
marker.setClickable(clickable);
|
||||
}
|
||||
|
||||
public void showInfoWindow() {
|
||||
marker.showInfoWindow();
|
||||
}
|
||||
|
||||
public void hideInfoWindow() {
|
||||
marker.hideInfoWindow();
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.amap.flutter.map.overlays.marker;
|
||||
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.MarkerOptions;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/6 6:17 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class MarkerOptionsBuilder implements MarkerOptionsSink {
|
||||
final MarkerOptions markerOptions;
|
||||
|
||||
MarkerOptionsBuilder() {
|
||||
this.markerOptions = new MarkerOptions();
|
||||
}
|
||||
|
||||
public MarkerOptions build() {
|
||||
return markerOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(float alpha) {
|
||||
markerOptions.alpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnchor(float u, float v) {
|
||||
markerOptions.anchor(u, v);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setDraggable(boolean draggable) {
|
||||
markerOptions.draggable(draggable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlat(boolean flat) {
|
||||
markerOptions.setFlat(flat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(BitmapDescriptor bitmapDescriptor) {
|
||||
markerOptions.icon(bitmapDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
markerOptions.title(title);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSnippet(String snippet) {
|
||||
markerOptions.snippet(snippet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(LatLng position) {
|
||||
markerOptions.position(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotation(float rotation) {
|
||||
markerOptions.rotateAngle(rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
markerOptions.visible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZIndex(float zIndex) {
|
||||
markerOptions.zIndex(zIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInfoWindowEnable(boolean enable) {
|
||||
markerOptions.infoWindowEnable(enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClickable(boolean clickable) {
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.amap.flutter.map.overlays.marker;
|
||||
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/6 6:12 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public interface MarkerOptionsSink {
|
||||
void setAlpha(float alpha);
|
||||
|
||||
void setAnchor(float u, float v);
|
||||
|
||||
void setDraggable(boolean draggable);
|
||||
|
||||
void setFlat(boolean flat);
|
||||
|
||||
void setIcon(BitmapDescriptor bitmapDescriptor);
|
||||
|
||||
void setTitle(String title);
|
||||
|
||||
void setSnippet(String snippet);
|
||||
|
||||
void setPosition(LatLng position);
|
||||
|
||||
void setRotation(float rotation);
|
||||
|
||||
void setVisible(boolean visible);
|
||||
|
||||
void setZIndex(float zIndex);
|
||||
|
||||
void setInfoWindowEnable(boolean enable);
|
||||
|
||||
void setClickable(boolean clickable);
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package com.amap.flutter.map.overlays.marker;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.amap.flutter.map.overlays.marker.MarkerOptionsSink;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/6 8:06 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class MarkerUtil {
|
||||
public static String interpretMarkerOptions(Object o, MarkerOptionsSink sink) {
|
||||
if (null == o) {
|
||||
return null;
|
||||
}
|
||||
final Map<?, ?> data = ConvertUtil.toMap(o);
|
||||
final Object alpha = data.get("alpha");
|
||||
if (alpha != null) {
|
||||
sink.setAlpha(ConvertUtil.toFloat(alpha));
|
||||
}
|
||||
final Object anchor = data.get("anchor");
|
||||
if (anchor != null) {
|
||||
final List<?> anchorData = ConvertUtil.toList(anchor);
|
||||
sink.setAnchor(ConvertUtil.toFloat(anchorData.get(0)), ConvertUtil.toFloat(anchorData.get(1)));
|
||||
}
|
||||
final Object consumeTapEvents = data.get("consumeTapEvents");
|
||||
final Object draggable = data.get("draggable");
|
||||
if (draggable != null) {
|
||||
sink.setDraggable(ConvertUtil.toBoolean(draggable));
|
||||
}
|
||||
final Object flat = data.get("flat");
|
||||
if (flat != null) {
|
||||
sink.setFlat(ConvertUtil.toBoolean(flat));
|
||||
}
|
||||
final Object icon = data.get("icon");
|
||||
if (icon != null) {
|
||||
sink.setIcon(ConvertUtil.toBitmapDescriptor(icon));
|
||||
}
|
||||
|
||||
final Object infoWindow = data.get("infoWindow");
|
||||
if (infoWindow != null) {
|
||||
interpretInfoWindowOptions(sink, (Map<String, Object>) infoWindow);
|
||||
}
|
||||
final Object position = data.get("position");
|
||||
if (position != null) {
|
||||
sink.setPosition(ConvertUtil.toLatLng(position));
|
||||
}
|
||||
final Object rotation = data.get("rotation");
|
||||
if (rotation != null) {
|
||||
sink.setRotation(Math.abs(360- ConvertUtil.toFloat(rotation)));
|
||||
}
|
||||
final Object visible = data.get("visible");
|
||||
if (visible != null) {
|
||||
sink.setVisible(ConvertUtil.toBoolean(visible));
|
||||
}
|
||||
final Object zIndex = data.get("zIndex");
|
||||
if (zIndex != null) {
|
||||
sink.setZIndex(ConvertUtil.toFloat(zIndex));
|
||||
}
|
||||
|
||||
final Object infoWindowEnable = data.get("infoWindowEnable");
|
||||
|
||||
if(infoWindowEnable != null) {
|
||||
sink.setInfoWindowEnable(ConvertUtil.toBoolean(infoWindowEnable));
|
||||
}
|
||||
|
||||
final Object clickable = data.get("clickable");
|
||||
if (null != clickable) {
|
||||
sink.setClickable(ConvertUtil.toBoolean(clickable));
|
||||
}
|
||||
|
||||
final String markerId = (String) data.get("id");
|
||||
if (markerId == null) {
|
||||
throw new IllegalArgumentException("markerId was null");
|
||||
} else {
|
||||
return markerId;
|
||||
}
|
||||
}
|
||||
|
||||
private static void interpretInfoWindowOptions(
|
||||
MarkerOptionsSink sink, Map<String, Object> infoWindow) {
|
||||
String title = (String) infoWindow.get("title");
|
||||
String snippet = (String) infoWindow.get("snippet");
|
||||
// snippet is nullable.
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
sink.setTitle(title);
|
||||
}
|
||||
if (!TextUtils.isEmpty(snippet)) {
|
||||
sink.setSnippet(snippet);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
package com.amap.flutter.map.overlays.marker;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.TextureMapView;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.Marker;
|
||||
import com.amap.api.maps.model.MarkerOptions;
|
||||
import com.amap.api.maps.model.Poi;
|
||||
import com.amap.api.maps.model.Polyline;
|
||||
import com.amap.flutter.map.MyMethodCallHandler;
|
||||
import com.amap.flutter.map.overlays.AbstractOverlayController;
|
||||
import com.amap.flutter.map.utils.Const;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/6 5:38 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class MarkersController
|
||||
extends AbstractOverlayController<MarkerController>
|
||||
implements MyMethodCallHandler,
|
||||
AMap.OnMapClickListener,
|
||||
AMap.OnMarkerClickListener,
|
||||
AMap.OnMarkerDragListener,
|
||||
AMap.OnPOIClickListener {
|
||||
private static final String CLASS_NAME = "MarkersController";
|
||||
private String selectedMarkerDartId;
|
||||
|
||||
public MarkersController(MethodChannel methodChannel, AMap amap) {
|
||||
super(methodChannel, amap);
|
||||
amap.addOnMarkerClickListener(this);
|
||||
amap.addOnMarkerDragListener(this);
|
||||
amap.addOnMapClickListener(this);
|
||||
amap.addOnPOIClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getRegisterMethodIdArray() {
|
||||
return Const.METHOD_ID_LIST_FOR_MARKER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
LogUtil.i(CLASS_NAME, "doMethodCall===>" + call.method);
|
||||
switch (call.method) {
|
||||
case Const.METHOD_MARKER_UPDATE:
|
||||
invokeMarkerOptions(call, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行主动方法更新marker
|
||||
*
|
||||
* @param methodCall
|
||||
* @param result
|
||||
*/
|
||||
public void invokeMarkerOptions(MethodCall methodCall, MethodChannel.Result result) {
|
||||
if (null == methodCall) {
|
||||
return;
|
||||
}
|
||||
Object markersToAdd = methodCall.argument("markersToAdd");
|
||||
addByList((List<Object>) markersToAdd);
|
||||
Object markersToChange = methodCall.argument("markersToChange");
|
||||
updateByList((List<Object>) markersToChange);
|
||||
Object markerIdsToRemove = methodCall.argument("markerIdsToRemove");
|
||||
removeByIdList((List<Object>) markerIdsToRemove);
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
public void addByList(List<Object> markersToAdd) {
|
||||
if (markersToAdd != null) {
|
||||
for (Object markerToAdd : markersToAdd) {
|
||||
add(markerToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void add(Object markerObj) {
|
||||
if (null != amap) {
|
||||
MarkerOptionsBuilder builder = new MarkerOptionsBuilder();
|
||||
String dartMarkerId = MarkerUtil.interpretMarkerOptions(markerObj, builder);
|
||||
if (!TextUtils.isEmpty(dartMarkerId)) {
|
||||
MarkerOptions markerOptions = builder.build();
|
||||
final Marker marker = amap.addMarker(markerOptions);
|
||||
Object clickable = ConvertUtil.getKeyValueFromMapObject(markerObj, "clickable");
|
||||
if (null != clickable) {
|
||||
marker.setClickable(ConvertUtil.toBoolean(clickable));
|
||||
}
|
||||
MarkerController markerController = new MarkerController(marker);
|
||||
controllerMapByDartId.put(dartMarkerId, markerController);
|
||||
idMapByOverlyId.put(marker.getId(), dartMarkerId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateByList(List<Object> markersToChange) {
|
||||
if (markersToChange != null) {
|
||||
for (Object markerToChange : markersToChange) {
|
||||
update(markerToChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void update(Object markerToChange) {
|
||||
Object dartMarkerId = ConvertUtil.getKeyValueFromMapObject(markerToChange, "id");
|
||||
if (null != dartMarkerId) {
|
||||
MarkerController markerController = controllerMapByDartId.get(dartMarkerId);
|
||||
if (null != markerController) {
|
||||
MarkerUtil.interpretMarkerOptions(markerToChange, markerController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void removeByIdList(List<Object> markerIdsToRemove) {
|
||||
if (markerIdsToRemove == null) {
|
||||
return;
|
||||
}
|
||||
for (Object rawMarkerId : markerIdsToRemove) {
|
||||
if (rawMarkerId == null) {
|
||||
continue;
|
||||
}
|
||||
String markerId = (String) rawMarkerId;
|
||||
final MarkerController markerController = controllerMapByDartId.remove(markerId);
|
||||
if (markerController != null) {
|
||||
|
||||
idMapByOverlyId.remove(markerController.getMarkerId());
|
||||
markerController.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showMarkerInfoWindow(String dartMarkId) {
|
||||
MarkerController markerController = controllerMapByDartId.get(dartMarkId);
|
||||
if (null != markerController) {
|
||||
markerController.showInfoWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void hideMarkerInfoWindow(String dartMarkId, LatLng newPosition) {
|
||||
if (TextUtils.isEmpty(dartMarkId)) {
|
||||
return;
|
||||
}
|
||||
if (!controllerMapByDartId.containsKey(dartMarkId)) {
|
||||
return;
|
||||
}
|
||||
MarkerController markerController = controllerMapByDartId.get(dartMarkId);
|
||||
if (null != markerController) {
|
||||
if (null != newPosition && null != markerController.getPosition()) {
|
||||
if (markerController.getPosition().equals(newPosition)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
markerController.hideInfoWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapClick(LatLng latLng) {
|
||||
hideMarkerInfoWindow(selectedMarkerDartId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMarkerClick(Marker marker) {
|
||||
String dartId = idMapByOverlyId.get(marker.getId());
|
||||
if (null == dartId) {
|
||||
return false;
|
||||
}
|
||||
final Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("markerId", dartId);
|
||||
selectedMarkerDartId = dartId;
|
||||
showMarkerInfoWindow(dartId);
|
||||
methodChannel.invokeMethod("marker#onTap", data);
|
||||
LogUtil.i(CLASS_NAME, "onMarkerClick==>" + data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkerDragStart(Marker marker) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkerDrag(Marker marker) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkerDragEnd(Marker marker) {
|
||||
String markerId = marker.getId();
|
||||
String dartId = idMapByOverlyId.get(markerId);
|
||||
LatLng latLng = marker.getPosition();
|
||||
if (null == dartId) {
|
||||
return;
|
||||
}
|
||||
final Map<String, Object> data = new HashMap<>(2);
|
||||
data.put("markerId", dartId);
|
||||
data.put("position", ConvertUtil.latLngToList(latLng));
|
||||
methodChannel.invokeMethod("marker#onDragEnd", data);
|
||||
|
||||
LogUtil.i(CLASS_NAME, "onMarkerDragEnd==>" + data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPOIClick(Poi poi) {
|
||||
hideMarkerInfoWindow(selectedMarkerDartId, null != poi ? poi.getCoordinate() : null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.amap.flutter.map.overlays.polygon;
|
||||
|
||||
import com.amap.api.maps.model.AMapPara;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.Polygon;
|
||||
import com.amap.api.maps.model.PolygonOptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/12 9:52 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class PolygonController implements PolygonOptionsSink{
|
||||
|
||||
private final Polygon polygon;
|
||||
private final String id;
|
||||
PolygonController(Polygon polygon){
|
||||
this.polygon = polygon;
|
||||
this.id = polygon.getId();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
polygon.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPoints(List<LatLng> points) {
|
||||
polygon.setPoints(points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStrokeWidth(float strokeWidth) {
|
||||
polygon.setStrokeWidth(strokeWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStrokeColor(int color) {
|
||||
polygon.setStrokeColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFillColor(int color) {
|
||||
polygon.setFillColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
polygon.setVisible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineJoinType(AMapPara.LineJoinType joinType) {
|
||||
//不支持动态修改
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.amap.flutter.map.overlays.polygon;
|
||||
|
||||
import com.amap.api.maps.model.AMapPara;
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.PolygonOptions;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
import com.amap.flutter.map.overlays.polyline.PolylineOptionsSink;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/12 9:51 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class PolygonOptionsBuilder implements PolygonOptionsSink {
|
||||
final PolygonOptions polygonOptions;
|
||||
PolygonOptionsBuilder() {
|
||||
polygonOptions = new PolygonOptions();
|
||||
//必须设置为true,否则会出现线条转折处出现断裂的现象
|
||||
polygonOptions.usePolylineStroke(true);
|
||||
}
|
||||
|
||||
public PolygonOptions build(){
|
||||
return polygonOptions;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setPoints(List<LatLng> points) {
|
||||
polygonOptions.setPoints(points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStrokeWidth(float strokeWidth) {
|
||||
polygonOptions.strokeWidth(strokeWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStrokeColor(int color) {
|
||||
polygonOptions.strokeColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFillColor(int color) {
|
||||
polygonOptions.fillColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
polygonOptions.visible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineJoinType(AMapPara.LineJoinType joinType) {
|
||||
polygonOptions.lineJoinType(joinType);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.amap.flutter.map.overlays.polygon;
|
||||
|
||||
import com.amap.api.maps.model.AMapPara;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/12 9:52 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
interface PolygonOptionsSink {
|
||||
//多边形坐标点列表
|
||||
void setPoints(List<LatLng> points);
|
||||
|
||||
//边框宽度
|
||||
void setStrokeWidth(float strokeWidth);
|
||||
|
||||
//边框颜色
|
||||
void setStrokeColor(int color);
|
||||
|
||||
//填充颜色
|
||||
void setFillColor(int color);
|
||||
|
||||
//是否显示
|
||||
void setVisible(boolean visible);
|
||||
|
||||
//边框连接类型
|
||||
void setLineJoinType(AMapPara.LineJoinType joinType);
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.amap.flutter.map.overlays.polygon;
|
||||
|
||||
import com.amap.api.maps.model.AMapPara;
|
||||
import com.amap.flutter.map.overlays.polyline.PolylineOptionsSink;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/12 10:11 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class PolygonUtil {
|
||||
|
||||
static String interpretOptions(Object o, PolygonOptionsSink sink) {
|
||||
final Map<?, ?> data = ConvertUtil.toMap(o);
|
||||
final Object points = data.get("points");
|
||||
if (points != null) {
|
||||
sink.setPoints(ConvertUtil.toPoints(points));
|
||||
}
|
||||
|
||||
final Object width = data.get("strokeWidth");
|
||||
if (width != null) {
|
||||
sink.setStrokeWidth(ConvertUtil.toFloatPixels(width));
|
||||
}
|
||||
|
||||
final Object strokeColor = data.get("strokeColor");
|
||||
if (strokeColor != null) {
|
||||
sink.setStrokeColor(ConvertUtil.toInt(strokeColor));
|
||||
}
|
||||
|
||||
final Object fillColor = data.get("fillColor");
|
||||
if (fillColor != null) {
|
||||
sink.setFillColor(ConvertUtil.toInt(fillColor));
|
||||
}
|
||||
|
||||
final Object visible = data.get("visible");
|
||||
if (visible != null) {
|
||||
sink.setVisible(ConvertUtil.toBoolean(visible));
|
||||
}
|
||||
|
||||
final Object joinType = data.get("joinType");
|
||||
if (joinType != null) {
|
||||
sink.setLineJoinType(AMapPara.LineJoinType.valueOf(ConvertUtil.toInt(joinType)));
|
||||
}
|
||||
|
||||
final String polylineId = (String) data.get("id");
|
||||
if (polylineId == null) {
|
||||
throw new IllegalArgumentException("polylineId was null");
|
||||
} else {
|
||||
return polylineId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package com.amap.flutter.map.overlays.polygon;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.model.Polygon;
|
||||
import com.amap.api.maps.model.PolygonOptions;
|
||||
import com.amap.flutter.map.MyMethodCallHandler;
|
||||
import com.amap.flutter.map.overlays.AbstractOverlayController;
|
||||
import com.amap.flutter.map.utils.Const;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/12 9:53 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class PolygonsController
|
||||
extends AbstractOverlayController<PolygonController>
|
||||
implements MyMethodCallHandler {
|
||||
|
||||
private static final String CLASS_NAME = "PolygonsController";
|
||||
|
||||
public PolygonsController(MethodChannel methodChannel, AMap amap) {
|
||||
super(methodChannel, amap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
String methodId = call.method;
|
||||
LogUtil.i(CLASS_NAME, "doMethodCall===>" +methodId);
|
||||
switch (methodId) {
|
||||
case Const.METHOD_POLYGON_UPDATE:
|
||||
invokePolylineOptions(call, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getRegisterMethodIdArray() {
|
||||
return Const.METHOD_ID_LIST_FOR_POLYGON;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param methodCall
|
||||
* @param result
|
||||
*/
|
||||
public void invokePolylineOptions(MethodCall methodCall, MethodChannel.Result result) {
|
||||
if (null == methodCall) {
|
||||
return;
|
||||
}
|
||||
Object listToAdd = methodCall.argument("polygonsToAdd");
|
||||
addByList((List<Object>) listToAdd);
|
||||
Object listToChange = methodCall.argument("polygonsToChange");
|
||||
updateByList((List<Object>) listToChange);
|
||||
Object listIdToRemove = methodCall.argument("polygonIdsToRemove");
|
||||
removeByIdList((List<Object>) listIdToRemove);
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
public void addByList(List<Object> polygonsToAdd) {
|
||||
if (polygonsToAdd != null) {
|
||||
for (Object polygonToAdd : polygonsToAdd) {
|
||||
add(polygonToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void add(Object polylineObj) {
|
||||
if (null != amap) {
|
||||
PolygonOptionsBuilder builder = new PolygonOptionsBuilder();
|
||||
String dartId = PolygonUtil.interpretOptions(polylineObj, builder);
|
||||
if (!TextUtils.isEmpty(dartId)) {
|
||||
PolygonOptions options = builder.build();
|
||||
final Polygon polygon = amap.addPolygon(options);
|
||||
PolygonController polygonController = new PolygonController(polygon);
|
||||
controllerMapByDartId.put(dartId, polygonController);
|
||||
idMapByOverlyId.put(polygon.getId(), dartId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateByList(List<Object> overlaysToChange) {
|
||||
if (overlaysToChange != null) {
|
||||
for (Object overlayToChange : overlaysToChange) {
|
||||
update(overlayToChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void update(Object toUpdate) {
|
||||
Object dartId = ConvertUtil.getKeyValueFromMapObject(toUpdate, "id");
|
||||
if (null != dartId) {
|
||||
PolygonController controller = controllerMapByDartId.get(dartId);
|
||||
if (null != controller) {
|
||||
PolygonUtil.interpretOptions(toUpdate, controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeByIdList(List<Object> toRemoveIdList) {
|
||||
if (toRemoveIdList == null) {
|
||||
return;
|
||||
}
|
||||
for (Object toRemoveId : toRemoveIdList) {
|
||||
if (toRemoveId == null) {
|
||||
continue;
|
||||
}
|
||||
String dartId = (String) toRemoveId;
|
||||
final PolygonController controller = controllerMapByDartId.remove(dartId);
|
||||
if (controller != null) {
|
||||
|
||||
idMapByOverlyId.remove(controller.getId());
|
||||
controller.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.amap.flutter.map.overlays.polyline;
|
||||
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.Polyline;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 2:58 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class PolylineController implements PolylineOptionsSink {
|
||||
final Polyline polyline;
|
||||
final String polylineId;
|
||||
PolylineController(Polyline polyline) {
|
||||
this.polyline = polyline;
|
||||
this.polylineId = polyline.getId();
|
||||
}
|
||||
|
||||
public String getPolylineId() {
|
||||
return polylineId;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if(null != polyline) {
|
||||
polyline.remove();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setPoints(List<LatLng> points) {
|
||||
polyline.setPoints(points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWidth(float width) {
|
||||
polyline.setWidth(width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(int color) {
|
||||
polyline.setColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
polyline.setVisible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomTexture(BitmapDescriptor customTexture) {
|
||||
polyline.setCustomTexture(customTexture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomTextureList(List<BitmapDescriptor> customTextureList) {
|
||||
polyline.setCustomTextureList(customTextureList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorList(List<Integer> colorList) {
|
||||
PolylineOptions options = polyline.getOptions();
|
||||
options.colorValues(colorList);
|
||||
polyline.setOptions(options);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomIndexList(List<Integer> customIndexList) {
|
||||
PolylineOptions options = polyline.getOptions();
|
||||
options.setCustomTextureIndex(customIndexList);
|
||||
polyline.setOptions(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGeodesic(boolean geodesic) {
|
||||
polyline.setGeodesic(geodesic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGradient(boolean gradient) {
|
||||
polyline.setGeodesic(gradient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(float alpha) {
|
||||
polyline.setTransparency(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDashLineType(int type) {
|
||||
PolylineOptions options = polyline.getOptions();
|
||||
options.setDottedLineType(type);
|
||||
polyline.setOptions(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDashLine(boolean dashLine) {
|
||||
polyline.setDottedLine(dashLine);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineCapType(PolylineOptions.LineCapType lineCapType) {
|
||||
PolylineOptions options = polyline.getOptions();
|
||||
options.lineCapType(lineCapType);
|
||||
polyline.setOptions(options);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setLineJoinType(PolylineOptions.LineJoinType joinType) {
|
||||
PolylineOptions options = polyline.getOptions();
|
||||
options.lineJoinType(joinType);
|
||||
polyline.setOptions(options);
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package com.amap.flutter.map.overlays.polyline;
|
||||
|
||||
import com.amap.api.maps.model.AMapPara;
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 2:57 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class PolylineOptionsBuilder implements PolylineOptionsSink {
|
||||
final PolylineOptions polylineOptions;
|
||||
|
||||
PolylineOptionsBuilder() {
|
||||
polylineOptions = new PolylineOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPoints(List<LatLng> points) {
|
||||
polylineOptions.setPoints(points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWidth(float width) {
|
||||
polylineOptions.width(width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(int color) {
|
||||
polylineOptions.color(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
polylineOptions.visible(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomTexture(BitmapDescriptor customTexture) {
|
||||
polylineOptions.setCustomTexture(customTexture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomTextureList(List<BitmapDescriptor> customTextureList) {
|
||||
polylineOptions.setCustomTextureList(customTextureList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorList(List<Integer> colorList) {
|
||||
polylineOptions.colorValues(colorList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomIndexList(List<Integer> customIndexList) {
|
||||
polylineOptions.setCustomTextureIndex(customIndexList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGeodesic(boolean geodesic) {
|
||||
polylineOptions.geodesic(geodesic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGradient(boolean gradient) {
|
||||
polylineOptions.useGradient(gradient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(float alpha) {
|
||||
polylineOptions.transparency(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDashLineType(int type) {
|
||||
polylineOptions.setDottedLineType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDashLine(boolean dashLine) {
|
||||
polylineOptions.setDottedLine(dashLine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineCapType(PolylineOptions.LineCapType lineCapType) {
|
||||
polylineOptions.lineCapType(lineCapType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineJoinType(PolylineOptions.LineJoinType joinType) {
|
||||
polylineOptions.lineJoinType(joinType);
|
||||
}
|
||||
|
||||
public PolylineOptions build(){
|
||||
return polylineOptions;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.amap.flutter.map.overlays.polyline;
|
||||
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 2:58 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public interface PolylineOptionsSink {
|
||||
//路线点
|
||||
void setPoints(List<LatLng> points);
|
||||
|
||||
//宽度
|
||||
void setWidth(float width);
|
||||
|
||||
//颜色
|
||||
void setColor(int color);
|
||||
|
||||
//是否显示
|
||||
void setVisible(boolean visible);
|
||||
|
||||
//纹理
|
||||
void setCustomTexture(BitmapDescriptor customTexture);
|
||||
|
||||
//纹理列表
|
||||
void setCustomTextureList(List<BitmapDescriptor> customTextureList);
|
||||
|
||||
//颜色列表
|
||||
void setColorList(List<Integer> colorList);
|
||||
|
||||
//纹理顺序
|
||||
void setCustomIndexList(List<Integer> customIndexList);
|
||||
|
||||
//是否大地曲线
|
||||
void setGeodesic(boolean geodesic);
|
||||
|
||||
//是否渐变
|
||||
void setGradient(boolean gradient);
|
||||
|
||||
//透明度
|
||||
void setAlpha(float alpha);
|
||||
|
||||
//虚线类型
|
||||
void setDashLineType(int type);
|
||||
|
||||
//是否虚线
|
||||
void setDashLine(boolean dashLine);
|
||||
|
||||
//线冒类型
|
||||
void setLineCapType(PolylineOptions.LineCapType lineCapType);
|
||||
|
||||
//线交接类型
|
||||
void setLineJoinType(PolylineOptions.LineJoinType joinType);
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.amap.flutter.map.overlays.polyline;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 4:34 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
class PolylineUtil {
|
||||
|
||||
private static final String CLASS_NAME = "PolylineUtil";
|
||||
//虚线类型
|
||||
private static final int[] DASH_LINE_TYPE = {-1,0,1};
|
||||
|
||||
static String interpretOptions(Object o, PolylineOptionsSink sink) {
|
||||
final Map<?, ?> data = ConvertUtil.toMap(o);
|
||||
|
||||
final Object points = data.get("points");
|
||||
if (points != null) {
|
||||
sink.setPoints(ConvertUtil.toPoints(points));
|
||||
}
|
||||
|
||||
final Object width = data.get("width");
|
||||
if (width != null) {
|
||||
sink.setWidth(ConvertUtil.toFloatPixels(width));
|
||||
}
|
||||
|
||||
final Object visible = data.get("visible");
|
||||
if (visible != null) {
|
||||
sink.setVisible(ConvertUtil.toBoolean(visible));
|
||||
}
|
||||
|
||||
final Object geodesic = data.get("geodesic");
|
||||
if (geodesic != null) {
|
||||
sink.setGeodesic(ConvertUtil.toBoolean(geodesic));
|
||||
}
|
||||
|
||||
final Object gradient = data.get("gradient");
|
||||
if (gradient != null) {
|
||||
sink.setGradient(ConvertUtil.toBoolean(gradient));
|
||||
}
|
||||
|
||||
final Object alpha = data.get("alpha");
|
||||
if (alpha != null) {
|
||||
sink.setAlpha(ConvertUtil.toFloat(alpha));
|
||||
}
|
||||
|
||||
final Object dashLineType = data.get("dashLineType");
|
||||
if (dashLineType != null) {
|
||||
int rawType = ConvertUtil.toInt(dashLineType);
|
||||
if (rawType > DASH_LINE_TYPE.length) {
|
||||
rawType = 0;
|
||||
}
|
||||
if(DASH_LINE_TYPE[rawType] == -1) {
|
||||
sink.setDashLine(false);
|
||||
} else {
|
||||
sink.setDashLine(true);
|
||||
sink.setDashLineType(DASH_LINE_TYPE[rawType]);
|
||||
}
|
||||
}
|
||||
|
||||
final Object capType = data.get("capType");
|
||||
if (capType != null) {
|
||||
sink.setLineCapType(PolylineOptions.LineCapType.valueOf(ConvertUtil.toInt(capType)));
|
||||
}
|
||||
|
||||
final Object joinType = data.get("joinType");
|
||||
if (joinType != null) {
|
||||
sink.setLineJoinType(PolylineOptions.LineJoinType.valueOf(ConvertUtil.toInt(joinType)));
|
||||
}
|
||||
|
||||
|
||||
final Object customTexture = data.get("customTexture");
|
||||
if (customTexture != null) {
|
||||
sink.setCustomTexture(ConvertUtil.toBitmapDescriptor(customTexture));
|
||||
}
|
||||
|
||||
final Object customTextureList = data.get("customTextureList");
|
||||
if (customTextureList != null) {
|
||||
sink.setCustomTextureList(ConvertUtil.toBitmapDescriptorList(customTextureList));
|
||||
}
|
||||
|
||||
final Object color = data.get("color");
|
||||
if (color != null) {
|
||||
sink.setColor(ConvertUtil.toInt(color));
|
||||
}
|
||||
|
||||
final Object colorList = data.get("colorList");
|
||||
if (colorList != null) {
|
||||
sink.setColorList((List<Integer>) ConvertUtil.toList(colorList));
|
||||
}
|
||||
|
||||
final String dartId = (String) data.get("id");
|
||||
if(TextUtils.isEmpty(dartId)) {
|
||||
Log.w(CLASS_NAME, "没有传入正确的dart层ID, 请确认对应的key值是否正确!!!");
|
||||
}
|
||||
return dartId;
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package com.amap.flutter.map.overlays.polyline;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.TextureMapView;
|
||||
import com.amap.api.maps.model.Polyline;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
import com.amap.flutter.map.MyMethodCallHandler;
|
||||
import com.amap.flutter.map.overlays.AbstractOverlayController;
|
||||
import com.amap.flutter.map.utils.Const;
|
||||
import com.amap.flutter.map.utils.ConvertUtil;
|
||||
import com.amap.flutter.map.utils.LogUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 2:58 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class PolylinesController
|
||||
extends AbstractOverlayController<PolylineController>
|
||||
implements MyMethodCallHandler,
|
||||
AMap.OnPolylineClickListener {
|
||||
|
||||
private static final String CLASS_NAME = "PolylinesController";
|
||||
|
||||
public PolylinesController(MethodChannel methodChannel, AMap amap) {
|
||||
super(methodChannel, amap);
|
||||
amap.addOnPolylineClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getRegisterMethodIdArray() {
|
||||
return Const.METHOD_ID_LIST_FOR_POLYLINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
LogUtil.i(CLASS_NAME, "doMethodCall===>" + call.method);
|
||||
String methodStr = call.method;
|
||||
switch (methodStr) {
|
||||
case Const.METHOD_POLYLINE_UPDATE:
|
||||
invokePolylineOptions(call, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPolylineClick(Polyline polyline) {
|
||||
String dartId = idMapByOverlyId.get(polyline.getId());
|
||||
if (null == dartId) {
|
||||
return;
|
||||
}
|
||||
final Map<String, Object> data = new HashMap<>(1);
|
||||
data.put("polylineId", dartId);
|
||||
methodChannel.invokeMethod("polyline#onTap", data);
|
||||
LogUtil.i(CLASS_NAME, "onPolylineClick==>" + data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param methodCall
|
||||
* @param result
|
||||
*/
|
||||
private void invokePolylineOptions(MethodCall methodCall, MethodChannel.Result result) {
|
||||
if (null == methodCall) {
|
||||
return;
|
||||
}
|
||||
Object listToAdd = methodCall.argument("polylinesToAdd");
|
||||
addByList((List<Object>) listToAdd);
|
||||
Object listToChange = methodCall.argument("polylinesToChange");
|
||||
updateByList((List<Object>) listToChange);
|
||||
Object polylineIdsToRemove = methodCall.argument("polylineIdsToRemove");
|
||||
removeByIdList((List<Object>) polylineIdsToRemove);
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
public void addByList(List<Object> polylinesToAdd) {
|
||||
if (polylinesToAdd != null) {
|
||||
for (Object markerToAdd : polylinesToAdd) {
|
||||
addPolyline(markerToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPolyline(Object polylineObj) {
|
||||
if (null != amap) {
|
||||
PolylineOptionsBuilder builder = new PolylineOptionsBuilder();
|
||||
String dartId = PolylineUtil.interpretOptions(polylineObj, builder);
|
||||
if (!TextUtils.isEmpty(dartId)) {
|
||||
PolylineOptions polylineOptions = builder.build();
|
||||
final Polyline polyline = amap.addPolyline(polylineOptions);
|
||||
PolylineController polylineController = new PolylineController(polyline);
|
||||
controllerMapByDartId.put(dartId, polylineController);
|
||||
idMapByOverlyId.put(polyline.getId(), dartId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateByList(List<Object> polylineToChange) {
|
||||
if (polylineToChange != null) {
|
||||
for (Object markerToChange : polylineToChange) {
|
||||
update(markerToChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void update(Object polylineToChange) {
|
||||
Object polylineId = ConvertUtil.getKeyValueFromMapObject(polylineToChange, "id");
|
||||
if (null != polylineId) {
|
||||
PolylineController polylineController = controllerMapByDartId.get(polylineId);
|
||||
if (null != polylineController) {
|
||||
PolylineUtil.interpretOptions(polylineToChange, polylineController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void removeByIdList(List<Object> polylineIdsToRemove) {
|
||||
if (polylineIdsToRemove == null) {
|
||||
return;
|
||||
}
|
||||
for (Object rawPolylineId : polylineIdsToRemove) {
|
||||
if (rawPolylineId == null) {
|
||||
continue;
|
||||
}
|
||||
String markerId = (String) rawPolylineId;
|
||||
final PolylineController polylineController = controllerMapByDartId.remove(markerId);
|
||||
if (polylineController != null) {
|
||||
idMapByOverlyId.remove(polylineController.getPolylineId());
|
||||
polylineController.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
50
android/src/main/java/com/amap/flutter/map/utils/Const.java
Normal file
50
android/src/main/java/com/amap/flutter/map/utils/Const.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.amap.flutter.map.utils;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/10 9:44 PM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class Const {
|
||||
/**
|
||||
* map
|
||||
*/
|
||||
public static final String METHOD_MAP_WAIT_FOR_MAP = "map#waitForMap";
|
||||
public static final String METHOD_MAP_CONTENT_APPROVAL_NUMBER = "map#contentApprovalNumber";
|
||||
public static final String METHOD_MAP_SATELLITE_IMAGE_APPROVAL_NUMBER = "map#satelliteImageApprovalNumber";
|
||||
public static final String METHOD_MAP_UPDATE = "map#update";
|
||||
public static final String METHOD_MAP_MOVE_CAMERA = "camera#move";
|
||||
public static final String METHOD_MAP_SET_RENDER_FPS = "map#setRenderFps";
|
||||
public static final String METHOD_MAP_TAKE_SNAPSHOT = "map#takeSnapshot";
|
||||
public static final String METHOD_MAP_CLEAR_DISK = "map#clearDisk";
|
||||
|
||||
public static final String[] METHOD_ID_LIST_FOR_MAP = {
|
||||
METHOD_MAP_CONTENT_APPROVAL_NUMBER,
|
||||
METHOD_MAP_SATELLITE_IMAGE_APPROVAL_NUMBER,
|
||||
METHOD_MAP_WAIT_FOR_MAP,
|
||||
METHOD_MAP_UPDATE,
|
||||
METHOD_MAP_MOVE_CAMERA,
|
||||
METHOD_MAP_SET_RENDER_FPS,
|
||||
METHOD_MAP_TAKE_SNAPSHOT,
|
||||
METHOD_MAP_CLEAR_DISK};
|
||||
|
||||
|
||||
/**
|
||||
* markers
|
||||
*/
|
||||
public static final String METHOD_MARKER_UPDATE = "markers#update";
|
||||
public static final String[] METHOD_ID_LIST_FOR_MARKER = {METHOD_MARKER_UPDATE};
|
||||
|
||||
/**
|
||||
* polygons
|
||||
*/
|
||||
public static final String METHOD_POLYGON_UPDATE = "polygons#update";
|
||||
public static final String[] METHOD_ID_LIST_FOR_POLYGON = {METHOD_POLYGON_UPDATE};
|
||||
|
||||
/**
|
||||
* polylines
|
||||
*/
|
||||
public static final String METHOD_POLYLINE_UPDATE = "polylines#update";
|
||||
public static final String[] METHOD_ID_LIST_FOR_POLYLINE = {METHOD_POLYLINE_UPDATE};
|
||||
}
|
@ -0,0 +1,521 @@
|
||||
package com.amap.flutter.map.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Point;
|
||||
import android.location.Location;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.CameraUpdate;
|
||||
import com.amap.api.maps.CameraUpdateFactory;
|
||||
import com.amap.api.maps.MapsInitializer;
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.LatLngBounds;
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
import com.amap.api.maps.model.Poi;
|
||||
import com.amap.flutter.map.core.AMapOptionsSink;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import io.flutter.view.FlutterMain;
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/10/29 11:01 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class ConvertUtil {
|
||||
|
||||
private static final String CLASS_NAME = "ConvertUtil";
|
||||
|
||||
public static float density;
|
||||
private static String apiKey;
|
||||
|
||||
public static void setPrivacyStatement(Context context, Object object) {
|
||||
if (null == object) {
|
||||
return;
|
||||
}
|
||||
Map<?, ?> privacyStatementMap = toMap(object);
|
||||
Object hasContainsObj = privacyStatementMap.get("hasContains");
|
||||
Object hasShowObj = privacyStatementMap.get("hasShow");
|
||||
Object hasAgreeObj = privacyStatementMap.get("hasAgree");
|
||||
|
||||
Class<MapsInitializer> clazz = MapsInitializer.class;
|
||||
|
||||
if (null != hasContainsObj
|
||||
&& null != hasShowObj) {
|
||||
boolean hasContains = toBoolean(hasContainsObj);
|
||||
boolean hasShow = toBoolean(hasShowObj);
|
||||
//使用反射的方法调用适配之前的版本
|
||||
try {
|
||||
Method method = clazz.getMethod("updatePrivacyShow", Context.class, boolean.class, boolean.class);
|
||||
method.invoke(null, context, hasContains, hasShow);
|
||||
} catch (Throwable e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (null != hasAgreeObj) {
|
||||
boolean hasAgree = toBoolean(hasAgreeObj);
|
||||
//使用反射的方法调用适配之前的版本
|
||||
try{
|
||||
Method method = clazz.getMethod("updatePrivacyAgree", Context.class, boolean.class);
|
||||
method.invoke(null, context, hasAgree);
|
||||
} catch (Throwable e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkApiKey(Object object) {
|
||||
if (null == object) {
|
||||
return;
|
||||
}
|
||||
Map<?, ?> keyMap = toMap(object);
|
||||
Object keyObject = keyMap.get("androidKey");
|
||||
if (null != keyObject) {
|
||||
final String aKey = toString(keyObject);
|
||||
if (TextUtils.isEmpty(apiKey)
|
||||
|| !aKey.equals(apiKey)) {
|
||||
apiKey = aKey;
|
||||
MapsInitializer.setApiKey(apiKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int toLocalMapType(int dartMapIndex) {
|
||||
int[] localTypeArray = {AMap.MAP_TYPE_NORMAL, AMap.MAP_TYPE_SATELLITE, AMap.MAP_TYPE_NIGHT, AMap.MAP_TYPE_NAVI, AMap.MAP_TYPE_BUS};
|
||||
if (dartMapIndex > localTypeArray.length) {
|
||||
return localTypeArray[0];
|
||||
}
|
||||
return localTypeArray[dartMapIndex];
|
||||
}
|
||||
|
||||
public static CameraUpdate toCameraUpdate(Object o) {
|
||||
final List<?> data = toList(o);
|
||||
switch (toString(data.get(0))) {
|
||||
case "newCameraPosition":
|
||||
return CameraUpdateFactory.newCameraPosition(toCameraPosition(data.get(1)));
|
||||
case "newLatLng":
|
||||
return CameraUpdateFactory.newLatLng(toLatLng(data.get(1)));
|
||||
case "newLatLngBounds":
|
||||
return CameraUpdateFactory.newLatLngBounds(
|
||||
toLatLngBounds(data.get(1)), toPixels(data.get(2)));
|
||||
case "newLatLngZoom":
|
||||
return CameraUpdateFactory.newLatLngZoom(toLatLng(data.get(1)), toFloat(data.get(2)));
|
||||
case "scrollBy":
|
||||
return CameraUpdateFactory.scrollBy( //
|
||||
toFloatPixels(data.get(1)), //
|
||||
toFloatPixels(data.get(2)));
|
||||
case "zoomBy":
|
||||
if (data.size() == 2) {
|
||||
return CameraUpdateFactory.zoomBy(toFloat(data.get(1)));
|
||||
} else {
|
||||
return CameraUpdateFactory.zoomBy(toFloat(data.get(1)), toPoint(data.get(2)));
|
||||
}
|
||||
case "zoomIn":
|
||||
return CameraUpdateFactory.zoomIn();
|
||||
case "zoomOut":
|
||||
return CameraUpdateFactory.zoomOut();
|
||||
case "zoomTo":
|
||||
return CameraUpdateFactory.zoomTo(toFloat(data.get(1)));
|
||||
default:
|
||||
throw new IllegalArgumentException("Cannot interpret " + o + " as CameraUpdate");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Point toPoint(Object o) {
|
||||
final List<?> data = toList(o);
|
||||
return new Point(toPixels(data.get(0)), toPixels(data.get(1)));
|
||||
}
|
||||
|
||||
public static float toFloatPixels(Object o) {
|
||||
return toFloat(o) * density;
|
||||
}
|
||||
|
||||
public static int toPixels(Object o) {
|
||||
return (int) toFloatPixels(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个对象转换成CameraPosition
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public static CameraPosition toCameraPosition(Object o) {
|
||||
final Map<?, ?> data = (Map<?, ?>) o;
|
||||
final CameraPosition.Builder builder = CameraPosition.builder();
|
||||
builder.bearing(toFloat(data.get("bearing")));
|
||||
builder.target(toLatLng(data.get("target")));
|
||||
builder.tilt(toFloat(data.get("tilt")));
|
||||
builder.zoom(toFloat(data.get("zoom")));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static Object cameraPositionToMap(CameraPosition position) {
|
||||
if (position == null) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, Object> data = new HashMap<>();
|
||||
data.put("bearing", position.bearing);
|
||||
data.put("target", latLngToList(position.target));
|
||||
data.put("tilt", position.tilt);
|
||||
data.put("zoom", position.zoom);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换AMapOptions
|
||||
*
|
||||
* @param o
|
||||
* @param sink
|
||||
*/
|
||||
public static void interpretAMapOptions(Object o, @NonNull AMapOptionsSink sink) {
|
||||
try {
|
||||
final Map<?, ?> data = (Map<?, ?>) o;
|
||||
final Object mapType = data.get("mapType");
|
||||
if (mapType != null) {
|
||||
sink.setMapType(toLocalMapType(toInt(mapType)));
|
||||
}
|
||||
|
||||
final Object buildingsEnabled = data.get("buildingsEnabled");
|
||||
if (null != buildingsEnabled) {
|
||||
sink.setBuildingsEnabled(toBoolean(buildingsEnabled));
|
||||
}
|
||||
|
||||
final Object customMapStyleOptions = data.get("customStyleOptions");
|
||||
if (null != customMapStyleOptions) {
|
||||
CustomMapStyleOptions customMapStyleOptions1 = toCustomMapStyleOptions(customMapStyleOptions);
|
||||
sink.setCustomMapStyleOptions(customMapStyleOptions1);
|
||||
}
|
||||
|
||||
final Object myLocationStyleData = data.get("myLocationStyle");
|
||||
if (null != myLocationStyleData) {
|
||||
sink.setMyLocationStyle(ConvertUtil.toMyLocationStyle(myLocationStyleData, density));
|
||||
}
|
||||
|
||||
final Object screenAnchor = data.get("screenAnchor");
|
||||
if (null != screenAnchor) {
|
||||
final List<?> anchorData = toList(screenAnchor);
|
||||
sink.setScreenAnchor(toFloat(anchorData.get(0)), toFloat(anchorData.get(1)));
|
||||
}
|
||||
|
||||
final Object compassEnabled = data.get("compassEnabled");
|
||||
if (null != compassEnabled) {
|
||||
sink.setCompassEnabled(toBoolean(compassEnabled));
|
||||
}
|
||||
|
||||
final Object labelsEnabled = data.get("labelsEnabled");
|
||||
if (null != labelsEnabled) {
|
||||
sink.setLabelsEnabled(toBoolean(labelsEnabled));
|
||||
}
|
||||
|
||||
final Object limitBounds = data.get("limitBounds");
|
||||
if (null != limitBounds) {
|
||||
final List<?> targetData = toList(limitBounds);
|
||||
sink.setLatLngBounds(toLatLngBounds(targetData));
|
||||
}
|
||||
|
||||
final Object minMaxZoomPreference = data.get("minMaxZoomPreference");
|
||||
if (null != minMaxZoomPreference) {
|
||||
final List<?> targetData = toList(minMaxZoomPreference);
|
||||
sink.setMinZoomLevel(toFloatWrapperWithDefault(targetData.get(0), 3));
|
||||
sink.setMaxZoomLevel(toFloatWrapperWithDefault(targetData.get(1), 20));
|
||||
}
|
||||
|
||||
final Object scaleEnabled = data.get("scaleEnabled");
|
||||
if (null != scaleEnabled) {
|
||||
sink.setScaleEnabled(toBoolean(scaleEnabled));
|
||||
}
|
||||
|
||||
final Object touchPoiEnabled = data.get("touchPoiEnabled");
|
||||
if (null != touchPoiEnabled) {
|
||||
sink.setTouchPoiEnabled(toBoolean(touchPoiEnabled));
|
||||
}
|
||||
|
||||
final Object trafficEnabled = data.get("trafficEnabled");
|
||||
if (null != trafficEnabled) {
|
||||
sink.setTrafficEnabled(toBoolean(trafficEnabled));
|
||||
}
|
||||
|
||||
final Object rotateGesturesEnabled = data.get("rotateGesturesEnabled");
|
||||
if (null != rotateGesturesEnabled) {
|
||||
sink.setRotateGesturesEnabled(toBoolean(rotateGesturesEnabled));
|
||||
}
|
||||
|
||||
final Object scrollGesturesEnabled = data.get("scrollGesturesEnabled");
|
||||
if (null != scrollGesturesEnabled) {
|
||||
sink.setScrollGesturesEnabled(toBoolean(scrollGesturesEnabled));
|
||||
}
|
||||
|
||||
final Object tiltGesturesEnabled = data.get("tiltGesturesEnabled");
|
||||
if (null != tiltGesturesEnabled) {
|
||||
sink.setTiltGesturesEnabled(toBoolean(tiltGesturesEnabled));
|
||||
}
|
||||
|
||||
final Object zoomGesturesEnabled = data.get("zoomGesturesEnabled");
|
||||
if (null != zoomGesturesEnabled) {
|
||||
sink.setZoomGesturesEnabled(toBoolean(zoomGesturesEnabled));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogUtil.e(CLASS_NAME, "interpretAMapOptions", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static CustomMapStyleOptions toCustomMapStyleOptions(Object o) {
|
||||
final Map<?, ?> map = toMap(o);
|
||||
final CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions();
|
||||
final Object enableData = map.get("enabled");
|
||||
if (null != enableData) {
|
||||
customMapStyleOptions.setEnable(toBoolean(enableData));
|
||||
}
|
||||
|
||||
final Object styleData = map.get("styleData");
|
||||
if (null != styleData) {
|
||||
customMapStyleOptions.setStyleData((byte[]) styleData);
|
||||
}
|
||||
final Object styleExtraData = map.get("styleExtraData");
|
||||
if (null != styleExtraData) {
|
||||
customMapStyleOptions.setStyleExtraData((byte[]) styleExtraData);
|
||||
}
|
||||
return customMapStyleOptions;
|
||||
}
|
||||
|
||||
private static final int[] LocationTypeMap = new int[]{MyLocationStyle.LOCATION_TYPE_SHOW, MyLocationStyle.LOCATION_TYPE_FOLLOW, MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE};
|
||||
|
||||
private static MyLocationStyle toMyLocationStyle(Object o, float density) {
|
||||
final Map<?, ?> map = toMap(o);
|
||||
final MyLocationStyle myLocationStyle = new MyLocationStyle();
|
||||
final Object enableData = map.get("enabled");
|
||||
if (null != enableData) {
|
||||
myLocationStyle.showMyLocation(toBoolean(enableData));
|
||||
}
|
||||
//两端差异比较大,Android端设置成跟随但是不移动到中心点模式,与iOS端兼容
|
||||
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
|
||||
// final Object trackingMode = map.get("trackingMode");
|
||||
// if (null != trackingMode) {
|
||||
// int trackingModeIndex = toInt(trackingMode);
|
||||
// if (trackingModeIndex < LocationTypeMap.length) {
|
||||
// myLocationStyle.myLocationType(LocationTypeMap[trackingModeIndex]);
|
||||
// }
|
||||
// }
|
||||
|
||||
final Object circleFillColorData = map.get("circleFillColor");
|
||||
if (null != circleFillColorData) {
|
||||
myLocationStyle.radiusFillColor(toInt(circleFillColorData));
|
||||
}
|
||||
final Object circleStrokeColorData = map.get("circleStrokeColor");
|
||||
if (null != circleStrokeColorData) {
|
||||
myLocationStyle.strokeColor(toInt(circleStrokeColorData));
|
||||
}
|
||||
|
||||
final Object circleStrokeWidthData = map.get("circleStrokeWidth");
|
||||
if (null != circleStrokeWidthData) {
|
||||
myLocationStyle.strokeWidth(toPixels(circleStrokeWidthData));
|
||||
}
|
||||
|
||||
final Object iconDta = map.get("icon");
|
||||
if (null != iconDta) {
|
||||
myLocationStyle.myLocationIcon(toBitmapDescriptor(iconDta));
|
||||
}
|
||||
return myLocationStyle;
|
||||
}
|
||||
|
||||
public static Object location2Map(Location location) {
|
||||
if (null == location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (location.getAltitude() > 90 ||
|
||||
location.getAltitude() < -90 ||
|
||||
location.getLongitude() > 180 ||
|
||||
location.getLongitude() < -180) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, Object> object = new HashMap<String, Object>();
|
||||
object.put("provider", location.getProvider());
|
||||
object.put("latLng", Arrays.asList(location.getLatitude(), location.getLongitude()));
|
||||
object.put("accuracy", location.getAccuracy());
|
||||
object.put("altitude", location.getAltitude());
|
||||
object.put("bearing", location.getBearing());
|
||||
object.put("speed", location.getSpeed());
|
||||
object.put("time", location.getTime());
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
public static BitmapDescriptor toBitmapDescriptor(Object o) {
|
||||
final List<?> data = toList(o);
|
||||
switch (toString(data.get(0))) {
|
||||
case "defaultMarker":
|
||||
if (data.size() == 1) {
|
||||
return BitmapDescriptorFactory.defaultMarker();
|
||||
} else {
|
||||
return BitmapDescriptorFactory.defaultMarker(toFloat(data.get(1)));
|
||||
}
|
||||
case "fromAsset":
|
||||
if (data.size() == 2) {
|
||||
return BitmapDescriptorFactory.fromAsset(
|
||||
FlutterMain.getLookupKeyForAsset(toString(data.get(1))));
|
||||
} else {
|
||||
return BitmapDescriptorFactory.fromAsset(
|
||||
FlutterMain.getLookupKeyForAsset(toString(data.get(1)), toString(data.get(2))));
|
||||
}
|
||||
case "fromAssetImage":
|
||||
if (data.size() == 3) {
|
||||
return BitmapDescriptorFactory.fromAsset(
|
||||
FlutterMain.getLookupKeyForAsset(toString(data.get(1))));
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"'fromAssetImage' Expected exactly 3 arguments, got: " + data.size());
|
||||
}
|
||||
case "fromBytes":
|
||||
return getBitmapFromBytes(data);
|
||||
default:
|
||||
throw new IllegalArgumentException("Cannot interpret " + o + " as BitmapDescriptor");
|
||||
}
|
||||
}
|
||||
|
||||
public static List<BitmapDescriptor> toBitmapDescriptorList(Object o) {
|
||||
List<?> rawList = ConvertUtil.toList(o);
|
||||
List<BitmapDescriptor> bitmapDescriptorList = new ArrayList<BitmapDescriptor>();
|
||||
for (Object obj : rawList) {
|
||||
bitmapDescriptorList.add(ConvertUtil.toBitmapDescriptor(obj));
|
||||
}
|
||||
return bitmapDescriptorList;
|
||||
}
|
||||
|
||||
private static BitmapDescriptor getBitmapFromBytes(List<?> data) {
|
||||
if (data.size() == 2) {
|
||||
try {
|
||||
Bitmap bitmap = toBitmap(data.get(1));
|
||||
return BitmapDescriptorFactory.fromBitmap(bitmap);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Unable to interpret bytes as a valid image.", e);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"fromBytes should have exactly one argument, the bytes. Got: " + data.size());
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap toBitmap(Object o) {
|
||||
byte[] bmpData = (byte[]) o;
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(bmpData, 0, bmpData.length);
|
||||
if (bitmap == null) {
|
||||
throw new IllegalArgumentException("Unable to decode bytes as a valid bitmap.");
|
||||
} else {
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object poiToMap(Poi poi) {
|
||||
if (null == poi) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, Object> data = new HashMap<>();
|
||||
data.put("id", poi.getPoiId());
|
||||
data.put("name", poi.getName());
|
||||
data.put("latLng", latLngToList(poi.getCoordinate()));
|
||||
return data;
|
||||
}
|
||||
|
||||
public static Object latLngToList(LatLng latLng) {
|
||||
if (null == latLng) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.asList(latLng.latitude, latLng.longitude);
|
||||
}
|
||||
|
||||
public static LatLng toLatLng(Object o) {
|
||||
final List<?> data = (List<?>) o;
|
||||
return new LatLng((Double) data.get(0), (Double) data.get(1));
|
||||
}
|
||||
|
||||
public static List<LatLng> toPoints(Object o) {
|
||||
final List<?> data = toList(o);
|
||||
final List<LatLng> points = new ArrayList<>(data.size());
|
||||
|
||||
for (Object ob : data) {
|
||||
final List<?> point = toList(ob);
|
||||
points.add(new LatLng(toFloat(point.get(0)), toFloat(point.get(1))));
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public static LatLngBounds toLatLngBounds(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
final List<?> data = toList(o);
|
||||
return new LatLngBounds(toLatLng(data.get(0)), toLatLng(data.get(1)));
|
||||
}
|
||||
|
||||
private static Float toFloatWrapper(Object o) {
|
||||
return (o == null) ? null : toFloat(o);
|
||||
}
|
||||
|
||||
public static Float toFloatWrapperWithDefault(Object o, float defaultValue) {
|
||||
return (o == null) ? defaultValue : toFloat(o);
|
||||
}
|
||||
|
||||
public static boolean toBoolean(Object o) {
|
||||
return (Boolean) o;
|
||||
}
|
||||
|
||||
public static int toInt(Object o) {
|
||||
return ((Number) o).intValue();
|
||||
}
|
||||
|
||||
public static double toDouble(Object o) {
|
||||
return ((Number) o).doubleValue();
|
||||
}
|
||||
|
||||
public static float toFloat(Object o) {
|
||||
return ((Number) o).floatValue();
|
||||
}
|
||||
|
||||
public static List<?> toList(Object o) {
|
||||
return (List<?>) o;
|
||||
}
|
||||
|
||||
public static Map<?, ?> toMap(Object o) {
|
||||
return (Map<?, ?>) o;
|
||||
}
|
||||
|
||||
public static String toString(Object o) {
|
||||
return (String) o;
|
||||
}
|
||||
|
||||
public static Object getKeyValueFromMapObject(Object object, String keyStr) {
|
||||
if (null == object) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Map<?, ?> mapData = toMap(object);
|
||||
return mapData.get(keyStr);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.amap.flutter.map.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* @author whm
|
||||
* @date 2020/11/6 11:04 AM
|
||||
* @mail hongming.whm@alibaba-inc.com
|
||||
* @since
|
||||
*/
|
||||
public class LogUtil {
|
||||
public static boolean isDebugMode = false;
|
||||
private static final String TAG = "AMapFlutter_";
|
||||
public static void i(String className, String message) {
|
||||
if(isDebugMode) {
|
||||
Log.i(TAG+className, message);
|
||||
}
|
||||
}
|
||||
public static void d(String className, String message) {
|
||||
if(isDebugMode) {
|
||||
Log.d(TAG+className, message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void w(String className, String message) {
|
||||
if(isDebugMode) {
|
||||
Log.w(TAG+className, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void e(String className, String methodName, Throwable e) {
|
||||
if (isDebugMode) {
|
||||
Log.e(TAG+className, methodName + " exception!!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user