hyzp_ybqx-Commit135:为了支持ios版在百度地图中显示文本图标,已经替换使用my_flutter_bmfmap-1.0.2插件,安卓版编译运行正常

master
WinUser01 4 years ago
parent 897adb2683
commit c4b9c508e0

@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":20220426,"versionName":"1.4.28","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":20220502,"versionName":"1.4.29","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

@ -0,0 +1,13 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart"
}
]
}

@ -0,0 +1,9 @@
## 1.0.0
* TODO: Describe initial release.
## 1.0.1
提升版本号
## 1.0.2
解决了与其它Flutter插件冲突的问题

@ -0,0 +1,13 @@
Copyright (C) 2020 Baidu, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,14 @@
# flutter_bmfmap
A new Flutter plugin for BaiDuMap.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/developing-packages/),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

@ -0,0 +1,27 @@
# include: package:pedantic/analysis_options.1.9.0.yaml
analyzer:
errors:
unused_import: warning
unused_shown_name: warning
exclude:
- 'doc/**'
- 'lib/src/third_party/pkg/**'
- 'lib/templates/*.html'
- 'pub.dartlang.org/**'
- 'testing/**'
- 'testing/test_package_flutter_plugin/**'
- 'testing/test_package_export_error/**'
linter:
rules:
# - always_declare_return_types
- annotate_overrides
- avoid_init_to_null
- directives_ordering
- no_adjacent_strings_in_list
- package_api_docs
- prefer_final_fields
- prefer_generic_function_type_aliases
- slash_for_doc_comments
- unawaited_futures
# - unnecessary_brace_in_string_interps

@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

@ -0,0 +1,46 @@
group 'com.baidu.flutter_bmfmap'
version '1.0'
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
}
lintOptions {
disable 'InvalidPackage'
}
}
repositories {
mavenLocal()
}
dependencies {
implementation fileTree(includes: ['*.jar'], dir: 'libs')
implementation rootProject.findProject(":flutter_bmfbase")
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
}

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

@ -0,0 +1 @@
rootProject.name = 'flutter_bmfmap'

@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.baidu.flutter_bmfmap">
</manifest>

@ -0,0 +1,38 @@
package com.baidu.flutter_bmfmap;
import android.content.Context;
import com.baidu.mapapi.map.MapView;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
public class BMFEventHandler<ViewType> implements EventChannel.StreamHandler {
private Context mContext;
private ViewType mMapView;
private BinaryMessenger mMessager;
private MethodChannel mMethodChannel;
private EventChannel mEventChannel;
public BMFEventHandler(Context context, ViewType mapView, MethodChannel methodChannel, EventChannel eventChannel){
mContext = context;
mMapView = mapView;
mMethodChannel = methodChannel;
mEventChannel = eventChannel;
}
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
}
@Override
public void onCancel(Object arguments) {
}
}

@ -0,0 +1,36 @@
package com.baidu.flutter_bmfmap;
import android.content.Context;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
public class BMFHandlerHelper <ViewType>{
private MethodChannel mMethodChannel;
private BMFMethodHandler mBMFMethodHandler;
private EventChannel mEventChannel;
private BMFEventHandler mBMFEventHandler;
public BMFHandlerHelper(Context context
, FlutterCommonMapView mapView
, MethodChannel methodChannel
, EventChannel eventChannel){
init(context, mapView, methodChannel, eventChannel);
}
private void init(Context context, FlutterCommonMapView mapView, MethodChannel methodChannel, EventChannel eventChannel){
mMethodChannel = methodChannel;
mBMFMethodHandler = new BMFMethodHandler(context, mapView, methodChannel, eventChannel);
mMethodChannel.setMethodCallHandler(mBMFMethodHandler);
mEventChannel = eventChannel;
mBMFEventHandler = new BMFEventHandler(context, mapView, methodChannel, eventChannel);
mEventChannel.setStreamHandler(mBMFEventHandler);
}
}

@ -0,0 +1,62 @@
package com.baidu.flutter_bmfmap;
import android.content.Context;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.mapHandler.BMapHandlerFactory;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.map.overlayHandler.OverlayHandlerFactory;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.mapapi.map.BaiduMap;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class BMFMethodHandler implements MethodChannel.MethodCallHandler {
private static final String TAG = "BMFMethodHandler";
private Context mContext;
private FlutterCommonMapView mMapView;
private final BaiduMap mBaiduMap;
private MethodChannel mMethodChannel;
private EventChannel mEventChannel;
public BMFMethodHandler(Context context
,FlutterCommonMapView mapView
,MethodChannel methodChannel
,EventChannel eventChannel){
mContext = context;
mMapView = mapView;
mBaiduMap = mapView.getBaiduMap();
mMethodChannel = methodChannel;
mEventChannel = eventChannel;
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if(Env.DEBUG){
Log.d(TAG,"onMethodCall enter");
}
if(null == call || null == result){
Log.d(TAG,"null == call || null == result");
return;
}
if (null == mMapView || null == mBaiduMap) {
Log.d(TAG,"mMapView == call || mBaiduMap == result");
return;
}
boolean ret = OverlayHandlerFactory.getInstance(mBaiduMap).dispatchMethodHandler(call,
result);
if (!ret) {
BMapHandlerFactory.getInstance(mMapView).dispatchMethodHandler(mContext,call,
result, mMethodChannel);
}
}
}

@ -0,0 +1,127 @@
package com.baidu.flutter_bmfmap;
import android.util.Log;
import androidx.annotation.NonNull;
import com.baidu.flutter_bmfmap.map.OfflineHandler;
import com.baidu.flutter_bmfmap.utils.Constants;
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.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.platform.PlatformViewRegistry;
/** FlutterBmfmapPlugin */
public class FlutterBmfmapPlugin implements FlutterPlugin, ActivityAware, MethodCallHandler {
private static final String TAG = FlutterBmfmapPlugin.class.getSimpleName();
private OfflineHandler mOfflineHandler;
private PlatformViewRegistry mPlatformViewRegistry;
private BinaryMessenger mMessenger;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
if(null == flutterPluginBinding){
return;
}
mMessenger = flutterPluginBinding.getBinaryMessenger();
if (null == mMessenger) {
return;
}
mOfflineHandler = new OfflineHandler();
mOfflineHandler.init(mMessenger);
mPlatformViewRegistry = flutterPluginBinding.getPlatformViewRegistry();
}
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
// plugin registration via this function while apps migrate to use the new Android APIs
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
//
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
// in the same class.
public static void registerWith(Registrar registrar) {
OfflineHandler offlineHandler = new OfflineHandler();
offlineHandler.init(registrar.messenger());
registrar.platformViewRegistry().registerViewFactory(
Constants.ViewType.sMapView,
new MapViewFactory(registrar.activity()
, registrar.messenger()
, Constants.ViewType.sMapView));
registrar.platformViewRegistry().registerViewFactory(
Constants.ViewType.sTextureMapView,
new TextureMapViewFactory(registrar.activity()
, registrar.messenger()
, Constants.ViewType.sTextureMapView));
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
}else{
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
if(null == binding){
return;
}
BinaryMessenger binaryMessenger = binding.getBinaryMessenger();
if(null == binaryMessenger){
return;
}
mOfflineHandler.unInit(binding.getBinaryMessenger());
}
@Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
if(null == binding || null == mPlatformViewRegistry || null == mMessenger){
return;
}
mPlatformViewRegistry.registerViewFactory(
Constants.ViewType.sMapView,
new MapViewFactory(binding.getActivity()
, mMessenger
, Constants.ViewType.sMapView));
mPlatformViewRegistry.registerViewFactory(
Constants.ViewType.sTextureMapView,
new TextureMapViewFactory(binding.getActivity()
, mMessenger
, Constants.ViewType.sTextureMapView));
}
@Override
public void onDetachedFromActivityForConfigChanges() {
Log.d(TAG, "onDetachedFromActivityForConfigChanges");
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
Log.d(TAG, "onReattachedToActivityForConfigChanges");
}
@Override
public void onDetachedFromActivity() {
Log.d(TAG, "onDetachedFromActivity");
}
}

@ -0,0 +1,40 @@
package com.baidu.flutter_bmfmap;
import android.content.Context;
import android.util.Log;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
import com.baidu.flutter_bmfmap.map.FlutterMapView;
import com.baidu.flutter_bmfmap.utils.Env;
public class MapViewFactory extends PlatformViewFactory {
private static final String TAG = "ViewFactory";
private BinaryMessenger mMessenger;
private Context mContext;
private String mViewType;
/**
* @param messenger the codec used to decode the args parameter of {@link #create}.
*/
public MapViewFactory(Context context, BinaryMessenger messenger, String viewType) {
super(StandardMessageCodec.INSTANCE);
if(Env.DEBUG){
Log.d(TAG, "ViewFactory");
}
mContext = context;
mMessenger = messenger;
mViewType = viewType;
}
@Override
public PlatformView create(Context context, int viewId, Object args) {
if(Env.DEBUG){
Log.d(TAG, "create");
}
return new FlutterMapView(mContext, mMessenger, viewId, args, mViewType);
}
}

@ -0,0 +1,42 @@
package com.baidu.flutter_bmfmap;
import android.content.Context;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterMapView;
import com.baidu.flutter_bmfmap.map.FlutterTextureMapView;
import com.baidu.flutter_bmfmap.utils.Env;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class TextureMapViewFactory extends PlatformViewFactory {
private static final String TAG = "ViewFactory";
private BinaryMessenger mMessenger;
private Context mContext;
private String mViewType;
/**
* @param messenger the codec used to decode the args parameter of {@link #create}.
*/
public TextureMapViewFactory(Context context, BinaryMessenger messenger, String viewType) {
super(StandardMessageCodec.INSTANCE);
if(Env.DEBUG){
Log.d(TAG, "ViewFactory");
}
mContext = context;
mMessenger = messenger;
mViewType = viewType;
}
@Override
public PlatformView create(Context context, int viewId, Object args) {
if(Env.DEBUG){
Log.d(TAG, "create");
}
return new FlutterTextureMapView(mContext, mMessenger, viewId, args, mViewType);
}
}

@ -0,0 +1,27 @@
package com.baidu.flutter_bmfmap.map;
import java.util.Map;
public abstract class FlutterBaseMapView {
protected String mViewType;
protected boolean mResume = false;
protected int mGetViewCount = 0;
protected abstract void init(int viewId, Object args);
protected abstract void initMapView(Object args, FlutterCommonMapView flutterCommonMapView);
protected void initMapStatus(Map<String, Object> mapOptionsMap,
FlutterCommonMapView flutterCommonMapView) {
if (null == mapOptionsMap) {
return;
}
MapStateUpdateImp.getInstance()
.setCommView(flutterCommonMapView)
.updateMapState(mapOptionsMap);
}
}

@ -0,0 +1,58 @@
package com.baidu.flutter_bmfmap.map;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.TextureMapView;
import java.util.Map;
public abstract class FlutterCommonMapView{
protected String mViewType;
public String getViewType(){
return mViewType;
}
public void setmViewType(String viewType){
mViewType = viewType;
}
abstract public MapView getMapView();
abstract public TextureMapView getTextureMapView();
public BaiduMap getBaiduMap(){
BaiduMap baiduMap = null;
switch (mViewType){
case Constants.ViewType.sMapView:
baiduMap = getBaiduMapFromMapView();
break;
case Constants.ViewType.sTextureMapView:
baiduMap = getBaiduMapFromTextureMapView();
break;
default:
break;
}
return baiduMap;
}
private BaiduMap getBaiduMapFromMapView(){
MapView mapView = this.getMapView();
if(null == mapView){
return null;
}
return mapView.getMap();
}
private BaiduMap getBaiduMapFromTextureMapView(){
TextureMapView textureMapView = this.getTextureMapView();
if(null == textureMapView){
return null;
}
return textureMapView.getMap();
}
}

@ -0,0 +1,170 @@
package com.baidu.flutter_bmfmap.map;
import static com.baidu.flutter_bmfmap.utils.Constants.MAX_GET_VIEW_CNT_BY_FLUTTER_RESIZE;
import java.util.Map;
import com.baidu.flutter_bmfmap.BMFHandlerHelper;
import com.baidu.flutter_bmfmap.map.mapHandler.BMapHandlerFactory;
import com.baidu.flutter_bmfmap.map.overlayHandler.OverlayHandlerFactory;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.mapapi.map.MapView;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
public class FlutterMapView extends FlutterBaseMapView implements PlatformView {
private static final String TAG = "FlutterMapView";
private MapView mMapView;
private Context mContext;
private BinaryMessenger mMessager;
private BMFHandlerHelper mBMFHandlerHelper;
private MethodChannel mMethodChannel;
private EventChannel mEventChannel;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Constants.sConfigChangedAction.equals(action) && !mResume) {
mResume = true;
}
}
};
public FlutterMapView(Context context,
BinaryMessenger messenger,
int viewId,
Object args,
String viewType) {
if (Env.DEBUG) {
Log.d(TAG, "FlutterMapView");
}
mContext = context;
mMessager = messenger;
mViewType = viewType;
init(viewId, args);
}
protected void init(int viewId, Object args) {
if (Env.DEBUG) {
Log.d(TAG, "init");
}
mMapView = new MapView(mContext);
FlutterCommonMapView mapViewWrapper = new MapViewWrapper(this, mViewType);
initMapView(args, mapViewWrapper);
mMethodChannel = new MethodChannel(mMessager,
Constants.VIEW_METHOD_CHANNEL_PREFIX + (char) (viewId + 97));
mEventChannel = new EventChannel(mMessager,
Constants.VIEW_EVENT_CHANNEL_PREFIX + (char) (viewId + 97));
mBMFHandlerHelper =
new BMFHandlerHelper(mContext, mapViewWrapper, mMethodChannel, mEventChannel);
new MapListener(new MapViewWrapper(this, mViewType), mMethodChannel);
IntentFilter intentFilter = new IntentFilter(Constants.sConfigChangedAction);
LocalBroadcastManager.getInstance(mContext).registerReceiver(mReceiver, intentFilter);
if (Env.DEBUG) {
Log.d(TAG, "init success");
}
}
protected void initMapView(Object args, FlutterCommonMapView flutterCommonMapView) {
if (null == mContext) {
return;
}
Map<String, Object> mapOptionsMap = (Map<String, Object>) args;
if (null == mapOptionsMap) {
return;
}
initMapStatus(mapOptionsMap, flutterCommonMapView);
}
@Override
public View getView() {
if (Env.DEBUG) {
Log.d(TAG, "getView");
}
if (mResume) {
mGetViewCount++;
}
if (mGetViewCount >= MAX_GET_VIEW_CNT_BY_FLUTTER_RESIZE - 1) {
mMapView.onResume();
mResume = false;
mGetViewCount = 0;
}
return mMapView;
}
@Override
public void onFlutterViewAttached(@NonNull View flutterView) {
if (Env.DEBUG) {
Log.d(TAG, "onFlutterViewAttached");
}
if (null != mMapView) {
mMapView.onResume();
}
}
@Override
public void onFlutterViewDetached() {
if (Env.DEBUG) {
Log.d(TAG, "onFlutterViewDetached");
}
if (null != mMapView) {
mMapView.onPause();
}
}
@Override
public void dispose() {
if (Env.DEBUG) {
Log.d(TAG, "dispose");
}
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReceiver);
BMapHandlerFactory.getInstance(null).clean();
OverlayHandlerFactory.getInstance(null).clean();
if (null != mMapView) {
mMapView.onDestroy();
}
}
public void setResumeState(boolean resume) {
mResume = true;
}
public MapView getMapView() {
return mMapView;
}
}

@ -0,0 +1,152 @@
package com.baidu.flutter_bmfmap.map;
import static com.baidu.flutter_bmfmap.utils.Constants.MAX_GET_VIEW_CNT_BY_FLUTTER_RESIZE;
import java.util.Map;
import com.baidu.flutter_bmfmap.BMFHandlerHelper;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.mapapi.map.TextureMapView;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
public class FlutterTextureMapView extends FlutterBaseMapView implements PlatformView {
private static final String TAG = "FlutterMapView";
private TextureMapView mTextureMapView;
private Context mContext;
private BinaryMessenger mMessager;
private BMFHandlerHelper mBMFHandlerHelper;
private MethodChannel mMethodChannel;
private EventChannel mEventChannel;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Constants.sConfigChangedAction.equals(action) && !mResume) {
mResume = true;
}
}
};
public FlutterTextureMapView(Context context,
BinaryMessenger messenger,
int viewId,
Object args,
String viewType) {
Log.d(TAG, "FlutterMapView");
mContext = context;
mMessager = messenger;
mViewType = viewType;
init(viewId, args);
}
protected void init(int viewId, Object args) {
if (Env.DEBUG) {
Log.d(TAG, "init");
}
mTextureMapView = new TextureMapView(mContext);
FlutterCommonMapView flutterCommonMapView =
new TextureMapViewWrapper(mTextureMapView, mViewType);
initMapView(args, flutterCommonMapView);
mMethodChannel = new MethodChannel(mMessager,
Constants.VIEW_METHOD_CHANNEL_PREFIX + (char) (viewId + 97));
mEventChannel = new EventChannel(mMessager,
Constants.VIEW_EVENT_CHANNEL_PREFIX + (char) (viewId + 97));
mBMFHandlerHelper =
new BMFHandlerHelper(mContext, flutterCommonMapView, mMethodChannel, mEventChannel);
new MapListener(new TextureMapViewWrapper(mTextureMapView, mViewType), mMethodChannel);
IntentFilter intentFilter = new IntentFilter(Constants.sConfigChangedAction);
LocalBroadcastManager.getInstance(mContext).registerReceiver(mReceiver, intentFilter);
if (Env.DEBUG) {
Log.d(TAG, "init success");
}
}
protected void initMapView(Object args, FlutterCommonMapView flutterCommonMapView) {
if (null == mContext) {
return;
}
Map<String, Object> mapOptionsMap = (Map<String, Object>) args;
if (null == mapOptionsMap) {
return;
}
initMapStatus(mapOptionsMap, flutterCommonMapView);
}
@Override
public View getView() {
if (Env.DEBUG) {
Log.d(TAG, "getView");
}
if (mResume) {
mGetViewCount++;
}
if (mGetViewCount >= MAX_GET_VIEW_CNT_BY_FLUTTER_RESIZE - 1) {
mTextureMapView.onResume();
mResume = false;
mGetViewCount = 0;
}
return mTextureMapView;
}
@Override
public void onFlutterViewAttached(@NonNull View flutterView) {
if (null != mTextureMapView) {
mTextureMapView.onResume();
}
}
@Override
public void onFlutterViewDetached() {
if (null != mTextureMapView) {
mTextureMapView.onPause();
}
}
@Override
public void dispose() {
if (Env.DEBUG) {
Log.d(TAG, "dispose");
}
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReceiver);
if (null != mTextureMapView) {
mTextureMapView.onDestroy();
}
}
}

@ -0,0 +1,696 @@
package com.baidu.flutter_bmfmap.map;
import android.graphics.Point;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import android.os.Message;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapBaseIndoorMapInfo;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.model.LatLng;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Handler;
import javax.microedition.khronos.opengles.GL10;
import io.flutter.plugin.common.MethodChannel;
import com.baidu.flutter_bmfmap.utils.ThreadPoolUtil;
import com.baidu.mapapi.model.LatLngBounds;
@SuppressWarnings("unchecked")
public class MapListener implements BaiduMap.OnMapClickListener ,BaiduMap.OnMapLoadedCallback,
BaiduMap.OnMapStatusChangeListener ,BaiduMap.OnMapRenderCallback,BaiduMap.OnMapDrawFrameCallback,
BaiduMap.OnBaseIndoorMapListener ,BaiduMap.OnMarkerClickListener,BaiduMap.OnPolylineClickListener,
BaiduMap.OnMapDoubleClickListener,BaiduMap.OnMapLongClickListener,BaiduMap.OnMarkerDragListener,
BaiduMap.OnMapRenderValidDataListener,BaiduMap.OnMyLocationClickListener {
private static final int DRAW_FRAME_MESSAGE = 0;
private static final String TAG = "MapListener";
private BaiduMap mBaiduMap;
private MethodChannel mMethodChannel;
private int mReason;
private HashMap<String, HashMap> mStatusMap;
private final Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == DRAW_FRAME_MESSAGE) {
if (null != mStatusMap){
mMethodChannel.invokeMethod(
Constants.MethodProtocol.MapStateProtocol.sMapOnDrawMapFrameCallback,mStatusMap);
}
}
}
};
public MapListener(FlutterCommonMapView mapView, MethodChannel methodChannel) {
this.mMethodChannel = methodChannel;
if (null == mapView) {
return;
}
mBaiduMap = mapView.getBaiduMap();
initListener();
}
private void initListener() {
if (null == mBaiduMap) {
return;
}
mBaiduMap.setOnMapClickListener(this);
mBaiduMap.setOnMapLoadedCallback(this);
mBaiduMap.setOnMapStatusChangeListener(this);
mBaiduMap.setOnMapDrawFrameCallback(this);
mBaiduMap.setOnMapRenderCallbadk(this);
mBaiduMap.setOnBaseIndoorMapListener(this);
mBaiduMap.setOnMarkerClickListener(this);
mBaiduMap.setOnPolylineClickListener(this);
mBaiduMap.setOnMapDoubleClickListener(this);
mBaiduMap.setOnMapLongClickListener(this);
mBaiduMap.setOnMarkerDragListener(this);
mBaiduMap.setOnMapRenderValidDataListener(this);
mBaiduMap.setOnMyLocationClickListener(this);
}
@Override
public void onMapClick(LatLng latLng) {
if (null == latLng || mMethodChannel == null) {
return;
}
HashMap<String, HashMap> coordinateMap = new HashMap<>();
HashMap<String, Double> coord = new HashMap<>();
coord.put("latitude",latLng.latitude);
coord.put("longitude",latLng.longitude);
coordinateMap.put("coord",coord);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapOnClickedMapBlankCallback,coordinateMap);
}
@Override
public void onMapPoiClick(MapPoi mapPoi) {
if (null == mapPoi || mMethodChannel == null) {
return;
}
HashMap<String, Double> pt = new HashMap<>();
LatLng position = mapPoi.getPosition();
if (null != position) {
pt.put("latitude",mapPoi.getPosition().latitude);
pt.put("longitude",mapPoi.getPosition().longitude);
}
HashMap<String, HashMap> poiMap = new HashMap<>();
HashMap poi = new HashMap();
poi.put("text",mapPoi.getName());
poi.put("uid",mapPoi.getUid());
poi.put("pt",pt);
poiMap.put("poi",poi);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapOnClickedMapPoiCallback,poiMap);
}
@Override
public void onMapLoaded() {
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapDidLoadCallback,"");
}
@Override
public void onMapStatusChangeStart(MapStatus mapStatus) {
if (null == mapStatus || mMethodChannel == null) {
return;
}
HashMap<String, Double> targetScreenMap = new HashMap<>();
Point targetScreen = mapStatus.targetScreen;
if (null == targetScreen) {
return;
}
targetScreenMap.put("x", (double) targetScreen.x);
targetScreenMap.put("y", (double) targetScreen.y);
HashMap<String, Double> targetMap = new HashMap<>();
LatLng latLng = mapStatus.target;
if (null == latLng){
return;
}
targetMap.put("latitude", latLng.latitude);
targetMap.put("longitude", latLng.longitude);
LatLngBounds bound = mapStatus.bound;
if (null == bound) {
return;
}
HashMap latLngBoundMap = latLngBounds(bound);
if (null == latLngBoundMap) {
return;
}
HashMap statusMap = new HashMap<>();
HashMap status = new HashMap();
status.put("fLevel",((double)mapStatus.zoom));
double rotate = mapStatus.rotate;
if (rotate > 180) {
rotate = rotate - 360;
}
status.put("fRotation", rotate);
status.put("fOverlooking",((double) mapStatus.overlook));
status.put("targetScreenPt",targetScreenMap);
status.put("targetGeoPt",targetMap);
status.put("visibleMapBounds",latLngBoundMap);
statusMap.put("mapStatus",status);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapRegionWillChangeCallback,statusMap);
}
@Override
public void onMapStatusChangeStart(MapStatus mapStatus, int reason) {
if (null == mapStatus || mMethodChannel == null) {
return;
}
mReason = reason;
HashMap<String, Double> targetScreenMap = new HashMap<>();
Point targetScreen = mapStatus.targetScreen;
if (null == targetScreen) {
return;
}
targetScreenMap.put("x", (double) targetScreen.x);
targetScreenMap.put("y", (double) targetScreen.y);
HashMap<String, Double> targetMap = new HashMap<>();
LatLng latLng = mapStatus.target;
if (null == latLng){
return;
}
targetMap.put("latitude", latLng.latitude);
targetMap.put("longitude", latLng.longitude);
LatLngBounds bound = mapStatus.bound;
if (null == bound) {
return;
}
HashMap latLngBoundMap = latLngBounds(bound);
if (null == latLngBoundMap) {
return;
}
HashMap statusMap = new HashMap<>();
HashMap status = new HashMap();
status.put("fLevel",((double)mapStatus.zoom));
double rotate = mapStatus.rotate;
if (rotate > 180) {
rotate = rotate - 360;
}
status.put("fRotation", rotate);
status.put("fOverlooking",((double) mapStatus.overlook));
status.put("targetScreenPt",targetScreenMap);
status.put("targetGeoPt",targetMap);
status.put("visibleMapBounds",latLngBoundMap);
statusMap.put("mapStatus",status);
statusMap.put("reason",mReason);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.
sMapRegionWillChangeWithReasonCallback,statusMap);
}
@Override
public void onMapStatusChange(MapStatus mapStatus) {
if (null == mapStatus || mMethodChannel == null) {
return;
}
HashMap<String, Double> targetScreenMap = new HashMap<>();
Point targetScreen = mapStatus.targetScreen;
if (null == targetScreen) {
return;
}
targetScreenMap.put("x", (double) targetScreen.x);
targetScreenMap.put("y", (double) targetScreen.y);
HashMap<String, Double> targetMap = new HashMap<>();
LatLng latLng = mapStatus.target;
if (null == latLng){
return;
}
targetMap.put("latitude", latLng.latitude);
targetMap.put("longitude", latLng.longitude);
LatLngBounds bound = mapStatus.bound;
if (null == bound) {
return;
}
HashMap latLngBoundMap = latLngBounds(bound);
if (null == latLngBoundMap) {
return;
}
HashMap statusMap = new HashMap<>();
HashMap status = new HashMap();
status.put("fLevel",((double)mapStatus.zoom));
double rotate = mapStatus.rotate;
if (rotate > 180) {
rotate = rotate - 360;
}
status.put("fRotation", rotate);
status.put("fOverlooking",((double) mapStatus.overlook));
status.put("targetScreenPt",targetScreenMap);
status.put("targetGeoPt",targetMap);
status.put("visibleMapBounds",latLngBoundMap);
statusMap.put("mapStatus",status);
mMethodChannel.invokeMethod(
Constants.MethodProtocol.MapStateProtocol.sMapRegionDidChangeCallback,statusMap);
}
@Override
public void onMapStatusChangeFinish(MapStatus mapStatus) {
if (null == mapStatus || mMethodChannel == null) {
return;
}
HashMap<String, Double> targetScreenMap = new HashMap<>();
Point targetScreen = mapStatus.targetScreen;
if (null == targetScreen) {
return;
}
targetScreenMap.put("x", (double) targetScreen.x);
targetScreenMap.put("y", (double) targetScreen.y);
HashMap<String, Double> targetMap = new HashMap<>();
LatLng latLng = mapStatus.target;
if (null == latLng){
return;
}
targetMap.put("latitude", latLng.latitude);
targetMap.put("longitude", latLng.longitude);
LatLngBounds bound = mapStatus.bound;
if (null == bound) {
return;
}
HashMap latLngBoundMap = latLngBounds(bound);
if (null == latLngBoundMap) {
return;
}
HashMap statusMap = new HashMap<>();
HashMap status = new HashMap();
status.put("fLevel",((double)mapStatus.zoom));
double rotate = mapStatus.rotate;
if (rotate > 180) {
rotate = rotate - 360;
}
status.put("fRotation", rotate);
status.put("fOverlooking",((double) mapStatus.overlook));
status.put("targetScreenPt",targetScreenMap);
status.put("targetGeoPt",targetMap);
status.put("visibleMapBounds",latLngBoundMap);
statusMap.put("mapStatus",status);
statusMap.put("reason",mReason);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapRegionDidChangeWithReasonCallback,statusMap);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapStatusDidChangedCallback,"");
}
@Override
public void onMapRenderFinished() {
HashMap hashMap = new HashMap();
hashMap.put("success",true);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapDidFinishRenderCallback,hashMap);
}
@Override
public void onMapDrawFrame(GL10 gl10, MapStatus mapStatus) {
}
@Override
public void onMapDrawFrame(MapStatus mapStatus) {
if (null == mapStatus || mMethodChannel == null) {
return;
}
HashMap<String, Double> targetScreenMap = new HashMap<>();
Point targetScreen = mapStatus.targetScreen;
if (null == targetScreen) {
return;
}
targetScreenMap.put("x", (double) targetScreen.x);
targetScreenMap.put("y", (double) targetScreen.y);
HashMap<String, Double> targetMap = new HashMap<>();
LatLng latLng = mapStatus.target;
if (null == latLng){
return;
}
targetMap.put("latitude", latLng.latitude);
targetMap.put("longitude", latLng.longitude);
LatLngBounds bound = mapStatus.bound;
if (null == bound) {
return;
}
HashMap latLngBoundMap = latLngBounds(bound);
if (null == latLngBoundMap) {
return;
}
mStatusMap = new HashMap<>();
HashMap status = new HashMap();
status.put("fLevel",((double)mapStatus.zoom));
double rotate = mapStatus.rotate;
if (rotate > 180) {
rotate = rotate - 360;
}
status.put("fRotation", rotate);
status.put("fOverlooking",((double) mapStatus.overlook));
status.put("targetScreenPt",targetScreenMap);
status.put("targetGeoPt",targetMap);
status.put("visibleMapBounds",latLngBoundMap);
mStatusMap.put("mapStatus",status);
ThreadPoolUtil.getInstance().execute(new Runnable() {
@Override
public void run() {
Message msg = Message.obtain();
msg.arg1 = DRAW_FRAME_MESSAGE;
mHandler.sendMessage(msg);
}
});
}
@Override
public void onBaseIndoorMapMode(boolean isIndoorMap, MapBaseIndoorMapInfo mapBaseIndoorMapInfo) {
if (mMethodChannel == null) {
return;
}
HashMap indoorHashMap = new HashMap();
indoorHashMap.put("flag",isIndoorMap);
HashMap indoorMap = new HashMap();
if (isIndoorMap) {
if (null == mapBaseIndoorMapInfo) {
return;
}
String curFloor = mapBaseIndoorMapInfo.getCurFloor();
String id = mapBaseIndoorMapInfo.getID();
ArrayList<String> floors = mapBaseIndoorMapInfo.getFloors();
indoorMap.put("strFloor", curFloor);
indoorMap.put("strID", id);
indoorMap.put("listStrFloors", floors);
}
indoorHashMap.put("info",indoorMap);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapInOrOutBaseIndoorMapCallback
,indoorHashMap);
}
@Override
public boolean onMarkerClick(Marker marker) {
if(Env.DEBUG){
Log.d(TAG, "onMarkerClick");
}
if(null == mMethodChannel){
return false;
}
Bundle bundle = marker.getExtraInfo();
if(null == bundle){
if(Env.DEBUG){
Log.d(TAG, "bundle is null");
}
return false;
}
String id = bundle.getString("id");
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "marker id is null ");
}
return false;
}
Map<String, Object> clickMap = new HashMap<>();
clickMap.put("id", id);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MarkerProtocol.sMapClickedmarkedMethod, clickMap);
return true;
}
@Override
public boolean onPolylineClick(Polyline polyline) {
Log.d("polyline", "polyline click");
HashMap hashMap = polylineClick(polyline);
HashMap<String, Object> polyLineMap = new HashMap<>();
polyLineMap.put("polyline", hashMap);
mMethodChannel.invokeMethod(Constants.MethodProtocol.PolylineProtocol.sMapOnClickedOverlayCallback, polyLineMap);
return true;
}
private HashMap polylineClick(Polyline polyline) {
if (null == polyline) {
return null;
}
Bundle bundle = polyline.getExtraInfo();
String id = bundle.getString("id");
HashMap polylineMap = new HashMap();
List<LatLng> points = polyline.getPoints();
List<Object> latlngLists = new ArrayList<>();
if (null != points){
for (int i = 0; i < points.size(); i++) {
HashMap<String, Double> latlngHashMap = new HashMap<>();
latlngHashMap.put("latitude",points.get(i).latitude);
latlngHashMap.put("longitude",points.get(i).longitude);
latlngLists.add(latlngHashMap);
}
}
polylineMap.put("id", id);
polylineMap.put("coordinates",latlngLists);
ArrayList<String> colorList = new ArrayList<>();
int[] colors = polyline.getColorList();
if(null != colors){
for(int i = 0; i < colors.length; i++){
colorList.add(Integer.toHexString(colors[i]));
}
}
polylineMap.put("colors", colorList);
polylineMap.put("color", polyline.getColor());
polylineMap.put("lineDashType", polyline.getDottedLineType());
polylineMap.put("lineCapType", 0);
polylineMap.put("lineJoinType", 0);
polylineMap.put("width", polyline.getWidth());
polylineMap.put("zIndex", polyline.getZIndex());
return polylineMap;
}
@Override
public void onMapDoubleClick(LatLng latLng) {
if (null == latLng || mMethodChannel == null) {
return;
}
HashMap<String, HashMap> coordinateMap = new HashMap<>();
HashMap<String, Double> coord = new HashMap<>();
coord.put("latitude",latLng.latitude);
coord.put("longitude",latLng.longitude);
coordinateMap.put("coord",coord);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapOnDoubleClickCallback,coordinateMap);
}
@Override
public void onMapLongClick(LatLng latLng) {
if (null == latLng || mMethodChannel == null) {
return;
}
HashMap<String, HashMap> coordinateMap = new HashMap<>();
HashMap<String, Double> coord = new HashMap<>();
coord.put("latitude",latLng.latitude);
coord.put("longitude",latLng.longitude);
coordinateMap.put("coord",coord);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapOnLongClickCallback,coordinateMap);
}
@Override
public void onMarkerDrag(Marker marker) {
if(Env.DEBUG){
Log.d(TAG, "onMarkerDrag");
}
if(null == mMethodChannel){
return;
}
Bundle bundle = marker.getExtraInfo();
if(null == bundle){
return;
}
String id = bundle.getString("id");
if(null == mMethodChannel){
return;
}
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "id is null");
}
return;
}
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "id is null");
}
return;
}
Map<String, Object> dragMap = new HashMap<>();
dragMap.put("id", id);
Map<String, Object> extraInfoMap = new HashMap<>();
extraInfoMap.put("state", Constants.MethodProtocol.MarkerProtocol.MarkerDragState.sDragging);
dragMap.put("extra", extraInfoMap);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MarkerProtocol.sMapDragMarkerMethod, dragMap);
}
@Override
public void onMarkerDragEnd(Marker marker) {
if(Env.DEBUG){
Log.d(TAG, "onMarkerDrag");
}
if(null == mMethodChannel){
return;
}
Bundle bundle = marker.getExtraInfo();
if(null == bundle){
return;
}
String id = bundle.getString("id");
if(null == mMethodChannel){
return;
}
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "id is null");
}
return;
}
LatLng center = marker.getPosition();
if(null == center){
return;
}
Map<String, Object> dragMap = new HashMap<>();
dragMap.put("id", id);
Map<String, Double> centerMap = new HashMap<>();
centerMap.put("latitude", center.latitude);
centerMap.put("longitude", center.longitude);
Map<String, Object> extraInfoMap = new HashMap<>();
extraInfoMap.put("center", centerMap);
extraInfoMap.put("state", Constants.MethodProtocol.MarkerProtocol.MarkerDragState.sDragEnd);
dragMap.put("extra", extraInfoMap);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MarkerProtocol.sMapDragMarkerMethod, dragMap);
}
@Override
public void onMarkerDragStart(Marker marker) {
if(Env.DEBUG){
Log.d(TAG, "onMarkerDrag");
}
Bundle bundle = marker.getExtraInfo();
if(null == bundle){
return;
}
String id = bundle.getString("id");
if(null == mMethodChannel){
return;
}
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "id is null");
}
return;
}
LatLng center = marker.getPosition();
if(null == center){
return;
}
Map<String, Object> dragMap = new HashMap<>();
dragMap.put("id", id);
Map<String, Double> centerMap = new HashMap<>();
centerMap.put("latitude", center.latitude);
centerMap.put("longitude", center.longitude);
Map<String, Object> extraInfoMap = new HashMap<>();
extraInfoMap.put("center", centerMap);
extraInfoMap.put("state", Constants.MethodProtocol.MarkerProtocol.MarkerDragState.sDragStart);
dragMap.put("extra", extraInfoMap);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MarkerProtocol.sMapDragMarkerMethod, dragMap);
}
@Override
public void onMapRenderValidData(boolean isValid, int errorCode, String errorMessage) {
HashMap hashMap = new HashMap();
hashMap.put("isValid",isValid);
hashMap.put("errorCode",errorCode);
hashMap.put("errorMessage",errorMessage);
mMethodChannel.invokeMethod(Constants.MethodProtocol.MapStateProtocol.sMapRenderValidDataCallback,hashMap);
}
@Override
public boolean onMyLocationClick() {
return false;
}
private HashMap latLngBounds(LatLngBounds latLngBounds) {
if (null == latLngBounds) {
return null;
}
// 该地理范围东北坐标
LatLng northeast = latLngBounds.northeast;
// 该地理范围西南坐标
LatLng southwest = latLngBounds.southwest;
HashMap boundsMap = new HashMap();
HashMap northeastMap = new HashMap<String,Double>();
if (null == northeast){
return null;
}
northeastMap.put("latitude", northeast.latitude);
northeastMap.put("longitude",northeast.longitude);
HashMap southwestMap = new HashMap<String,Double>();
if (null == southwest) {
return null;
}
southwestMap.put("latitude",southwest.latitude);
southwestMap.put("longitude", southwest.longitude);
boundsMap.put("northeast",northeastMap);
boundsMap.put("southwest",southwestMap);
return boundsMap;
}
}

@ -0,0 +1,363 @@
package com.baidu.flutter_bmfmap.map;
import java.util.Map;
import com.baidu.flutter_bmfmap.map.mapHandler.BMFMapStatus;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.LogoPosition;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.map.UiSettings;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import android.graphics.Point;
import android.text.TextUtils;
/**
*
*/
public class MapStateUpdateImp {
private static MapStateUpdateImp sInstance = null;
private String mViewType;
private FlutterCommonMapView mFlutterCommonMapView;
private BaiduMap mBaiduMap;
private UiSettings mUiSettings;
public static MapStateUpdateImp getInstance() {
if (null == sInstance) {
sInstance = new MapStateUpdateImp();
}
return sInstance;
}
public MapStateUpdateImp setCommView(FlutterCommonMapView commonMapView) {
if(null == commonMapView){
return sInstance;
}
if( mFlutterCommonMapView == commonMapView){
return sInstance;
}
mFlutterCommonMapView = commonMapView;
mBaiduMap = commonMapView.getBaiduMap();
mViewType = mFlutterCommonMapView.getViewType();
mBaiduMap = mFlutterCommonMapView.getBaiduMap();
mUiSettings = mBaiduMap.getUiSettings();
return sInstance;
}
public boolean updateMapState(Map<String, Object> mapOptionsMap) {
if (null == mapOptionsMap) {
return false;
}
if (null == mFlutterCommonMapView ||
null == mBaiduMap ||
null == mUiSettings ||
TextUtils.isEmpty(mViewType)) {
return false;
}
// 设置地图类型
Integer mapType = new TypeConverter<Integer>().getValue(mapOptionsMap, "mapType");
if (null != mapType) {
setMapType(mapType);
}
// 设置指南针显示位置
Map<String, Object> compassPosMap = new TypeConverter<Map<String, Object>>().getValue(mapOptionsMap, "compassPosition");
Point compassPos = FlutterDataConveter.mapToPoint(compassPosMap);
if (null != compassPos) {
mBaiduMap.setCompassPosition(compassPos);
}
// 设置地图中心点
Map<String, Object> centerMap = new TypeConverter<Map<String, Object>>().getValue(mapOptionsMap, "center");
LatLng center = FlutterDataConveter.mapToLatlng(centerMap);
if (null != center) {
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(center);
mBaiduMap.setMapStatus(mapStatusUpdate);
}
// 设置地图缩放级别
Integer zoomLevel = new TypeConverter<Integer>().getValue(mapOptionsMap, "zoomLevel");
if (null != zoomLevel) {
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomTo(zoomLevel.floatValue());
mBaiduMap.setMapStatus(mapStatusUpdate);
}
// 设置地图最大、最小缩放级别
Integer minZoomLevel = new TypeConverter<Integer>().getValue(mapOptionsMap, "minZoomLevel");
Integer maxZoomLevel = new TypeConverter<Integer>().getValue(mapOptionsMap, "maxZoomLevel");
if (null != minZoomLevel && null != maxZoomLevel) {
mBaiduMap.setMaxAndMinZoomLevel(maxZoomLevel.floatValue(), minZoomLevel.floatValue());
} else if (null == minZoomLevel && null != maxZoomLevel ) {
mBaiduMap.setMaxAndMinZoomLevel(maxZoomLevel.floatValue(),mBaiduMap.getMinZoomLevel());
} else if (null != minZoomLevel && null == maxZoomLevel) {
mBaiduMap.setMaxAndMinZoomLevel(mBaiduMap.getMaxZoomLevel(), minZoomLevel.floatValue());
}
// 设置地图旋转角度
Double rotation = new TypeConverter<Double>().getValue(mapOptionsMap, "rotation");
if (null != rotation) {
setRotation(rotation.floatValue());
}
// 设置地图俯仰角度
if (mapOptionsMap.containsKey("overlooking")) {
Double overlooking = (Double) mapOptionsMap.get("overlooking");
if (overlooking != null) {
MapStatus build = new MapStatus.Builder().overlook(overlooking.floatValue()).build();
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(build);
mBaiduMap.setMapStatus(mapStatusUpdate);
}
}
// 是否显示3d建筑物
Boolean buildingsEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "buildingsEnabled");
if (null != buildingsEnabled) {
mBaiduMap.setBuildingsEnabled(buildingsEnabled);
}
// 设置是否显示poi信息
Boolean showMapPoi = new TypeConverter<Boolean>().getValue(mapOptionsMap, "showMapPoi");
if (null != showMapPoi) {
mBaiduMap.showMapPoi(showMapPoi);
}
// 设置是否显示路况信息
Boolean trafficEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "trafficEnabled");
if (null != trafficEnabled) {
mBaiduMap.setTrafficEnabled(trafficEnabled);
}
// 限制地图的显示范围
if (mapOptionsMap.containsKey("limitMapBounds")) {
Map<String, Object> limitMapRegion = (Map<String, Object>) mapOptionsMap.get("limitMapBounds");
if (null != limitMapRegion) {
setMapLimits(limitMapRegion);
}
}
// 设置是否显示百度自有热力图
Boolean baiduHeatMapEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "baiduHeatMapEnabled");
if (null != baiduHeatMapEnabled) {
mBaiduMap.setBaiduHeatMapEnabled(baiduHeatMapEnabled);
}
// 设置是否启用手势
Boolean gesturesEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "gesturesEnabled");
if (null != gesturesEnabled) {
mUiSettings.setAllGesturesEnabled(gesturesEnabled);
}
// 设置是否开启放大缩小
Boolean zoomEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "zoomEnabled");
if (null != zoomEnabled) {
mUiSettings.setZoomGesturesEnabled(zoomEnabled);
}
// 设置地图是否可滑动
Boolean scrollEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "scrollEnabled");
if (null != scrollEnabled) {
mUiSettings.setScrollGesturesEnabled(scrollEnabled);
}
// 设置是否开启俯仰角
Boolean overlookEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "overlookEnabled");
if (null != overlookEnabled) {
mUiSettings.setOverlookingGesturesEnabled(overlookEnabled);
}
// 设置是否开启旋转角
Boolean rotateEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "rotateEnabled");
if (null != rotateEnabled) {
mUiSettings.setRotateGesturesEnabled(rotateEnabled);
}
// 设置比例尺是否显示
Boolean showMapScaleBar = new TypeConverter<Boolean>().getValue(mapOptionsMap, "showMapScaleBar");
if (null != showMapScaleBar) {
showScaleControl(showMapScaleBar);
}
// 设置比例尺显示位置
Map<String, Object> mapScaleBarPosMap = new TypeConverter<Map<String, Object>>().getValue(mapOptionsMap, "mapScaleBarPosition");
Point mapScaleBarPos = FlutterDataConveter.mapToPoint(mapScaleBarPosMap);
if (null != mapScaleBarPos) {
setScaleControlPosition(mapScaleBarPos);
}
// 设置百度logo显示位置
Integer logoPosition = new TypeConverter<Integer>().getValue(mapOptionsMap, "logoPosition");
if (null != logoPosition
&& logoPosition >= LogoPosition.logoPostionleftBottom.ordinal()
&& logoPosition <= LogoPosition.logoPostionRightTop.ordinal()) {
setLogoPosition(LogoPosition.values()[logoPosition.intValue()]);
}
// 设置地图padding
Map<String, Double> mapPadding = new TypeConverter<Map<String, Double>>().getValue(mapOptionsMap, "mapPadding");
if (null != mapPadding) {
if (mapPadding.containsKey("top") && mapPadding.containsKey("left")
&& mapPadding.containsKey("bottom") && mapPadding.containsKey("right")) {
Double top = mapPadding.get("top");
Double left = mapPadding.get("left");
Double bottom = mapPadding.get("bottom");
Double right = mapPadding.get("right");
if (top != null && left != null && bottom != null && right != null) {
int iTop = top.intValue();
int iLeft = left.intValue();
int iBottom = bottom.intValue();
int iRight = right.intValue();
mBaiduMap.setViewPadding(iLeft, iTop, iRight, iBottom);
}
}
}
// 设置双击屏幕放大地图时,是否改变地图中心点为当前点击点
Boolean changeCenterWithDoubleTouchPointEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "changeCenterWithDoubleTouchPointEnabled");
if (null != changeCenterWithDoubleTouchPointEnabled) {
// 这个值sdk好像取的是反的这个设个反值
mUiSettings.setEnlargeCenterWithDoubleClickEnable(!changeCenterWithDoubleTouchPointEnabled);
}
// 设置是否开启室内图
Boolean baseIndoorMapEnabled = new TypeConverter<Boolean>().getValue(mapOptionsMap, "baseIndoorMapEnabled");
if (null != baseIndoorMapEnabled) {
mBaiduMap.setIndoorEnable(baseIndoorMapEnabled);
BMFMapStatus.getsInstance().setBaseIndoorEnable(baseIndoorMapEnabled);
}
// 设置是否开启室内图poi
Boolean showIndoorMapPoi = new TypeConverter<Boolean>().getValue(mapOptionsMap, "showIndoorMapPoi");
if (null != showIndoorMapPoi) {
mBaiduMap.showMapIndoorPoi(showIndoorMapPoi);
BMFMapStatus.getsInstance().setIndoorMapPoiEnable(showIndoorMapPoi);
}
// 设置地图可视区域
Map<String, Object> visibleMapBounds = new TypeConverter<Map<String, Object>>().getValue(mapOptionsMap, "visibleMapBounds");
LatLngBounds latLngBounds = FlutterDataConveter.mapToLatlngBounds(visibleMapBounds);
if (null != latLngBounds) {
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngBounds(latLngBounds);
mBaiduMap.setMapStatus(mapStatusUpdate);
}
return true;
}
private void setMapType(Integer mapType) {
switch (mapType) {
case Env.MAP_TYPE_NONE:
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
break;
case Env.MAP_TYPE_NORMAL:
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
break;
case Env.MAP_TYPE_SATELLITE:
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
break;
default:
break;
}
}
private void setRotation(float rotation) {
if (rotation < 0) {
rotation = rotation + 360;
}
MapStatus mapStatus = new MapStatus.Builder().rotate(rotation).build();
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
mBaiduMap.setMapStatus(mapStatusUpdate);
}
private void showScaleControl(boolean showScaleControl) {
switch(mViewType){
case Constants.ViewType.sMapView:
MapView mapView = mFlutterCommonMapView.getMapView();
if (null != mapView) {
mapView.showScaleControl(showScaleControl);
}
break;
case Constants.ViewType.sTextureMapView:
TextureMapView textureMapView = mFlutterCommonMapView.getTextureMapView();
if (null != textureMapView) {
textureMapView.showScaleControl(showScaleControl);
}
break;
default:
break;
}
}
private void setScaleControlPosition(Point mapScaleBarPos) {
switch (mViewType) {
case Constants.ViewType.sMapView:
MapView mapView = mFlutterCommonMapView.getMapView();
if (null != mapView) {
mapView.setScaleControlPosition(mapScaleBarPos);
}
break;
case Constants.ViewType.sTextureMapView:
TextureMapView textureMapView = mFlutterCommonMapView.getTextureMapView();
if (null != textureMapView) {
textureMapView.setScaleControlPosition(mapScaleBarPos);
}
break;
default:
break;
}
}
private void setLogoPosition(LogoPosition logoPos) {
switch (mViewType) {
case Constants.ViewType.sMapView:
MapView mapView = mFlutterCommonMapView.getMapView();
if(null != mapView){
mapView.setLogoPosition(logoPos);
}
break;
case Constants.ViewType.sTextureMapView:
TextureMapView textureMapView = mFlutterCommonMapView.getTextureMapView();
if (null != textureMapView) {
textureMapView.setLogoPosition(logoPos);
}
break;
default:
break;
}
}
/**
*
*/
private void setMapLimits(Map<String, Object> limitMapBounds) {
LatLngBounds latLngBounds = FlutterDataConveter.mapToLatlngBounds(limitMapBounds);
if (null == latLngBounds) {
return;
}
mBaiduMap.setMapStatusLimits(latLngBounds);
}
}

@ -0,0 +1,27 @@
package com.baidu.flutter_bmfmap.map;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.TextureMapView;
public class MapViewWrapper extends FlutterCommonMapView {
FlutterMapView mFlutterMapView;
public MapViewWrapper(FlutterMapView mapView, String viewType) {
mFlutterMapView = mapView;
mViewType = viewType;
}
@Override
public MapView getMapView() {
return mFlutterMapView.getMapView();
}
public FlutterMapView getFlutterMapView() {
return mFlutterMapView;
}
@Override
public TextureMapView getTextureMapView() {
return null;
}
}

@ -0,0 +1,451 @@
package com.baidu.flutter_bmfmap.map;
import android.text.TextUtils;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.mapapi.map.offline.MKOLSearchRecord;
import com.baidu.mapapi.map.offline.MKOLUpdateElement;
import com.baidu.mapapi.map.offline.MKOfflineMap;
import com.baidu.mapapi.map.offline.MKOfflineMapListener;
import com.baidu.mapapi.model.LatLng;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
/**
* 线handler
*/
public class OfflineHandler implements MethodChannel.MethodCallHandler {
private MKOfflineMap mMKOfflineMap;
private MethodChannel channel;
public void init(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "flutter_bmfmap/offlineMap");
channel.setMethodCallHandler(this);
}
public void unInit(BinaryMessenger messenger) {
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (null == call) {
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
return;
}
switch (methodId) {
case Constants.MethodProtocol.BMFOfflineMethodId.sMapInitOfflineMethod:
initOfflineMap(result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapStartOfflineMethod:
statOfflineMap(call,result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapPauseOfflineMethod:
pauseOfflineMap(call,result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapRemoveOfflineMethod:
removeOfflineMap(call,result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapUpdateOfflineMethod:
updateOffline(call,result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapDestroyOfflineMethod:
destroyOffline(result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapGetHotCityListMethod:
getHotCityList(result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapGetOfflineCityListMethod:
getOfflineCityList(result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapSearchCityMethod:
seachCityList(call, result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapGetAllUpdateInfoMethod:
getAllUpdateInfo(result);
break;
case Constants.MethodProtocol.BMFOfflineMethodId.sMapGetUpdateInfoMethod:
getUpdateInfo(call,result);
break;
default:
break;
}
}
/**
*
*/
private void initOfflineMap(MethodChannel.Result result) {
mMKOfflineMap = new MKOfflineMap();
mMKOfflineMap.init(new MKOfflineMapListener() {
@Override
public void onGetOfflineMapState(int type, int state) {
HashMap hashMap = new HashMap();
hashMap.put("type",type);
hashMap.put("state",state);
channel.invokeMethod(Constants.MethodProtocol.BMFOfflineMethodId.sMapOfflineCallBackMethod,hashMap);
}
});
result.success(true);
}
/**
* 线
*/
private void destroyOffline(MethodChannel.Result result) {
if (null == mMKOfflineMap) {
result.success(false);
return;
}
mMKOfflineMap.destroy();
result.success(true);
}
/**
* ID线
*/
private void updateOffline(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMKOfflineMap) {
result.success(false);
return;
}
if (!argument.containsKey("cityID")) {
result.success(false);
return;
}
Integer cityID = (Integer) argument.get("cityID");
if (null != cityID) {
boolean update = mMKOfflineMap.update(cityID);
result.success(update);
}
}
/**
* ID线
*/
private void removeOfflineMap(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMKOfflineMap) {
result.success(false);
return;
}
if (!argument.containsKey("cityID")) {
result.success(false);
return;
}
Integer cityID = (Integer) argument.get("cityID");
if (null != cityID) {
boolean remove = mMKOfflineMap.remove(cityID);
result.success(remove);
}
}
/**
* ID线
*/
private void pauseOfflineMap(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMKOfflineMap) {
result.success(false);
return;
}
if (!argument.containsKey("cityID")) {
result.success(false);
return;
}
Integer cityID = (Integer) argument.get("cityID");
if (null != cityID) {
boolean pause = mMKOfflineMap.pause(cityID);
result.success(pause);
}
}
/**
* ID线线
*/
private void statOfflineMap(MethodCall call,MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMKOfflineMap) {
result.success(false);
return;
}
if (!argument.containsKey("cityID")) {
result.success(false);
return;
}
Integer cityID = (Integer) argument.get("cityID");
if (null != cityID) {
boolean start = mMKOfflineMap.start(cityID);
result.success(start);
}
}
/**
* ID线
*/
private void getUpdateInfo(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMKOfflineMap) {
result.success(null);
return;
}
if (!argument.containsKey("cityID")) {
result.success(null);
return;
}
Integer id = (Integer) argument.get("cityID");
MKOLUpdateElement updateInfo = mMKOfflineMap.getUpdateInfo(id);
if (null != id && null != updateInfo) {
Map map = new HashMap();
int cityID = updateInfo.cityID;
int ratio = updateInfo.ratio;
int status = updateInfo.status;
String cityName = updateInfo.cityName;
int size = updateInfo.size;
int serversize = updateInfo.serversize;
int level = updateInfo.level;
boolean update = updateInfo.update;
LatLng latLng = updateInfo.geoPt;
HashMap<String, Double> geoPt = new HashMap<>();
geoPt.put("latitude", latLng.latitude);
geoPt.put("longitude", latLng.longitude);
map.put("cityID", cityID);
map.put("ratio", ratio);
map.put("status", status);
map.put("cityName", cityName);
map.put("geoPt", geoPt);
map.put("size", size);
map.put("serversize", serversize);
map.put("level", level);
map.put("update", update);
result.success(map);
} else {
result.success(null);
return;
}
}
/**
* 线
*/
private void getAllUpdateInfo(MethodChannel.Result result) {
if (null == mMKOfflineMap) {
result.success(null);
return;
}
ArrayList<MKOLUpdateElement> allUpdateInfo = mMKOfflineMap.getAllUpdateInfo();
if (null == allUpdateInfo || allUpdateInfo.size() == 0) {
result.success(null);
return;
}
ArrayList<Map> arrayMap = new ArrayList<>();
HashMap<String, ArrayList> offlineCityMap = new HashMap<>();
for (int i = 0; i < allUpdateInfo.size(); i++) {
Map map = new HashMap();
int cityID = allUpdateInfo.get(i).cityID;
int ratio = allUpdateInfo.get(i).ratio;
String cityName = allUpdateInfo.get(i).cityName;
int size = allUpdateInfo.get(i).size;
int serversize = allUpdateInfo.get(i).serversize;
int level = allUpdateInfo.get(i).level;
boolean update = allUpdateInfo.get(i).update;
LatLng latLng = allUpdateInfo.get(i).geoPt;
HashMap<String, Double> geoPt = new HashMap<>();
geoPt.put("latitude",latLng.latitude);
geoPt.put("longitude",latLng.longitude);
map.put("cityID",cityID);
map.put("ratio",ratio);
map.put("cityName",cityName);
map.put("geoPt",geoPt);
map.put("size",size);
map.put("serversize",serversize);
map.put("level",level);
map.put("update",update);
arrayMap.add(map);
}
offlineCityMap.put("updateElements", arrayMap);
result.success(offlineCityMap);
}
/**
* 线
*/
private void seachCityList(MethodCall call,MethodChannel.Result result) {
if (null == mMKOfflineMap) {
result.success(null);
return;
}
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMKOfflineMap) {
result.success(null);
return;
}
if (!argument.containsKey("cityName")) {
result.success(null);
return;
}
String sCityName = (String) argument.get("cityName");
if (null == sCityName) {
result.success(null);
return;
}
ArrayList<MKOLSearchRecord> seachCityList = mMKOfflineMap.searchCity(sCityName);
if (null == seachCityList){
result.success(null);
return;
}
ArrayList<Map> arrayMap = new ArrayList<>();
HashMap<String, ArrayList> offlineCityMap = new HashMap<>();
for (int i = 0; i < seachCityList.size(); i++) {
Map map = new HashMap();
int cityID = seachCityList.get(i).cityID;
int cityType = seachCityList.get(i).cityType;
int dataSize = (int) seachCityList.get(i).dataSize;
String cityName = seachCityList.get(i).cityName;
ArrayList<MKOLSearchRecord> childCities = seachCityList.get(i).childCities;
ArrayList<Map> childArray = new ArrayList<>();
if (null != childCities && childCities.size() > 0) {
for (int j = 0; j < childCities.size(); j++) {
HashMap childMap = new HashMap();
int childCityID = childCities.get(j).cityID;
int childCityType = childCities.get(j).cityType;
int childDataSize = (int) childCities.get(j).dataSize;
String childCityName = childCities.get(j).cityName;
childMap.put("cityID",childCityID);
childMap.put("cityType",childCityType);
childMap.put("dataSize",childDataSize);
childMap.put("cityName",childCityName);
childArray.add(childMap);
}
}
map.put("cityID",cityID);
map.put("dataSize",dataSize);
map.put("cityName",cityName);
map.put("cityType",cityType);
map.put("childCities",childArray);
arrayMap.add(map);
}
offlineCityMap.put("searchCityRecord", arrayMap);
result.success(offlineCityMap);
}
/**
*
*/
private void getHotCityList(MethodChannel.Result result) {
if (null == mMKOfflineMap) {
result.success(null);
return;
}
ArrayList<MKOLSearchRecord> hotCityList = mMKOfflineMap.getHotCityList();
if (null == hotCityList){
result.success(null);
return;
}
ArrayList<Map> arrayMap = new ArrayList<>();
HashMap<String, ArrayList> hotCityMap = new HashMap<>();
for (int i = 0; i < hotCityList.size(); i++) {
Map map = new HashMap();
int cityID = hotCityList.get(i).cityID;
int cityType = hotCityList.get(i).cityType;
int dataSize = (int) hotCityList.get(i).dataSize;
String cityName = hotCityList.get(i).cityName;
ArrayList<MKOLSearchRecord> childCities = hotCityList.get(i).childCities;
ArrayList<Map> childArray = new ArrayList<>();
if (null != childCities && childCities.size() > 0) {
for (int j = 0; j < childCities.size(); j++) {
HashMap childMap = new HashMap();
int childCityID = childCities.get(j).cityID;
int childCityType = childCities.get(j).cityType;
int childDataSize = (int) childCities.get(j).dataSize;
String childCityName = childCities.get(j).cityName;
childMap.put("cityID",childCityID);
childMap.put("cityType",childCityType);
childMap.put("dataSize",childDataSize);
childMap.put("cityName",childCityName);
childArray.add(childMap);
}
}
map.put("cityID",cityID);
map.put("dataSize",dataSize);
map.put("cityName",cityName);
map.put("cityType",cityType);
map.put("childCities",childArray);
arrayMap.add(map);
}
hotCityMap.put("searchCityRecord", arrayMap);
result.success(hotCityMap);
}
/**
* 线
*/
private void getOfflineCityList(MethodChannel.Result result) {
if (null == mMKOfflineMap) {
result.success(null);
return;
}
ArrayList<MKOLSearchRecord> offlineCityList = mMKOfflineMap.getOfflineCityList();
if (null == offlineCityList){
result.success(null);
return;
}
ArrayList<Map> arrayMap = new ArrayList<>();
HashMap<String, ArrayList> offlineCityMap = new HashMap<>();
for (int i = 0; i < offlineCityList.size(); i++) {
Map map = new HashMap();
int cityID = offlineCityList.get(i).cityID;
int cityType = offlineCityList.get(i).cityType;
int dataSize = (int) offlineCityList.get(i).dataSize;
String cityName = offlineCityList.get(i).cityName;
ArrayList<MKOLSearchRecord> childCities = offlineCityList.get(i).childCities;
ArrayList<Map> childArray = new ArrayList<>();
if (null != childCities && childCities.size() > 0) {
for (int j = 0; j < childCities.size(); j++) {
HashMap childMap = new HashMap();
int childCityID = childCities.get(j).cityID;
int childCityType = childCities.get(j).cityType;
int childDataSize = (int) childCities.get(j).dataSize;
String childCityName = childCities.get(j).cityName;
childMap.put("cityID",childCityID);
childMap.put("cityType",childCityType);
childMap.put("dataSize",childDataSize);
childMap.put("cityName",childCityName);
childArray.add(childMap);
}
}
map.put("cityID",cityID);
map.put("dataSize",dataSize);
map.put("cityName",cityName);
map.put("cityType",cityType);
map.put("childCities",childArray);
arrayMap.add(map);
}
offlineCityMap.put("searchCityRecord", arrayMap);
result.success(offlineCityMap);
}
}

@ -0,0 +1,24 @@
package com.baidu.flutter_bmfmap.map;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.TextureMapView;
class TextureMapViewWrapper extends FlutterCommonMapView {
private TextureMapView mTextureMapView;
public TextureMapViewWrapper(TextureMapView textureMapView, String viewType){
mTextureMapView = textureMapView;
mViewType = viewType;
}
@Override
public MapView getMapView() {
return null;
}
@Override
public TextureMapView getTextureMapView() {
return mTextureMapView;
}
}

@ -0,0 +1,45 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
/**
* getleiflutter
*/
public class BMFMapStatus {
private static volatile BMFMapStatus sInstance;
public static BMFMapStatus getsInstance(){
if (null == sInstance) {
synchronized(BMFMapStatus.class) {
if (null == sInstance) {
sInstance = new BMFMapStatus();
}
}
}
return sInstance;
}
public boolean isBaseIndoorEnable() {
return mBaseIndoorEnable;
}
public void setBaseIndoorEnable(boolean mBaseIndoorEnable) {
this.mBaseIndoorEnable = mBaseIndoorEnable;
}
public boolean isIndoorMapPoiEnable() {
return mIndoorMapPoiEnable;
}
public void setIndoorMapPoiEnable(boolean mIndoorMapPoiEnable) {
this.mIndoorMapPoiEnable = mIndoorMapPoiEnable;
}
/**
*
*/
private boolean mBaseIndoorEnable = false;
private boolean mIndoorMapPoiEnable = true;
}

@ -0,0 +1,24 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public abstract class BMapHandler{
protected FlutterCommonMapView mMapView;
public BMapHandler(FlutterCommonMapView mapView){
this.mMapView = mapView;
}
public abstract void handlerMethodCallResult(Context context,MethodCall call, MethodChannel.Result result);
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
}
public void clean(){}
}

@ -0,0 +1,200 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Constants;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.CustomMapProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.MapStateProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.HeatMapProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.TileMapProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.MarkerProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.InfoWindowProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.ProjectionMethodId;
import com.baidu.flutter_bmfmap.utils.Env;
public class BMapHandlerFactory{
private static volatile BMapHandlerFactory sInstance;
private HashMap<Integer, BMapHandler> mMapHandlerHashMap;
public static BMapHandlerFactory getInstance(FlutterCommonMapView mapView) {
if (null == sInstance) {
synchronized (BMapHandlerFactory.class) {
if (null == sInstance) {
sInstance = new BMapHandlerFactory(mapView);
} else {
sInstance.updateMapView(mapView);
}
}
} else {
sInstance.updateMapView(mapView);
}
return sInstance;
}
private void updateMapView(FlutterCommonMapView mapView) {
if (null == mapView) {
return;
}
if(null == mMapHandlerHashMap || mMapHandlerHashMap.isEmpty()){
init(mapView);
}
Iterator it = mMapHandlerHashMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, BMapHandler> entry = (Map.Entry<Integer, BMapHandler>) it.next();
BMapHandler bMapHandler = entry.getValue();
if (null != bMapHandler) {
bMapHandler.updateMapView(mapView);
}
}
}
private BMapHandlerFactory(FlutterCommonMapView mapView) {
init(mapView);
}
private void init(FlutterCommonMapView mapView) {
if (null == mapView) {
return;
}
mMapHandlerHashMap = new HashMap<>();
mMapHandlerHashMap.put(Constants.BMapHandlerType.CUSTOM_MAP,new CustomMapHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.MAP_STATE,new MapStateHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.INDOOR_MAP, new IndoorMapHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.MAP_UPDATE, new MapUpdateHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.HEAT_MAP, new HeatMapHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.TILE_MAP, new TileMapHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.INFOWINDOW_HANDLER, new InfoWindowHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.MARKER_HANDLER, new MarkerHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.LOCATION_LAYER, new LocationLayerHandler(mapView));
mMapHandlerHashMap.put(Constants.BMapHandlerType.PROJECTION, new ProjectionHandler(mapView));
}
public boolean dispatchMethodHandler(Context context, MethodCall call, MethodChannel.Result result,
MethodChannel methodChannel) {
if (null == call) {
return false;
}
String methodId = call.method;
if(Env.DEBUG){
Log.d("BMapHandlerFactory", "dispatchMethodHandler: " + methodId);
}
BMapHandler bMapHandler = null;
switch (methodId) {
case CustomMapProtocol.sMapSetCustomMapStyleEnableMethod:
case CustomMapProtocol.sMapSetCustomMapStylePathMethod:
case CustomMapProtocol.sMapSetCustomMapStyleWithOptionMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.CUSTOM_MAP);
break;
case Constants.MethodProtocol.IndoorMapProtocol.sShowBaseIndoorMapMethod:
case Constants.MethodProtocol.IndoorMapProtocol.sShowBaseIndoorMapPoiMethod:
case Constants.MethodProtocol.IndoorMapProtocol.sSwitchBaseIndoorMapFloorMethod:
case Constants.MethodProtocol.IndoorMapProtocol.sGetFocusedBaseIndoorMapInfoMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.INDOOR_MAP);
break;
case MapStateProtocol.sMapUpdateMethod:
case MapStateProtocol.sMapSetVisibleMapBoundsMethod:
case MapStateProtocol.sMapSetVisibleMapBoundsWithPaddingMethod:
case MapStateProtocol.sMapSetCompassImageMethod:
case MapStateProtocol.sMapSetCustomTrafficColorMethod:
case MapStateProtocol.sMapTakeSnapshotMethod:
case MapStateProtocol.sMapTakeSnapshotWithRectMethod:
case MapStateProtocol.sMapDidUpdateWidget:
case MapStateProtocol.sMapReassemble:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.MAP_STATE);
break;
case MapStateProtocol.sMapZoomInMethod:
case MapStateProtocol.sMapZoomOutMethod:
case MapStateProtocol.sMapSetCenterCoordinateMethod:
case MapStateProtocol.sMapSetCenterZoomMethod:
case MapStateProtocol.sMapSetMapStatusMethod:
case MapStateProtocol.sMapSetScrollByMethod:
case MapStateProtocol.sMapSetZoomByMethod:
case MapStateProtocol.sMapSetZoomPointByMethod:
case MapStateProtocol.sMapSetZoomToMethod:
case MapStateProtocol.sMapGetMapStatusMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.MAP_UPDATE);
break;
case HeatMapProtocol.sMapAddHeatMapMethod:
case HeatMapProtocol.sMapRemoveHeatMapMethod:
case HeatMapProtocol.sShowHeatMapMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.HEAT_MAP);
break;
case TileMapProtocol.sAddTileMapMethod:
case TileMapProtocol.sRemoveTileMapMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.TILE_MAP);
break;
case MarkerProtocol.sMapAddMarkerMethod:
case MarkerProtocol.sMapAddMarkersMethod:
case MarkerProtocol.sMapRemoveMarkerMethod:
case MarkerProtocol.sMapRemoveMarkersMethod:
case MarkerProtocol.sMapDidSelectMarkerMethod:
case MarkerProtocol.sMapDidDeselectMarkerMethod:
case MarkerProtocol.sMapCleanAllMarkersMethod:
case MarkerProtocol.sMapUpdateMarkerMemberMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.MARKER_HANDLER);
break;
case InfoWindowProtocol.sAddInfoWindowMapMethod:
case InfoWindowProtocol.sRemoveInfoWindowMapMethod:
case InfoWindowProtocol.sAddInfoWindowsMapMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.INFOWINDOW_HANDLER);
break;
case Constants.LocationLayerMethodId.sMapShowUserLocationMethod:
case Constants.LocationLayerMethodId.sMapUpdateLocationDataMethod:
case Constants.LocationLayerMethodId.sMapUserTrackingModeMethod:
case Constants.LocationLayerMethodId.sMapUpdateLocationDisplayParamMethod:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.LOCATION_LAYER);
break;
case ProjectionMethodId.sFromScreenLocation:
case ProjectionMethodId.sToScreenLocation:
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.PROJECTION);
break;
default:
if(methodId.startsWith("flutter_bmfmap/map/get")){
bMapHandler = mMapHandlerHashMap.get(Constants.BMapHandlerType.MAP_UPDATE);
}
break;
}
if (null == bMapHandler) {
return false;
}
bMapHandler.handlerMethodCallResult(context,call, result);
return true;
}
public void clean(){
if (null == mMapHandlerHashMap || mMapHandlerHashMap.size() == 0) {
return;
}
BMapHandler bMapHandler = null;
Iterator iterator = mMapHandlerHashMap.values().iterator();
while (iterator.hasNext()){
bMapHandler = (BMapHandler) iterator.next();
if(null == bMapHandler){
continue;
}
bMapHandler.clean();
}
}
}

@ -0,0 +1,437 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.mapapi.map.CustomMapStyleCallBack;
import com.baidu.mapapi.map.MapCustomStyleOptions;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.TextureMapView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.view.FlutterMain;
public class CustomMapHandler extends BMapHandler {
private MapViewCustomMapHandler mMapViewCustomMapHandler;
private TextureMapViewCustomMapHandler mTextureMapViewCustomMapHandler;
public CustomMapHandler(FlutterCommonMapView mapView) {
super(mapView);
mMapViewCustomMapHandler = new MapViewCustomMapHandler(mMapView);
mTextureMapViewCustomMapHandler = new TextureMapViewCustomMapHandler(mMapView);
}
@Override
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
mMapViewCustomMapHandler.updateMapView(mapView);
mTextureMapViewCustomMapHandler.updateMapView(mapView);
}
@Override
public void handlerMethodCallResult(Context context,MethodCall call, MethodChannel.Result result) {
switch (mMapView.getViewType()){
case Constants.ViewType.sMapView:
mMapViewCustomMapHandler.handlerMethodCallResult(context, call, result);
break;
case Constants.ViewType.sTextureMapView:
mTextureMapViewCustomMapHandler.handlerMethodCallResult(context, call, result);
break;
default:
break;
}
}
class MapViewCustomMapHandler extends BMapHandler {
private MapView mRealMapView;
public MapViewCustomMapHandler(FlutterCommonMapView mapView) {
super(mapView);
mRealMapView = mMapView.getMapView();
}
@Override
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
if(null != mMapView){
mRealMapView = mMapView.getMapView();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result) {
if (null == call) {
result.success(false);
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
result.success(false);
return;
}
switch (methodId) {
case Constants.MethodProtocol.CustomMapProtocol.sMapSetCustomMapStyleEnableMethod:
setCustomMapStyleEnable(call, result);
break;
case Constants.MethodProtocol.CustomMapProtocol.sMapSetCustomMapStylePathMethod:
setCustomMapStylePath(context,call,result);
break;
case Constants.MethodProtocol.CustomMapProtocol.sMapSetCustomMapStyleWithOptionMethod:
setMapCustomStyle(call,result);
break;
default:
break;
}
}
/**
*
*/
private void setCustomMapStyleEnable(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView) {
result.success(false);
return;
}
if (!argument.containsKey("enable")) {
result.success(false);
return;
}
boolean enable = (boolean) argument.get("enable");
mRealMapView.setMapCustomStyleEnable(enable);
result.success(true);
}
/**
*
*/
private void setCustomMapStylePath(Context context, MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView || context == null) {
result.success(false);
return;
}
if (!argument.containsKey("path") || !argument.containsKey("mode")) {
result.success(false);
return;
}
String path = (String) argument.get("path");
if (path.isEmpty()) {
result.success(false);
return;
}
String customStyleFilePath = getCustomStyleFilePath(context, path);
if(TextUtils.isEmpty(customStyleFilePath)){
result.success(false);
return;
}
mRealMapView.setMapCustomStylePath(customStyleFilePath);
result.success(true);
}
private String getCustomStyleFilePath(Context context, String customStyleFilePath) {
if (customStyleFilePath.isEmpty()) {
return null;
}
FileOutputStream outputStream = null;
InputStream inputStream = null;
String parentPath = null;
String customStyleFileName = null;
try {
customStyleFileName = FlutterMain.getLookupKeyForAsset(customStyleFilePath);
inputStream = context.getAssets().open(customStyleFileName);
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
parentPath = context.getCacheDir().getAbsolutePath();
String substr = customStyleFileName.substring(0, customStyleFileName.lastIndexOf("/"));
File customStyleFile = new File(parentPath + "/" + customStyleFileName);
if (customStyleFile.exists()) {
customStyleFile.delete();
}
File dirFile = new File(parentPath + "/" + substr);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
customStyleFile.createNewFile();
outputStream = new FileOutputStream(customStyleFile);
outputStream.write(buffer);
} catch (IOException e) {
Log.e("TAG", "Copy file failed", e);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
Log.e("TAG", "Close stream failed", e);
}
}
return parentPath + "/" + customStyleFileName;
}
/**
* 线
*/
private void setMapCustomStyle(MethodCall call, final MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView) {
result.success(false);
return;
}
if (!argument.containsKey("customMapStyleOption")) {
return;
}
Map<String, Object> customMapStyleOption = (Map<String, Object>) argument.get("customMapStyleOption");
if (!customMapStyleOption.containsKey("customMapStyleID")
|| !customMapStyleOption.containsKey("customMapStyleFilePath")) {
return;
}
String customMapStyleID = (String) customMapStyleOption.get("customMapStyleID");
String customMapStyleFilePath = (String) customMapStyleOption.get("customMapStyleFilePath");
if (customMapStyleID.isEmpty() && customMapStyleFilePath.isEmpty()) {
return;
}
MapCustomStyleOptions mapCustomStyleOptions = new MapCustomStyleOptions();
mapCustomStyleOptions.customStyleId(customMapStyleID);
mapCustomStyleOptions.localCustomStylePath(customMapStyleFilePath);
final HashMap<String, String> reslutMap = new HashMap<>();
mRealMapView.setMapCustomStyle(mapCustomStyleOptions, new CustomMapStyleCallBack() {
@Override
public boolean onPreLoadLastCustomMapStyle(String path) {
reslutMap.put("preloadPath", path);
result.success(reslutMap);
return false;
}
@Override
public boolean onCustomMapStyleLoadSuccess(boolean b, String path) {
// TODO: 2020-03-05 回调的 boolean 类型没有返回之后补齐
reslutMap.put("successPath", path);
result.success(reslutMap);
return false;
}
@Override
public boolean onCustomMapStyleLoadFailed(int status, String message, String path) {
String sStatus = String.valueOf(status);
reslutMap.put("errorCode", sStatus);
reslutMap.put("successPath", path);
result.success(reslutMap);
return false;
}
});
}
}
class TextureMapViewCustomMapHandler extends BMapHandler {
private TextureMapView mTextureMapView;
public TextureMapViewCustomMapHandler(FlutterCommonMapView mapView) {
super(mapView);
mTextureMapView = mMapView.getTextureMapView();
}
@Override
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
if(null != mMapView){
mTextureMapView = mMapView.getTextureMapView();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result) {
if (null == call) {
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
return;
}
switch (methodId) {
case Constants.MethodProtocol.CustomMapProtocol.sMapSetCustomMapStyleEnableMethod:
setCustomMapStyleEnable(call, result);
break;
case Constants.MethodProtocol.CustomMapProtocol.sMapSetCustomMapStylePathMethod:
setCustomMapStylePath(context,call,result);
break;
case Constants.MethodProtocol.CustomMapProtocol.sMapSetCustomMapStyleWithOptionMethod:
setMapCustomStyle(context, call,result);
break;
default:
break;
}
}
/**
*
*/
private void setCustomMapStyleEnable(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView) {
result.success(false);
return;
}
if (!argument.containsKey("enable")) {
result.success(false);
return;
}
boolean enable = (boolean) argument.get("enable");
mTextureMapView.setMapCustomStyleEnable(enable);
result.success(true);
}
/**
*
*/
private void setCustomMapStylePath(Context context, MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView || context == null) {
result.success(false);
return;
}
if (!argument.containsKey("path") || !argument.containsKey("mode")) {
result.success(false);
return;
}
String path = (String) argument.get("path");
if (path.isEmpty()) {
result.success(false);
return;
}
String customStyleFilePath = getCustomStyleFilePath(context, path);
mTextureMapView.setMapCustomStylePath(customStyleFilePath);
result.success(true);
}
private String getCustomStyleFilePath(Context context, String customStyleFilePath) {
if (customStyleFilePath.isEmpty()) {
return null;
}
FileOutputStream outputStream = null;
InputStream inputStream = null;
String parentPath = null;
String customStyleFileName = null;
try {
customStyleFileName = FlutterMain.getLookupKeyForAsset(customStyleFilePath);
inputStream = context.getAssets().open(customStyleFileName);
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
parentPath = context.getCacheDir().getAbsolutePath();
String substr = customStyleFileName.substring(0, customStyleFileName.lastIndexOf("/"));
File customStyleFile = new File(parentPath + "/" + customStyleFileName);
if (customStyleFile.exists()) {
customStyleFile.delete();
}
File dirFile = new File(parentPath + "/" + substr);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
customStyleFile.createNewFile();
outputStream = new FileOutputStream(customStyleFile);
outputStream.write(buffer);
} catch (IOException e) {
Log.e("TAG", "Copy file failed", e);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
Log.e("TAG", "Close stream failed", e);
}
}
return parentPath + "/" + customStyleFileName;
}
/**
* 线
*/
private void setMapCustomStyle(Context context, MethodCall call,
final MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView) {
result.success(false);
return;
}
if (!argument.containsKey("customMapStyleOption")) {
return;
}
Map<String, Object> customMapStyleOption = (Map<String, Object>) argument.get("customMapStyleOption");
if (!customMapStyleOption.containsKey("customMapStyleID")
|| !customMapStyleOption.containsKey("customMapStyleFilePath")) {
return;
}
String customMapStyleID = (String) customMapStyleOption.get("customMapStyleID");
String customMapStyleFilePath = (String) customMapStyleOption.get("customMapStyleFilePath");
customMapStyleFilePath = getCustomStyleFilePath(context, customMapStyleFilePath);
if (customMapStyleID.isEmpty() && customMapStyleFilePath.isEmpty()) {
return;
}
MapCustomStyleOptions mapCustomStyleOptions = new MapCustomStyleOptions();
mapCustomStyleOptions.customStyleId(customMapStyleID);
mapCustomStyleOptions.localCustomStylePath(customMapStyleFilePath);
final HashMap<String, String> reslutMap = new HashMap<>();
mTextureMapView.setMapCustomStyle(mapCustomStyleOptions, new CustomMapStyleCallBack() {
@Override
public boolean onPreLoadLastCustomMapStyle(String path) {
reslutMap.put("preloadPath", path);
result.success(reslutMap);
return false;
}
@Override
public boolean onCustomMapStyleLoadSuccess(boolean b, String path) {
// TODO: 2020-03-05 回调的 boolean 类型没有返回之后补齐
reslutMap.put("successPath", path);
result.success(reslutMap);
return false;
}
@Override
public boolean onCustomMapStyleLoadFailed(int status, String message, String path) {
String sStatus = String.valueOf(status);
reslutMap.put("errorCode", sStatus);
reslutMap.put("successPath", path);
result.success(reslutMap);
return false;
}
});
}
}
}

@ -0,0 +1,270 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Gradient;
import com.baidu.mapapi.map.HeatMap;
import com.baidu.mapapi.map.WeightedLatLng;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.HeatMapProtocol;
class HeatMapHandler extends BMapHandler {
private static final String TAG = "HeapMapHandler";
HeatMap mHeatMap = null;
public HeatMapHandler(FlutterCommonMapView mapView) {
super(mapView);
}
@Override
public void handlerMethodCallResult(Context context,MethodCall call, MethodChannel.Result result) {
if (null == call) {
result.success(false);
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
result.success(false);
return;
}
boolean ret = false;
switch (methodId) {
case HeatMapProtocol.sMapAddHeatMapMethod:
ret = addHeapMap(context, call);
break;
case HeatMapProtocol.sMapRemoveHeatMapMethod:
ret = switchHeatMap(context, call);
break;
case HeatMapProtocol.sShowHeatMapMethod:
ret = isShowBaiduHeatMap(call);
break;
default:
break;
}
result.success(ret);
}
/**
*
*/
public boolean isShowBaiduHeatMap(MethodCall call) {
Map<String, Object> argument = call.arguments();
if (argument == null || !argument.containsKey("show")) {
return false;
}
Boolean show = (Boolean) argument.get("show");
if (null == show) {
return false;
}
if (null == mMapView) {
return false;
}
BaiduMap baiduMap = mMapView.getBaiduMap();
baiduMap.setBaiduHeatMapEnabled(show);
return true;
}
public boolean addHeapMap(Context context,MethodCall call){
if(Env.DEBUG){
Log.d(TAG, "addHeapMap enter");
}
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
return false;
}
Object heatMapObj = argument.get("heatMap");
if(null == heatMapObj){
if(Env.DEBUG){
Log.d(TAG, "null == heatMapObj");
}
return false;
}
Map<String, Object> heatMapMap = (Map<String, Object>)heatMapObj;
if(null == heatMapMap){
if(Env.DEBUG){
Log.d(TAG, "null == heatMapMap");
}
return false;
}
if(!heatMapMap.containsKey("data")
|| !heatMapMap.containsKey("radius")
|| !heatMapMap.containsKey("opacity")
|| !heatMapMap.containsKey("gradient")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain"+ argument.toString());
}
return false;
}
HeatMap.Builder builder = new HeatMap.Builder();
List<WeightedLatLng> weightedLatLngList = getData(heatMapMap);
if(null == weightedLatLngList){
if(Env.DEBUG){
Log.d(TAG, "null == weightedLatLngList");
}
return false;
}
builder.weightedData(weightedLatLngList);
Object gradientObj = heatMapMap.get("gradient");
if(null == gradientObj){
if(Env.DEBUG){
Log.d(TAG, "null == gradientObj");
}
return false;
}
Map<String, Object> gradientMap = (Map<String, Object>)gradientObj;
if(null == gradientMap){
if(Env.DEBUG){
Log.d(TAG, "null == gradientMap");
}
return false;
}
Gradient gradient = getGradient(gradientMap);
builder.gradient(gradient);
Double opacity = new TypeConverter<Double>().getValue(heatMapMap, "opacity");
if(null == opacity){
if(Env.DEBUG){
Log.d(TAG, "null == opacity");
}
return false;
}
builder.opacity(opacity);
Integer radius = new TypeConverter<Integer>().getValue(heatMapMap, "radius");
if(null == radius) {
if(Env.DEBUG){
Log.d(TAG, "null == radius");
}
return false;
}
builder.radius(radius);
mHeatMap = builder.build();
if(null == mHeatMap){
if(Env.DEBUG){
Log.d(TAG, "null == mHeatMap");
}
return false;
}
BaiduMap baiduMap = mMapView.getBaiduMap();
if(null == baiduMap){
return false;
}
baiduMap.addHeatMap(mHeatMap);
return true;
}
private List<WeightedLatLng> getData(Map<String, Object> heatMapMap){
List<WeightedLatLng> weightedLatLngList = null;
Object dataObj = heatMapMap.get("data");
if(null == dataObj){
return null;
}
List<Map<String, Object> > dataList = (List<Map<String, Object> >)dataObj;
if(null == dataList){
return null;
}
weightedLatLngList = FlutterDataConveter.mapToWeightedLatLngList(dataList);
return weightedLatLngList;
}
private Gradient getGradient(Map<String, Object> heatMapMap){
if(!heatMapMap.containsKey("colors") || !heatMapMap.containsKey("startPoints")){
return null;
}
Object colorsObj = heatMapMap.get("colors");
Object startPointsObj = heatMapMap.get("startPoints");
if(null == colorsObj || null == startPointsObj){
return null;
}
List<String> colorsList = (List<String>)colorsObj;
List<Double> startPointsList = (List<Double>)startPointsObj;
if(null == colorsList || null == startPointsList){
return null;
}
int[] intColors = new int[colorsList.size()];
Iterator<String> itr = colorsList.iterator();
int i = 0;
while (itr.hasNext()){
String colorStr = itr.next();
int color = FlutterDataConveter.strColorToInteger(colorStr);
intColors[i++] = color;
}
float[] startPoints = new float[startPointsList.size()];
Iterator<Double> startPointsItr = startPointsList.iterator();
i = 0;
while (startPointsItr.hasNext()){
startPoints[i++] = startPointsItr.next().floatValue();
}
Gradient gradient = new Gradient(intColors, startPoints);
return gradient;
}
public boolean switchHeatMap(Context context,MethodCall call){
if(Env.DEBUG){
Log.d(TAG, "switchHeatMap enter");
}
if(null == mHeatMap){
return false;
}
BaiduMap baiduMap = mMapView.getBaiduMap();
if(null == baiduMap){
if (Env.DEBUG) {
Log.d(TAG, "baiduMap is null");
}
return false;
}
mHeatMap.removeHeatMap();
mHeatMap = null;
return true;
}
}

@ -0,0 +1,195 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapBaseIndoorMapInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class IndoorMapHandler extends BMapHandler {
private static final String TAG = "IndoorMapHandler";
private BaiduMap mBaiduMap;
public IndoorMapHandler(FlutterCommonMapView mapView) {
super(mapView);
if(null != mapView){
mBaiduMap = mapView.getBaiduMap();
}
}
@Override
public void updateMapView(FlutterCommonMapView mapView) {
super.updateMapView(mapView);
if(null != mapView){
mBaiduMap = mapView.getBaiduMap();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result) {
if(Env.DEBUG){
Log.d(TAG, "handlerMethodCallResult enter");
}
if (null == call) {
result.success(false);
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
result.success(false);
return;
}
switch (methodId) {
case Constants.MethodProtocol.IndoorMapProtocol.sShowBaseIndoorMapMethod:
setIndoorMap(call, result);
break;
case Constants.MethodProtocol.IndoorMapProtocol.sShowBaseIndoorMapPoiMethod:
setIndoorMapPoi(call, result);
break;
case Constants.MethodProtocol.IndoorMapProtocol.sSwitchBaseIndoorMapFloorMethod:
switchIndoorMapFloor(call, result);
break;
case Constants.MethodProtocol.IndoorMapProtocol.sGetFocusedBaseIndoorMapInfoMethod:
getFocusedBaseIndoorMapInfo(call, result);
break;
default:
break;
}
}
/**
*
*/
private void setIndoorMap(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("show")) {
result.success(false);
}
boolean showIndoorMap = (boolean) argument.get("show");
mBaiduMap.setIndoorEnable(showIndoorMap);
BMFMapStatus.getsInstance().setBaseIndoorEnable(showIndoorMap);
result.success(true);
}
/**
* poi
*/
private void setIndoorMapPoi(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mMapView) {
result.success(false);
return;
}
if(null == mBaiduMap){
return;
}
if (!argument.containsKey("showIndoorPoi")) {
result.success(false);
}
boolean showIndoorPoi = (boolean) argument.get("showIndoorPoi");
mBaiduMap.showMapIndoorPoi(showIndoorPoi);
BMFMapStatus.getsInstance().setIndoorMapPoiEnable(showIndoorPoi);
result.success(true);
}
/**
*
*/
private void switchIndoorMapFloor(MethodCall call, MethodChannel.Result result) {
HashMap<String, Integer> errorMap = new HashMap<>();
int switchIndoorFloorSuccess = Constants.SwitchIndoorFloorError.FAILED;
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
errorMap.put("result", switchIndoorFloorSuccess);
result.success(errorMap);
return;
}
if (!argument.containsKey("floorId") || !argument.containsKey("indoorId")) {
errorMap.put("result", switchIndoorFloorSuccess);
result.success(errorMap);
return;
}
String floorId = (String) argument.get("floorId");
String indoorId = (String) argument.get("indoorId");
if (floorId.isEmpty() || indoorId.isEmpty()) {
return;
}
MapBaseIndoorMapInfo.SwitchFloorError switchFloorError = mBaiduMap.switchBaseIndoorMapFloor(floorId, indoorId);
switch (switchFloorError) {
case SWITCH_OK:
switchIndoorFloorSuccess = Constants.SwitchIndoorFloorError.SUCCESS;
break;
case SWITCH_ERROR:
switchIndoorFloorSuccess = Constants.SwitchIndoorFloorError.FAILED;
break;
case FOCUSED_ID_ERROR:
switchIndoorFloorSuccess = Constants.SwitchIndoorFloorError.NOT_FOCUSED;
break;
case FLOOR_OVERLFLOW:
switchIndoorFloorSuccess = Constants.SwitchIndoorFloorError.NOT_EXIST;
break;
case FLOOR_INFO_ERROR:
switchIndoorFloorSuccess = Constants.SwitchIndoorFloorError.SWICH_FLOOR_INFO_ERROR;
break;
default:
break;
}
errorMap.put("result", switchIndoorFloorSuccess);
result.success(errorMap);
}
/**
*
*/
private void getFocusedBaseIndoorMapInfo(MethodCall call, MethodChannel.Result result) {
if (null == mBaiduMap) {
return;
}
MapBaseIndoorMapInfo focusedBaseIndoorMapInfo = mBaiduMap.getFocusedBaseIndoorMapInfo();
BMFBaseIndoorMapInfo bmfBaseIndoorMapInfo = new BMFBaseIndoorMapInfo();
if (null != focusedBaseIndoorMapInfo) {
bmfBaseIndoorMapInfo.strFloor = focusedBaseIndoorMapInfo.getCurFloor();
bmfBaseIndoorMapInfo.strID = focusedBaseIndoorMapInfo.getID();
bmfBaseIndoorMapInfo.listStrFloors = focusedBaseIndoorMapInfo.getFloors();
}
HashMap<String, Object> stringObjectHashMap = new HashMap<>();
stringObjectHashMap.put("listStrFloors", bmfBaseIndoorMapInfo.listStrFloors);
stringObjectHashMap.put("strFloor", bmfBaseIndoorMapInfo.strFloor);
stringObjectHashMap.put("strID", bmfBaseIndoorMapInfo.strID);
result.success(stringObjectHashMap);
}
class BMFBaseIndoorMapInfo {
private String strID = "";
private String strFloor = "";
private ArrayList<String> listStrFloors;
}
}

@ -0,0 +1,306 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.mapHandler.BMapHandler;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.InfoWindowProtocol;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.model.LatLng;
public class InfoWindowHandler extends BMapHandler{
private static final String TAG = "InfoWindowHandler";
private HashMap<String, InfoWindow> mInfoWindows;
private HashMap<String, BitmapDescriptor> mBitmapMap = new HashMap<>();
private MethodChannel mMethodChannel;
private BaiduMap mBaiduMap;
public InfoWindowHandler(FlutterCommonMapView mapView){
super(mapView);
if(null != mMapView){
mBaiduMap = mMapView.getBaiduMap();
}
mInfoWindows = new HashMap<>();
}
@Override
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
if(null != mMapView){
mBaiduMap = mMapView.getBaiduMap();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result) {
if(Env.DEBUG){
Log.d(TAG, "handlerMethodCallResult enter");
}
if(null == mBaiduMap){
if(Env.DEBUG){
Log.d(TAG, "mBaidumap is null");
}
return;
}
String methodId = call.method;
switch (methodId){
case InfoWindowProtocol.sAddInfoWindowMapMethod:
addInfoWindow(call, result);
break;
case InfoWindowProtocol.sAddInfoWindowsMapMethod:
addInfoWindows(call,result);
break;
case InfoWindowProtocol.sRemoveInfoWindowMapMethod:
removeInfoWindow(call, result);
break;
default:
break;
}
}
/**
* infoWindow
* @param call
* @param result
*/
private void addInfoWindow(MethodCall call, MethodChannel.Result result){
if(Env.DEBUG){
Log.d(TAG, "addInfoWindow enter");
}
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
return;
}
addOneInfoWindowImp(argument);
}
/**
* infowindow
* @param infoWindowMap
*/
private void addOneInfoWindowImp(Map<String, Object> infoWindowMap){
AbstractMap.SimpleEntry<String,InfoWindow> infoWindowEntry = MaptoInfoWindowEntry(infoWindowMap);
if(null == infoWindowEntry){
return;
}
mInfoWindows.put(infoWindowEntry.getKey(), infoWindowEntry.getValue());
mBaiduMap.showInfoWindow(infoWindowEntry.getValue());
}
private AbstractMap.SimpleEntry<String, InfoWindow> MaptoInfoWindowEntry(Map<String, Object> infoWindowMap){
if(null == infoWindowMap){
return null;
}
if(!infoWindowMap.containsKey("id")){
if(Env.DEBUG){
Log.d(TAG, "argument does not contain");
}
return null;
}
final String id = new TypeConverter<String>().getValue(infoWindowMap, "id");
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "TextUtils.isEmpty(id)");
}
return null;
}
if(mInfoWindows.containsKey(id)){
if(Env.DEBUG){
Log.d(TAG, "infowindow already added");
}
return null;
}
String image = new TypeConverter<String>().getValue(infoWindowMap, "image");
if(TextUtils.isEmpty(image)){
if(Env.DEBUG){
Log.d(TAG, "TextUtils.isEmpty(image)");
}
return null;
}
Map<String, Object> latLngMap = new TypeConverter<Map<String, Object>>().getValue(infoWindowMap, "coordinate");
LatLng latLng = FlutterDataConveter.mapToLatlng(latLngMap);
if(null == latLng){
if(Env.DEBUG){
Log.d(TAG, "null == latLng");
}
return null;
}
Double yOffSet = new TypeConverter<Double>().getValue(infoWindowMap, "yOffset");
if(null == yOffSet){
if(Env.DEBUG){
Log.d(TAG, "null == yOffSet");
}
return null;
}
Boolean isAddWithBitmapDescriptor = new TypeConverter<Boolean>().getValue(infoWindowMap, "isAddWithBitmapDescriptor");
if(null == isAddWithBitmapDescriptor){
if(Env.DEBUG){
Log.d(TAG, "null == isAddWithBitmapDescriptor");
}
return null;
}
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromAsset("flutter_assets/" + image);
if(null == bitmap){
if(Env.DEBUG){
Log.d(TAG, "null == bitmap");
}
return null;
}
mBitmapMap.put(id, bitmap);
InfoWindow infoWindow = new InfoWindow(bitmap, latLng, yOffSet.intValue(), new InfoWindow.OnInfoWindowClickListener(){
@Override
public void onInfoWindowClick() {
if(null == mMethodChannel){
return;
}
Map<String, Object> infoWindowMap = new HashMap<>();
infoWindowMap.put("id", id);
mMethodChannel.invokeMethod(InfoWindowProtocol.sMapDidClickedInfoWindowMethod, infoWindowMap);
}
} );
return new AbstractMap.SimpleEntry<String, InfoWindow>(id, infoWindow);
}
/**
* infowindow
* @param call
* @param result
*/
private void addInfoWindows(MethodCall call, MethodChannel.Result result) {
if(Env.DEBUG){
Log.d(TAG, "addInfoWindows enter");
}
List<Object> arguments = (List<Object>)call.arguments;
if(null == arguments){
if(Env.DEBUG){
Log.d(TAG, "arguments is null");
}
return;
}
List<InfoWindow> infoWindowList = new ArrayList<>();
Iterator itr = arguments.iterator();
while (itr.hasNext()){
Map<String, Object> infoWindowMap = (Map<String, Object> )itr.next();
if(null == infoWindowMap){
continue;
}
AbstractMap.SimpleEntry<String,InfoWindow> infoWindowEntry = MaptoInfoWindowEntry(infoWindowMap);
if(null == infoWindowEntry){
continue;
}
infoWindowList.add(infoWindowEntry.getValue());
mInfoWindows.put(infoWindowEntry.getKey(), infoWindowEntry.getValue());
}
if(infoWindowList.size() > 0){
mBaiduMap.showInfoWindows(infoWindowList);
}
}
private void removeInfoWindow(MethodCall call, MethodChannel.Result result){
if(null == mBaiduMap){
return;
}
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
return;
}
String id = new TypeConverter<String>().getValue(argument, "id");
if(TextUtils.isEmpty(id)){
if(Env.DEBUG){
Log.d(TAG, "TextUtils.isEmpty(id)");
}
return;
}
InfoWindow infoWindow = mInfoWindows.get(id);
if(null == infoWindow){
if(Env.DEBUG){
Log.d(TAG, "null == infoWindow");
}
return;
}
if(Env.DEBUG){
Log.d(TAG, "removeInfoWindow success");
}
mBaiduMap.hideInfoWindow(infoWindow);
mInfoWindows.remove(id);
BitmapDescriptor bitmapDescriptor = mBitmapMap.get(id);
if(null != bitmapDescriptor){
bitmapDescriptor.recycle();
}
}
@Override
public void clean(){
super.clean();
Iterator iterator = mBitmapMap.values().iterator();
BitmapDescriptor bitmapDescriptor;
while (iterator.hasNext()){
bitmapDescriptor = (BitmapDescriptor)iterator.next();
if(null != bitmapDescriptor){
bitmapDescriptor.recycle();
}
}
if(null != mInfoWindows) {
mInfoWindows.clear();
}
}
}

@ -0,0 +1,330 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.graphics.Color;
import android.text.TextUtils;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.flutter_bmfmap.utils.Env;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class LocationLayerHandler extends BMapHandler {
private BaiduMap mBaiduMap;
public LocationLayerHandler(FlutterCommonMapView mapView) {
super(mapView);
if (null != mapView) {
mBaiduMap = mapView.getBaiduMap();
}
}
@Override
public void updateMapView(FlutterCommonMapView mapView) {
super.updateMapView(mapView);
if (null != mapView) {
mBaiduMap = mapView.getBaiduMap();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result) {
if (null == call) {
result.success(false);
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
result.success(false);
return;
}
switch (methodId) {
case Constants.LocationLayerMethodId.sMapShowUserLocationMethod:
setLocationEnabled(call, result);
break;
case Constants.LocationLayerMethodId.sMapUpdateLocationDataMethod:
setUpdateLocationData(call, result);
break;
case Constants.LocationLayerMethodId.sMapUserTrackingModeMethod:
setLoctype(call, result);
break;
case Constants.LocationLayerMethodId.sMapUpdateLocationDisplayParamMethod:
setCustomLocation(call, result);
break;
default:
break;
}
}
/**
*
*/
private void setCustomLocation(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("userlocationDisplayParam")) {
result.success(false);
return;
}
Map<String, Object> locationDisplayParam = (Map<String, Object>) argument.get("userlocationDisplayParam");
if (null == locationDisplayParam) {
result.success(false);
return;
}
if (!locationDisplayParam.containsKey("userTrackingMode")
|| !locationDisplayParam.containsKey("enableDirection")
|| !locationDisplayParam.containsKey("accuracyCircleStrokeColor")
|| !locationDisplayParam.containsKey("accuracyCircleFillColor")
|| !locationDisplayParam.containsKey("locationViewImage")
|| !locationDisplayParam.containsKey("locationViewHierarchy")) {
result.success(false);
return;
}
Integer userTrackingMode = (Integer) locationDisplayParam.get("userTrackingMode");
Boolean enableDirection = (Boolean) locationDisplayParam.get("enableDirection");
String locationViewImage = (String) locationDisplayParam.get("locationViewImage");
String accuracyCircleStrokeColor = (String) locationDisplayParam.get("accuracyCircleStrokeColor");
String accuracyCircleFillColor = (String) locationDisplayParam.get("accuracyCircleFillColor");
BitmapDescriptor bitmap = null;
if (!TextUtils.isEmpty(locationViewImage)) {
bitmap = BitmapDescriptorFactory.fromAsset("flutter_assets/" + locationViewImage);
}
int strokeColor = 0;
String color = "#";
if (!TextUtils.isEmpty(accuracyCircleStrokeColor)) {
strokeColor = Color.parseColor(color.concat(accuracyCircleStrokeColor));
}
int fillColor = 0;
if (!TextUtils.isEmpty(accuracyCircleFillColor)) {
fillColor = Color.parseColor(color.concat(accuracyCircleFillColor));
}
if (null != userTrackingMode && null != enableDirection && null != bitmap
&& strokeColor != 0 && fillColor != 0) {
switch (userTrackingMode) {
case Env.LocationMode.NORMAL:
case Env.LocationMode.MODEHEADING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.NORMAL, enableDirection,
bitmap,fillColor,strokeColor));
break;
case Env.LocationMode.FOLLOWING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING, enableDirection,
bitmap,fillColor,strokeColor));
break;
case Env.LocationMode.COMPASS:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.COMPASS, enableDirection,
bitmap,fillColor,strokeColor));
break;
default:
break;
}
} else if (null != userTrackingMode && null != enableDirection && strokeColor != 0 && fillColor != 0) {
switch (userTrackingMode) {
case Env.LocationMode.NORMAL:
case Env.LocationMode.MODEHEADING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.NORMAL, enableDirection,
null,fillColor,strokeColor));
break;
case Env.LocationMode.FOLLOWING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING, enableDirection,
null,fillColor,strokeColor));
break;
case Env.LocationMode.COMPASS:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.COMPASS, enableDirection,
null,fillColor,strokeColor));
break;
default:
break;
}
}
}
/**
*
*/
private void setLoctype(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("userTrackingMode")
|| !argument.containsKey("enableDirection")
|| !argument.containsKey("customMarker")) {
result.success(false);
return;
}
Integer userTrackingMode = (Integer) argument.get("userTrackingMode");
Boolean enableDirection = (Boolean) argument.get("enableDirection");
String customMarker = (String) argument.get("customMarker");
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromAsset("flutter_assets/" + customMarker);
if (null != userTrackingMode && null != enableDirection && null != bitmap) {
switch (userTrackingMode) {
case Env.LocationMode.NORMAL:
case Env.LocationMode.MODEHEADING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.NORMAL, enableDirection, bitmap));
break;
case Env.LocationMode.FOLLOWING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING, enableDirection, bitmap));
break;
case Env.LocationMode.COMPASS:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.COMPASS, enableDirection, bitmap));
break;
default:
break;
}
result.success(true);
} else if (null != userTrackingMode && null != enableDirection) {
switch (userTrackingMode) {
case Env.LocationMode.NORMAL:
case Env.LocationMode.MODEHEADING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.NORMAL, enableDirection, null));
break;
case Env.LocationMode.FOLLOWING:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING, enableDirection, null));
break;
case Env.LocationMode.COMPASS:
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.COMPASS, enableDirection, null));
break;
default:
break;
}
result.success(true);
}
result.success(false);
}
/**
*
*/
private void setUpdateLocationData(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
MyLocationData.Builder builder = new MyLocationData.Builder();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("userLocation")) {
result.success(false);
return;
}
Map<String,Object> userLocation = (Map<String, Object>) argument.get("userLocation");
if (null == userLocation) {
result.success(false);
return;
}
if (!userLocation.containsKey("location")) {
result.success(false);
return;
}
Map<String,Object> location = (Map<String, Object>) userLocation.get("location");
if (null == location) {
result.success(false);
return;
}
if (!location.containsKey("coordinate") || !location.containsKey("course")
|| !location.containsKey("speed") || !location.containsKey("accuracy")
|| !location.containsKey("satellitesNum")) {
result.success(false);
return;
}
Map<String,Double> coordinate = (Map<String, Double>) location.get("coordinate");
if (null != coordinate) {
if (coordinate.containsKey("latitude") && coordinate.containsKey("longitude")) {
Double latitude = coordinate.get("latitude");
Double longitude = coordinate.get("longitude");
if (null != latitude && null != longitude) {
builder.latitude(latitude);
builder.longitude(longitude);
}
}
}
Double course = (Double) location.get("course");
if (null != course) {
builder.accuracy(course.floatValue());
}
Double speed = (Double) location.get("speed");
if (null != speed) {
builder.speed(speed.floatValue());
}
Double accuracy = (Double) location.get("accuracy");
if (null != accuracy) {
builder.speed(accuracy.floatValue());
}
Integer satellitesNum = (Integer) location.get("satellitesNum");
if (null != satellitesNum) {
builder.satellitesNum(satellitesNum);
}
mBaiduMap.setMyLocationData(builder.build());
result.success(true);
}
/**
*
*/
private void setLocationEnabled(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("show")) {
result.success(false);
return;
}
Boolean show = (Boolean) argument.get("show");
if (null == show) {
result.success(false);
return;
}
mBaiduMap.setMyLocationEnabled(show);
result.success(true);
}
}

@ -0,0 +1,409 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.map.FlutterMapView;
import com.baidu.flutter_bmfmap.map.MapStateUpdateImp;
import com.baidu.flutter_bmfmap.map.MapViewWrapper;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.map.WinRound;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.text.TextUtils;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class MapStateHandler extends BMapHandler {
private static final String TAG = MapStateHandler.class.getSimpleName();
private BaiduMap mBaiduMap;
private String mViewType;
public MapStateHandler(FlutterCommonMapView mapView) {
super(mapView);
mViewType = mapView.getViewType();
mBaiduMap = mapView.getBaiduMap();
}
@Override
public void updateMapView(FlutterCommonMapView mapView) {
super.updateMapView(mapView);
if (null != mapView) {
mBaiduMap = mapView.getBaiduMap();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call,
MethodChannel.Result result) {
if (null == call) {
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
return;
}
switch (methodId) {
case Constants.MethodProtocol.MapStateProtocol.sMapUpdateMethod:
setMapUpdate(call, result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapTakeSnapshotMethod:
mapSnapshot(result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapTakeSnapshotWithRectMethod:
snapShotRect(call, result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapSetCompassImageMethod:
setCompassImage(call, result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapSetCustomTrafficColorMethod:
setCustomTrafficColor(call, result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapSetVisibleMapBoundsMethod:
setNewCoordinateBounds(call, result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapSetVisibleMapBoundsWithPaddingMethod:
setVisibleMapBoundsWithPaddingMethod(call, result);
break;
case Constants.MethodProtocol.MapStateProtocol.sMapDidUpdateWidget:
case Constants.MethodProtocol.MapStateProtocol.sMapReassemble:
resumeMap();
break;
default:
break;
}
}
/**
*
*/
private void setCustomTrafficColor(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("smooth") || !argument.containsKey("slow")
|| !argument.containsKey("congestion") || !argument
.containsKey("severeCongestion")) {
result.success(false);
return;
}
String smooth = (String) argument.get("smooth");
String slow = (String) argument.get("slow");
String congestion = (String) argument.get("congestion");
String severeCongestion = (String) argument.get("severeCongestion");
if (smooth == null || slow == null || congestion == null || severeCongestion == null) {
result.success(false);
return;
}
String color = "#";
String severeCongestionColor = color.concat(severeCongestion);
String congestionColor = color.concat(congestion);
String slowColor = color.concat(slow);
String smoothColor = color.concat(smooth);
mBaiduMap.setCustomTrafficColor(severeCongestionColor, congestionColor, slowColor,
smoothColor);
result.success(true);
}
/**
*
*/
private void setCompassImage(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("imagePath")) {
result.success(false);
return;
}
String imagePath = (String) argument.get("imagePath");
if (imagePath == null) {
result.success(false);
return;
}
BitmapDescriptor bitmapDescriptor =
BitmapDescriptorFactory.fromAsset("flutter_assets/" + imagePath);
Bitmap bitmap = bitmapDescriptor.getBitmap();
mBaiduMap.setCompassIcon(bitmap);
result.success(true);
}
/**
*
*/
private void snapShotRect(MethodCall call, final MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(null);
return;
}
if (!argument.containsKey("rect")) {
result.success(null);
return;
}
Map<String, Object> rect = (Map<String, Object>) argument.get("rect");
WinRound winRound = FlutterDataConveter.BMFRectToWinRound(rect);
if (null == winRound) {
result.success(null);
return;
}
if (winRound.left > winRound.right || winRound.top > winRound.bottom) {
result.success(null);
return;
}
if (winRound.right - winRound.left > getMapViewWidth()
|| winRound.bottom - winRound.top > getMapViewHeight()) {
result.success(null);
return;
}
// 矩形区域保证left <= right top <= bottom 否则截屏失败
Rect recta = new Rect(winRound.left, winRound.top, winRound.right, winRound.bottom);
mBaiduMap.snapshotScope(recta, new BaiduMap.SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap bitmap) {
if (null == bitmap) {
result.success(null);
return;
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
result.success(byteArrayOutputStream.toByteArray());
}
});
}
private int getMapViewWidth() {
int width = 0;
switch (mViewType) {
case Constants.ViewType.sMapView:
MapView mapView = mMapView.getMapView();
width = null != mapView ? mapView.getWidth() : 0;
break;
case Constants.ViewType.sTextureMapView:
TextureMapView textureMapView = mMapView.getTextureMapView();
width = null != textureMapView ? textureMapView.getWidth() : 0;
break;
default:
break;
}
return width;
}
private int getMapViewHeight() {
int height = 0;
switch (mViewType) {
case Constants.ViewType.sMapView:
MapView mapView = mMapView.getMapView();
height = null != mapView ? mapView.getHeight() : 0;
break;
case Constants.ViewType.sTextureMapView:
TextureMapView textureMapView = mMapView.getTextureMapView();
height = null != textureMapView ? textureMapView.getHeight() : 0;
break;
default:
break;
}
return height;
}
/**
*
*/
private void mapSnapshot(final MethodChannel.Result result) {
if (null == mBaiduMap) {
result.success(null);
return;
}
mBaiduMap.snapshot(new BaiduMap.SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap bitmap) {
if (null == bitmap) {
result.success(null);
return;
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
result.success(byteArrayOutputStream.toByteArray());
}
});
}
/**
*
*/
private void setMapUpdate(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
boolean ret = MapStateUpdateImp.getInstance()
.setCommView(mMapView)
.updateMapState(argument);
result.success(ret);
}
/**
*
*/
private void setNewCoordinateBounds(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("visibleMapBounds")) {
result.success(false);
return;
}
Map<String, Object> visibleMapBounds =
(Map<String, Object>) argument.get("visibleMapBounds");
if (null == visibleMapBounds) {
result.success(false);
return;
}
LatLngBounds latLngBounds = visibleMapBoundsImp(visibleMapBounds);
if (null == latLngBounds) {
result.success(false);
return;
}
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLngBounds(latLngBounds));
result.success(true);
}
private LatLngBounds visibleMapBoundsImp(Map<String, Object> visibleMapBounds) {
if (!visibleMapBounds.containsKey("northeast") || !visibleMapBounds
.containsKey("southwest")) {
return null;
}
HashMap<String, Double> northeast =
(HashMap<String, Double>) visibleMapBounds.get("northeast");
HashMap<String, Double> southwest =
(HashMap<String, Double>) visibleMapBounds.get("southwest");
if (null == northeast || null == southwest) {
return null;
}
if (!northeast.containsKey("latitude") || !northeast.containsKey("longitude")
|| !southwest.containsKey("latitude") || !southwest.containsKey("longitude")) {
return null;
}
Double northeastLatitude = northeast.get("latitude");
Double northeastLongitude = northeast.get("longitude");
Double southwestLatitude = southwest.get("latitude");
Double southwestLongitude = southwest.get("longitude");
if (null == northeastLatitude || null == northeastLongitude
|| null == southwestLatitude || null == southwestLongitude) {
return null;
}
LatLng northeastLatLng = new LatLng(northeastLatitude, northeastLongitude);
LatLng southwestLatLng = new LatLng(southwestLatitude, southwestLongitude);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(northeastLatLng);
builder.include(southwestLatLng);
return builder.build();
}
/**
* Padding
*/
private void setVisibleMapBoundsWithPaddingMethod(MethodCall call,
MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument || null == mBaiduMap) {
result.success(false);
return;
}
if (!argument.containsKey("visibleMapBounds") || !argument.containsKey("insets")) {
result.success(false);
return;
}
Map<String, Object> visibleMapBounds =
(Map<String, Object>) argument.get("visibleMapBounds");
Map<String, Double> insets = (Map<String, Double>) argument.get("insets");
if (null == visibleMapBounds || null == insets) {
result.success(false);
return;
}
LatLngBounds latLngBounds = visibleMapBoundsImp(visibleMapBounds);
if (null == latLngBounds) {
result.success(false);
return;
}
if (!insets.containsKey("left") || !insets.containsKey("top")
|| !insets.containsKey("right") || !insets.containsKey("bottom")) {
result.success(false);
return;
}
Double left = insets.get("left");
Double top = insets.get("top");
Double right = insets.get("right");
Double bottom = insets.get("bottom");
if (null == left || null == top || null == right || null == bottom) {
result.success(false);
return;
}
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngBounds(latLngBounds,
left.intValue(), top.intValue(), right.intValue(), bottom.intValue());
mBaiduMap.setMapStatus(mapStatusUpdate);
result.success(true);
}
private void updateMap() {
MapStatus.Builder builder = new MapStatus.Builder();
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(builder.build());
mBaiduMap.setMapStatus(mapStatusUpdate);
}
private void resumeMap() {
MapViewWrapper mapViewWrapper = (MapViewWrapper) mMapView;
FlutterMapView flutterMapView = mapViewWrapper.getFlutterMapView();
flutterMapView.setResumeState(true);
}
}

@ -0,0 +1,616 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.map.mapHandler.BMapHandler;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.model.LatLng;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class MarkerHandler extends BMapHandler {
private static final String TAG = "MarkerHandler";
private HashMap<String, Overlay> mOverlayMap = new HashMap<>();
private HashMap<String, BitmapDescriptor> mMarkerBitmapMap = new HashMap<>();
private BaiduMap mBaiduMap;
public MarkerHandler(FlutterCommonMapView mapView) {
super(mapView);
if (null != mMapView) {
mBaiduMap = mMapView.getBaiduMap();
}
}
@Override
public void updateMapView(FlutterCommonMapView mapView) {
mMapView = mapView;
if (null != mMapView) {
mBaiduMap = mMapView.getBaiduMap();
}
}
@Override
public void clean() {
super.clean();
Iterator iterator = mMarkerBitmapMap.values().iterator();
BitmapDescriptor bitmapDescriptor;
while (iterator.hasNext()) {
bitmapDescriptor = (BitmapDescriptor) iterator.next();
if (null != bitmapDescriptor) {
bitmapDescriptor.recycle();
}
}
mMarkerBitmapMap.clear();
mOverlayMap.clear();
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call,
MethodChannel.Result result) {
if (null == call) {
result.success(false);
return;
}
if (null == mBaiduMap) {
result.success(false);
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
result.success(false);
return;
}
boolean ret = false;
switch (methodId) {
case Constants.MethodProtocol.MarkerProtocol.sMapAddMarkerMethod:
ret = addMarker(call);
break;
case Constants.MethodProtocol.MarkerProtocol.sMapAddMarkersMethod:
ret = addMarkers(call);
break;
case Constants.MethodProtocol.MarkerProtocol.sMapRemoveMarkerMethod:
ret = removeMarker(call);
break;
case Constants.MethodProtocol.MarkerProtocol.sMapRemoveMarkersMethod:
ret = removeMarkers(call);
break;
case Constants.MethodProtocol.MarkerProtocol.sMapDidSelectMarkerMethod:
break;
case Constants.MethodProtocol.MarkerProtocol.sMapDidDeselectMarkerMethod:
break;
case Constants.MethodProtocol.MarkerProtocol.sMapCleanAllMarkersMethod:
ret = cleanAllMarker(call);
break;
case Constants.MethodProtocol.MarkerProtocol.sMapUpdateMarkerMemberMethod:
ret = updateMarkerMember(call, result);
break;
default:
break;
}
result.success(ret);
return;
}
private boolean addMarker(MethodCall call) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
return false;
}
return addMarkerImp(argument);
}
private boolean addMarkerImp(Map<String, Object> argument) {
if (Env.DEBUG) {
Log.d(TAG, "addMarkerImp enter");
}
if (null == argument) {
return false;
}
if (!argument.containsKey("id")
|| !argument.containsKey("position")
|| !argument.containsKey("icon")) {
return false;
}
String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return false;
}
if (mOverlayMap.containsKey(id)) {
return false;
}
Map<String, Object> latlngMap = (Map<String, Object>) argument.get("position");
String title = (String) argument.get("title");
String subTitle = (String) argument.get("subtitle");
LatLng latLng = FlutterDataConveter.mapToLatlng(latlngMap);
if (null == latLng) {
if (Env.DEBUG) {
Log.d(TAG, "latLng is null");
}
return false;
}
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
setScreenLockPoint(argument, markerOptions);
if (!setMarkerOptions(argument, markerOptions, id)) {
return false;
}
Overlay overlay = mBaiduMap.addOverlay(markerOptions);
Bundle bundle = new Bundle();
bundle.putString("id", id);
overlay.setExtraInfo(bundle);
mOverlayMap.put(id, overlay);
return true;
}
private boolean setScreenLockPoint(Map<String, Object> argumentMap,
MarkerOptions markerOptions) {
if (null == argumentMap || null == markerOptions) {
return false;
}
Boolean isLockedToScreen =
new TypeConverter<Boolean>().getValue(argumentMap, "isLockedToScreen");
if (null == isLockedToScreen || false == isLockedToScreen) {
return false;
}
Map<String, Object> screenPointToLockMap =
new TypeConverter<Map<String, Object>>().getValue(argumentMap, "screenPointToLock");
if (null == screenPointToLockMap
|| !screenPointToLockMap.containsKey("x")
|| !screenPointToLockMap.containsKey("y")) {
return false;
}
Double x = new TypeConverter<Double>().getValue(screenPointToLockMap, "x");
Double y = new TypeConverter<Double>().getValue(screenPointToLockMap, "y");
if (null == x || null == y) {
return false;
}
Point point = new Point(x.intValue(), y.intValue());
markerOptions.fixedScreenPosition(point);
return true;
}
/// Add Begin
/*
http://blog.csdn.net/alex_zhuang/article/details/7340901
Java.lang.RuntimeException: java.lang.IllegalArgumentException: File /data/data/com.alex.datasave/files/user.txt contains a path separator
fis = this.context.openFileInput("/data/data/com.alex.datasave/files/user.txt");
// 正确代码:
File file = new File("/data/data/com.alex.datasave/files/user.txt");
fis = new FileInputStream(file); // 注意: 1.FileInputStream 与 openFileInput
*/
public BitmapDescriptor my_fromFile(String var0) {
// System.out.println("my_fromFile var0 = " + var0);
if (var0 != null && !var0.equals("")) {
Context var1 = BMapManager.getContext();
if (null == var1) {
return null;
} else {
try {
// FileInputStream var2 = var1.openFileInput(var0);
// System.out.print("my_fromFile : var0 = %s, var1 = %s", var0, var1);
// System.out.println("my_fromFile in var0 = " + var0);
// System.out.println("my_fromFile in var1 = " + var1);
// 正确代码:
File file = new File(var0);
FileInputStream var2 = new FileInputStream(file); // 注意: 1.FileInputStream 与 openFileInput
Bitmap var3 = BitmapFactory.decodeStream(var2);
var2.close();
if (var3 != null) {
BitmapDescriptor var4 = BitmapDescriptorFactory.fromBitmap(var3);
var3.recycle();
return var4;
}
} catch (FileNotFoundException var5) {
Log.e("my_fromFile", "FileNotFoundException happened", var5);
} catch (IOException var6) {
Log.e("my_fromFile", "IOException happened", var6);
}
return null;
}
} else {
return null;
}
}
/// Add End
/**
* markertions
*
* @return
*/
private boolean setMarkerOptions(Map<String, Object> markerOptionsMap,
MarkerOptions markerOptions, String id) {
//icon是必须的
String icon = new TypeConverter<String>().getValue(markerOptionsMap, "icon");
if (TextUtils.isEmpty(icon)) {
return false;
}
/// Add Begin
BitmapDescriptor bitmapDescriptor;
// System.out.println("my log:" + icon.substring(0, 1));
if (icon.substring(0, 1).equals("/")) {
// System.out.println("my log in");
// bitmapDescriptor = BitmapDescriptorFactory.fromAsset("flutter_assets/" + icon);
bitmapDescriptor = my_fromFile(icon);
} else {
bitmapDescriptor = BitmapDescriptorFactory.fromAsset("flutter_assets/" + icon);
}
/// Add End
// BitmapDescriptor bitmapDescriptor =
// BitmapDescriptorFactory.fromAsset("flutter_assets/" + icon);
if (null == bitmapDescriptor) {
return false;
}
markerOptions.icon(bitmapDescriptor);
mMarkerBitmapMap.put(id, bitmapDescriptor);
//centerOffset
Map<String, Object> centerOffset =
new TypeConverter<Map<String, Object>>().getValue(markerOptionsMap, "centerOffset");
if (null != centerOffset) {
Double y = new TypeConverter<Double>().getValue(centerOffset, "y");
if (null != y) {
markerOptions.yOffset(y.intValue());
}
}
Boolean enable = new TypeConverter<Boolean>().getValue(markerOptionsMap, "enabled");
if (markerOptionsMap.containsKey("enabled")) {
if (Env.DEBUG) {
Log.d(TAG, "enbale" + enable);
}
markerOptions.clickable(enable);
}
Boolean draggable = new TypeConverter<Boolean>().getValue(markerOptionsMap, "draggable");
if (null != draggable) {
markerOptions.draggable(draggable);
}
Integer zIndex = new TypeConverter<Integer>().getValue(markerOptionsMap, "zIndex");
if (null != zIndex) {
markerOptions.zIndex(zIndex);
}
Boolean visible = new TypeConverter<Boolean>().getValue(markerOptionsMap, "visible");
if (null != visible) {
markerOptions.visible(visible);
}
Double scaleX = new TypeConverter<Double>().getValue(markerOptionsMap, "scaleX");
if (null != scaleX) {
markerOptions.scaleX(scaleX.floatValue());
}
Double scaleY = new TypeConverter<Double>().getValue(markerOptionsMap, "scaleY");
if (null != scaleY) {
markerOptions.scaleX(scaleY.floatValue());
}
Double alpha = new TypeConverter<Double>().getValue(markerOptionsMap, "alpha");
if (null != alpha) {
markerOptions.alpha(alpha.floatValue());
}
Boolean isPerspective = new TypeConverter<Boolean>().getValue(markerOptionsMap, "isPerspective");
if (null != isPerspective) {
markerOptions.perspective(isPerspective);
}
return true;
}
private boolean addMarkers(MethodCall call) {
if (Env.DEBUG) {
Log.d(TAG, "addMarkers enter");
}
if (null == call) {
return false;
}
List<Object> arguments = call.arguments();
if (null == arguments) {
return false;
}
Iterator itr = arguments.iterator();
while (itr.hasNext()) {
Map<String, Object> argument = (Map<String, Object>) itr.next();
addMarkerImp(argument);
}
return true;
}
private boolean removeMarker(MethodCall call) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
return false;
}
removeMarkerImp(argument);
return true;
}
private boolean removeMarkerImp(Map<String, Object> argument) {
String id = new TypeConverter<String>().getValue(argument, "id");
Overlay overlay = mOverlayMap.get(id);
BitmapDescriptor bitmapDescriptor = mMarkerBitmapMap.get(id);
boolean ret = true;
if (null != overlay) {
overlay.remove();
mOverlayMap.remove(id);
} else {
ret = false;
}
if (null != bitmapDescriptor) {
bitmapDescriptor.recycle();
mMarkerBitmapMap.remove(id);
} else {
ret = false;
}
return ret;
}
private boolean removeMarkers(MethodCall call) {
List<Object> markersList = call.arguments();
if (null == markersList) {
return false;
}
Iterator itr = markersList.iterator();
while (itr.hasNext()) {
Map<String, Object> marker = (Map<String, Object>) itr.next();
if (null != marker) {
removeMarkerImp(marker);
}
}
return true;
}
private boolean selectMarker(MethodCall call) {
return true;
}
private boolean deSelectMarker(MethodCall call) {
return true;
}
private boolean cleanAllMarker(MethodCall call) {
mBaiduMap.clear();
this.clean();
return true;
}
/**
* marker
*
* @param call
* @param result
* @return
*/
private boolean updateMarkerMember(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
return false;
}
String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return false;
}
if (!mMarkerBitmapMap.containsKey(id)) {
return false;
}
Marker marker = (Marker) mOverlayMap.get(id);
if (null == marker) {
return false;
}
String member = new TypeConverter<String>().getValue(argument, "member");
if (TextUtils.isEmpty(member)) {
return false;
}
Object value = argument.get("value");
if (null == value) {
return false;
}
boolean ret = false;
switch (member) {
case "title":
String titile = (String) value;
if (!TextUtils.isEmpty(titile)) {
marker.setTitle(titile);
ret = true;
}
break;
case "position":
Map<String, Object> position = (Map<String, Object>) value;
LatLng latLng = FlutterDataConveter.mapToLatlng(position);
if (null != latLng) {
marker.setPosition(latLng);
ret = true;
}
break;
case "isLockedToScreen":
Boolean isLockedToScreen = (Boolean) value;
if (null != isLockedToScreen && isLockedToScreen) {
Map<String, Object> pointMap =
new TypeConverter<Map<String, Object>>().getValue(argument,
"screenPointToLock");
Point point = FlutterDataConveter.mapToPoint(pointMap);
if (null != point) {
marker.setFixedScreenPosition(point);
ret = true;
}
}
break;
case "icon":
String icon = (String) value;
BitmapDescriptor bitmapDescriptor = mMarkerBitmapMap.get(id);
if (null != bitmapDescriptor) {
bitmapDescriptor.recycle();
}
bitmapDescriptor = BitmapDescriptorFactory.fromAsset("flutter_assets/" + icon);
if (null != bitmapDescriptor) {
marker.setIcon(bitmapDescriptor);
mMarkerBitmapMap.put(id, bitmapDescriptor);
ret = true;
}
break;
case "centerOffset":
Map<String, Object> centerOffset = (Map<String, Object>) value;
if (null != centerOffset) {
Double y = new TypeConverter<Double>().getValue(centerOffset, "y");
if (null != y) {
marker.setYOffset(y.intValue());
ret = true;
}
}
break;
case "enabled":
Boolean enabled = (Boolean) value;
if (null != enabled) {
marker.setClickable(enabled);
ret = true;
}
break;
case "draggable":
Boolean draggable = (Boolean) value;
if (null != draggable) {
marker.setDraggable(draggable);
ret = true;
}
break;
case "visible":
Boolean visible = (Boolean) value;
if (null != visible) {
marker.setVisible(visible);
ret = true;
}
break;
case "zIndex":
Integer zIndex = (Integer) value;
if (null != zIndex) {
marker.setZIndex(zIndex);
ret = true;
}
break;
case "scaleX":
Double scaleX = (Double) value;
if (null != scaleX) {
marker.setScaleX(scaleX.floatValue());
ret = true;
}
break;
case "scaleY":
Double scaleY = (Double) value;
if (null != scaleY) {
marker.setScaleY(scaleY.floatValue());
ret = true;
}
break;
case "alpha":
Double alpha = (Double) value;
if (null != alpha) {
marker.setAlpha(alpha.floatValue());
ret = true;
}
break;
case "isPerspective":
Boolean isPerspective = (Boolean) value;
if (null != isPerspective) {
marker.setPerspective(isPerspective);
ret = true;
}
break;
default:
break;
}
return ret;
}
}

@ -0,0 +1,212 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.graphics.Point;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.mapapi.map.Projection;
import com.baidu.mapapi.model.LatLng;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import static com.baidu.flutter_bmfmap.utils.Constants.ErrorCode;
class ProjectionHandler extends BMapHandler {
private static final String TAG = "ProjectionHandler";
private Projection mProjection = null;
public ProjectionHandler(FlutterCommonMapView mapView) {
super(mapView);
if(null != mapView && null != mapView.getBaiduMap()){
mProjection = mapView.getBaiduMap().getProjection();
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result){
if(Env.DEBUG){
Log.d(TAG, "handlerMethodCallResult");
}
if (null == call) {
result.success(null);
return;
}
String methodId = call.method;
if (TextUtils.isEmpty(methodId)) {
if(Env.DEBUG){
Log.d(TAG, "methodId is null");
}
result.success(null);
return;
}
switch (methodId) {
case Constants.MethodProtocol.ProjectionMethodId.sFromScreenLocation:
fromScreenLocation(call, result);
break;
case Constants.MethodProtocol.ProjectionMethodId.sToScreenLocation:
toScreenLocation(call, result);
break;
default:
break;
}
}
/**
*
*
* @param call
* @param result
* @return
*/
public boolean fromScreenLocation(MethodCall call, MethodChannel.Result result) {
if(Env.DEBUG){
Log.d(TAG, "fromScreenLocation enter");
}
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
result.error(String.valueOf(ErrorCode.sErrorNullFlutterParam)
, "MethodCall arguments is null"
,null);
return false;
}
Map<String, Object> pointMap = (Map<String, Object> )argument.get("point");
Point point = FlutterDataConveter.mapToPoint(pointMap);
if(null == point){
result.error(String.valueOf(ErrorCode.sErrorParamConvertFailed)
, "conver pointMap failed"
,null);
if(Env.DEBUG){
Log.d(TAG, "conver pointMap failed");
}
return false;
}
LatLng latLng = mProjection.fromScreenLocation(point);
if(null == latLng){
result.error(String.valueOf(ErrorCode.sErrorEngineError)
, "引擎调用失败"
,null);
if(Env.DEBUG){
Log.d(TAG, "fromScreenLocation failed");
}
return false;
}
final Map<String, Double> resultMap = FlutterDataConveter.latLngToMap(latLng);
if(Env.DEBUG){
Log.d(TAG, "handlerMethodCallResult success");
}
result.success(new HashMap<String, Object>(){
{
put("coordinate",resultMap);
}
});
return true;
}
/**
*
*
* @return
*/
public boolean toScreenLocation(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
result.error(String.valueOf(ErrorCode.sErrorNullFlutterParam)
, "MethodCall arguments is null"
,null);
return false;
}
Map<String, Object> coordinateMap = (Map<String, Object> )argument.get("coordinate");
LatLng latLng = FlutterDataConveter.mapToLatlng(coordinateMap);
if(null == latLng){
result.error(String.valueOf(ErrorCode.sErrorParamConvertFailed)
, "MethodCall arguments is null"
,null);
if(Env.DEBUG){
Log.d(TAG, "null == latLng");
}
return false;
}
Point point = mProjection.toScreenLocation(latLng);
if(null == point){
result.error(String.valueOf(ErrorCode.sErrorEngineError)
, "MethodCall arguments is null"
,null);
if(Env.DEBUG){
Log.d(TAG, "null == point");
}
return false;
}
final Map<String, Double> pointMap = FlutterDataConveter.pointToMap(point);
if(Env.DEBUG){
Log.d(TAG, "toScreenLocation success");
}
result.success(new HashMap<String, Object>(){
{
put("point",pointMap);
}
});
return true;
}
// /**
// * 该方法把以米为计量单位的距离(沿赤道)在当前缩放水平下转换到一个以像素(水平)为计量单位的距离。 在默认的Mercator投影变换下对于给定的距离当远离赤道时变换后确切的像素数量会增加。
// *
// * @param meters 以米为单位的距离
// * @return 相对给定距离的像素数量。在当前的缩放水平,如果沿赤道测量,返回值可能是个近似值
// */
// public float metersToEquatorPixels(MethodCall call, MethodChannel.Result result) {
// if (meters <= 0) {
// return 0;
// }
//
// return (float) (meters / (mBaseMap.getZoomUnitsInMeter()));
// }
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
if(null != mapView && null != mapView.getBaiduMap()){
mProjection = mapView.getBaiduMap().getProjection();
}
}
}

@ -0,0 +1,378 @@
package com.baidu.flutter_bmfmap.map.mapHandler;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.flutter_bmfmap.map.FlutterCommonMapView;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.IOStreamUtils;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.FileTileProvider;
import com.baidu.mapapi.map.Projection;
import com.baidu.mapapi.map.Tile;
import com.baidu.mapapi.map.TileOverlay;
import com.baidu.mapapi.map.TileOverlayOptions;
import com.baidu.mapapi.map.TileProvider;
import com.baidu.mapapi.map.UrlTileProvider;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.TileMapProtocol;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
class TileMapHandler extends BMapHandler {
private Tile mOfflineTile;
// 设置瓦片图的在线缓存大小默认为20 M
private static final int TILE_TMP = 20 * 1024 * 1024;
private static final int MAX_LEVEL = 21;
private static final int MIN_LEVEL = 4;
private int mMaxLevel = MAX_LEVEL;
private int mMinLevel = MIN_LEVEL;
private int mTileTmp = TILE_TMP;
private String mUrlString;
private Projection mProjection;
private BaiduMap mBaiduMap;
private HashMap<String, TileOverlay> mTileOverlayMap = new HashMap<>();
public static class TileType{
public static final int URL_TILE_PROVIDER = 0;
public static final int FILE_TILE_PROVIDER_ASYNC = 1;
public static final int FILE_TILE_PROVIDER_SYNC = 2;
}
private static final String TAG = "TileMapHandler";
public TileMapHandler(FlutterCommonMapView mapView) {
super(mapView);
if(null != mapView){
mBaiduMap = mapView.getBaiduMap();
if(null != mBaiduMap){
mProjection = mBaiduMap.getProjection();
}
}
}
@Override
public void updateMapView(FlutterCommonMapView mapView){
mMapView = mapView;
if(null != mMapView){
mBaiduMap = mMapView.getBaiduMap();
if(null != mBaiduMap){
mProjection = mBaiduMap.getProjection();
}
}
}
@Override
public void handlerMethodCallResult(Context context, MethodCall call, MethodChannel.Result result) {
if(Env.DEBUG){
Log.d(TAG, "handlerMethodCallResult enter");
}
String methodID = call.method;
switch (methodID){
case TileMapProtocol.sAddTileMapMethod:
addTile(context, call, result);
break;
case TileMapProtocol.sRemoveTileMapMethod:
removeTile(context, call, result);
break;
default:
break;
}
}
private void addTile(Context context, MethodCall call, MethodChannel.Result result){
if(Env.DEBUG){
Log.d(TAG, "addTile enter");
}
if(null == mProjection || null == mBaiduMap){
if(Env.DEBUG){
Log.d(TAG, "null == mProjection || null == mBaiduMap");
}
result.success(false);
return;
}
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
result.success(false);
return;
}
TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();
String id = new TypeConverter<String>().getValue(argument, "id");
if(null == id){
result.success(false);
return;
}
Integer maxZoom = new TypeConverter<Integer>().getValue(argument, "maxZoom");
if(null != maxZoom){
mMaxLevel = maxZoom.intValue();
if(Env.DEBUG) {
Log.d(TAG, "maxZoom:" + maxZoom);
}
}
Integer minZoom = new TypeConverter<Integer>().getValue(argument, "minZoom");
if(null != maxZoom){
mMinLevel = minZoom.intValue();
if(Env.DEBUG) {
Log.d(TAG, "minZoom:" + minZoom);
}
}
Integer maxTileTmp = new TypeConverter<Integer>().getValue(argument, "maxTileTmp");
if(null != maxTileTmp){
mTileTmp = maxTileTmp.intValue();
}
Map<String, Object> visibleMapBounds = new TypeConverter<Map<String, Object>>().getValue(argument,
"visibleMapBounds");
if(null == visibleMapBounds){
if(Env.DEBUG){
Log.d(TAG, "null == visibleMapBounds");
}
return;
}
LatLngBounds latLngBounds = visibleMapBoundsImp(visibleMapBounds);
if (null == latLngBounds) {
if(Env.DEBUG){
Log.d(TAG, "null == latLngBounds");
}
return;
}
tileOverlayOptions.setPositionFromBounds(latLngBounds);
TileProvider tileProvider = getTileProvider(context, argument);
if(null == tileProvider){
if(Env.DEBUG){
Log.d(TAG, "null == tileProvider");
}
result.success(false);
return;
}
tileOverlayOptions.tileProvider(tileProvider);
if(Env.DEBUG){
Log.d(TAG, "addTile success");
}
TileOverlay tileOverlay = mBaiduMap.addTileLayer(tileOverlayOptions);
mTileOverlayMap.put(id, tileOverlay);
result.success(true);
}
private LatLngBounds visibleMapBoundsImp(Map<String, Object> visibleMapBounds) {
if (!visibleMapBounds.containsKey("northeast") || !visibleMapBounds.containsKey("southwest")) {
return null;
}
HashMap<String,Double> northeast = (HashMap<String, Double>) visibleMapBounds.get("northeast");
HashMap<String,Double> southwest = (HashMap<String, Double>) visibleMapBounds.get("southwest");
if (null == northeast || null == southwest) {
return null;
}
if (!northeast.containsKey("latitude") || !northeast.containsKey("longitude")
|| !southwest.containsKey("latitude") || !southwest.containsKey("longitude")) {
return null;
}
Double northeastLatitude = northeast.get("latitude");
Double northeastLongitude = northeast.get("longitude");
Double southwestLatitude = southwest.get("latitude");
Double southwestLongitude = southwest.get("longitude");
if (null == northeastLatitude || null == northeastLongitude
|| null == southwestLatitude || null == southwestLongitude) {
return null;
}
LatLng northeastLatLng = new LatLng(northeastLatitude, northeastLongitude);
LatLng southwestLatLng = new LatLng(southwestLatitude, southwestLongitude);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(northeastLatLng);
builder.include(southwestLatLng);
return builder.build();
}
private TileProvider getTileProvider(Context context, Map<String, Object> tileProviderMap){
Integer tileType = new TypeConverter<Integer>().getValue(tileProviderMap, "tileLoadType");
if(null == tileType){
return null;
}
TileProvider tileProvider = null;
switch (tileType){
case TileType.FILE_TILE_PROVIDER_ASYNC:
case TileType.FILE_TILE_PROVIDER_SYNC:
tileProvider = getFileTileProvider(context);
break;
case TileType.URL_TILE_PROVIDER:
tileProvider = getUrlTileProvider(context, tileProviderMap);
break;
default:
break;
}
return tileProvider;
}
private TileProvider getFileTileProvider(final Context context){
TileProvider tileProvider = new FileTileProvider() {
@Override
public Tile getTile(int x, int y, int z) {
// 根据地图某一状态下x、y、z加载指定的瓦片图
String filedir = "flutter_assets/resoures/bmflocaltileimage/" + z + "/" + z + "_" + x + "_" + y + ".jpg";
// FlutterMain.getLookupKeyForAsset();
Bitmap bm = getFromAssets(context, filedir);
if (bm == null) {
return null;
}
// 瓦片图尺寸必须满足256 * 256
mOfflineTile = new Tile(bm.getWidth(), bm.getHeight(), toRawData(bm));
bm.recycle();
return mOfflineTile;
}
@Override
public int getMaxDisLevel() {
return 0;
}
@Override
public int getMinDisLevel() {
return 0;
}
};
return tileProvider;
}
private TileProvider getUrlTileProvider(Context context, Map<String, Object> tileProviderMap){
TileProvider tileProvider = null;
if(tileProviderMap.containsKey("url")){
Object urlObj = tileProviderMap.get("url");
if(null != urlObj){
mUrlString = (String)urlObj;
/*线Provider
MAX_LEVELMIN_LEVEL
urlString 线URL*/
tileProvider = new UrlTileProvider() {
@Override
public int getMaxDisLevel() {
return mMaxLevel;
}
@Override
public int getMinDisLevel() {
return mMinLevel;
}
@Override
public String getTileUrl() {
return mUrlString;
}
};
}
}
return tileProvider;
}
/**
* Bitmap
*
* @param fileName
* @return Bitmap
*/
public Bitmap getFromAssets(Context context, String fileName) {
AssetManager assetManager = context.getAssets();
InputStream inputStream = null;
Bitmap bitmap;
try {
if(Env.DEBUG){
Log.d(TAG, fileName);
}
inputStream = assetManager.open(fileName);
bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
IOStreamUtils.closeSilently(inputStream);
}
}
/**
* Bitmap
*
* @param bitmap
* @return
*/
byte[] toRawData(Bitmap bitmap) {
ByteBuffer buffer = ByteBuffer.allocate(bitmap.getWidth() * bitmap.getHeight() * 4);
bitmap.copyPixelsToBuffer(buffer);
byte[] data = buffer.array();
buffer.clear();
return data;
}
private void removeTile(Context context, MethodCall call, MethodChannel.Result result){
if(Env.DEBUG){
Log.d(TAG, "removeTile enter");
}
Map<String, Object> argument = call.arguments();
if(null == argument){
if(Env.DEBUG){
Log.d(TAG, "argument is null");
}
result.success(false);
return;
}
String id = new TypeConverter<String>().getValue(argument, "id");
if(TextUtils.isEmpty(id)){
result.success(false);
return;
}
TileOverlay tileOverlay = mTileOverlayMap.get(id);
if(null != tileOverlay){
if(Env.DEBUG){
Log.d(TAG, "remove tile success");
}
tileOverlay.removeTileOverlay();
result.success(true);
}else {
result.success(false);
}
}
}

@ -0,0 +1,102 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.mapapi.map.ArcOptions;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.model.LatLng;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class ArcLineHandler extends OverlayHandler {
private static final String TAG = "ArcLineHandler";
public ArcLineHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
return null;
}
if (!argument.containsKey("id")
|| !argument.containsKey("coordinates")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain");
}
return null;
}
ArcOptions arcOptions = new ArcOptions();
final String id = (String) argument.get("id");
if (TextUtils.isEmpty(id)) {
return null;
}
List<Map<String, Object>> coordinates =
(List<Map<String, Object>>) argument.get("coordinates");
if (coordinates.size() < 3) {
if (Env.DEBUG) {
Log.d(TAG, "atlngs.size() < 3");
}
return null;
}
LatLng latLngStart = FlutterDataConveter.mapToLatlng(coordinates.get(0));
LatLng latLngMiddle = FlutterDataConveter.mapToLatlng(coordinates.get(1));
LatLng latLngEnd = FlutterDataConveter.mapToLatlng(coordinates.get(2));
if (null == latLngStart
|| null == latLngMiddle
|| null == latLngEnd) {
if (Env.DEBUG) {
Log.d(TAG, "null == latLngStart\n" +
" || null == latLngMiddle\n" +
" || null == latLngEnd");
}
return null;
}
arcOptions.points(latLngStart, latLngMiddle, latLngEnd);
if (argument.containsKey("width")) {
int width = (Integer) argument.get("width");
arcOptions.width(width);
}
if (argument.containsKey("color")) {
String strokeColorStr = (String) argument.get("color");
int strokeColor = FlutterDataConveter.strColorToInteger(strokeColorStr);
arcOptions.color(strokeColor);
}
if (argument.containsKey("zIndex")) {
int zIndex = (Integer) argument.get("zIndex");
arcOptions.zIndex(zIndex);
}
if (argument.containsKey("visible")) {
boolean visible = (Boolean) argument.get("visible");
arcOptions.visible(visible);
}
final Overlay overlay = mBaiduMap.addOverlay(arcOptions);
return new HashMap<String, Overlay>() {
{
put(id, overlay);
}
};
}
}

@ -0,0 +1,130 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.CircleDottedStrokeType;
import com.baidu.mapapi.map.CircleOptions;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.Stroke;
import com.baidu.mapapi.model.LatLng;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class CircleHandler extends OverlayHandler {
private static final String TAG = "CircleHandler";
public CircleHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
if (!argument.containsKey("id")
|| !argument.containsKey("center")
|| !argument.containsKey("radius")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain");
}
return null;
}
CircleOptions circleOptions = new CircleOptions();
final String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return null;
}
Map<String, Object> centerMap = (Map<String, Object>) argument.get("center");
LatLng center = FlutterDataConveter.mapToLatlng(centerMap);
if (null != center) {
circleOptions.center(center);
}
double radius = (Double) argument.get("radius");
circleOptions.radius((int) radius);
if (argument.containsKey("width") && argument.containsKey("strokeColor")) {
int width = (Integer) argument.get("width");
String strokeColorStr = (String) argument.get("strokeColor");
if (!TextUtils.isEmpty(strokeColorStr)) {
int strokeColor = FlutterDataConveter.strColorToInteger(strokeColorStr);
Stroke stroke = new Stroke(width, strokeColor);
circleOptions.stroke(stroke);
}
}
if (argument.containsKey("fillColor")) {
String fillColorStr = (String) argument.get("fillColor");
int fillColor = FlutterDataConveter.strColorToInteger(fillColorStr);
circleOptions.fillColor(fillColor);
}
if (argument.containsKey("zIndex")) {
int zIndex = (Integer) argument.get("zIndex");
circleOptions.zIndex(zIndex);
}
if (argument.containsKey("visible")) {
boolean visible = (Boolean) argument.get("visible");
circleOptions.visible(visible);
}
setLineDashType(argument, circleOptions);
final Overlay overlay = mBaiduMap.addOverlay(circleOptions);
return new HashMap<String, Overlay>() {
{
put(id, overlay);
}
};
}
private void setLineDashType(Map<String, Object> circleOptionsMap,
CircleOptions circleOptions) {
if (null == circleOptionsMap || null == circleOptions) {
return;
}
Integer lineDashType =
new TypeConverter<Integer>().getValue(circleOptionsMap, "lineDashType");
if (null == lineDashType) {
return;
}
switch (lineDashType) {
case OverlayCommon.LineDashType.sLineDashTypeNone:
circleOptions.dottedStroke(false);
break;
case OverlayCommon.LineDashType.sLineDashTypeSquare:
circleOptions.dottedStroke(true);
circleOptions.dottedStrokeType(CircleDottedStrokeType.DOTTED_LINE_SQUARE);
break;
case OverlayCommon.LineDashType.sLineDashTypeDot:
circleOptions.dottedStroke(true);
circleOptions.dottedStrokeType(CircleDottedStrokeType.DOTTED_LINE_CIRCLE);
break;
default:
break;
}
}
}

@ -0,0 +1,99 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.DotOptions;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.model.LatLng;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class DotHandler extends OverlayHandler {
public static final String TAG = "DotHandler";
public DotHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
if (!argument.containsKey("id")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain" + argument.toString());
}
return null;
}
final String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return null;
}
DotOptions dotOptions = new DotOptions();
Map<String, Object> centerMap =
new TypeConverter<Map<String, Object>>().getValue(argument, "center");
LatLng center = FlutterDataConveter.mapToLatlng(centerMap);
if (null == center) {
if (Env.DEBUG) {
Log.d(TAG, "center is null");
}
return null;
}
dotOptions.center(center);
Double radius = new TypeConverter<Double>().getValue(argument, "radius");
if (null == radius) {
if (Env.DEBUG) {
Log.d(TAG, "radius is null");
}
return null;
}
dotOptions.radius(radius.intValue());
String colorStr = new TypeConverter<String>().getValue(argument, "color");
if (TextUtils.isEmpty(colorStr)) {
if (Env.DEBUG) {
Log.d(TAG, "colorStr is null");
}
return null;
}
int color = FlutterDataConveter.strColorToInteger(colorStr);
dotOptions.color(color);
Integer zIndex = new TypeConverter<Integer>().getValue(argument, "zIndex");
if (null != zIndex) {
dotOptions.zIndex(zIndex);
}
Boolean visible = new TypeConverter<Boolean>().getValue(argument, "visible");
if (null != visible) {
dotOptions.visible(visible);
}
final Overlay overlay = mBaiduMap.addOverlay(dotOptions);
return new HashMap<String, Overlay>() {
{
put(id, overlay);
}
};
}
}

@ -0,0 +1,177 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.GroundOverlay;
import com.baidu.mapapi.map.GroundOverlayOptions;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
class GroundHandler extends OverlayHandler {
private static final String TAG = "GroundHandler";
private HashMap<String, BitmapDescriptor> mBitmapMap = new HashMap<>();
public GroundHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
if (Env.DEBUG) {
Log.d(TAG, "handlerMethodCall enter");
}
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
if (!argument.containsKey("id")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain" + argument.toString());
}
return null;
}
final String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return null;
}
GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();
setGroundOptions(id, argument, groundOverlayOptions);
final Overlay overlay = mBaiduMap.addOverlay(groundOverlayOptions);
return new HashMap<String, Overlay>() {
{
put(id, overlay);
}
};
}
/**
*
*/
private void setGroundOptions(String id, Map<String, Object> groundOptionsMap,
GroundOverlayOptions groundOverlayOptions) {
if (null == groundOptionsMap) {
return;
}
String image = new TypeConverter<String>().getValue(groundOptionsMap, "image");
if (!TextUtils.isEmpty(image)) {
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromAsset("flutter_assets/" + image);
if (null != bitmap) {
if (Env.DEBUG) {
Log.d(TAG, "image");
}
groundOverlayOptions.image(bitmap);
mBitmapMap.put(id, bitmap);
}
}
Double anchorX = new TypeConverter<Double>().getValue(groundOptionsMap, "anchorX");
Double anchorY = new TypeConverter<Double>().getValue(groundOptionsMap, "anchorY");
if (null != anchorX && null != anchorY) {
groundOverlayOptions.anchor(anchorX.floatValue(), anchorY.floatValue());
}
Map<String, Object> centerMap =
new TypeConverter<Map<String, Object>>().getValue(groundOptionsMap, "position");
if (null != centerMap) {
LatLng center = FlutterDataConveter.mapToLatlng(centerMap);
if (null != center) {
if (Env.DEBUG) {
Log.d(TAG, "position");
}
groundOverlayOptions.position(center);
}
}
Double width = new TypeConverter<Double>().getValue(groundOptionsMap, "width");
Double height = new TypeConverter<Double>().getValue(groundOptionsMap, "height");
if(null != width && null != height){
groundOverlayOptions.dimensions(width.intValue(), height.intValue());
}
Map<String, Object> boundsMap =
new TypeConverter<Map<String, Object>>().getValue(groundOptionsMap, "bounds");
LatLngBounds latLngBounds = FlutterDataConveter.mapToLatlngBounds(boundsMap);
if (null != latLngBounds) {
if (Env.DEBUG) {
Log.d(TAG, "bounds");
}
groundOverlayOptions.positionFromBounds(latLngBounds);
}
Double transparency =
new TypeConverter<Double>().getValue(groundOptionsMap, "transparency");
if (null != transparency) {
groundOverlayOptions.transparency(transparency.floatValue());
}
Integer zIndex = new TypeConverter<Integer>().getValue(groundOptionsMap, "zIndex");
if (null != zIndex) {
groundOverlayOptions.zIndex(zIndex);
}
Boolean visible = new TypeConverter<Boolean>().getValue(groundOptionsMap, "visible");
if (null != visible) {
groundOverlayOptions.visible(visible);
}
}
public void clean(){
super.clean();
Iterator iterator = mBitmapMap.values().iterator();
BitmapDescriptor bitmapDescriptor;
while (iterator.hasNext()){
bitmapDescriptor = (BitmapDescriptor)iterator.next();
if(null != bitmapDescriptor){
bitmapDescriptor.recycle();
}
}
mBitmapMap.clear();
}
public void clean(String id) {
if (TextUtils.isEmpty(id)) {
return;
}
BitmapDescriptor bitmapDescriptor = mBitmapMap.get(id);
if (null != bitmapDescriptor) {
bitmapDescriptor.recycle();
}
mBitmapMap.remove(id);
}
}

@ -0,0 +1,21 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
public class OverlayCommon{
public static class LineDashType{
/**
* 线
*/
public static final int sLineDashTypeNone = 0;
/**
*
*/
public static final int sLineDashTypeSquare = 1;
/**
*
*/
public static final int sLineDashTypeDot = 2;
}
}

@ -0,0 +1,43 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.Map;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Overlay;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public abstract class OverlayHandler {
protected BaiduMap mBaiduMap;
protected Overlay mCurrentOverlay;
public OverlayHandler(BaiduMap baiduMap) {
this.mBaiduMap = baiduMap;
}
public abstract Map<String, Overlay> handlerMethodCall(MethodCall call,
MethodChannel.Result result);
public void updateBaiduMap(BaiduMap baiduMap) {
mBaiduMap = baiduMap;
}
public void setCurrentOverlay(Overlay overlay){
mCurrentOverlay = overlay;
}
/**
*
*/
public void clean(){}
/**
* idoverlay
* @param id
*/
public void clean(String id) {
}
}

@ -0,0 +1,235 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.ArclineProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.CirclelineProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.DotProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.GroundProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.OverlayProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.PolygonProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.PolylineProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.TextProtocol;
import com.baidu.flutter_bmfmap.utils.Constants.OverlayHandlerType;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.mapapi.map.Arc;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Circle;
import com.baidu.mapapi.map.Dot;
import com.baidu.mapapi.map.GroundOverlay;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.Polygon;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.Text;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class OverlayHandlerFactory {
private static final String TAG = "OverlayHandlerFactory";
private static volatile OverlayHandlerFactory sInstance;
private HashMap<Integer, OverlayHandler> overlayHandlerHashMap;
private OverlayManagerHandler mOverlayManagerHandler;
private OverlayHandlerFactory(BaiduMap baiduMap) {
init(baiduMap);
}
public static OverlayHandlerFactory getInstance(BaiduMap baiduMap) {
if (null == sInstance) {
synchronized(OverlayHandlerFactory.class) {
if (null == sInstance) {
sInstance = new OverlayHandlerFactory(baiduMap);
} else {
sInstance.updateBaiduMap(baiduMap);
}
}
} else {
sInstance.updateBaiduMap(baiduMap);
}
return sInstance;
}
private void updateBaiduMap(BaiduMap baiduMap) {
if (null == baiduMap) {
return;
}
if(null == overlayHandlerHashMap || overlayHandlerHashMap.isEmpty()){
init(baiduMap);
}
Iterator it = overlayHandlerHashMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, OverlayHandler> entry =
(Map.Entry<Integer, OverlayHandler>) it.next();
OverlayHandler overlayHandler = entry.getValue();
if (null != overlayHandler) {
overlayHandler.updateBaiduMap(baiduMap);
}
}
}
private void init(BaiduMap baiduMap) {
if (null == baiduMap) {
return;
}
mOverlayManagerHandler = new OverlayManagerHandler(baiduMap);
overlayHandlerHashMap = new HashMap<>();
overlayHandlerHashMap.put(OverlayHandlerType.CIRCLE_HANDLER, new CircleHandler(baiduMap));
overlayHandlerHashMap.put(OverlayHandlerType.DOT_HANDLER, new DotHandler(baiduMap));
overlayHandlerHashMap.put(OverlayHandlerType.POLYGON_HANDLER, new PolygonHandler(baiduMap));
overlayHandlerHashMap
.put(OverlayHandlerType.POLYLINE_HANDLER, new PolylineHandler(baiduMap));
overlayHandlerHashMap.put(OverlayHandlerType.TEXT_HANDLER, new TextHandler(baiduMap));
overlayHandlerHashMap.put(OverlayHandlerType.ARCLINE_HANDLER, new ArcLineHandler(baiduMap));
overlayHandlerHashMap.put(OverlayHandlerType.CIRCLE_HANDLER, new CircleHandler(baiduMap));
overlayHandlerHashMap.put(OverlayHandlerType.GROUND_HANDLER, new GroundHandler(baiduMap));
}
public boolean dispatchMethodHandler(MethodCall call, MethodChannel.Result result) {
if (null == call) {
if (Env.DEBUG) {
Log.d(TAG, "dispatchMethodHandler: null == call");
}
return false;
}
String methodId = call.method;
Log.d(TAG, "dispatchMethodHandler: " + methodId);
OverlayHandler overlayHandler = null;
Overlay overlay;
int handlerType = -1;
switch (methodId) {
case ArclineProtocol.sMapAddArclinelineMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.ARCLINE_HANDLER);
break;
case PolygonProtocol.sMapAddPolygonMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.POLYGON_HANDLER);
break;
case CirclelineProtocol.sMapAddCirclelineMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.CIRCLE_HANDLER);
break;
case PolylineProtocol.sMapAddPolylineMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.POLYLINE_HANDLER);
break;
case DotProtocol.sMapAddDotMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.DOT_HANDLER);
break;
case TextProtocol.sMapAddTextMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.TEXT_HANDLER);
break;
case GroundProtocol.sMapAddGroundMethod:
overlayHandler = overlayHandlerHashMap.get(OverlayHandlerType.GROUND_HANDLER);
break;
case OverlayProtocol.sMapRemoveOverlayMethod:
OverlayHandler specOverlayHandler = getCurrentOverlayHandler(call);
mOverlayManagerHandler.setCurrentOverlayHandler(specOverlayHandler);
overlayHandler = mOverlayManagerHandler;
break;
case PolylineProtocol.sMapUpdatePolylineMemberMethod:
overlayHandler = getCurrentOverlayHandler(call);
break;
default:
break;
}
if (null == overlayHandler) {
return false;
}
Map<String, Overlay> overlayMap = overlayHandler.handlerMethodCall(call, result);
if (null == overlayMap) {
return false;
}
mOverlayManagerHandler.addOverlay(overlayMap);
return true;
}
private Overlay getCurrentOverlay(MethodCall call) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
if (!argument.containsKey("id")) {
return null;
}
String id = (String) argument.get("id");
return mOverlayManagerHandler.getOverlay(id);
}
private int getHandlerType(Overlay overlay) {
int handlerType = -1;
if (overlay instanceof Polyline) {
handlerType = OverlayHandlerType.POLYLINE_HANDLER;
} else if (overlay instanceof Polygon) {
handlerType = OverlayHandlerType.POLYGON_HANDLER;
} else if (overlay instanceof Arc) {
handlerType = OverlayHandlerType.ARCLINE_HANDLER;
} else if (overlay instanceof Circle) {
handlerType = OverlayHandlerType.CIRCLE_HANDLER;
} else if (overlay instanceof Dot) {
handlerType = OverlayHandlerType.DOT_HANDLER;
} else if (overlay instanceof GroundOverlay) {
handlerType = OverlayHandlerType.GROUND_HANDLER;
} else if (overlay instanceof Text) {
handlerType = OverlayHandlerType.TEXT_HANDLER;
}
return handlerType;
}
public void clean(){
if(null == overlayHandlerHashMap || overlayHandlerHashMap.size() == 0) {
return;
}
OverlayHandler overlayHandler= null;
Iterator iterator = overlayHandlerHashMap.values().iterator();
while (iterator.hasNext()){
overlayHandler = (OverlayHandler) iterator.next();
if(null == overlayHandler){
continue;
}
overlayHandler.clean();
}
}
private OverlayHandler getCurrentOverlayHandler(MethodCall call) {
if (null == call) {
return null;
}
Overlay overlay = getCurrentOverlay(call);
if (null == overlay) {
return null;
}
int handlerType = getHandlerType(overlay);
OverlayHandler overlayHandler = overlayHandlerHashMap.get(handlerType);
if( null != overlayHandler) {
overlayHandler.setCurrentOverlay(overlay);
}
return overlayHandler;
}
}

@ -0,0 +1,103 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Constants.MethodProtocol.OverlayProtocol;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Overlay;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class OverlayManagerHandler extends OverlayHandler {
private static final String TAG = "OverlayManagerHandler";
private HashMap<String, Overlay> mOverlayMap = new HashMap<>();
private OverlayHandler mCurrentOverlayHandler;
public OverlayManagerHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
if (Env.DEBUG) {
Log.d(TAG, "handlerMethodCall enter");
//result.success(false);
}
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
result.success(false);
return null;
}
boolean ret = false;
String methodId = call.method;
switch (methodId) {
case OverlayProtocol.sMapRemoveOverlayMethod:
ret = removeOverlay(argument);
break;
default:
break;
}
result.success(ret);
return null;
}
public void addOverlay(Map<String, Overlay> overlayMap) {
mOverlayMap.putAll(overlayMap);
}
public Overlay getOverlay(String id) {
return mOverlayMap.get(id);
}
public void setCurrentOverlayHandler(OverlayHandler overlayHandler) {
mCurrentOverlayHandler = overlayHandler;
}
/**
* overlay
*
* @param argument
* @return
*/
private boolean removeOverlay(Map<String, Object> argument) {
String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return false;
}
Overlay overlay = mOverlayMap.get(id);
if (null == overlay) {
if (Env.DEBUG) {
Log.d(TAG, "not found overlay with id:" + id);
}
return false;
}
overlay.remove();
mOverlayMap.remove(id);
if(null != mCurrentOverlayHandler) {
mCurrentOverlayHandler.clean(id);
mCurrentOverlayHandler = null;
}
if (Env.DEBUG) {
Log.d(TAG, "remove Overlay success");
}
return true;
}
}

@ -0,0 +1,117 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.PolygonOptions;
import com.baidu.mapapi.map.Stroke;
import com.baidu.mapapi.model.LatLng;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class PolygonHandler extends OverlayHandler {
private static final String TAG = "PolygonHandler";
public PolygonHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
if (Env.DEBUG) {
Log.d(TAG, "handlerMethodCall enter0");
}
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
if (!argument.containsKey("id")
|| !argument.containsKey("coordinates")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain");
}
return null;
}
final String id = (String) argument.get("id");
if (TextUtils.isEmpty(id)) {
return null;
}
List<Map<String, Double>> coordinates =
(List<Map<String, Double>>) argument.get("coordinates");
if (coordinates.size() < 1) {
if (Env.DEBUG) {
Log.d(TAG, "coordinates.size() < 1");
}
return null;
}
PolygonOptions polygonOptions = new PolygonOptions();
List<LatLng> coordinatesList = FlutterDataConveter.mapToLatlngs(coordinates);
if (null == coordinatesList) {
if (Env.DEBUG) {
Log.d(TAG, "coordinatesList is null");
}
return null;
}
polygonOptions.points(coordinatesList);
if (argument.containsKey("width") && argument
.containsKey("strokeColor")) {
int width = (Integer) argument.get("width");
String strokeColorStr = (String) argument.get("strokeColor");
if (Env.DEBUG) {
Log.d(TAG, "strokeColorStr:" + strokeColorStr);
}
if (!TextUtils.isEmpty(strokeColorStr)) {
int strokeColor = FlutterDataConveter.strColorToInteger(strokeColorStr);
Stroke stroke = new Stroke(width, strokeColor);
polygonOptions.stroke(stroke);
}
}
if (argument.containsKey("fillColor")) {
String fillColorStr = (String) argument.get("fillColor");
if (Env.DEBUG) {
Log.d(TAG, "fillColorStr:" + fillColorStr);
}
if (!TextUtils.isEmpty(fillColorStr)) {
int fillColor = FlutterDataConveter.strColorToInteger(fillColorStr);
polygonOptions.fillColor(fillColor);
}
}
if (argument.containsKey("zIndex")) {
int zIndex = (Integer) argument.get("zIndex");
polygonOptions.zIndex(zIndex);
}
if (argument.containsKey("visible")) {
boolean visible = (Boolean) argument.get("visible");
polygonOptions.visible(visible);
}
final Overlay overlay = mBaiduMap.addOverlay(polygonOptions);
return new HashMap<String, Overlay>() {
{
put(id, overlay);
}
};
}
}

@ -0,0 +1,620 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Constants;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnPolylineClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.PolylineDottedLineType;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class PolylineHandler extends OverlayHandler {
private static final String TAG = "PolylineHandler";
private HashMap<String, List<BitmapDescriptor>> mBitmapMap = new HashMap<>();
private OnPolylineClickListener mOnPolylineClickListener = new OnPolylineClickListener() {
@Override
public boolean onPolylineClick(Polyline polyline) {
return false;
}
};
public PolylineHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
if (Env.DEBUG) {
Log.d(TAG, "handlerMethodCall enter");
}
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
String methodId = call.method;
Map<String, Overlay> overlayMap = null;
switch (methodId) {
case Constants.MethodProtocol.PolylineProtocol.sMapAddPolylineMethod:
overlayMap = addPolyLine(argument);
break;
case Constants.MethodProtocol.PolylineProtocol.sMapUpdatePolylineMemberMethod:
overlayMap = updateMember(argument);
break;
default:
break;
}
return overlayMap;
}
private Map<String, Overlay> addPolyLine(Map<String, Object> argument) {
if (!argument.containsKey("id")
|| !argument.containsKey("coordinates")
|| !argument.containsKey("indexs")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain");
}
return null;
}
final String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
if (Env.DEBUG) {
Log.d(TAG, "id is null");
}
return null;
}
List<Map<String, Double>> coordinates =
new TypeConverter<List<Map<String, Double>>>().getValue(argument, "coordinates");
List<LatLng> latLngList = FlutterDataConveter.mapToLatlngs(coordinates);
if (null == latLngList) {
if (Env.DEBUG) {
Log.d(TAG, "latLngList is null");
}
return null;
}
PolylineOptions polylineOptions = new PolylineOptions().points(latLngList);
int pointNum = coordinates.size();
List<Integer> indexs = new TypeConverter<List<Integer>>().getValue(argument, "indexs");
setOptions(id, argument, polylineOptions, indexs, pointNum);
if (Env.DEBUG) {
Log.d(TAG, "addOverlay success");
}
final Polyline polyline = (Polyline) mBaiduMap.addOverlay(polylineOptions);
Bundle bundle = new Bundle();
bundle.putCharArray("id", id.toCharArray());
polyline.setExtraInfo(bundle);
if (null != polyline) {
mBaiduMap.setOnPolylineClickListener(mOnPolylineClickListener);
return new HashMap<String, Overlay>() {
{
put(id, polyline);
}
};
}
return null;
}
private void setOptions(String id, Map<String, Object> polylineOptionsMap,
PolylineOptions polylineOptions,
List<Integer> indexs,
int pointNumn) {
if (null == polylineOptionsMap || null == polylineOptions || null == indexs) {
return;
}
Integer width = new TypeConverter<Integer>().getValue(polylineOptionsMap, "width");
if (null != width) {
polylineOptions.width(width);
}
Boolean clickable = new TypeConverter<Boolean>().getValue(polylineOptionsMap, "clickable");
if (null != clickable) {
polylineOptions.clickable(clickable);
}
Boolean isKeepScale =
new TypeConverter<Boolean>().getValue(polylineOptionsMap, "isKeepScale");
if (null != isKeepScale) {
polylineOptions.keepScale(isKeepScale);
}
Boolean isFocus = new TypeConverter<Boolean>().getValue(polylineOptionsMap, "isFocus");
if (null != isFocus) {
polylineOptions.focus(isFocus);
}
Integer zIndex = new TypeConverter<Integer>().getValue(polylineOptionsMap, "zIndex");
if (null != zIndex) {
polylineOptions.zIndex(zIndex);
}
Boolean visible = new TypeConverter<Boolean>().getValue(polylineOptionsMap, "visible");
if (null != visible) {
polylineOptions.visible(visible);
}
Boolean isThined = new TypeConverter<Boolean>().getValue(polylineOptionsMap, "isThined");
if(null != isThined){
polylineOptions.isThined(isThined);
}
Boolean dottedLine = new TypeConverter<Boolean>().getValue(polylineOptionsMap, "dottedLine");
if (null != dottedLine) {
polylineOptions.dottedLine(dottedLine);
}
List<String> colors =
new TypeConverter<List<String>>().getValue(polylineOptionsMap, "colors");
if (null != colors && colors.size() > 0) {
List<Integer> intColors = FlutterDataConveter.getColors(colors);
if (null != intColors) {
if (intColors.size() == 1) {
polylineOptions.color(intColors.get(0));
} else {
List<Integer> correctColors = correctColors(indexs, intColors, pointNumn);
polylineOptions.colorsValues(correctColors);
}
}
}
/*
*colorsicons
*/
if (null == colors || colors.size() <= 0) {
List<String> icons =
new TypeConverter<List<String>>().getValue(polylineOptionsMap, "textures");
if (null != icons && icons.size() > 0) {
List<BitmapDescriptor> bitmapDescriptors = FlutterDataConveter.getIcons(icons);
if (null != bitmapDescriptors) {
if (bitmapDescriptors.size() == 1) {
polylineOptions.customTexture(bitmapDescriptors.get(0));
} else {
polylineOptions.textureIndex(indexs);
polylineOptions.customTextureList(bitmapDescriptors);
}
clearTextureBitMap(id);
mBitmapMap.put(id, bitmapDescriptors);
}
}
}
setLineDashType(polylineOptionsMap, polylineOptions);
}
/**
* android polylinecolors
* fluttercolorsindexs
* indexspointNum -1,indexspoinNum - 1
*/
private List<Integer> correctColors(List<Integer> indexs,
List<Integer> colors,
int pointNum) {
// 通过colors的size对索引数组进行修正
List<Integer> tmpIndexs = new ArrayList<>();
for (Integer i : indexs) {
if (i < colors.size()) {
tmpIndexs.add(i);
} else {
tmpIndexs.add(colors.size() - 1);
}
}
int tmpIndexSize = tmpIndexs.size();
int lastIndexValue = tmpIndexs.get(tmpIndexSize - 1);
// 通过pointNum对索引数组进行修正
if (tmpIndexSize < pointNum - 1) {
for (int i = tmpIndexSize; i < pointNum - 1; i++) {
tmpIndexs.add(lastIndexValue);
}
}
List<Integer> tmpColors = new ArrayList<>();
for (int i = 0; i < pointNum - 1; i++) {
tmpColors.add(colors.get(tmpIndexs.get(i)));
}
return tmpColors;
}
private void setLineDashType(Map<String, Object> polylineOptionsMap,
PolylineOptions polylineOptions) {
if (null == polylineOptionsMap || null == polylineOptions) {
return;
}
Integer lineDashType =
new TypeConverter<Integer>().getValue(polylineOptionsMap, "lineDashType");
if (null == lineDashType) {
return;
}
switch (lineDashType) {
case OverlayCommon.LineDashType.sLineDashTypeSquare:
polylineOptions.dottedLineType(PolylineDottedLineType.DOTTED_LINE_SQUARE);
break;
case OverlayCommon.LineDashType.sLineDashTypeDot:
polylineOptions.dottedLineType(PolylineDottedLineType.DOTTED_LINE_CIRCLE);
break;
default:
break;
}
}
/**
* polyline
*
* @param argument
* @return
*/
private Map<String, Overlay> updateMember(Map<String, Object> argument) {
if (null == mCurrentOverlay || !(mCurrentOverlay instanceof Polyline)) {
return null;
}
final Polyline polyline = (Polyline) mCurrentOverlay;
final String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return null;
}
String member = new TypeConverter<String>().getValue(argument, "member");
if (TextUtils.isEmpty(member)) {
return null;
}
switch (member) {
case "coordinates":
if (!updateCoordinates(argument, polyline)) {
return null;
}
break;
case "width":
Integer width = new TypeConverter<Integer>().getValue(argument, "value");
if (null == width) {
return null;
}
polyline.setWidth(width);
break;
case "indexs":
if (!updateIndexs(argument, polyline)) {
return null;
}
break;
case "colors":
if (!updateColors(argument, polyline)) {
return null;
}
break;
case "textures":
if (!updateTextures(argument, polyline)) {
return null;
}
break;
case "lineDashType":
if (!updateLinashType(argument, polyline)) {
return null;
}
break;
case "lineCapType":
case "lineJoinType":
return null;
case "clickable":
Boolean clickable = new TypeConverter<Boolean>().getValue(argument, "value");
if (null == clickable) {
return null;
}
polyline.setClickable(clickable);
break;
case "isKeepScale":
Boolean isKeepScale = new TypeConverter<Boolean>().getValue(argument, "value");
if (null == isKeepScale) {
return null;
}
polyline.setIsKeepScale(isKeepScale);
break;
case "isFocus":
Boolean isFocus = new TypeConverter<Boolean>().getValue(argument, "value");
if (null == isFocus) {
return null;
}
polyline.setFocus(isFocus);
break;
case "visible":
Boolean visible = new TypeConverter<Boolean>().getValue(argument, "value");
if (null == visible) {
return null;
}
polyline.setVisible(visible);
break;
case "zIndex":
Integer zIndex = new TypeConverter<Integer>().getValue(argument, "value");
if (null == zIndex) {
return null;
}
polyline.setZIndex(zIndex);
break;
case "isThined":
Boolean isThined = new TypeConverter<Boolean>().getValue(argument, "value");
if(null != isThined){
polyline.setThined(isThined);
}
break;
case "dottedLine":
Boolean dottedLine = new TypeConverter<Boolean>().getValue(argument, "value");
if (null != dottedLine) {
polyline.setDottedLine(dottedLine);
}
break;
default:
break;
}
return new HashMap<String, Overlay>() {
{
put(id, polyline);
}
};
}
private boolean updateCoordinates(Map<String, Object> argument, Polyline polyline) {
List<Map<String, Double>> coordinates =
new TypeConverter<List<Map<String, Double>>>().getValue(argument,
"value");
if (null == coordinates) {
return false;
}
List<LatLng> latLngList = FlutterDataConveter.mapToLatlngs(coordinates);
if (null == latLngList) {
return false;
}
polyline.setPoints(latLngList);
List<Integer> indexs = new TypeConverter<List<Integer>>().getValue(argument, "indexs");
if (null != indexs) {
int[] nIndexs = new int[indexs.size()];
for (int i = 0; i < indexs.size(); i++) {
nIndexs[i] = indexs.get(i);
}
polyline.setIndexs(nIndexs);
}
return true;
}
private boolean updateIndexs(Map<String, Object> argument, Polyline polyline) {
List<Integer> indexs = new TypeConverter<List<Integer>>().getValue(argument, "value");
if (null == indexs) {
return false;
}
int[] nIndexs = new int[indexs.size()];
for (int i = 0; i < indexs.size(); i++) {
nIndexs[i] = indexs.get(i);
}
polyline.setIndexs(nIndexs);
List<LatLng> points = polyline.getPoints();
if (null != points) {
polyline.setPoints(points);
}
return true;
}
private boolean updateColors(Map<String, Object> argument, Polyline polyline) {
boolean ret = false;
List<String> colors =
new TypeConverter<List<String>>().getValue(argument, "value");
List<Integer> indexs =
new TypeConverter<List<Integer>>().getValue(argument, "indexs");
List<LatLng> points = polyline.getPoints();
if (null != colors &&
colors.size() > 0 &&
null != indexs &&
indexs.size() > 0 &&
null != points &&
points.size() > 0) {
List<Integer> intColors = FlutterDataConveter.getColors(colors);
List<Integer> correctColors = correctColors(indexs, intColors, points.size());
if (null != correctColors) {
if (correctColors.size() == 1) {
polyline.setColor(correctColors.get(0));
ret = true;
} else {
int[] nColors = new int[correctColors.size()];
for (int i = 0; i < correctColors.size(); i++) {
nColors[i] = correctColors.get(i);
}
polyline.setColorList(nColors);
ret = true;
}
polyline.setPoints(points);
}
}
return ret;
}
private boolean updateTextures(Map<String, Object> argument, Polyline polyline) {
List<String> icons =
new TypeConverter<List<String>>().getValue(argument, "value");
if (null == icons) {
return false;
}
boolean ret = false;
if (null != icons && icons.size() > 0) {
List<BitmapDescriptor> bitmapDescriptors = FlutterDataConveter.getIcons(icons);
if (null != bitmapDescriptors) {
if (bitmapDescriptors.size() == 1) {
polyline.setTexture(bitmapDescriptors.get(0));
ret = true;
} else {
polyline.setTextureList(bitmapDescriptors);
ret = true;
}
List<LatLng> points = polyline.getPoints();
if (null != points) {
polyline.setPoints(points);
}
Bundle bundle = polyline.getExtraInfo();
String id = bundle.getString("id");
clearTextureBitMap(id);
mBitmapMap.put(id, bitmapDescriptors);
}
}
return ret;
}
private boolean updateLinashType(Map<String, Object> argument, Polyline polyline) {
Integer lineDashType = new TypeConverter<Integer>().getValue(argument, "value");
if (null == lineDashType) {
return false;
}
switch (lineDashType) {
case OverlayCommon.LineDashType.sLineDashTypeNone:
break;
case OverlayCommon.LineDashType.sLineDashTypeSquare:
polyline.setDottedLineType(PolylineDottedLineType.DOTTED_LINE_SQUARE);
break;
case OverlayCommon.LineDashType.sLineDashTypeDot:
polyline.setDottedLineType(PolylineDottedLineType.DOTTED_LINE_CIRCLE);
break;
default:
break;
}
return true;
}
private void clearTextureBitMap(String id) {
if (TextUtils.isEmpty(id)) {
return;
}
List<BitmapDescriptor> bitmapDescriptors = mBitmapMap.get(id);
if (null == bitmapDescriptors) {
return;
}
Iterator itr = bitmapDescriptors.iterator();
BitmapDescriptor bitmapDescriptor;
while (itr.hasNext()) {
bitmapDescriptor = (BitmapDescriptor) itr.next();
if (null == bitmapDescriptor) {
continue;
}
bitmapDescriptor.recycle();
}
mBitmapMap.remove(id);
}
public void clean(){
Iterator itr = mBitmapMap.values().iterator();
List<BitmapDescriptor> bitmapDescriptors;
BitmapDescriptor bitmapDescriptor;
while (itr.hasNext()) {
bitmapDescriptors = (List<BitmapDescriptor>) itr.next();
if (null == bitmapDescriptors) {
continue;
}
Iterator listItr = bitmapDescriptors.iterator();
while (listItr.hasNext()) {
bitmapDescriptor = (BitmapDescriptor)listItr.next();
if (null == bitmapDescriptor) {
continue;
}
bitmapDescriptor.recycle();
}
}
mBitmapMap.clear();
}
public void clean(String id) {
if (TextUtils.isEmpty(id)) {
return;
}
List<BitmapDescriptor> bitmapDescriptors = mBitmapMap.get(id);
if (null == bitmapDescriptors) {
return;
}
Iterator itr = bitmapDescriptors.iterator();
BitmapDescriptor bitmapDescriptor;
while (itr.hasNext()) {
bitmapDescriptor = (BitmapDescriptor)itr.next();
if (null == bitmapDescriptor) {
continue;
}
bitmapDescriptor.recycle();
}
mBitmapMap.remove(id);
}
}

@ -0,0 +1,137 @@
package com.baidu.flutter_bmfmap.map.overlayHandler;
import java.util.HashMap;
import java.util.Map;
import com.baidu.flutter_bmfmap.utils.Env;
import com.baidu.flutter_bmfmap.utils.converter.FlutterDataConveter;
import com.baidu.flutter_bmfmap.utils.converter.TypeConverter;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.TextOptions;
import com.baidu.mapapi.model.LatLng;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class TextHandler extends OverlayHandler {
private static final String TAG = "TextHandler";
public TextHandler(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public Map<String, Overlay> handlerMethodCall(MethodCall call, MethodChannel.Result result) {
Map<String, Object> argument = call.arguments();
if (null == argument) {
if (Env.DEBUG) {
Log.d(TAG, "argument is null");
}
return null;
}
if (!argument.containsKey("id")
|| !argument.containsKey("text")
|| !argument.containsKey("position")) {
if (Env.DEBUG) {
Log.d(TAG, "argument does not contain" + argument.toString());
}
return null;
}
final String id = new TypeConverter<String>().getValue(argument, "id");
if (TextUtils.isEmpty(id)) {
return null;
}
TextOptions textOptions = new TextOptions();
Object posObj = (argument.get("position"));
if (null != posObj) {
Map<String, Object> posMap = (Map<String, Object>) posObj;
LatLng pos = FlutterDataConveter.mapToLatlng(posMap);
if (null != pos) {
if (Env.DEBUG) {
Log.d(TAG, "pos");
}
textOptions.position(pos);
}
}
String text = new TypeConverter<String>().getValue(argument, "text");
if (TextUtils.isEmpty(text)) {
return null;
}
textOptions.text(text);
setTextOptions(argument, textOptions);
final Overlay overlay = mBaiduMap.addOverlay(textOptions);
return new HashMap<String, Overlay>() {
{
put(id, overlay);
}
};
}
private void setTextOptions(Map<String, Object> textOptionsMap, TextOptions textOptions) {
if (null == textOptionsMap || null == textOptions) {
return;
}
String bgColorStr = new TypeConverter<String>().getValue(textOptionsMap, "bgColor");
if (!TextUtils.isEmpty(bgColorStr)) {
int bgColor = FlutterDataConveter.strColorToInteger(bgColorStr);
textOptions.bgColor(bgColor);
}
String fongColorStr = new TypeConverter<String>().getValue(textOptionsMap, "fontColor");
if (!TextUtils.isEmpty(fongColorStr)) {
int fontColor = FlutterDataConveter.strColorToInteger(fongColorStr);
textOptions.fontColor(fontColor);
}
Integer fontSize = new TypeConverter<Integer>().getValue(textOptionsMap, "fontSize");
if (null != fontSize) {
textOptions.fontSize(fontSize);
}
Integer alignx = new TypeConverter<Integer>().getValue(textOptionsMap, "alignX");
Integer aligny = new TypeConverter<Integer>().getValue(textOptionsMap, "alignY");
if (null != alignx && null != aligny) {
textOptions.align(alignx, aligny);
}
Double roate = new TypeConverter<Double>().getValue(textOptionsMap, "rotate");
if (null != roate) {
textOptions.rotate(roate.floatValue());
}
Integer zIndex = new TypeConverter<Integer>().getValue(textOptionsMap, "zIndex");
if (null != zIndex) {
textOptions.zIndex(zIndex);
}
Boolean visible = new TypeConverter<Boolean>().getValue(textOptionsMap, "visible");
if (null != visible) {
textOptions.visible(visible);
}
Map<String, Object> typeFaceMap =
new TypeConverter<Map<String, Object>>().getValue(textOptionsMap, "typeFace");
if (null != typeFaceMap) {
String familyName = new TypeConverter<String>().getValue(typeFaceMap, "familyName");
Integer textStype = new TypeConverter<Integer>().getValue(typeFaceMap, "textStype");
if (!TextUtils.isEmpty(familyName) && textStype >= 0 && textStype <= 4) {
Typeface typeface = Typeface.create(familyName, textStype);
textOptions.typeface(typeface);
}
}
}
}

@ -0,0 +1,623 @@
package com.baidu.flutter_bmfmap.utils;
public class Constants {
public static final String VIEW_METHOD_CHANNEL_PREFIX = "flutter_bmfmap/map_";
public static final String VIEW_EVENT_CHANNEL_PREFIX = "flutter_bmfmap/event_";
public static final String sConfigChangedAction = "com.baidu.flutter_bmfmap.configChanged";
/**
* flutter widget update FlutterMapView FlutterTextureMapView
*/
public static final int MAX_GET_VIEW_CNT_BY_FLUTTER_RESIZE = 3;
/**
* view
*/
public static class ViewType{
public static final String sMapView = "flutter_bmfmap/map/BMKMapView";
public static final String sTextureMapView = "flutter_bmfmap/map/BMKTextureMapView";
}
/**
* overlayHandler
*/
public static class OverlayHandlerType{
public static final int CIRCLE_HANDLER = 0;
public static final int DOT_HANDLER = 1;
public static final int POLYGON_HANDLER = 2;
public static final int POLYLINE_HANDLER = 3;
public static final int TEXT_HANDLER = 4;
public static final int ARCLINE_HANDLER = 5;
public static final int GROUND_HANDLER = 6;
}
/**
* MapHandler
*/
public static class BMapHandlerType{
public static final int CUSTOM_MAP = 0;
public static final int MAP_STATE = 1;
public static final int INDOOR_MAP = 2;
public static final int MAP_SNAPSHOT = 3;
public static final int CUSTOM_COMPASS = 4;
public static final int CUSTOM_TRAFFIC_COLOR = 5;
public static final int MAP_UPDATE = 6;
public static final int HEAT_MAP = 7;
public static final int TILE_MAP = 8;
public static final int INFOWINDOW_HANDLER = 9;
public static final int MARKER_HANDLER = 10;
public static final int LOCATION_LAYER = 11;
public static final int PROJECTION = 12;
}
/**
* flutter method
*/
public static class MethodProtocol {
/**
*
*/
public static class IndoorMapProtocol {
/**
* map
*/
public static final String sShowBaseIndoorMapMethod = "flutter_bmfmap/map/showBaseIndoorMap";
/**
* map
*/
public static final String sShowBaseIndoorMapPoiMethod = "flutter_bmfmap/map/showBaseIndoorMapPoi";
/**
* map
*/
public static final String sSwitchBaseIndoorMapFloorMethod = "flutter_bmfmap/map/switchBaseIndoorMapFloor";
/**
* map
*/
public static final String sGetFocusedBaseIndoorMapInfoMethod= "flutter_bmfmap/map/getFocusedBaseIndoorMapInfo";
}
/**
*
*/
public static class CustomMapProtocol {
/**
*
*/
public static final String sMapSetCustomMapStyleEnableMethod = "flutter_bmfmap/map/setCustomMapStyleEnable";
/**
*
*/
public static final String sMapSetCustomMapStylePathMethod = "flutter_bmfmap/map/setCustomMapStylePath";
/**
* 线
*/
public static final String sMapSetCustomMapStyleWithOptionMethod = "flutter_bmfmap/map/setCustomMapStyleWithOption";
}
/**
* overlay
*/
public static class OverlayProtocol{
/**
* overlay
*/
public static final String sMapRemoveOverlayMethod = "flutter_bmfmap/overlay/removeOverlay";
}
/**
* marker
*/
public static class MarkerProtocol {
/**
* marker
*/
public static final String sMapAddMarkerMethod = "flutter_bmfmap/marker/addMarker";
/**
* markers
*/
public static final String sMapAddMarkersMethod = "flutter_bmfmap/marker/addMarkers";
/**
* marker
*/
public static final String sMapRemoveMarkerMethod = "flutter_bmfmap/marker/removeMarker";
/**
* markers
*/
public static final String sMapRemoveMarkersMethod = "flutter_bmfmap/marker/removeMarkers";
/**
* markers
*/
public static final String sMapCleanAllMarkersMethod = "flutter_bmfmap/marker/cleanAllMarkers";
/**
* marker
*/
public static final String sMapClickedmarkedMethod = "flutter_bmfmap/marker/clickedMarker";
/**
* marker
*/
public static final String sMapDidSelectMarkerMethod = "flutter_bmfmap/marker/didSelectedMarker";
/**
* marker
*/
public static final String sMapDidDeselectMarkerMethod = "flutter_bmfmap/marker/didDeselectMarker";
/**
* marker
*/
public static final String sMapDragMarkerMethod = "flutter_bmfmap/marker/dragMarker";
/**
* marker
*/
public static final String sMapUpdateMarkerMemberMethod = "flutter_bmfmap/marker/updateMarkerMember";
/**
* marker
*/
public static class MarkerDragState{
/**
*
*/
public static final String sDragStart = "dragStart";
/**
*
*/
public static final String sDragging = "dragging";
/**
*
*/
public static final String sDragEnd = "dragEnd";
}
}
/**
* infowindow
*/
public static class InfoWindowProtocol {
/**
* markerinfoWindowiOS paopaoView
*/
public static final String sMapDidClickedInfoWindowMethod = "flutter_bmfmap/map/didClickedInfoWindow";
// 添加infoWindow
public static final String sAddInfoWindowMapMethod = "flutter_bmfmap/map/addInfoWindow";
// 添加infoWindow
public static final String sAddInfoWindowsMapMethod = "flutter_bmfmap/map/addInfoWindows";
// 移除infoWindow
public static final String sRemoveInfoWindowMapMethod = "flutter_bmfmap/map/removeInfoWindow";
}
/**
* polyline
*/
public static class PolylineProtocol {
/**
* polyline
*/
public static final String sMapAddPolylineMethod = "flutter_bmfmap/overlay/addPolyline";
/**
* polyline
*/
public static final String sMapOnClickedOverlayCallback = "flutter_bmfmap/overlay/onClickedOverlay";
/**
* polyline
*/
public static final String sMapUpdatePolylineMemberMethod = "flutter_bmfmap/overlay/updatePolylineMember";
}
/**
* polygon
*/
public static class PolygonProtocol {
/**
* polyline
*/
public static final String sMapAddPolygonMethod = "flutter_bmfmap/overlay/addPolygon";
}
/**
* arline
*/
public static class ArclineProtocol {
/**
* arcline
*/
public static final String sMapAddArclinelineMethod = "flutter_bmfmap/overlay/addArcline";
}
/**
* circleline
*/
public static class CirclelineProtocol {
/**
* circlr
*/
public static final String sMapAddCirclelineMethod = "flutter_bmfmap/overlay/addCircle";
}
/**
* dot
*/
public static class DotProtocol {
/**
* Dot
*/
public static final String sMapAddDotMethod = "flutter_bmfmap/overlay/addDot";
}
/**
* text
*/
public static class TextProtocol {
/**
* text
*/
// 添加dot
public static final String sMapAddTextMethod = "flutter_bmfmap/overlay/addText";
}
/**
* dot
*/
public static class GroundProtocol {
/**
* Ground
*/
public static final String sMapAddGroundMethod = "flutter_bmfmap/overlay/addGround";
}
public static class HeatMapProtocol {
/**
* HeapMap
*/
public static final String sMapAddHeatMapMethod = "flutter_bmfmap/heatMap/addHeatMap";
/**
*
*/
public static final String sMapRemoveHeatMapMethod = "flutter_bmfmap/heatMap/removeHeatMap";
/**
*
*/
public static final String sShowHeatMapMethod = "flutter_bmfmap/heatMap/showHeatMap";
}
/**
* mapState
*/
public static class MapStateProtocol {
// 更新地图参数
public static final String sMapUpdateMethod = "flutter_bmfmap/map/updateMapOptions";
// map放大一级比例尺
public static final String sMapZoomInMethod = "flutter_bmfmap/map/zoomIn";
// map缩小一级比例尺
public static final String sMapZoomOutMethod = "flutter_bmfmap/map/zoomOut";
// 设置路况颜色
public static final String sMapSetCustomTrafficColorMethod =
"flutter_bmfmap/map/setCustomTrafficColor";
// 更新地图状态
public static final String sMapSetMapStatusMethod = "flutter_bmfmap/map/setMapStatus";
// 获取地图状态
public static final String sMapGetMapStatusMethod = "flutter_bmfmap/map/getMapStatus";
// 按像素移动地图中心点
public static final String sMapSetScrollByMethod = "flutter_bmfmap/map/setScrollBy";
// 根据给定增量缩放地图级别
public static final String sMapSetZoomByMethod = "flutter_bmfmap/map/setZoomBy";
// 根据给定增量以及给定的屏幕坐标缩放地图级别
public static final String sMapSetZoomPointByMethod = "flutter_bmfmap/map/setZoomPointBy";
// 设置地图缩放级别
public static final String sMapSetZoomToMethod = "flutter_bmfmap/map/setZoomTo";
// 设定地图中心点坐标
public static final String sMapSetCenterCoordinateMethod =
"flutter_bmfmap/map/setCenterCoordinate";
// 设置地图中心点以及缩放级别
public static final String sMapSetCenterZoomMethod = "flutter_bmfmap/map/setMapCenterZoom";
// 获得地图当前可视区域截图
public static final String sMapTakeSnapshotMethod = "flutter_bmfmap/map/takeSnapshot";
// 获得地图指定区域截图
public static final String sMapTakeSnapshotWithRectMethod =
"flutter_bmfmap/map/takeSnapshotWithRect";
// 设置罗盘的图片
public static final String sMapSetCompassImageMethod = "flutter_bmfmap/map/setCompassImage";
// 设置显示在屏幕中的地图地理范围
public static final String sMapSetVisibleMapBoundsMethod = "flutter_bmfmap/map/setVisibleMapBounds";
// 设定地图的显示范围,并使mapRect四周保留insets指定的边界区域
public static final String sMapSetVisibleMapBoundsWithPaddingMethod =
"flutter_bmfmap/map/setVisibleMapBoundsWithPadding";
// map加载完成
public static final String sMapDidLoadCallback = "flutter_bmfmap/map/mapViewDidFinishLoad";
// map渲染完成
public static final String sMapDidFinishRenderCallback =
"flutter_bmfmap/map/mapViewDidFinishRender";
// 地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口
public static final String sMapOnDrawMapFrameCallback =
"flutter_bmfmap/map/mapViewOnDrawMapFrame";
// 地图绘制出有效数据的监听
public static final String sMapRenderValidDataCallback = "flutter_bmfmap/map/mapRenderValidDataCallback";
// 地图View进入/移出室内图
public static final String sMapInOrOutBaseIndoorMapCallback =
"flutter_bmfmap/map/mapViewInOrOutBaseIndoorMap";
// 地图区域即将改变时会调用此接口
public static final String sMapRegionWillChangeCallback =
"flutter_bmfmap/map/mapViewRegionWillChange";
// 地图区域即将改变时会调用此接口reason
public static final String sMapRegionWillChangeWithReasonCallback =
"flutter_bmfmap/map/mapViewRegionWillChangeWithReason";
// 地图区域改变完成后会调用此接口
public static final String sMapRegionDidChangeCallback =
"flutter_bmfmap/map/mapViewRegionDidChange";
// 地图区域改变完成后会调用此接口reason
public static final String sMapRegionDidChangeWithReasonCallback =
"flutter_bmfmap/map/mapViewRegionDidChangeWithReason";
// 点中底图空白处会回调此接口
public static final String sMapOnClickedMapBlankCallback =
"flutter_bmfmap/map/mapViewOnClickedMapBlank";
// 点中底图标注后会回调此接口
public static final String sMapOnClickedMapPoiCallback =
"flutter_bmfmap/map/mapViewonClickedMapPoi";
// 双击地图时会回调此接口
public static final String sMapOnDoubleClickCallback =
"flutter_bmfmap/map/mapViewOnDoubleClick";
// 长按地图时会回调此接口
public static final String sMapOnLongClickCallback =
"flutter_bmfmap/map/mapViewOnLongClick";
// 地图状态改变完成后会调用此接口
public static final String sMapStatusDidChangedCallback =
"flutter_bmfmap/map/mapViewStatusDidChanged";
// widget 状态更新
public static final String sMapDidUpdateWidget = "flutter_bmfmap/map/didUpdateWidget";
// widget 热重载
public static final String sMapReassemble = "flutter_bmfmap/map/reassemble";
}
/**
* id
*/
public static class BMFMapGetPropertyMethodId {
// 获取map的展示类型
public static final String sMapGetMapTypeMethod = "flutter_bmfmap/map/getMapType";
// 获取map的比例尺级别
public static final String sMapGetZoomLevelMethod = "flutter_bmfmap/map/getZoomLevel";
// 获取map的自定义最小比例尺级别
public static final String sMapGetMinZoomLevelMethod = "flutter_bmfmap/map/getMinZoomLevel";
// 获取map的自定义最大比例尺级别
public static final String sMapGetMaxZoomLevelMethod = "flutter_bmfmap/map/getMaxZoomLevel";
// 获取map的旋转角度
public static final String sMapGetRotationMethod = "flutter_bmfmap/map/getRotation";
// 获取map的地图俯视角度
public static final String sMapGetOverlookingMethod = "flutter_bmfmap/map/getOverlooking";
// 获取map的是否现显示3D楼块效果
public static final String sMapGetBuildingsEnabledMethod = "flutter_bmfmap/map/getBuildingsEnabled";
// 获取map的是否打开路况图层
public static final String sMapGetTrafficEnabledMethod = "flutter_bmfmap/map/getTrafficEnabled";
// 获取map的是否打开百度城市热力图图层
public static final String sMapGetBaiduHeatMapEnabledMethod = "flutter_bmfmap/map/getBaiduHeatMapEnabled";
// 获取map的是否支持所有手势操作
public static final String sMapGetGesturesEnabledMethod = "flutter_bmfmap/map/getGesturesEnabled";
// 获取map是否支持缩放
public static final String sMapGetZoomEnabledMethod = "flutter_bmfmap/map/getZoomEnabled";
// 获取map是否支持拖拽手势
public static final String sMapGetScrollEnabledMethod = "flutter_bmfmap/map/getScrollEnabled";
// 获取map是否支持俯仰角
public static final String sMapGetOverlookEnabledMethod = "flutter_bmfmap/map/getOverlookEnabled";
// 获取map是否支持旋转
public static final String sMapGetRotateEnabledMethod = "flutter_bmfmap/map/getRotateEnabled";
// 获取map的比例尺的位置
public static final String sMapGetMapScaleBarPositionMethod = "flutter_bmfmap/map/getMapScaleBarPosition";
// 获取map的logo位置
public static final String sMapGetLogoPositionMethod = "flutter_bmfmap/map/getLogoPosition";
// 获取map的可视范围
public static final String sMapGetVisibleMapBoundsMethod = "flutter_bmfmap/map/getVisibleMapBounds";
// 获取map的显示室内图
public static final String sMapGetBaseIndoorMapEnabledMethod = "flutter_bmfmap/map/getBaseIndoorMapEnabled";
// 获取map的室内图标注是否显示
public static final String sMapGetShowIndoorMapPoiMethod = "flutter_bmfmap/map"
+ "/getShowIndoorMapPoi";
}
public static class BMFOfflineMethodId {
// 初使化
public static final String sMapInitOfflineMethod = "flutter_bmfmap/offlineMap/initOfflineMap";
// 状态回调
public static final String sMapOfflineCallBackMethod = "flutter_bmfmap/offlineMap/offlineCallBack";
// 启动下载指定城市ID的离线地图或在暂停更新某城市后继续更新下载某城市离线地图
public static final String sMapStartOfflineMethod = "flutter_bmfmap/offlineMap/startOfflineMap";
// 启动更新指定城市ID的离线地图
public static final String sMapUpdateOfflineMethod = "flutter_bmfmap/offlineMap/updateOfflineMap";
// 暂停下载或更新指定城市ID的离线地图
public static final String sMapPauseOfflineMethod = "flutter_bmfmap/offlineMap/pauseOfflineMap";
// 删除指定城市ID的离线地图
public static final String sMapRemoveOfflineMethod = "flutter_bmfmap/offlineMap/removeOfflineMap";
// 销毁离线地图管理模块,不用时调用
public static final String sMapDestroyOfflineMethod = "flutter_bmfmap/offlineMap/destroyOfflineMap";
// 返回热门城市列表
public static final String sMapGetHotCityListMethod = "flutter_bmfmap/offlineMap/getHotCityList";
// 返回支持离线地图城市列表
public static final String sMapGetOfflineCityListMethod = "flutter_bmfmap/offlineMap/getOfflineCityList";
// 根据城市名搜索该城市离线地图记录
public static final String sMapSearchCityMethod = "flutter_bmfmap/offlineMap/searchCityList";
// 返回各城市离线地图更新信息
public static final String sMapGetAllUpdateInfoMethod = "flutter_bmfmap/offlineMap/getAllUpdateInfo";
// 返回指定城市ID离线地图更新信息
public static final String sMapGetUpdateInfoMethod = "flutter_bmfmap/offlineMap/getUpdateInfo";
}
public static class ProjectionMethodId {
//屏幕坐标转地理坐标ID
public static final String sFromScreenLocation = "flutter_bmfmap/projection/screenPointfromCoordinate";
//将地理坐标转换成屏幕坐标
public static final String sToScreenLocation = "flutter_bmfmap/projection/coordinateFromScreenPoint";
//米为计量单位的距离(沿赤道)在当前缩放水平下转换到一个以像素(水平)为计量单位的距离
public static final String sMetersToEquatorPixels = "flutter_bmfmap/map/metersToEquatorPixels";
}
public static class TileMapProtocol {
// 添加室内地图
public static final String sAddTileMapMethod = "flutter_bmfmap/overlay/addTile";
// 展示室内地图
public static final String sRemoveTileMapMethod = "flutter_bmfmap/overlay/removeTile";
}
}
public static class ErrorCode{
/**
*
*/
public static final int sErrorNon = 0;
/**
* flutter
*/
public static final int sErrorNullFlutterParam = 1;
/**
* flutter
*/
public static final int sErrorFlutterParamMissingContent = 2;
/**
* flutter
*/
public static final int sErrorFlutterParamType= 3;
/**
* flutter
*/
public static final int sErrorParamConvertFailed= 4;
/**
* flutter
*/
public static final int sErrorEngineError= 5;
}
// 定位图层
public static class LocationLayerMethodId {
// 设定是否显示定位图层
public static final String sMapShowUserLocationMethod =
"flutter_bmfmap/userLocation/showUserLocation";
// 设定定位模式取值为BMFUserTrackingMode
public static final String sMapUserTrackingModeMethod =
"flutter_bmfmap/userLocation/userTrackingMode";
// 动态定制我的位置样式
public static final String sMapUpdateLocationDisplayParamMethod =
"flutter_bmfmap/userLocation/updateLocationDisplayParam";
// 动态更新我的位置数据
public static final String sMapUpdateLocationDataMethod =
"flutter_bmfmap/userLocation/updateLocationData";
}
/**
*
*/
public class SwitchIndoorFloorError {
/** 切换楼层成功 */
public static final int SUCCESS = 0;
/** 切换楼层失败 */
public static final int FAILED = 1;
/** 地图还未聚焦到传入的室内图 */
public static final int NOT_FOCUSED = 2;
/** 当前室内图不存在该楼层 */
public static final int NOT_EXIST = 3;
/** 切换楼层, 室内ID信息错误 [android] 独有 */
public static final int SWICH_FLOOR_INFO_ERROR = 4;
}
}

@ -0,0 +1,76 @@
package com.baidu.flutter_bmfmap.utils;
public class Env {
public static Boolean DEBUG = false;
/**
*
*/
public static final int MAP_TYPE_NONE = 0;
/**
*
*/
public static final int MAP_TYPE_NORMAL = 1;
/**
*
*/
public static final int MAP_TYPE_SATELLITE = 2;
/**
*
*/
public static final int LOGO_POSITION_LEFT_BOTTOM = 0;
/**
*
*/
public static final int LOGO_POSITION_LEFT_TOP = 1;
/**
*
*/
public static final int LOGO_POSITION_CENTER_BOTTOM = 2;
/**
*
*/
public static final int LOGO_POSITION_CENTER_TOP = 3;
/**
*
*/
public static final int LOGO_POSITION_RIGTH_BOTTOM = 4;
/**
*
*/
public static final int LOGO_POSITION_RIGTH_TOP = 5;
/**
*
*/
public static class LocationMode {
/**
*
*/
public static final int NORMAL = 0;
/**
*
*/
public static final int MODEHEADING = 1;
/**
*
*/
public static final int FOLLOWING = 2;
/**
*
*/
public static final int COMPASS = 3;
}
}

@ -0,0 +1,38 @@
package com.baidu.flutter_bmfmap.utils;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.io.Closeable;
import java.io.IOException;
/**
* closeable
*/
public class IOStreamUtils{
public static void closeSilently(Closeable o){
if(null == o){
return;
}
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void closeSilently(AutoCloseable o){
if(null == o){
return;
}
try {
o.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,74 @@
package com.baidu.flutter_bmfmap.utils;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPoolUtil {
private ThreadFactory mThreadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r,"mapThread"+mAtomicInteger.getAndIncrement());
return t;
}
};
private AtomicInteger mAtomicInteger = new AtomicInteger(0);
private final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
private final int MAX_POLL_SIZE = CORE_POOL_SIZE*2;
private final int KEEP_ALIVE = 3; //空线程alive时间
private ExecutorService mExecutorService;
private ScheduledExecutorService mScheduleExecutorService;
private static volatile ThreadPoolUtil sInstance;
public static ThreadPoolUtil getInstance(){
if(null == sInstance){
synchronized (ThreadPoolUtil.class){
if(null == sInstance){
sInstance = new ThreadPoolUtil();
}
}
}
return sInstance;
}
public ThreadPoolUtil(){
mExecutorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POLL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000),
mThreadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
mScheduleExecutorService = new ScheduledThreadPoolExecutor(CORE_POOL_SIZE, mThreadFactory);
}
public void execute(Runnable runnable){
if(null == mExecutorService){
return;
}
mExecutorService.execute(runnable);
}
public ScheduledFuture execute(Runnable runnable, int delayTime){
if(null == mScheduleExecutorService){
return null;
}
return mScheduleExecutorService.schedule(runnable, delayTime, TimeUnit.MILLISECONDS);
}
}

@ -0,0 +1,435 @@
package com.baidu.flutter_bmfmap.utils.converter;
import android.graphics.Color;
import android.graphics.Point;
import android.text.TextUtils;
import android.util.Size;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.Projection;
import com.baidu.mapapi.map.WeightedLatLng;
import com.baidu.mapapi.map.WinRound;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class FlutterDataConveter {
/**
* map
* @param latlngMap
* @return
*/
public static LatLng mapToLatlng(Map<String, Object> latlngMap){
if(null == latlngMap){
return null;
}
if(!latlngMap.containsKey("latitude")
|| !latlngMap.containsKey("longitude")){
return null;
}
Object latitudeObj = latlngMap.get("latitude");
Object longitudeObj = latlngMap.get("longitude");
if(null == latitudeObj || null == longitudeObj){
return null;
}
LatLng latLng = new LatLng((double)latitudeObj, (double)longitudeObj);
return latLng;
}
/**
* map
* @param latlngList
* @return
*/
public static List<LatLng> mapToLatlngs(List<Map<String, Double> > latlngList) {
if (null == latlngList) {
return null;
}
Iterator itr = latlngList.iterator();
ArrayList<LatLng> latLngs = new ArrayList<>();
while (itr.hasNext()){
Map<String, Object> latlngMap = (Map<String, Object>)itr.next();
LatLng latLng = mapToLatlng(latlngMap);
if(null == latLng){
break;
}
latLngs.add(latLng);
}
if(latLngs.size() != latlngList.size()){
return null;
}
return latLngs;
}
/**
* 16
* @param number
* @return
*/
private static String intToHexValue(int number) {
String result = Integer.toHexString(number & 0xff);
while (result.length() < 2) {
result = "0" + result;
}
return result.toUpperCase();
}
/**
* 16
* @param str 16
* @return
*/
public static int strColorToInteger(String str) {
if(TextUtils.isEmpty(str) || str.length() < 8){
return 0;
}
String str1 = str.substring(0, 2);
String str2 = str.substring(2, 4);
String str3 = str.substring(4, 6);
String str4 = str.substring(6, 8);
int alpha = Integer.parseInt(str1, 16);
int red = Integer.parseInt(str2, 16);
int green = Integer.parseInt(str3, 16);
int blue = Integer.parseInt(str4, 16);
return Color.argb(alpha, red, green, blue);
}
/**
* iconBitmapDescriptor
* @param icons
* @return
*/
public static List<BitmapDescriptor> getIcons(List<String> icons){
if(null == icons){
return null;
}
List<BitmapDescriptor> bitmapIcons = new ArrayList<>();
Iterator itr = icons.iterator();
while (itr.hasNext()){
String icon = (String) itr.next();
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset("flutter_assets/" + icon);
bitmapIcons.add(bitmapDescriptor);
}
return bitmapIcons;
}
/**
* 16
* @param colors
* @return
*/
public static List<Integer> getColors(List<String> colors){
if(null == colors || colors.size() <= 0){
return null;
}
List<Integer> intColors = new ArrayList<>();
Iterator iterator = colors.iterator();
while (iterator.hasNext()){
String colorStr = (String)iterator.next();
if(TextUtils.isEmpty(colorStr)){
return null;
}
int color = FlutterDataConveter.strColorToInteger(colorStr);
intColors.add(color);
}
return intColors;
}
/**
* mapboundsLatLngBounds
* @param boundsMap
* @return
*/
public static LatLngBounds mapToLatlngBounds(Map<String, Object> boundsMap){
if(null == boundsMap){
return null;
}
if(!boundsMap.containsKey("northeast") || !boundsMap.containsKey("southwest")){
return null;
}
Map<String, Object> northeastMap = (Map<String, Object>)boundsMap.get("northeast");
Map<String, Object> southwestMap = (Map<String, Object>)boundsMap.get("southwest");
if(null == northeastMap || null == southwestMap){
return null;
}
LatLng northeast = mapToLatlng(northeastMap);
LatLng southwest = mapToLatlng(southwestMap);
return new LatLngBounds.Builder().include(northeast).include(southwest).build();
}
/**
* LatLngBoundsmap
* @param latLngBounds
* @return
*/
public static Map<String, Object> latlngBoundsToMap(LatLngBounds latLngBounds){
if(null == latLngBounds){
return null;
}
LatLng southwest = latLngBounds.southwest;
LatLng northeast = latLngBounds.northeast;
Map<String, Double> southwestMap = FlutterDataConveter.latLngToMap(southwest);
Map<String, Double> northeastMap = FlutterDataConveter.latLngToMap(northeast);
HashMap<String, Object> latLngBoundsMap = new HashMap<>();
latLngBoundsMap.put("southwest", southwestMap);
latLngBoundsMap.put("northeast", northeastMap);
return latLngBoundsMap;
}
/**
* map
* @param dataList
* @return
*/
public static List<WeightedLatLng> mapToWeightedLatLngList(List<Map<String, Object> > dataList) {
if(null == dataList){
return null;
}
List<WeightedLatLng> weightedLatLngList = new ArrayList<WeightedLatLng>();
Iterator itr = dataList.iterator();
while (itr.hasNext()){
Map<String, Object> data = ( Map<String, Object> )itr.next();
if(null == data){
return null;
}
if(!data.containsKey("pt")
|| !data.containsKey("intensity")){
return null;
}
Object intensityObj = data.get("intensity");
if(null == intensityObj){
return null;
}
double intensity = (double)intensityObj;
Object ptObj = data.get("pt");
if(null == ptObj){
return null;
}
Map<String, Object> ptMap = (Map<String, Object>)ptObj;
if(null == ptMap){
return null;
}
LatLng latLng = FlutterDataConveter.mapToLatlng(ptMap);
WeightedLatLng weightedLatLng = new WeightedLatLng(latLng, intensity);
weightedLatLngList.add(weightedLatLng);
}
return weightedLatLngList;
}
/**
* mapPoint
* @param pointMap
* @return
*/
public static Point mapToPoint(Map<String, Object> pointMap){
if(null == pointMap){
return null;
}
if(!pointMap.containsKey("x") || !pointMap.containsKey("y")){
return null;
}
Object xObj = pointMap.get("x");
Object yObj = pointMap.get("y");
if(null == xObj || null == yObj){
return null;
}
double x = (double)xObj;
double y = (double)yObj;
Point point = new Point((int)x, (int)y);
return point;
}
/**
* LatLngmap
* @param latLng
* @return
*/
public static Map<String, Double> latLngToMap(LatLng latLng){
if(null == latLng){
return null;
}
Map<String, Double> resultMap = new HashMap<String, Double>();
resultMap.put("latitude", latLng.latitude);
resultMap.put("longitude", latLng.longitude);
resultMap.put("latitudeE6", latLng.latitudeE6);
resultMap.put("longitudeE6", latLng.longitudeE6);
return resultMap;
}
/**
* Pointmap
* @param point
* @return
*/
public static Map<String, Double> pointToMap(Point point){
if(null == point){
return null;
}
Map<String, Double> resultMap = new HashMap<String, Double>();
resultMap.put("x", (double)point.x);
resultMap.put("y", (double)point.y);
return resultMap;
}
/**
* flutterBMFRectWinRound
* BMFRect
* /// 屏幕左上点对应的直角地理坐标
* final BMFPoint origin;
*
* /// 坐标范围
* final BMFSize size;
*
* WinRound:
* public int left = 0;
* public int right = 0;
* public int top = 0;
* public int bottom = 0;
*/
public static WinRound BMFRectToWinRound(Map<String, Object> bmfRect){
if(null == bmfRect){
return null;
}
if(!bmfRect.containsKey("origin") || !bmfRect.containsKey("size")){
return null;
}
Map<String, Object> pointMap = (Map<String, Object>)bmfRect.get("origin");
Point point = FlutterDataConveter.mapToPoint(pointMap);
if(null == point){
return null;
}
Map<String, Object> sizeMap = (Map<String, Object>)bmfRect.get("size");
if(null == sizeMap){
return null;
}
if(null == sizeMap){
return null;
}
Double width = new TypeConverter<Double>().getValue(sizeMap, "width");
Double height = new TypeConverter<Double>().getValue(sizeMap, "height");
if(null == width || null == height){
return null;
}
WinRound winRound = new WinRound();
winRound.left = point.x;
winRound.top = point.y;
winRound.right = point.x + width.intValue();
winRound.bottom = point.y + height.intValue();
return winRound;
}
public static WinRound insetsToWinRound(Map<String, Object> insets){
if(null == insets){
return null;
}
if(!insets.containsKey("top")
||!insets.containsKey("left")
|| !insets.containsKey("bottom")
|| !insets.containsKey("right")){
return null;
}
Double top = new TypeConverter<Double>().getValue(insets, "top");
Double left = new TypeConverter<Double>().getValue(insets, "left");
Double bottom = new TypeConverter<Double>().getValue(insets, "bottom");
Double right = new TypeConverter<Double>().getValue(insets, "right");
if(null == top
|| null == left
|| null == bottom
|| null == right){
return null;
}
WinRound winRound = new WinRound();
winRound.left = left.intValue();
winRound.top = top.intValue();
winRound.right = right.intValue();
winRound.bottom = bottom.intValue();
return winRound;
}
public static LatLngBounds BMFRectToLatLngBounds(BaiduMap baiduMap, Map<String, Object> bmfRect){
if(null == baiduMap || null == bmfRect){
return null;
}
WinRound winRound = FlutterDataConveter.BMFRectToWinRound(bmfRect);
if(null == bmfRect){
return null;
}
Point notrhEastPoint = new Point();
notrhEastPoint.x = winRound.left;
notrhEastPoint.y = winRound.top;
Point southWestPoint = new Point();
southWestPoint.x = winRound.right;
southWestPoint.y = winRound.bottom;
Projection projection = baiduMap.getProjection();
LatLng northEast = projection.fromScreenLocation(notrhEastPoint);
LatLng southWest = projection.fromScreenLocation(southWestPoint);
LatLngBounds latLngBounds = new LatLngBounds.Builder().include(northEast).include(southWest).build();
return latLngBounds;
}
}

@ -0,0 +1,23 @@
package com.baidu.flutter_bmfmap.utils.converter;
import java.util.Map;
/**
* mapvalue
* @param <T>
*/
public class TypeConverter<T>{
public T getValue(Map<String, Object> map, String key){ //泛型方法getKey的返回值类型为TT的类型由外部指定
if(null == map){
return null;
}
Object valueObj = map.get(key);
if(null == valueObj){
return null;
}
T value = (T)valueObj;
return value;
}
}

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:radius="3dip"/>
<stroke
android:width="1dip"
android:color="#0000FF" />
</shape>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:radius="3dip"/>
<stroke
android:width="1dip"
android:color="#728ea3" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -0,0 +1,23 @@
# This file is used by dartdoc when generating API documentation for Flutter.
dartdoc:
include: ['bmfmap_map']
# linkToSource:
# root: '.'
# uriTemplate:
showUndocumentedCategories: true
ignore:
- ambiguous-doc-reference
errors:
- unresolved-doc-reference
warnings:
- tool-error
# Before you can run dartdoc, the snippets tool needs to have a snapshot built.
# The dev/tools/dartdoc.dart script does this automatically.
tools:
snippet:
command: ["dev/snippets/lib/main.dart", "--type=application"]
description: "Creates application sample code documentation output from embedded documentation samples."
sample:
command: ["dev/snippets/lib/main.dart", "--type=sample"]
description: "Creates sample code documentation output from embedded documentation samples."

@ -0,0 +1,30 @@
//
// BMFFileManager.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/12.
//
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface BMFFileManager : NSObject
/// registar
@property (nonatomic, strong) NSObject<FlutterPluginRegistrar> *registar;
/// BMFFileManagerCenter
+ (instancetype)defaultCenter;
/// 获取flutter端图片资源路径
- (NSString *)pathForFlutterImageName:(NSString *)imageName;
/// 获取flutter端文件资源路径
- (NSString *)pathForFlutterFileName:(NSString *)fileName;
/// 获取flutter端瓦片图路径
- (NSString *)pathForFlutterTileResources:(NSString *)tileName;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,39 @@
//
// BMFFileManager.m
// flutter_bmfmap
//
// Created by zbj on 2020/2/12.
//
#import "BMFFileManager.h"
@implementation BMFFileManager
static BMFFileManager *_instance = nil;
+ (instancetype)defaultCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFFileManager alloc] init];
});
}
return _instance;
}
/// 获取flutter端图片资源路径
- (NSString *)pathForFlutterImageName:(NSString *)imageName{
if (!_registar) return nil;
return [[NSBundle mainBundle] pathForResource:[_registar lookupKeyForAsset:imageName] ofType:nil];
}
/// 获取flutter端文件资源路径
- (NSString *)pathForFlutterFileName:(NSString *)fileName{
if (!_registar) return nil;
return [[NSBundle mainBundle] pathForResource:[_registar lookupKeyForAsset:fileName] ofType:nil];
}
/// 获取flutter端瓦片图路径
- (NSString *)pathForFlutterTileResources:(NSString *)tileName{
if (!_registar) return nil;
// 指定resoures/bmflocaltileimage/目录下存放瓦片图资源
return [[NSBundle mainBundle] pathForResource:[_registar lookupKeyForAsset:[NSString stringWithFormat:@"resoures/bmflocaltileimage/%@", tileName]] ofType:nil];
}
@end

@ -0,0 +1,7 @@
#import <Flutter/Flutter.h>
@interface FlutterBmfmapPlugin : NSObject <FlutterPlugin>
//@property (nonatomic, strong) FlutterMethodChannel *channel;
@end

@ -0,0 +1,30 @@
#import "FlutterBmfmapPlugin.h"
#import <BaiduMapAPI_Base/BMKBaseComponent.h>
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#import "BMFMapViewController.h"
#import "BMFFileManager.h"
#import "BMFOfflineMapManager.h"
static NSString *kBMFMapIdentifier = @"flutter_bmfmap/map/BMKMapView";
@interface FlutterBmfmapPlugin()<BMKGeneralDelegate>
@end
@implementation FlutterBmfmapPlugin
/// 注册
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
// 初始化BMFFileManagerCenter
[BMFFileManager defaultCenter].registar = registrar;
// mapView
[registrar registerViewFactory:[[FlutterMapViewFactory alloc] initWithMessenger:registrar.messenger] withId:kBMFMapIdentifier];
// 离线地图
[BMFOfflineMapManager registerWithRegistrar:registrar];
}
@end

@ -0,0 +1,44 @@
//
// BMFAnnotationHandles.h
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/2/11.
//
#import "BMFMapViewHandle.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMFAnnotationHandles : NSObject
/// BMFAnnotationHandler管理中心
+ (instancetype)defalutCenter;
- (NSDictionary<NSString *, NSString *> *)annotationHandles;
@end
#pragma mark - marker
@interface BMFAddAnnotation : NSObject<BMFMapViewHandler>
@end
@interface BMFAddAnnotations : NSObject<BMFMapViewHandler>
@end
@interface BMFRemoveAnnotation : NSObject<BMFMapViewHandler>
@end
@interface BMFRemoveAnnotations : NSObject<BMFMapViewHandler>
@end
@interface BMFCleanAllAnnotations : NSObject<BMFMapViewHandler>
@end
@interface BMFUpdateAnnotation : NSObject<BMFMapViewHandler>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,280 @@
//
// BMFAnnotationHandles.m
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/2/11.
//
#import "BMFAnnotationHandles.h"
#import "BMFMapView.h"
#import "NSObject+BMFVerify.h"
#import "BMFAnnotationMethodConst.h"
#import "BMFFileManager.h"
#import "UIColor+BMFString.h"
#import "BMFAnnotation.h"
#import "BMFMapModels.h"
@interface BMFAnnotationHandles ()
{
NSDictionary *_handles;
}
@end
@implementation BMFAnnotationHandles
static BMFAnnotationHandles *_instance = nil;
+ (instancetype)defalutCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFAnnotationHandles alloc] init];
});
}
return _instance;
}
- (NSDictionary<NSString *, NSString *> *)annotationHandles{
if (!_handles) {
_handles = @{
kBMFMapAddMarkerMethod: NSStringFromClass([BMFAddAnnotation class]),
kBMFMapAddMarkersMethod: NSStringFromClass([BMFAddAnnotations class]),
kBMFMapRemoveMarkerMethod: NSStringFromClass([BMFRemoveAnnotation class]),
kBMFMapRemoveMarkersMethod: NSStringFromClass([BMFRemoveAnnotations class]),
kBMFMapCleanAllMarkersMethod: NSStringFromClass([BMFCleanAllAnnotations class]),
kBMFMapUpdateMarkerMemberMethod: NSStringFromClass([BMFUpdateAnnotation class])
};
}
return _handles;
}
@end
#pragma mark - marker
@implementation BMFAddAnnotation
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKPointAnnotation *annotation = [BMKPointAnnotation annotationWith:call.arguments];
if (annotation) {
[_mapView addAnnotation:annotation];
result(@YES);
} else {
result(@NO);
}
}
@end
@implementation BMFAddAnnotations
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
NSMutableArray *annotations = @[].mutableCopy;
for (NSDictionary *dic in (NSArray *)call.arguments) {
BMKPointAnnotation *an = [BMKPointAnnotation annotationWith:dic];
[annotations addObject:an];
}
[_mapView addAnnotations:annotations];
result(@YES);
}
@end
@implementation BMFRemoveAnnotation
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || ![call.arguments safeObjectForKey:@"id"]) {
result(@NO);
return;
}
NSString *ID = [call.arguments safeObjectForKey:@"id"];
__weak __typeof__(_mapView) weakMapView = _mapView;
[_mapView.annotations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([ID isEqualToString:((BMKPointAnnotation *) obj).Id]) {
[weakMapView removeAnnotation:obj];
result(@YES);
*stop = YES;
}
}];
}
@end
@implementation BMFRemoveAnnotations
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
__block NSMutableArray <BMKPointAnnotation*> *annotations = @[].mutableCopy;
for (NSDictionary *dic in (NSArray *)call.arguments) {
[_mapView.annotations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([[dic safeObjectForKey:@"id"] isEqualToString:((BMKPointAnnotation *) obj).Id]) {
[annotations addObject:obj];
*stop = YES;
}
}];
}
[_mapView removeAnnotations:annotations];
result(@YES);
}
@end
@implementation BMFCleanAllAnnotations
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
[_mapView removeAnnotations:_mapView.annotations];
result(@YES);
}
@end
@implementation BMFUpdateAnnotation
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || ![call.arguments safeObjectForKey:@"id"]) {
result(@NO);
return;
}
NSString *ID = [call.arguments safeObjectForKey:@"id"];
__block BMKPointAnnotation *annotation;
// __weak __typeof__(_mapView) weakMapView = _mapView;
[_mapView.annotations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([ID isEqualToString:((BMKPointAnnotation *) obj).Id]) {
annotation = (BMKPointAnnotation *) obj;
*stop = YES;
}
}];
if (!annotation) {
NSLog(@"根据ID(%@)未找到对应的marker", ID);
result(@NO);
}
NSString *member = [call.arguments safeObjectForKey:@"member"];
if ([member isEqualToString:@"title"]) {
annotation.title = [call.arguments safeObjectForKey:@"value"];
result(@YES);
return;
} else if ([member isEqualToString:@"subtitle"]) {
annotation.subtitle = [call.arguments safeObjectForKey:@"value"];
result(@YES);
return;
} else if ([member isEqualToString:@"position"]) {
BMFCoordinate *coord = [BMFCoordinate bmf_modelWith:[call.arguments safeObjectForKey:@"value"]];
annotation.coordinate = [coord toCLLocationCoordinate2D];
result(@YES);
return;
} else if ([member isEqualToString:@"isLockedToScreen"]) {
annotation.isLockedToScreen = [[call.arguments safeObjectForKey:@"value"] boolValue];
if (annotation.isLockedToScreen) {
annotation.screenPointToLock = [[BMFMapPoint bmf_modelWith:[call.arguments safeObjectForKey:@"screenPointToLock"]] toCGPoint];
}
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if ([member isEqualToString:@"icon"]) {
BMKPinAnnotationView *view = (BMKPinAnnotationView *)[_mapView viewForAnnotation:annotation];
view.image = [UIImage imageWithContentsOfFile:[[BMFFileManager defaultCenter] pathForFlutterImageName:[call.arguments safeObjectForKey:@"value"]]];
result(@YES);
return;
} else if ([member isEqualToString:@"centerOffset"]) {
BMKPinAnnotationView *view = (BMKPinAnnotationView *)[_mapView viewForAnnotation:annotation];
BMFMapPoint *point = [BMFMapPoint bmf_modelWith:[call.arguments safeObjectForKey:@"value"]];
view.centerOffset = [point toCGPoint];
result(@YES);
return;
} else if ([member isEqualToString:@"enabled3D"]) {
BMKPinAnnotationView *view = (BMKPinAnnotationView *)[_mapView viewForAnnotation:annotation];
BOOL value = [[call.arguments safeObjectForKey:@"value"] boolValue];
view.enabled3D = value;
result(@YES);
return;
} else if ([member isEqualToString:@"enabled"]) {
BMKPinAnnotationView *view = (BMKPinAnnotationView *)[_mapView viewForAnnotation:annotation];
BOOL value = [[call.arguments safeObjectForKey:@"value"] boolValue];
view.enabled = value;
result(@YES);
return;
} else if ([member isEqualToString:@"draggable"]) {
BMKPinAnnotationView *view = (BMKPinAnnotationView *)[_mapView viewForAnnotation:annotation];
BOOL value = [[call.arguments safeObjectForKey:@"value"] boolValue];
view.draggable = value;
result(@YES);
return;
} else if ([member isEqualToString:@"zIndex"]) {
NSLog(@"ios - 暂不支持设置zIndex");
result(@YES);
return;
} else if ([member isEqualToString:@"visible"]) {
NSLog(@"ios - 暂不支持设置visible");
result(@YES);
return;
} else {
result(@YES);
}
}
@end

@ -0,0 +1,32 @@
//
// BMFHeatMapHandles.h
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/4/3.
//
#import "BMFMapViewHandle.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMFHeatMapHandles : NSObject
/// BMFHeatMapHandles管理中心
+ (instancetype)defalutCenter;
- (NSDictionary<NSString *, NSString *> *)heatMapHandles;
@end
#pragma mark - heatMap
@interface BMFShowHeatMap : NSObject<BMFMapViewHandler>
@end
@interface BMFAddHeatMap : NSObject<BMFMapViewHandler>
@end
@interface BMFRemoveHeatMap : NSObject<BMFMapViewHandler>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,100 @@
//
// BMFHeatMapHandles.m
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/4/3.
//
#import "BMFHeatMapHandles.h"
#import "BMFMapView.h"
#import "BMFHeatMapConst.h"
#import "NSObject+BMFVerify.h"
#import "BMFHeatMapModel.h"
@interface BMFHeatMapHandles ()
{
NSDictionary *_handles;
}
@end
@implementation BMFHeatMapHandles
static BMFHeatMapHandles *_instance = nil;
+ (instancetype)defalutCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFHeatMapHandles alloc] init];
});
}
return _instance;
}
- (NSDictionary<NSString *, NSString *> *)heatMapHandles{
if (!_handles) {
_handles = @{
kBMFMapShowHeatMapMethod: NSStringFromClass([BMFShowHeatMap class]),
kBMFMapAddHeatMapMethod: NSStringFromClass([BMFAddHeatMap class]),
kBMFMapRemoveHeatMapMethod: NSStringFromClass([BMFRemoveHeatMap class]),
};
}
return _handles;
}
@end
#pragma mark - heatMap
@implementation BMFShowHeatMap
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"show"]) {
result(@NO);
return;
}
_mapView.baiduHeatMapEnabled = [[call.arguments safeValueForKey:@"show"] boolValue];
result(@YES);
}
@end
@implementation BMFAddHeatMap
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"heatMap"]) {
result(@NO);
return;
}
BMFHeatMapModel *heatMap = [BMFHeatMapModel bmf_modelWith:[call.arguments safeObjectForKey:@"heatMap"]];
[_mapView addHeatMap:[heatMap toBMKHeatMap]];
result(@YES);
}
@end
@implementation BMFRemoveHeatMap
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
[_mapView removeHeatMap];
result(@YES);
}
@end

@ -0,0 +1,27 @@
//
// BMFMapView.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/10.
//
#ifndef __BMFMapView__H__
#define __BMFMapView__H__
#ifdef __OBJC__
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#endif
#endif
NS_ASSUME_NONNULL_BEGIN
@interface BMFMapView : BMKMapView
+ (instancetype)viewWithFrame:(CGRect)frame;
+ (instancetype)viewWithFrame:(CGRect)frame dic:(NSDictionary *)dic;
/// 更新地图属性(初始化时,部分参数会不生效),在地图加载完成时调用
- (BOOL)updateMapOptions;
- (BOOL)updateMapViewWith:(NSDictionary *)dic;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,205 @@
//
// BMFMapView.m
// flutter_bmfmap
//
// Created by zbj on 2020/2/10.
//
#import "BMFMapView.h"
#import "BMFMapModels.h"
#import "BMFEdgeInsets.h"
@interface BMFMapView ()
/// map属性集合
@property (nonatomic, strong) NSDictionary *mapViewOptions;
@end
@implementation BMFMapView
+ (instancetype)viewWithFrame:(CGRect)frame {
return [[BMFMapView alloc] initWithFrame:frame];
}
+ (instancetype)viewWithFrame:(CGRect)frame dic:(NSDictionary *)dic{
BMFMapView *map = [[BMFMapView alloc] initWithFrame:frame];
map.mapViewOptions = dic;
[map updateMapViewWith:dic];
return map;
}
// 此方法解决初始时设置的属性不生效问题
- (BOOL)updateMapOptions {
if (_mapViewOptions) {
// logo位置 默认BMKLogoPositionLeftBottom
if ([_mapViewOptions[@"logoPosition"] isValidParam]) {
self.logoPosition = [_mapViewOptions[@"logoPosition"] intValue];
}
// 指南针的位置,设定坐标以BMKMapView左上角为原点,向右向下增长
if ([_mapViewOptions[@"compassPosition"] isValidParam]) {
BMFMapPoint *point = [BMFMapPoint bmf_modelWith:_mapViewOptions[@"compassPosition"]];
self.compassPosition = [point toCGPoint];
}
// 设定地图是否打开百度城市热力图图层(百度自有数据)
if ([_mapViewOptions[@"baiduHeatMapEnabled"] isValidParam]) {
self.baiduHeatMapEnabled = [_mapViewOptions[@"baiduHeatMapEnabled"] boolValue];
}
// 设定是否显式比例尺
if ([_mapViewOptions[@"showMapScaleBar"] isValidParam]) {
self.showMapScaleBar = [_mapViewOptions[@"showMapScaleBar"] boolValue];
}
// 比例尺的位置,设定坐标以BMKMapView左上角为原点,向右向下增长
if ([_mapViewOptions[@"mapScaleBarPosition"] isValidParam]) {
self.mapScaleBarPosition = [[BMFMapPoint bmf_modelWith:_mapViewOptions[@"mapScaleBarPosition"]] toCGPoint];
}
return YES;
}
return NO;
}
- (BOOL)updateMapViewWith:(NSDictionary *)dic {
BOOL result = NO;
if (dic) {
// 当前地图类型,可设定为标准地图、卫星地图
if ([dic[@"mapType"] isValidParam]) {
self.mapType = [dic[@"mapType"] intValue];
}
// 限制地图的显示范围(地图状态改变时,该范围不会在地图显示范围外。设置成功后,会调整地图显示该范围)
if ([dic[@"limitMapBounds"] isValidParam]) {
BMFCoordinateBounds *limitMapBounds = [BMFCoordinateBounds bmf_modelWith:dic[@"limitMapBounds"]];
self.limitMapRegion = [limitMapBounds toCoordinateRegion];
}
// logo位置 默认BMKLogoPositionLeftBottom
if ([_mapViewOptions[@"logoPosition"] isValidParam]) {
self.logoPosition = [dic[@"logoPosition"] intValue];
}
// 指南针的位置,设定坐标以BMKMapView左上角为原点,向右向下增长
if ([dic[@"compassPosition"] isValidParam]) {
BMFMapPoint *point = [BMFMapPoint bmf_modelWith:dic[@"compassPosition"]];
self.compassPosition = [point toCGPoint];
}
// 当前地图的中心点,改变该值时,地图的比例尺级别不会发生变化
if ([dic[@"center"] isValidParam]) {
BMFCoordinate *coord = [BMFCoordinate bmf_modelWith:dic[@"center"]];
[self setCenterCoordinate:[coord toCLLocationCoordinate2D]];
}
// 地图比例尺级别,在手机上当前可使用的级别为4-21
if ([dic[@"zoomLevel"] isValidParam]) {
self.zoomLevel = [dic[@"zoomLevel"] intValue];
}
// 地图的自定义最大比例尺级别
if ([dic[@"minZoomLevel"] isValidParam]) {
self.minZoomLevel = [dic[@"minZoomLevel"] intValue];
}
// 地图的自定义最大比例尺级别
if ([dic[@"maxZoomLevel"] isValidParam]) {
self.maxZoomLevel = [dic[@"maxZoomLevel"] intValue];
}
// 地图旋转角度,在手机上当前可使用的范围为-180180
if ([dic[@"rotation"] isValidParam]) {
self.rotation = [dic[@"rotation"] intValue];
}
// 地图俯视角度,在手机上当前可使用的范围为-450
if ([dic[@"overlooking"] isValidParam]) {
self.overlooking = [dic[@"overlooking"] intValue];
}
// 地图俯视角度最小值(即角度最大值),在手机上当前可设置的范围为-790
if ([dic[@"minOverlooking"] isValidParam]) {
self.minOverlooking = [dic[@"minOverlooking"] intValue];
}
// 设定地图是否现显示3D楼块效果
if ([dic[@"buildingsEnabled"] isValidParam]) {
self.buildingsEnabled = [dic[@"buildingsEnabled"] boolValue];
[self setMapStatus:[self getMapStatus]];
}
// 设定地图是否显示底图poi标注(不包含室内图标注),默认YES
if ([dic[@"showMapPoi"] isValidParam]) {
self.showMapPoi = [dic[@"showMapPoi"] boolValue];
}
// 设定地图是否打开路况图层
if ([dic[@"trafficEnabled"] isValidParam]) {
self.trafficEnabled = [dic[@"trafficEnabled"] boolValue];
}
// 设定地图是否打开百度城市热力图图层(百度自有数据)
if ([dic[@"baiduHeatMapEnabled"] isValidParam]) {
self.baiduHeatMapEnabled = [dic[@"baiduHeatMapEnabled"] boolValue];
}
// 设定地图View能否支持所有手势操作
if ([dic[@"gesturesEnabled"] isValidParam]) {
self.gesturesEnabled = [dic[@"gesturesEnabled"] boolValue];
}
// 设定地图View能否支持用户多点缩放(双指)
if ([dic[@"zoomEnabled"] isValidParam]) {
self.zoomEnabled = [dic[@"zoomEnabled"] boolValue];
}
// 设定地图View能否支持用户缩放(双击或双指单击)
if ([dic[@"zoomEnabledWithTap"] isValidParam]) {
self.zoomEnabledWithTap = [dic[@"zoomEnabledWithTap"] boolValue];
}
// 设定地图View能否支持用户移动地图
if ([dic[@"scrollEnabled"] isValidParam]) {
self.scrollEnabled = [dic[@"scrollEnabled"] boolValue];
}
// 设定地图View能否支持俯仰角
if ([dic[@"overlookEnabled"] isValidParam]) {
self.overlookEnabled = [dic[@"overlookEnabled"] boolValue];
}
// 设定地图View能否支持旋转
if ([dic[@"rotateEnabled"] isValidParam]) {
self.rotateEnabled = [dic[@"rotateEnabled"] boolValue];
}
// 设定地图是否回调force touch事件,默认为NO,仅适用于支持3D Touch的情况,
// 开启后会回调 - mapview:onForceTouch:force:maximumPossibleForce:
if ([dic[@"forceTouchEnabled"] isValidParam]) {
self.forceTouchEnabled = [dic[@"forceTouchEnabled"] boolValue];
}
// 设定是否显式比例尺
if ([dic[@"showMapScaleBar"] isValidParam]) {
self.showMapScaleBar = [dic[@"showMapScaleBar"] boolValue];
}
// 比例尺的位置,设定坐标以BMKMapView左上角为原点,向右向下增长
if ([dic[@"mapScaleBarPosition"] isValidParam]) {
self.mapScaleBarPosition = [[BMFMapPoint bmf_modelWith:dic[@"mapScaleBarPosition"]] toCGPoint];
}
// 当前地图范围,采用直角坐标系表示,向右向下增长
if ([dic[@"visibleMapBounds"] isValidParam]) {
BMFCoordinateBounds *visibleMapBounds = [BMFCoordinateBounds bmf_modelWith:dic[@"visibleMapBounds"]];
[self setVisibleMapRect:[visibleMapBounds toBMKMapRect] animated:YES];
}
// 地图预留边界
if ([dic[@"mapPadding"] isValidParam]) {
BMFEdgeInsets *edge = [BMFEdgeInsets bmf_modelWith:dic[@"mapPadding"]];
self.mapPadding = [edge toUIEdgeInsets];
}
// 设置mapPadding时,地图中心(屏幕坐标:BMKMapStatus.targetScreenPt)是否跟着改变,默认YES
if ([dic[@"updateTargetScreenPtWhenMapPaddingChanged"] isValidParam]) {
self.updateTargetScreenPtWhenMapPaddingChanged = [dic[@"updateTargetScreenPtWhenMapPaddingChanged"] boolValue];
}
// 设定双指手势操作时,BMKMapView的旋转和缩放效果的中心点。
// 设置为YES时,以手势的中心点(二个指头的中心点)为中心进行旋转和缩放,地图中心点会改变;
// 设置为NO时,以当前地图的中心点为中心进行旋转和缩放,地图中心点不变;
// 默认值为NO
if ([dic[@"changeWithTouchPointCenterEnabled"] isValidParam]) {
self.ChangeWithTouchPointCenterEnabled = [dic[@"changeWithTouchPointCenterEnabled"] boolValue];
}
// 设定双击手势放大地图时,BMKMapView的放大效果的中心点。
// 设置为YES时,以双击的位置为中心点进行放大,地图中心点会改变;
// 设置为NO时,以当前地图的中心点为中心进行放大,地图中心点不变;
// 默认值为YES
if ([dic[@"changeCenterWithDoubleTouchPointEnabled"] isValidParam]) {
self.ChangeCenterWithDoubleTouchPointEnabled = [dic[@"changeCenterWithDoubleTouchPointEnabled"] boolValue];
}
// 设定地图是否显示室内图
if ([dic[@"baseIndoorMapEnabled"] isValidParam]) {
self.baseIndoorMapEnabled = [dic[@"baseIndoorMapEnabled"] boolValue];
}
// 设定室内图标注是否显示,默认YES,仅当显示室内图(baseIndoorMapEnabledYES)时生效
if ([dic[@"showIndoorMapPoi"] isValidParam] && self.baseIndoorMapEnabled) {
self.showIndoorMapPoi = [dic[@"showIndoorMapPoi"] boolValue];
}
result = YES;
}
return result;
}
- (void)dealloc {
_mapViewOptions = nil;
// NSLog(@"-mapView-dealloc");
}
@end

@ -0,0 +1,27 @@
//
// BMFMapViewController.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/6.
//
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface BMFMapViewController : NSObject<FlutterPlatformView>
- (instancetype)initWithWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
@end
@interface FlutterMapViewFactory : NSObject<FlutterPlatformViewFactory>
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messager;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,506 @@
//
// BMFMapViewController.m
// flutter_bmfmap
//
// Created by zbj on 2020/2/6.
//
#import "BMFMapViewController.h"
#import "BMFMapView.h"
#import "BMFMapCallBackConst.h"
#import "BMFMapViewHandles.h"
#import "BMFAnnotationHandles.h"
#import "BMFOverlayHandles.h"
#import "BMFHeatMapHandles.h"
#import "BMFUserLocationHandles.h"
#import "BMFProjectionHandles.h"
#import "BMFMapModels.h"
#import "BMFMapStatusModel.h"
#import "BMFMapPoiModel.h"
#import "BMFIndoorMapInfoModel.h"
#import "BMFAnnotation.h"
#import "BMFFileManager.h"
#import "BMFPolyline.h"
#import "BMFArcline.h"
#import "BMFCircle.h"
#import "BMFPolygon.h"
#import "UIColor+BMFString.h"
static NSString *kBMFMapChannelName = @"flutter_bmfmap/map_";
static NSString *kMapMethods = @"flutter_bmfmap/map/";
static NSString *kMarkerMethods = @"flutter_bmfmap/marker/";
static NSString *kOverlayMethods = @"flutter_bmfmap/overlay/";
static NSString *kHeatMapMethods = @"flutter_bmfmap/heatMap/";
static NSString *kUserLocationMethods = @"flutter_bmfmap/userLocation/";
static NSString *kProjectionMethods = @"flutter_bmfmap/projection/";
@interface BMFMapViewController()<BMKMapViewDelegate>
{
FlutterMethodChannel *_channel;
BMFMapView *_mapView;
}
@end
@implementation BMFMapViewController
- (instancetype)initWithWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger{
if ([super init]) {
int Id = (int)(viewId + 97);
NSString *channelName = [NSString stringWithFormat:@"%@%@", kBMFMapChannelName, [NSString stringWithFormat:@"%c", Id]];
_channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
_mapView = [BMFMapView viewWithFrame:frame dic:(NSDictionary*)args];
_mapView.delegate = self;
#pragma mark - flutter -> ios
__weak __typeof__(_mapView) weakMapView = _mapView;
[_channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
NSObject<BMFMapViewHandler> *handler;
// map
if ([call.method hasPrefix:kMapMethods]) {
handler = [NSClassFromString([BMFMapViewHandles defalutCenter].mapViewHandles[call.method]) new];
}
// marker
if ([call.method hasPrefix:kMarkerMethods]) {
handler = [NSClassFromString([BMFAnnotationHandles defalutCenter].annotationHandles[call.method]) new];
}
// overlay
if ([call.method hasPrefix:kOverlayMethods]) {
handler = [NSClassFromString([BMFOverlayHandles defalutCenter].overlayHandles[call.method]) new];
}
// 热力图
if ([call.method hasPrefix:kHeatMapMethods]) {
handler = [NSClassFromString([BMFHeatMapHandles defalutCenter].heatMapHandles[call.method]) new];
}
// 定位图层
if ([call.method hasPrefix:kUserLocationMethods]) {
handler = [NSClassFromString([BMFUserLocationHandles defalutCenter].userLocationHandles[call.method]) new];
}
// 数据转换
if ([call.method hasPrefix:kProjectionMethods]) {
handler = [NSClassFromString([BMFProjectionHandles defalutCenter].projectionHandles[call.method]) new];
}
if (handler) {
[[handler initWith:weakMapView] handleMethodCall:call result:result];
} else {
if ([call.method isEqualToString:@"flutter_bmfmap/map/didUpdateWidget"]) {
// NSLog(@"native - didUpdateWidget");
return;
}
if ([call.method isEqualToString:@"flutter_bmfmap/map/reassemble"]) {
// NSLog(@"native - reassemble");
return;
}
result(FlutterMethodNotImplemented);
}
}];
}
return self;
}
- (nonnull UIView *)view {
return _mapView;
}
- (void)dealloc {
_channel = nil;
_mapView.delegate = nil;
_mapView = nil;
// NSLog(@"-BMFMapViewController-dealloc");
}
#pragma mark - ios -> flutter
#pragma mark - BMKMapViewDelegate
/// 地图加载完成
- (void)mapViewDidFinishLoading:(BMKMapView *)mapView{
if (_mapView) {
// 对初始时不生效的属性,在此再调用一次.暂时这么解决
[_mapView updateMapOptions];
}
if (!_channel) return;
[_channel invokeMethod:kBMFMapDidLoadCallback arguments:@{@"success": @YES} result:nil];
}
/// 地图渲染完成
- (void)mapViewDidFinishRendering:(BMKMapView *)mapView{
if (!_channel) return;
[_channel invokeMethod:kBMFMapDidRenderCallback arguments:@{@"success": @YES} result:nil];
}
/// 地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口
- (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus*)status{
if (!_channel) return;
BMFMapStatusModel *mapStatus = [BMFMapStatusModel fromMapStatus:status];
[_channel invokeMethod:kBMFMapOnDrawMapFrameCallback
arguments:@{@"mapStatus": [mapStatus bmf_toDictionary]}
result:nil];
}
/// 地图区域即将改变时会调用此接口
- (void)mapView:(BMKMapView *)mapView regionWillChangeAnimated:(BOOL)animated{
if (!_channel) return;
BMFMapStatusModel *mapStatus = [BMFMapStatusModel fromMapStatus:[_mapView getMapStatus]];
[_channel invokeMethod:kBMFMapRegionWillChangeCallback
arguments:@{@"mapStatus": [mapStatus bmf_toDictionary]}
result:nil];
}
/// 地图区域即将改变时会调用此接口
- (void)mapView:(BMKMapView *)mapView regionWillChangeAnimated:(BOOL)animated reason:(BMKRegionChangeReason)reason{
if (!_channel) return;
BMFMapStatusModel *mapStatus = [BMFMapStatusModel fromMapStatus:[_mapView getMapStatus]];
[_channel invokeMethod:kBMFMapRegionWillChangeWithReasonCallback
arguments:@{@"mapStatus": [mapStatus bmf_toDictionary], @"reason": @(reason)}
result:nil];
}
/// 地图区域改变完成后会调用此接口
- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
if (!_channel) return;
BMFMapStatusModel *mapStatus = [BMFMapStatusModel fromMapStatus:[_mapView getMapStatus]];
[_channel invokeMethod:kBMFMapRegionDidChangeCallback
arguments:@{@"mapStatus": [mapStatus bmf_toDictionary]}
result:nil];
}
/// 地图区域改变完成后会调用此接口
- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated reason:(BMKRegionChangeReason)reason{
if (!_channel) return;
BMFMapStatusModel *mapStatus = [BMFMapStatusModel fromMapStatus:[_mapView getMapStatus]];
[_channel invokeMethod:kBMFMapRegionDidChangeWithReasonCallback
arguments:@{@"mapStatus": [mapStatus bmf_toDictionary], @"reason": @(reason)}
result:nil];
}
/// 点中底图标注后会回调此接口
- (void)mapView:(BMKMapView *)mapView onClickedMapPoi:(BMKMapPoi *)mapPoi{
if (!_channel) return;
BMFMapPoiModel *model = [BMFMapPoiModel fromBMKMapPoi:mapPoi];
[_channel invokeMethod:kBMFMapOnClickedMapPoiCallback arguments:@{@"poi": [model bmf_toDictionary]} result:nil];
}
/// 点中底图空白处会回调此接口
- (void)mapView:(BMKMapView *)mapView onClickedMapBlank:(CLLocationCoordinate2D)coordinate{
if (!_channel) return;
BMFCoordinate *coord = [BMFCoordinate fromCLLocationCoordinate2D:coordinate];
[_channel invokeMethod:kBMFMapOnClickedMapBlankCallback arguments:@{@"coord": [coord bmf_toDictionary]} result:nil];
}
/// 双击地图时会回调此接口
- (void)mapview:(BMKMapView *)mapView onDoubleClick:(CLLocationCoordinate2D)coordinate{
if (!_channel) return;
BMFCoordinate *coord = [BMFCoordinate fromCLLocationCoordinate2D:coordinate];
[_channel invokeMethod:kBMFMapOnDoubleClickCallback arguments:@{@"coord": [coord bmf_toDictionary]} result:nil];
}
/// 长按地图时会回调此接口
- (void)mapview:(BMKMapView *)mapView onLongClick:(CLLocationCoordinate2D)coordinate{
if (!_channel) return;
BMFCoordinate *coord = [BMFCoordinate fromCLLocationCoordinate2D:coordinate];
[_channel invokeMethod:kBMFMapOnLongClickCallback arguments:@{@"coord": [coord bmf_toDictionary]} result:nil];
}
/// 3DTouch 按地图时会回调此接口(仅在支持3D Touch,且fouchTouchEnabled属性为YES时,会回调此接口)
/// force 触摸该点的力度(参考UITouchforce属性)
/// maximumPossibleForce 当前输入机制下的最大可能力度(参考UITouchmaximumPossibleForce属性)
- (void)mapview:(BMKMapView *)mapView onForceTouch:(CLLocationCoordinate2D)coordinate force:(CGFloat)force maximumPossibleForce:(CGFloat)maximumPossibleForce{
if (!_channel) return;
BMFCoordinate *coord = [BMFCoordinate fromCLLocationCoordinate2D:coordinate];
[_channel invokeMethod:kBMFMapOnForceTouchCallback arguments:@{@"coord": [coord bmf_toDictionary], @"force": @(force), @"maximumPossibleForce": @(maximumPossibleForce)} result:nil];
}
///地图状态改变完成后会调用此接口
- (void)mapStatusDidChanged:(BMKMapView *)mapView{
if (!_channel) return;
[_channel invokeMethod:kBMFMapStatusDidChangedCallback arguments:nil result:nil];
}
- (void)mapview:(BMKMapView *)mapView baseIndoorMapWithIn:(BOOL)flag baseIndoorMapInfo:(BMKBaseIndoorMapInfo *)info{
if (!_channel) return;
BMFIndoorMapInfoModel *model = [BMFIndoorMapInfoModel new];
model.strID = info.strID;
model.strFloor = info.strFloor;
model.listStrFloors = info.arrStrFloors;
[_channel invokeMethod:kBMFMapInOrOutBaseIndoorMapCallback arguments:@{@"flag": @(flag), @"info": [model bmf_toDictionary]} result:nil];
}
#pragma mark - annotationView
- (BMFAnnotationModel *)annotationModelfromAnnotionView:(BMKAnnotationView *)view{
BMFAnnotationModel *model = [BMFAnnotationModel new];
BMKPointAnnotation *an = (BMKPointAnnotation *)view.annotation;
model.Id = an.Id;
model.title = an.title;
model.subtitle = an.subtitle;
model.position = [BMFCoordinate fromCLLocationCoordinate2D:an.coordinate];
model.isLockedToScreen = an.isLockedToScreen;
model.screenPointToLock = [BMFMapPoint fromCGPoint:an.screenPointToLock];
model.annotationViewOptions = an.annotationViewOptions;
return model;
}
/// 根据anntation生成对应的View
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation{
if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
BMFAnnotationViewOptions *options =((BMKPointAnnotation *)annotation).annotationViewOptions;
NSString *identifier = options.identifier ? options.identifier : NSStringFromClass([BMKPointAnnotation class]);
BMKPinAnnotationView *annotationView = (BMKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView) {
annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
}
if (options.icon) {
//TODO:image加入空值判断
if ([[options.icon substringToIndex:1] isEqualToString:@"/"]) {
annotationView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:options.icon] scale:[[UIScreen mainScreen] scale]];
} else {
annotationView.image = [UIImage imageWithContentsOfFile:[[BMFFileManager defaultCenter] pathForFlutterImageName:options.icon]];
}
}
if (options.centerOffset) {
annotationView.centerOffset = [options.centerOffset toCGPoint];
}
annotationView.selected = options.selected;
annotationView.draggable = options.draggable;
annotationView.enabled = options.enabled;
annotationView.enabled3D = options.enabled3D;
return annotationView;
}
return nil;
}
///mapView新添加annotation views时,调用此接口
- (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
if (!_channel) return;
}
/// 每次点击BMKAnnotationView都会回调此接口。
- (void)mapView:(BMKMapView *)mapView clickAnnotationView:(BMKAnnotationView *)view{
if (!_channel) return;
if ([view isKindOfClass:NSClassFromString(@"BMKUserLocationView")]) {
return;
}
// 改为回调id
BMFAnnotationModel *model = [self annotationModelfromAnnotionView:view];
[_channel invokeMethod:kBMFMapClickedMarkerCallback arguments:@{@"id": model.Id} result:^(id _Nullable result) {
}];
}
/// 当选中一个annotation views时,调用此接口
/// @param mapView 地图View
/// @param view 选中的annotation views
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view{
if (!_channel) return;
if ([view isKindOfClass:NSClassFromString(@"BMKUserLocationView")]) {
return;
}
// 改为回调id
BMFAnnotationModel *model = [self annotationModelfromAnnotionView:view];
[_channel invokeMethod:kBMFMapDidSelectMarkerCallback arguments:@{@"id": model.Id} result:nil];
}
/// 当取消选中一个annotationView时,调用此接口
- (void)mapView:(BMKMapView *)mapView didDeselectAnnotationView:(BMKAnnotationView *)view{
if (!_channel) return;
// 改为回调id
BMFAnnotationModel *model = [self annotationModelfromAnnotionView:view];
[_channel invokeMethod:kBMFMapDidDeselectMarkerCallback arguments:@{@"id": model.Id} result:nil];
}
/// 拖动annotation view时,若view的状态发生变化,会调用此函数。ios3.2以后支持
- (void)mapView:(BMKMapView *)mapView annotationView:(BMKAnnotationView *)view didChangeDragState:(BMKAnnotationViewDragState)newState
fromOldState:(BMKAnnotationViewDragState)oldState{
if (!_channel) return;
// 改为回调id
BMFAnnotationModel *model = [self annotationModelfromAnnotionView:view];
[_channel invokeMethod:kBMFMapDidDragMarkerCallback arguments:@{@"id": model.Id} result:nil];
}
/// 当点击annotationView的泡泡view时,调用此接口
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view{
if (!_channel) return;
// 改为回调id
BMFAnnotationModel *model = [self annotationModelfromAnnotionView:view];
[_channel invokeMethod:kBMFMapDidClickedPaoPaoCallback arguments:@{@"id": model.Id} result:nil];
}
#pragma mark - overlayView
- (BMFPolylineModel *)polylineModelWith:(BMKPolylineView *)view{
BMFPolylineModel *model = [BMFPolylineModel new];
BMKPolyline *line = view.polyline;
model = line.polylineModel;
return model;
}
- (BMKPolylineView *)viewForPolyline:(BMKPolyline *)polyline{
BMFPolylineViewOptions *options = polyline.polylineModel.polylineOptions;
BMKPolylineView *polylineView = [[BMKPolylineView alloc] initWithPolyline:polyline];
polylineView.lineWidth = options.width;
polylineView.lineDashType = options.lineDashType;
polylineView.lineCapType = options.lineCapType;
polylineView.lineJoinType = options.lineJoinType;
switch (polyline.lineType) {
case kBMFDashLine:
case kBMFColorLine:{
if ([options.colors firstObject]) {
polylineView.strokeColor = [UIColor fromColorString:[options.colors firstObject]];
} else {
// TODO:strokeColor 默认值
}
break;
}
case kBMFMultiDashLine:
case kBMFColorsLine:{
size_t colorsCount = options.colors.count;
NSMutableArray<UIColor *> *colors = [NSMutableArray array];
for (size_t i = 0; i < colorsCount; i++) {
// TODO:colors加入空值判断
[colors addObject:[UIColor fromColorString:options.colors[i]]];
}
polylineView.colors = colors;
break;
}
case kBMFTextureLine:{
// TODO:iamge加入空值判断
NSString *imagePath = [[BMFFileManager defaultCenter] pathForFlutterImageName:[options.textures firstObject]];
[polylineView loadStrokeTextureImage:[UIImage imageWithContentsOfFile:imagePath]];
break;
}
case kBMFTexturesLine:{
NSMutableArray<UIImage *> *images = [NSMutableArray array];
size_t imagesCount = options.textures.count;
NSString *imagePath = nil;
for (size_t i = 0; i < imagesCount; i++) {
//TODO:image加入空值判断
imagePath = options.textures[i];
UIImage *image = [UIImage imageWithContentsOfFile:[[BMFFileManager defaultCenter] pathForFlutterImageName:imagePath]];
[images addObject:image];
}
[polylineView loadStrokeTextureImages:images];
break;
}
default:
break;
}
return polylineView;
}
- (BMKArclineView *)viewForArcline:(BMKArcline *)arcline{
BMFArclineViewOptions *options = arcline.arclineViewOptions;
BMKArclineView *arclineView = [[BMKArclineView alloc] initWithArcline:arcline];
if (options.color) {
arclineView.strokeColor = [UIColor fromColorString:options.color];
} else {
arclineView.strokeColor = [UIColor colorWithRed:0.f green:0.f blue:1.f alpha:1.f];
}
arclineView.lineWidth = options.width;
arclineView.lineDashType = options.lineDashType;
return arclineView;
}
- (BMKPolygonView *)viewForPolygon:(BMKPolygon *)polygon{
BMFPolygonViewOptions *options = polygon.polygonViewOptions;
BMKPolygonView *polygonView = [[BMKPolygonView alloc] initWithPolygon:polygon];
if (options.strokeColor) {
polygonView.strokeColor = [UIColor fromColorString:options.strokeColor];
} else {
polygonView.strokeColor = [UIColor colorWithRed:0.f green:0.f blue:1.f alpha:1.f];
}
if (options.fillColor) {
polygonView.fillColor = [UIColor fromColorString:options.fillColor];
}
polygonView.lineWidth = options.width;
polygonView.lineDashType = options.lineDashType;
return polygonView;
}
- (BMKCircleView *)viewForCircleline:(BMKCircle *)circle{
BMFCircleViewOptions *options = circle.circleViewOptions;
BMKCircleView *circleView = [[BMKCircleView alloc] initWithCircle:circle];
if (options.strokeColor) {
circleView.strokeColor = [UIColor fromColorString:options.strokeColor];
} else {
circleView.strokeColor = [UIColor colorWithRed:0.f green:0.f blue:1.f alpha:1.f];
}
if (options.fillColor) {
circleView.fillColor = [UIColor fromColorString:options.fillColor];
}
circleView.lineWidth = options.width;
circleView.lineDashType = options.lineDashType;
return circleView;
}
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay{
if ([overlay isKindOfClass:[BMKPolyline class]]) {
return [self viewForPolyline:(BMKPolyline *)overlay];
} else if ([overlay isKindOfClass:[BMKArcline class]]) {
return [self viewForArcline:(BMKArcline *)overlay];
} else if ([overlay isKindOfClass:[BMKPolygon class]]){
return [self viewForPolygon:(BMKPolygon *)overlay];
} else if ([overlay isKindOfClass:[BMKCircle class]]) {
return [self viewForCircleline:(BMKCircle *)overlay];
} else if ([overlay isKindOfClass:[BMKTileLayer class]]){
return [[BMKTileLayerView alloc] initWithTileLayer:overlay];
} else if ([overlay isKindOfClass:[BMKGroundOverlay class]]) {
return [[BMKGroundOverlayView alloc] initWithGroundOverlay:overlay];
}
return nil;
}
/**
*mapView新添加overlay views时,调用此接口
*@param mapView 地图View
*@param overlayViews 新添加的overlay views
*/
- (void)mapView:(BMKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews{
if (!_channel) return;
//TODO:didAddOverlayViews
}
/**
*点中覆盖物后会回调此接口,目前只支持点中BMKPolylineView时回调
*@param mapView 地图View
*@param overlayView 覆盖物view信息
*/
-(void)mapView:(BMKMapView *)mapView onClickedBMKOverlayView:(BMKOverlayView *)overlayView{
if (!_channel) return;
if ([overlayView isKindOfClass:[BMKPolylineView class]]) {
BMFPolylineModel *model = [self polylineModelWith:(BMKPolylineView *)overlayView];
// NSLog(@"%@", [model bmf_toDictionary]);
// 暂时只传id
[_channel invokeMethod:kMapOnClickedOverlayCallback arguments:@{@"polyline": @{@"id" :model.Id}} result:nil];
}
}
@end
@interface FlutterMapViewFactory()
{
NSObject<FlutterBinaryMessenger> *_messenger;
}
@end
@implementation FlutterMapViewFactory
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger> *)messager{
if ([super init]) {
_messenger = messager;
}
return self;
}
- (NSObject<FlutterMessageCodec> *)createArgsCodec{
return [FlutterStandardMessageCodec sharedInstance];
}
- (NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{
BMFMapViewController *mapViewController = [[BMFMapViewController alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
return mapViewController;
}
@end

@ -0,0 +1,29 @@
//
// BMFMapViewHandle.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/11.
//
#import <Flutter/Flutter.h>
@class BMFMapView;
NS_ASSUME_NONNULL_BEGIN
@protocol BMFMapViewHandler <NSObject>
@required
/// mapView (弱引用)
@property(nonatomic, weak) BMFMapView *_mapView;
/// 创建协议实例
- (NSObject <BMFMapViewHandler> *)initWith:(BMFMapView *)mapView;
/// flutter --> ios
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,197 @@
//
// BMFMapViewHandles.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/11.
//
#import "BMFMapViewHandle.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMFMapViewHandles : NSObject
/// BMFMapViewHandler管理中心
+ (instancetype)defalutCenter;
- (NSDictionary<NSString *, NSString *> *)mapViewHandles;
@end
#pragma mark - map
@interface BMFUpdateMap : NSObject<BMFMapViewHandler>
@end
@interface BMFShowBaseIndoorMap : NSObject<BMFMapViewHandler>
@end
@interface BMFShowBaseIndoorMapPoi : NSObject<BMFMapViewHandler>
@end
@interface BMFSwitchBaseIndoorMapFloor : NSObject<BMFMapViewHandler>
@end
@interface BMFGetFocusedBaseIndoorMapInfo : NSObject<BMFMapViewHandler>
@end
@interface BMFSetCustomMapStyleEnable : NSObject<BMFMapViewHandler>
@end
@interface BMFSetCustomMapStylePath : NSObject<BMFMapViewHandler>
@end
@interface BMFSetCustomMapStyleWithOption : NSObject<BMFMapViewHandler>
@end
@interface BMFZoomIn : NSObject<BMFMapViewHandler>
@end
@interface BMFZoomOut : NSObject<BMFMapViewHandler>
@end
@interface BMFSetCustomTrafficColor : NSObject<BMFMapViewHandler>
@end
@interface BMFSetCenterCoordinate : NSObject<BMFMapViewHandler>
@end
@interface BMFTakeSnapshot : NSObject<BMFMapViewHandler>
@end
@interface BMFTakeSnapshotWithRect : NSObject<BMFMapViewHandler>
@end
@interface BMFSetCompassImage : NSObject<BMFMapViewHandler>
@end
@interface BMFSetVisibleMapBounds : NSObject<BMFMapViewHandler>
@end
@interface BMFSetVisibleMapBoundsWithPadding : NSObject<BMFMapViewHandler>
@end
@interface BMFSetMapStatus : NSObject<BMFMapViewHandler>
@end
#pragma mark - Get
@interface BMFGetMapStatus : NSObject<BMFMapViewHandler>
@end
@interface BMFGetMapType : NSObject<BMFMapViewHandler>
@end
@interface BMFGetZoomLevel : NSObject<BMFMapViewHandler>
@end
@interface BMFGetMinZoomLevel : NSObject<BMFMapViewHandler>
@end
@interface BMFGetMaxZoomLevel : NSObject<BMFMapViewHandler>
@end
@interface BMFGetRotation : NSObject<BMFMapViewHandler>
@end
@interface BMFGetOverlooking : NSObject<BMFMapViewHandler>
@end
@interface BMFGetMinOverlooking : NSObject<BMFMapViewHandler>
@end
@interface BMFGetBuildingsEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetShowMapPoi : NSObject<BMFMapViewHandler>
@end
@interface BMFGetTrafficEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetBaiduHeatMapEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetGesturesEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetZoomEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetZoomEnabledWithTap : NSObject<BMFMapViewHandler>
@end
@interface BMFGetScrollEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetOverlookEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetRotateEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetForceTouchEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetShowMapScaleBar : NSObject<BMFMapViewHandler>
@end
@interface BMFGetMapScaleBarPosition : NSObject<BMFMapViewHandler>
@end
@interface BMFGetLogoPosition : NSObject<BMFMapViewHandler>
@end
@interface BMFGetVisibleMapBounds : NSObject<BMFMapViewHandler>
@end
@interface BMFGetBaseIndoorMapEnabled : NSObject<BMFMapViewHandler>
@end
@interface BMFGetShowIndoorMapPoi : NSObject<BMFMapViewHandler>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,886 @@
//
// BMFMapViewHandles.m
// flutter_bmfmap
//
// Created by zbj on 2020/2/11.
//
#import "BMFMapViewHandles.h"
#import "BMFMapView.h"
#import "BMFMapMethodConst.h"
#import "BMFAnnotationMethodConst.h"
#import "BMFFileManager.h"
#import "UIColor+BMFString.h"
#import "BMFMapModels.h"
#import "BMFEdgeInsets.h"
#import "BMFIndoorMapInfoModel.h"
#import "BMFMapStatusModel.h"
@interface BMFMapViewHandles ()
{
NSDictionary *_handles;
}
@end
@implementation BMFMapViewHandles
static BMFMapViewHandles *_instance = nil;
+ (instancetype)defalutCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFMapViewHandles alloc] init];
});
}
return _instance;
}
- (NSDictionary<NSString *, NSString *> *)mapViewHandles{
if (!_handles) {
_handles = @{
kBMFMapUpdateMethod: NSStringFromClass([BMFUpdateMap class]),
kBMFMapShowBaseIndoorMapMethod: NSStringFromClass([BMFShowBaseIndoorMap class]),
kBMFMapShowBaseIndoorMapPoiMethod: NSStringFromClass([BMFShowBaseIndoorMapPoi class]),
kBMFMapSwitchBaseIndoorMapFloorMethod: NSStringFromClass([BMFSwitchBaseIndoorMapFloor class]),
kBMFMapGetFocusedBaseIndoorMapInfoMethod: NSStringFromClass([BMFGetFocusedBaseIndoorMapInfo class]),
kBMFMapSetCustomMapStyleEnableMethod: NSStringFromClass([BMFSetCustomMapStyleEnable class]),
kBMFMapSetCustomMapStylePathMethod: NSStringFromClass([BMFSetCustomMapStylePath class]),
kBMFMapSetCustomMapStyleWithOptionMethod: NSStringFromClass([BMFSetCustomMapStyleWithOption class]),
kBMFMapZoomInMethod: NSStringFromClass([BMFZoomIn class]),
kBMFMapZoomOutMethod: NSStringFromClass([BMFZoomOut class]),
kBMFMapSetCustomTrafficColorMethod: NSStringFromClass([BMFSetCustomTrafficColor class]),
kBMFMapSetCenterCoordinateMethod: NSStringFromClass([BMFSetCenterCoordinate class]),
kBMFMapTakeSnapshotMethod: NSStringFromClass([BMFTakeSnapshot class]),
kBMFMapTakeSnapshotWithRectMethod: NSStringFromClass([BMFTakeSnapshotWithRect class]),
kBMFMapSetCompassImageMethod: NSStringFromClass([BMFSetCompassImage class]),
kBMFMapSetVisibleMapBoundsMethod: NSStringFromClass([BMFSetVisibleMapBounds class]),
kBMFMapSetVisibleMapBoundsWithPaddingMethod: NSStringFromClass([BMFSetVisibleMapBoundsWithPadding class]),
kBMFMapSetMapStatusMethod: NSStringFromClass([BMFSetMapStatus class]),
kBMFMapGetMapStatusMethod: NSStringFromClass([BMFGetMapStatus class]),
kBMFMapGetMapTypeMethod: NSStringFromClass([BMFGetMapType class]),
kBMFMapGetZoomLevelMethod: NSStringFromClass([BMFGetZoomLevel class]),
kBMFMapGetMinZoomLevelMethod: NSStringFromClass([BMFGetMinZoomLevel class]),
kBMFMapGetMaxZoomLevelMethod: NSStringFromClass([BMFGetMaxZoomLevel class]),
kBMFMapGetRotationMethod: NSStringFromClass([BMFGetRotation class]),
kBMFMapGetOverlookingMethod: NSStringFromClass([BMFGetOverlooking class]),
kBMFMapGetMinOverlookingMethod: NSStringFromClass([BMFGetMinOverlooking class]),
kBMFMapGetBuildingsEnabledMethod: NSStringFromClass([BMFGetBuildingsEnabled class]),
kBMFMapGetShowMapPoiMethod: NSStringFromClass([BMFGetShowMapPoi class]),
kBMFMapGetTrafficEnabledMethod: NSStringFromClass([BMFGetTrafficEnabled class]),
kBMFMapGetBaiduHeatMapEnabledMethod: NSStringFromClass([BMFGetBaiduHeatMapEnabled class]),
kBMFMapGetGesturesEnabledMethod: NSStringFromClass([BMFGetGesturesEnabled class]),
kBMFMapGetZoomEnabledMethod: NSStringFromClass([BMFGetZoomEnabled class]),
kBMFMapGetZoomEnabledWithTapMethod: NSStringFromClass([BMFGetZoomEnabledWithTap class]),
kBMFMapGetScrollEnabledMethod: NSStringFromClass([BMFGetScrollEnabled class]),
kBMFMapGetOverlookEnabledMethod: NSStringFromClass([BMFGetOverlookEnabled class]),
kBMFMapGetRotateEnabledMethod: NSStringFromClass([BMFGetRotateEnabled class]),
kBMFMapGetForceTouchEnabledMethod: NSStringFromClass([BMFGetForceTouchEnabled class]),
kBMFMapGetShowMapScaleBarMethod: NSStringFromClass([BMFGetShowMapScaleBar class]),
kBMFMapGetMapScaleBarPositionMethod: NSStringFromClass([BMFGetMapScaleBarPosition class]),
kBMFMapGetLogoPositionMethod: NSStringFromClass([BMFGetLogoPosition class]),
kBMFMapGetVisibleMapBoundsMethod: NSStringFromClass([BMFGetVisibleMapBounds class]),
kBMFMapGetBaseIndoorMapEnabledMethod: NSStringFromClass([BMFGetBaseIndoorMapEnabled class]),
kBMFMapGetShowIndoorMapPoiMethod: NSStringFromClass([BMFGetShowIndoorMapPoi class])
};
}
return _handles;
}
@end
#pragma mark - map
@implementation BMFUpdateMap
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
BOOL success = [_mapView updateMapViewWith:call.arguments];
result(@(success));
}
@end
@implementation BMFShowBaseIndoorMap
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
_mapView.baseIndoorMapEnabled = [[call.arguments safeValueForKey:@"show"] boolValue];
[_mapView setMapStatus:[_mapView getMapStatus]];
result(@YES);
}
@end
@implementation BMFShowBaseIndoorMapPoi
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !_mapView.baseIndoorMapEnabled) {
result(@NO);
return;
}
_mapView.showIndoorMapPoi = [[call.arguments safeValueForKey:@"showIndoorPoi"] boolValue];
result(@YES);
}
@end
@implementation BMFSwitchBaseIndoorMapFloor
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKSwitchIndoorFloorError error;
if (!call.arguments || !call.arguments[@"floorId"] || !call.arguments[@"indoorId"] || !_mapView.baseIndoorMapEnabled) {
error = BMKSwitchIndoorFloorFailed;
result(@{@"result":@(error)});
return;
}
error = [_mapView switchBaseIndoorMapFloor:[call.arguments safeValueForKey:@"floorId"] withID:[call.arguments safeValueForKey:@"indoorId"]];
result(@{@"result":@(error)});
}
@end
@implementation BMFGetFocusedBaseIndoorMapInfo
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!_mapView.baseIndoorMapEnabled) {
result(@{@"result": [NSNull null]});
return;
}
BMKBaseIndoorMapInfo *info = [_mapView getFocusedBaseIndoorMapInfo];
BMFIndoorMapInfoModel *model = [BMFIndoorMapInfoModel new];
model.strID = info.strID;
model.strFloor = info.strFloor;
model.listStrFloors = info.arrStrFloors;
result([model bmf_toDictionary]);
}
@end
@implementation BMFSetCustomMapStyleEnable
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
[_mapView setCustomMapStyleEnable:[[call.arguments safeValueForKey:@"enable"] boolValue]];
result(@YES);
}
@end
@implementation BMFSetCustomMapStylePath
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
NSString *path = [[BMFFileManager defaultCenter] pathForFlutterFileName:[call.arguments safeValueForKey:@"path"]];
[_mapView setCustomMapStylePath:path mode:[[call.arguments safeValueForKey:@"mode"] intValue]];
result(@YES);
}
@end
@implementation BMFSetCustomMapStyleWithOption
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
BMKCustomMapStyleOption *options = [BMKCustomMapStyleOption new];
options.customMapStyleID = [[call.arguments safeObjectForKey:@"customMapStyleOption"] safeValueForKey:@"customMapStyleID"];
NSString *localPath = [[call.arguments safeObjectForKey:@"customMapStyleOption"] safeValueForKey:@"customMapStyleFilePath"];
if (localPath && localPath.length > 0) {
options.customMapStyleFilePath = [[BMFFileManager defaultCenter] pathForFlutterFileName:localPath];
}
[_mapView setCustomMapStyleWithOption:options preLoad:^(NSString *path) {
if (path) {
result(@{@"preloadPath": path});
}
} success:^(NSString *path) {
if (path) {
result(@{@"successPath": path});
}
} failure:^(NSError *error, NSString *path) {
if (error) {
result(@{@"errorCode": @(error.code), @"errorPath": path ? path : [NSNull null]});
}
// NSLog(@"failure-error=%@,path=%@", error, path);
}];
}
@end
@implementation BMFZoomIn
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BOOL flag = [_mapView zoomIn];
result(@(flag));
}
@end
@implementation BMFZoomOut
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BOOL flag = [_mapView zoomOut];
result(@(flag));
}
@end
@implementation BMFSetCustomTrafficColor
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
UIColor *smooth = [UIColor fromColorString:[call.arguments safeValueForKey:@"smooth"]];
UIColor *slow = [UIColor fromColorString:[call.arguments safeValueForKey:@"slow"]];
UIColor *congestion = [UIColor fromColorString:[call.arguments safeValueForKey:@"congestion"]];
UIColor *severeCongestion = [UIColor fromColorString:[call.arguments safeValueForKey:@"severeCongestion"]];
if (smooth && slow && congestion && severeCongestion) {
BOOL flag = [_mapView setCustomTrafficColorForSmooth:smooth slow:slow congestion:congestion severeCongestion:severeCongestion];
result(@(flag));
return;
} else {
result(@NO);
}
}
@end
@implementation BMFSetCenterCoordinate
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
BMFCoordinate *coordinate = [BMFCoordinate bmf_modelWith:[call.arguments safeObjectForKey:@"coordinate"]];
if (coordinate) {
[_mapView setCenterCoordinate:[coordinate toCLLocationCoordinate2D] animated:[[call.arguments safeValueForKey:@"animated"] boolValue]];
result(@YES);
return;
} else {
result(@NO);
}
}
@end
@implementation BMFTakeSnapshot
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
UIImage *image = [_mapView takeSnapshot];
if (!image) {
result(@[]);
return;
}
NSData *data = UIImageJPEGRepresentation(image, 100);
FlutterStandardTypedData *fData = [FlutterStandardTypedData typedDataWithBytes:data];
result(fData);
}
@end
@implementation BMFTakeSnapshotWithRect
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"rect"]) {
result(@[]);
return;
}
CGRect rect = [[BMFMapRect bmf_modelWith:[call.arguments safeObjectForKey:@"rect"]] toCGRect];
UIImage *image = [_mapView takeSnapshot:rect];
if (!image) {
result(@[]);
return;
}
NSData *data = UIImageJPEGRepresentation(image, 100);
FlutterStandardTypedData *fData = [FlutterStandardTypedData typedDataWithBytes:data];
result(fData);
}
@end
@implementation BMFSetCompassImage
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"imagePath"]) {
result(@NO);
return;
}
UIImage *image = [UIImage imageWithContentsOfFile:[[BMFFileManager defaultCenter] pathForFlutterImageName:[call.arguments safeValueForKey:@"imagePath"]]];
[_mapView setCompassImage:image];
result(@YES);
}
@end
@implementation BMFSetVisibleMapBounds
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"visibleMapBounds"] || !call.arguments[@"animated"]) {
result(@NO);
return;
}
BMFCoordinateBounds *bounds = [BMFCoordinateBounds bmf_modelWith:[call.arguments safeObjectForKey:@"visibleMapBounds"]];
[_mapView setVisibleMapRect:[bounds toBMKMapRect] animated:[[call.arguments safeValueForKey:@"animated"] boolValue]];
result(@YES);
}
@end
@implementation BMFSetVisibleMapBoundsWithPadding
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"visibleMapBounds"] || !call.arguments[@"insets"] || !call.arguments[@"animated"]) {
result(@NO);
return;
}
BMFCoordinateBounds *bounds = [BMFCoordinateBounds bmf_modelWith:[call.arguments safeObjectForKey:@"visibleMapBounds"]];
BMFEdgeInsets *insets = [BMFEdgeInsets bmf_modelWith:[call.arguments safeObjectForKey:@"insets"]];
[_mapView setVisibleMapRect:[bounds toBMKMapRect] edgePadding:[insets toUIEdgeInsets] animated:[[call.arguments safeValueForKey:@"animated"] boolValue]];
result(@YES);
}
@end
@implementation BMFSetMapStatus
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"mapStatus"] || !call.arguments[@"animateDurationMs"] ) {
result(@NO);
return;
}
BMFMapStatusModel *status = [BMFMapStatusModel bmf_modelWith:[call.arguments safeObjectForKey:@"mapStatus"]];
int animate = [[call.arguments safeValueForKey:@"animateDurationMs"] intValue];
[_mapView setMapStatus:[status toMapStatus] withAnimation: animate!=0 ? YES : NO];
result(@YES);
}
@end
#pragma mark - Get
@implementation BMFGetMapStatus
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMFMapStatusModel *status = [BMFMapStatusModel fromMapStatus:[_mapView getMapStatus]];
status ? result(@{@"mapStatus":[status bmf_toDictionary]}) : result(@{@"mapStatus":[NSNull null]});
}
@end
@implementation BMFGetMapType
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"mapType" : @(_mapView.mapType)});
}
@end
@implementation BMFGetZoomLevel
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"zoomLevel": @((int)_mapView.zoomLevel)});
}
@end
@implementation BMFGetMinZoomLevel
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"minZoomLevel": @((int)_mapView.minZoomLevel)});
}
@end
@implementation BMFGetMaxZoomLevel
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"maxZoomLevel" : @((int)_mapView.maxZoomLevel)});
}
@end
@implementation BMFGetRotation
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"rotation" : @((float)_mapView.rotation)});
}
@end
@implementation BMFGetOverlooking
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"overlooking": @((float)_mapView.overlooking)});
}
@end
@implementation BMFGetMinOverlooking
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"minOverlooking" : @(_mapView.minOverlooking)});
}
@end
@implementation BMFGetBuildingsEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"buildingsEnabled": @(_mapView.buildingsEnabled)});
}
@end
@implementation BMFGetShowMapPoi
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"showMapPoi" : @(_mapView.showMapPoi)});
}
@end
@implementation BMFGetTrafficEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"trafficEnabled": @(_mapView.trafficEnabled)});
}
@end
@implementation BMFGetBaiduHeatMapEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"baiduHeatMapEnabled": @(_mapView.baiduHeatMapEnabled)});
}
@end
@implementation BMFGetGesturesEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"gesturesEnabled" : @(_mapView.gesturesEnabled)});
}
@end
@implementation BMFGetZoomEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"zoomEnabled": @(_mapView.zoomEnabled)});
}
@end
@implementation BMFGetZoomEnabledWithTap
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"zoomEnabledWithTap" : @(_mapView.zoomEnabledWithTap)});
}
@end
@implementation BMFGetScrollEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"scrollEnabled" : @(_mapView.scrollEnabled)});
}
@end
@implementation BMFGetOverlookEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"overlookEnabled": @(_mapView.overlookEnabled)});
}
@end
@implementation BMFGetRotateEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"rotateEnabled": @(_mapView.rotateEnabled)});
}
@end
@implementation BMFGetForceTouchEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"forceTouchEnabled": @(_mapView.forceTouchEnabled)});
}
@end
@implementation BMFGetShowMapScaleBar
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"showMapScaleBar" : @(_mapView.showMapScaleBar)});
}
@end
@implementation BMFGetMapScaleBarPosition
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMFMapPoint *point = [BMFMapPoint fromCGPoint:_mapView.mapScaleBarPosition];
result(@{@"mapScaleBarPosition": [point bmf_toDictionary]});
}
@end
@implementation BMFGetLogoPosition
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"logoPosition" : @(_mapView.logoPosition)});
}
@end
@implementation BMFGetVisibleMapBounds
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMFMapRect *mapRect = [BMFMapRect fromBMKMapRect:_mapView.visibleMapRect];
BMFCoordinateBounds *visibleMapBounds = [mapRect toBMFCoordinateBounds];
result(@{@"visibleMapBounds": [visibleMapBounds bmf_toDictionary]});
}
@end
@implementation BMFGetBaseIndoorMapEnabled
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"baseIndoorMapEnabled" : @(_mapView.baseIndoorMapEnabled)});
}
@end
@implementation BMFGetShowIndoorMapPoi
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
result(@{@"showIndoorMapPoi" : @(_mapView.showIndoorMapPoi)});
}
@end

@ -0,0 +1,57 @@
//
// BMFOverlayHandles.h
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/2/12.
//
#import "BMFMapViewHandle.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMFOverlayHandles : NSObject
/// BMFOverlayHandler管理中心
+ (instancetype)defalutCenter;
- (NSDictionary<NSString *, NSString *> *)overlayHandles;
@end
#pragma mark - overlay
@interface BMFAddPolyline : NSObject<BMFMapViewHandler>
@end
@interface BMFAddArcline : NSObject<BMFMapViewHandler>
@end
@interface BMFAddPolygon : NSObject<BMFMapViewHandler>
@end
@interface BMFAddCircle : NSObject<BMFMapViewHandler>
@end
@interface BMFAddTile : NSObject<BMFMapViewHandler>
@end
@interface BMFAddGround : NSObject<BMFMapViewHandler>
@end
@interface BMFRemoveOverlay : NSObject<BMFMapViewHandler>
@end
@interface BMFRemoveTileOverlay : NSObject<BMFMapViewHandler>
@end
@interface BMFUpdatePolyline : NSObject<BMFMapViewHandler>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,576 @@
//
// BMFOverlayHandles.m
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/2/12.
//
#import "BMFOverlayHandles.h"
#import "BMFMapView.h"
#import "BMFOverlayMethodConst.h"
#import "BMFFileManager.h"
#import "UIColor+BMFString.h"
#import "BMFMapModels.h"
#import "BMFPolyline.h"
#import "BMFArcline.h"
#import "BMFPolygon.h"
#import "BMFCircle.h"
#import "BMFTileModel.h"
#import "BMFURLTileLayer.h"
#import "BMFAsyncTileLayer.h"
#import "BMFSyncTileLayer.h"
#import "BMFGroundOverlay.h"
@interface BMFOverlayHandles ()
{
NSDictionary *_handles;
}
@end
@implementation BMFOverlayHandles
static BMFOverlayHandles *_instance = nil;
+ (instancetype)defalutCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFOverlayHandles alloc] init];
});
}
return _instance;
}
- (NSDictionary<NSString *, NSString *> *)overlayHandles{
if (!_handles) {
_handles = @{
kBMFMapAddPolylineMethod: NSStringFromClass([BMFAddPolyline class]),
kBMFMapAddArcineMethod: NSStringFromClass([BMFAddArcline class]),
kBMFMapAddPolygonMethod: NSStringFromClass([BMFAddPolygon class]),
kBMFMapAddCircleMethod: NSStringFromClass([BMFAddCircle class]),
kBMFMapAddTileMethod: NSStringFromClass([BMFAddTile class]),
kBMFMapAddGroundMethod: NSStringFromClass([BMFAddGround class]),
kBMFMapRemoveOverlayMethod: NSStringFromClass([BMFRemoveOverlay class]),
kBMFMapRemoveTileMethod: NSStringFromClass([BMFRemoveTileOverlay class]),
kBMFMapUpdatePolylineMemberMethod: NSStringFromClass([BMFUpdatePolyline class])
};
}
return _handles;
}
@end
#pragma mark - overlay
@implementation BMFAddPolyline
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKPolyline *polyline = [BMKPolyline polylineWith:call.arguments];
if (polyline) {
[_mapView addOverlay:polyline];
result(@YES);
} else {
result(@NO);
}
}
@end
@implementation BMFAddArcline
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKArcline *arcline = [BMKArcline arclineWith:call.arguments];
if (arcline) {
[_mapView addOverlay:arcline];
result(@YES);
} else {
result(@NO);
}
}
@end
@implementation BMFAddPolygon
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKPolygon *polygon = [BMKPolygon polygonWith:call.arguments];
if (polygon) {
[_mapView addOverlay:polygon];
result(@YES);
} else {
result(@NO);
}
}
@end
@implementation BMFAddCircle
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKCircle *circle = [BMKCircle circlelineWith:call.arguments];
if (circle) {
[_mapView addOverlay:circle];
result(@YES);
return;
} else {
result(@NO);
}
}
@end
@implementation BMFAddTile
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments) {
result(@NO);
return;
}
BMFTileModel *model = [BMFTileModel bmf_modelWith:call.arguments];
model.tileOptions = [BMFTileModelOptions bmf_modelWith:call.arguments];
// NSLog(@"%@", [model bmf_toDictionary]);
if (!model) {
result(@NO);
return;
}
if (model.tileOptions.tileLoadType == kBMFTileLoadUrl && model.tileOptions.url) {
BMFURLTileLayer *urlTileLayer = [BMFURLTileLayer urlTileLayerWith:model];
[_mapView addOverlay:urlTileLayer];
result(@YES);
return;
} else if (model.tileOptions.tileLoadType == kBMFTileLoadLocalAsync) {
BMFAsyncTileLayer *asyncTileLayer = [BMFAsyncTileLayer asyncTileLayerWith:model];
[_mapView addOverlay:asyncTileLayer];
result(@YES);
return;
} else if (model.tileOptions.tileLoadType == kBMFTileLoadLocalSync) {
BMFSyncTileLayer *syncTileLayer = [BMFSyncTileLayer syncTileLayerWith:model];
[_mapView addOverlay:syncTileLayer];
result(@YES);
return;
} else {
result(@NO);
return;
}
}
@end
@implementation BMFAddGround
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
BMKGroundOverlay *ground = [BMKGroundOverlay groundOverlayWith:call.arguments];
if (ground) {
[_mapView addOverlay:ground];
result(@YES);
return;
} else {
result(@NO);
}
}
@end
@implementation BMFRemoveOverlay
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"id"]) {
result(@NO);
return;
}
NSString *ID = [call.arguments safeValueForKey:@"id"];
__weak __typeof__(_mapView) weakMapView = _mapView;
[_mapView.overlays enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// 折线
if ([obj isKindOfClass:[BMKPolyline class]]) {
BMKPolyline *overlay = (BMKPolyline *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
// 多边形
if ([obj isKindOfClass:[BMKPolygon class]]) {
BMKPolygon *overlay = (BMKPolygon *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
// 弧线
if ([obj isKindOfClass:[BMKArcline class]]) {
BMKArcline *overlay = (BMKArcline *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
//
if ([obj isKindOfClass:[BMKCircle class]]) {
BMKCircle *overlay = (BMKCircle *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
// ground
if ([obj isKindOfClass:[BMKGroundOverlay class]]) {
BMKGroundOverlay *overlay = (BMKGroundOverlay *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
// 瓦片图
if ([obj isKindOfClass:[BMFURLTileLayer class]]) {
BMFURLTileLayer *overlay = (BMFURLTileLayer *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
if ([obj isKindOfClass:[BMFAsyncTileLayer class]]) {
BMFAsyncTileLayer *overlay = (BMFAsyncTileLayer *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
if ([obj isKindOfClass:[BMFSyncTileLayer class]]) {
BMFSyncTileLayer *overlay = (BMFSyncTileLayer *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
}];
}
@end
@implementation BMFRemoveTileOverlay
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"id"]) {
result(@NO);
return;
}
NSString *ID = [call.arguments safeValueForKey:@"id"];
__weak __typeof__(_mapView) weakMapView = _mapView;
[_mapView.overlays enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// 瓦片图
if ([obj isKindOfClass:[BMFURLTileLayer class]]) {
BMFURLTileLayer *overlay = (BMFURLTileLayer *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
if ([obj isKindOfClass:[BMFAsyncTileLayer class]]) {
BMFAsyncTileLayer *overlay = (BMFAsyncTileLayer *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
if ([obj isKindOfClass:[BMFSyncTileLayer class]]) {
BMFSyncTileLayer *overlay = (BMFSyncTileLayer *)obj;
if ([ID isEqualToString:overlay.Id]) {
[weakMapView removeOverlay:obj];
result(@YES);
*stop = YES;
return;
}
}
}];
}
@end
#pragma mark - Update
@implementation BMFUpdatePolyline
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"id"]) {
result(@NO);
return;
}
NSString *ID = [call.arguments safeValueForKey:@"id"];
__block BMKPolyline *polyline;
[_mapView.overlays enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:[BMKPolyline class]]) {
BMKPolyline *line = (BMKPolyline *)obj;
if ([ID isEqualToString:line.Id]) {
polyline = line;
*stop = YES;
}
}
}];
if (!polyline) {
result(@NO);
return;
}
NSString *member = [call.arguments safeValueForKey:@"member"];
// kBMFColorLine = 0, ///< 单色折线
// kBMFColorsLine, ///< 多色折线
// kBMFTextureLine, ///< 单纹理折线
// kBMFTexturesLine, ///< 多纹理折线
// kBMFDashLine, ///< 虚线
// kBMFMultiDashLine ///< 多色虚线
if ([member isEqualToString:@"coordinates"]) {
NSArray<NSDictionary *> *coordinates = [call.arguments safeObjectForKey:@"value"];
if (!coordinates || coordinates.count <= 1) {
result(@NO);
return;
}
CLLocationCoordinate2D coords[coordinates.count];
for (size_t i = 0, count = coordinates.count; i < count; i++) {
BMFCoordinate *coord = [BMFCoordinate bmf_modelWith:coordinates[i]];
coords[i] = [coord toCLLocationCoordinate2D];
}
switch (polyline.lineType) {
case kBMFColorLine:
case kBMFTextureLine:
case kBMFDashLine: {
[polyline setPolylineWithCoordinates:coords count:coordinates.count];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
}
break;
case kBMFColorsLine:
case kBMFTexturesLine:
case kBMFMultiDashLine: {
if (![call.arguments safeObjectForKey:@"indexs"]) {
result(@NO);
return;
}
NSMutableArray<NSNumber *> *indexs = [NSMutableArray array];
for (NSNumber *value in call.arguments[@"indexs"]) {
[indexs addObject:value];
}
[polyline setPolylineWithCoordinates:coords count:coordinates.count textureIndex:indexs];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
}
break;
default:
break;
}
} else if ([member isEqualToString:@"width"]) {
BMKPolylineView *view = (BMKPolylineView *)[_mapView viewForOverlay:polyline];
view.lineWidth = [[call.arguments safeValueForKey:@"value"] floatValue];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if ([member isEqualToString:@"colors"]) {
NSArray *colorsData = [call.arguments safeObjectForKey:@"value"];
if (!colorsData || colorsData.count <= 0) {
result(@NO);
return;
}
BMKPolylineView *view = (BMKPolylineView *)[_mapView viewForOverlay:polyline];
NSMutableArray<UIColor *> *colors = [NSMutableArray array];
for (NSString *color in colorsData) {
[colors addObject:[UIColor fromColorString:color]];
}
if (polyline.lineType == kBMFColorsLine || polyline.lineType == kBMFMultiDashLine) {
view.colors = [colors copy];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if (polyline.lineType ==kBMFColorLine || polyline.lineType == kBMFDashLine) {
view.strokeColor = [colors firstObject];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else {
NSLog(@"ios - 纹理折线不支持更新colors");
result(@NO);
return;
}
} else if ([member isEqualToString:@"lineDashType"]) {
if (polyline.lineType == kBMFTextureLine || polyline.lineType == kBMFTexturesLine) {
NSLog(@"ios - 纹理折线不支持虚线类型");
result(@NO);
return;
}
BMFPolylineModel *model = polyline.polylineModel;
model.polylineOptions.lineDashType = [[call.arguments safeValueForKey:@"value"] intValue];
[_mapView removeOverlay:polyline];
BMKPolyline *dashLine = [BMKPolyline polylineWithModel:model];
[_mapView addOverlay:dashLine];
// BMKPolylineView *view = (BMKPolylineView *)[_mapView viewForOverlay:polyline];
// view.lineDashType = [[call.arguments safeValueForKey:@"value"] intValue];
// [_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if ([member isEqualToString:@"lineCapType"]) {
if (polyline.lineType == kBMFDashLine || polyline.lineType == kBMFMultiDashLine) {
NSLog(@"ios - lineCapType不支持虚线");
result(@NO);
return;
}
BMKPolylineView *view = (BMKPolylineView *)[_mapView viewForOverlay:polyline];
view.lineCapType = [[call.arguments safeValueForKey:@"value"] intValue];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if ([member isEqualToString:@"lineJoinType"]) {
if (polyline.lineType == kBMFDashLine || polyline.lineType == kBMFMultiDashLine) {
NSLog(@"ios - lineJoinType不支持虚线");
result(@NO);
return;
}
BMKPolylineView *view = (BMKPolylineView *)[_mapView viewForOverlay:polyline];
view.lineJoinType = [[call.arguments safeValueForKey:@"value"] intValue];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if ([member isEqualToString:@"isThined"]) {
polyline.isThined = [[call.arguments safeValueForKey:@"value"] boolValue];
[_mapView setMapStatus:_mapView.getMapStatus];
result(@YES);
return;
} else if ([member isEqualToString:@"textures"]) {
NSLog(@"ios - 暂不支持更新textures");
result(@YES);
return;
} else if ([member isEqualToString:@"clickable"]) {
NSLog(@"ios - 暂不支持设置clickable");
result(@YES);
return;
} else if ([member isEqualToString:@"isKeepScale"]) {
NSLog(@"ios - 暂不支持设置isKeepScale");
result(@YES);
return;
} else if ([member isEqualToString:@"isFocus"]) {
NSLog(@"ios - 暂不支持设置isFocus");
result(@YES);
return;
} else if ([member isEqualToString:@"visible"]) {
NSLog(@"ios - 暂不支持设置visible");
result(@YES);
return;
} else if ([member isEqualToString:@"zIndex"]) {
NSLog(@"ios - 暂不支持设置zIndex");
result(@YES);
return;
} else {
result(@YES);
}
}
@end

@ -0,0 +1,28 @@
//
// BMFProjectionHandles.h
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/4/1.
//
#import "BMFMapViewHandle.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMFProjectionHandles : NSObject
/// BMFProjectionHandles管理中心
+ (instancetype)defalutCenter;
- (NSDictionary<NSString *, NSString *> *)projectionHandles;
@end
#pragma mark - convert
@interface BMFCoordinateFromBMFPoint : NSObject<BMFMapViewHandler>
@end
@interface BMFPointFromBMFCoordinate : NSObject<BMFMapViewHandler>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,86 @@
//
// BMFProjectionHandles.m
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/4/1.
//
#import "BMFProjectionHandles.h"
#import "BMFProjectionConst.h"
#import "BMFMapView.h"
#import "BMFMapModels.h"
@interface BMFProjectionHandles ()
{
NSDictionary *_handles;
}
@end
@implementation BMFProjectionHandles
static BMFProjectionHandles *_instance = nil;
+ (instancetype)defalutCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFProjectionHandles alloc] init];
});
}
return _instance;
}
- (NSDictionary<NSString *, NSString *> *)projectionHandles{
if (!_handles) {
_handles = @{
kBMFCoordinateFromScreenPointMethod: NSStringFromClass([BMFCoordinateFromBMFPoint class]),
kBMFScreenPointFromCoordinateMethod: NSStringFromClass([BMFPointFromBMFCoordinate class]),
};
}
return _handles;
}
@end
#pragma mark - convert
@implementation BMFCoordinateFromBMFPoint
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || call.arguments[@"point"]) {
result([NSNull null]);
return;
}
BMFMapPoint *point = [BMFMapPoint bmf_modelWith:[call.arguments safeObjectForKey:@"point"]];
CLLocationCoordinate2D coord = [_mapView convertPoint:[point toCGPoint] toCoordinateFromView:_mapView];
BMFCoordinate *coordinate = [BMFCoordinate fromCLLocationCoordinate2D:coord];
result(@{@"coordinate" : [coordinate bmf_toDictionary]});
}
@end
@implementation BMFPointFromBMFCoordinate
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || call.arguments[@"coordinate"]) {
result([NSNull null]);
return;
}
BMFCoordinate *coord = [BMFCoordinate bmf_modelWith:[call.arguments safeObjectForKey:@"coordinate"]];
CGPoint p = [_mapView convertCoordinate:[coord toCLLocationCoordinate2D] toPointToView:_mapView];
BMFMapPoint *point = [BMFMapPoint fromCGPoint:p];
result(@{@"point" : [point bmf_toDictionary]});
}
@end

@ -0,0 +1,40 @@
//
// BMFUserLocationHandles.h
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/3/01.
//
#import "BMFMapViewHandle.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMFUserLocationHandles : NSObject
/// BMFUserLocationHandler管理中心
+ (instancetype)defalutCenter;
- (NSDictionary<NSString *, NSString *> *)userLocationHandles;
@end
#pragma mark - userLocation
@interface BMFShowUserLocation : NSObject<BMFMapViewHandler>
@end
@interface BMFSetUserTrackingMode : NSObject<BMFMapViewHandler>
@end
@interface BMFIsUserLocationVisible : NSObject<BMFMapViewHandler>
@end
@interface BMFUpdateLocationData : NSObject<BMFMapViewHandler>
@end
@interface BMFUpdateLocationDisplayParam : NSObject<BMFMapViewHandler>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,151 @@
//
// BMFUserLocationHandles.m
// flutter_bmfmap
//
// Created by zhangbaojin on 2020/3/01.
//
#import "BMFUserLocationHandles.h"
#import "BMFMapView.h"
#import "BMFUserLocationConst.h"
#import "NSObject+BMFVerify.h"
#import "BMFUserLocationModel.h"
@interface BMFUserLocationHandles ()
{
NSDictionary *_handles;
}
@end
@implementation BMFUserLocationHandles
static BMFUserLocationHandles *_instance = nil;
+ (instancetype)defalutCenter{
if (!_instance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[BMFUserLocationHandles alloc] init];
});
}
return _instance;
}
- (NSDictionary<NSString *, NSString *> *)userLocationHandles{
if (!_handles) {
_handles = @{
kBMFMapShowUserLocationMethod: NSStringFromClass([BMFShowUserLocation class]),
kBMFMapUserTrackingModeMethod: NSStringFromClass([BMFSetUserTrackingMode class]),
kBMFMapIsUserLocationVisibleMethod : NSStringFromClass([BMFIsUserLocationVisible class]),
kBMFMapUpdateLocationDataMethod: NSStringFromClass([BMFUpdateLocationData class]),
kBMFMapUpdateLocationDisplayParamMethod : NSStringFromClass([BMFUpdateLocationDisplayParam class]),
};
}
return _handles;
}
@end
#pragma mark - userLocation
@implementation BMFShowUserLocation
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"show"]) {
result(@NO);
return;
}
// NSLog(@"ios-call.arguments=%@", call.arguments);
_mapView.showsUserLocation = [[call.arguments safeValueForKey:@"show"] boolValue];
result(@YES);
}
@end
@implementation BMFSetUserTrackingMode
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
if (!call.arguments || !call.arguments[@"userTrackingMode"]) {
result(@NO);
return;
}
_mapView.userTrackingMode = [[call.arguments safeValueForKey:@"userTrackingMode"] intValue];
result(@YES);
}
@end
@implementation BMFIsUserLocationVisible
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
// NSLog(@"ios-BMFIsUserLocationVisible");
if (!_mapView.showsUserLocation) {
result(@{@"userLocationVisible": @NO});
return;
}
result(@{@"userLocationVisible": @(_mapView.userLocationVisible)});
}
@end
@implementation BMFUpdateLocationData
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
// NSLog(@"ios-BMFUpdateLocationData-call.arguments=%@", call.arguments);
if (!call.arguments || !call.arguments[@"userLocation"]) {
result(@NO);
return;
}
BMFUserLocationModel *userLocation = [BMFUserLocationModel bmf_modelWith:[call.arguments safeObjectForKey:@"userLocation"]];
[_mapView updateLocationData:[userLocation toBMKUserLocation]];
result(@YES);
}
@end
@implementation BMFUpdateLocationDisplayParam
@synthesize _mapView;
- (nonnull NSObject<BMFMapViewHandler> *)initWith:(nonnull BMFMapView *)mapView {
_mapView = mapView;
return self;
}
- (void)handleMethodCall:(nonnull FlutterMethodCall *)call result:(nonnull FlutterResult)result {
// NSLog(@"ios-BMFUpdateLocationDisplayParam-call.arguments=%@", call.arguments);
if (!call.arguments || !call.arguments[@"userlocationDisplayParam"]) {
result(@NO);
return;
}
BMFLocationViewDisplayParam *displayParam = [BMFLocationViewDisplayParam bmf_modelWith:[call.arguments safeObjectForKey:@"userlocationDisplayParam"]];
[_mapView updateLocationViewWithParam:[displayParam toBMKLocationViewDisplayParam]];
result(@YES);
}
@end

@ -0,0 +1,32 @@
//
// BMFAnnotation.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/11.
//
#ifndef __BMFAnnotation__H__
#define __BMFAnnotation__H__
#ifdef __OBJC__
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#endif
#endif
#import "BMFAnnotationModel.h"
NS_ASSUME_NONNULL_BEGIN
// 改为分类,继承会出现固定屏幕不生效
@interface BMKPointAnnotation (BMFAnnotation)
/// BMFAnnotation
+ (instancetype)annotationWith:(NSDictionary *)dic;
/// annotation唯一id
@property (nonatomic, copy,readonly) NSString *Id;
/// annotationView的属性配置model
@property (nonatomic, strong,readonly) BMFAnnotationViewOptions *annotationViewOptions;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,65 @@
//
// BMFAnnotation.m
// flutter_bmfmap
//
// Created by zbj on 2020/2/11.
//
#import "BMFAnnotation.h"
#import <objc/runtime.h>
#import "BMFMapModels.h"
static const void *IDKey = &IDKey;
static const void *annotationViewOptionsKey = &annotationViewOptionsKey;
@implementation BMKPointAnnotation (BMFAnnotation)
- (NSString *)Id{
return objc_getAssociatedObject(self, IDKey);
}
- (void)setId:(NSString * _Nonnull)Id{
objc_setAssociatedObject(self, IDKey, Id, OBJC_ASSOCIATION_COPY);
}
- (BMFAnnotationViewOptions *)annotationViewOptions{
return objc_getAssociatedObject(self, annotationViewOptionsKey);
}
- (void)setAnnotationViewOptions:(BMFAnnotationViewOptions * _Nonnull)annotationViewOptions {
objc_setAssociatedObject(self, annotationViewOptionsKey, annotationViewOptions, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (instancetype)annotationWith:(NSDictionary *)dic{
return [[self alloc] initWith:dic];
}
- (instancetype)initWith:(NSDictionary *)dic{
if ([super init]) {
if (dic) {
BMFAnnotationModel *model = [BMFAnnotationModel bmf_modelWith:dic];
model.annotationViewOptions = [BMFAnnotationViewOptions bmf_modelWith:dic];
[self configAnnotation:model];
}
}
return self;
}
- (void)configAnnotation:(BMFAnnotationModel*)model{
if (model.Id) {
self.Id = model.Id;
}
if (model.title) {
self.title = model.title;
}
if (model.subtitle) {
self.subtitle = model.subtitle;
}
if (model.position) {
self.coordinate = [model.position toCLLocationCoordinate2D];
}
self.isLockedToScreen = model.isLockedToScreen;
if (model.screenPointToLock) {
self.screenPointToLock = [model.screenPointToLock toCGPoint];
}
self.annotationViewOptions = model.annotationViewOptions;
}
@end

@ -0,0 +1,31 @@
//
// BMFArcline.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/15.
//
#ifndef __BMFArcline__H__
#define __BMFArcline__H__
#ifdef __OBJC__
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#endif
#endif
#import "BMFArclineModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMKArcline (BMFArcline)
/// arclineView唯一id
@property (nonatomic, copy, readonly) NSString *Id;
/// arclineViewOptions
@property (nonatomic, strong, readonly) BMFArclineViewOptions *arclineViewOptions;
+ (BMKArcline *)arclineWith:(NSDictionary *)dic;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,51 @@
//
// BMFArcline.m
// flutter_bmfmap
//
// Created by zbj on 2020/2/15.
//
#import "BMFArcline.h"
#import <objc/runtime.h>
#import "BMFMapModels.h"
static const void *IDKey = &IDKey;
static const void *arclineViewOptionsKey = &arclineViewOptionsKey;
@implementation BMKArcline (BMFArcline)
+ (BMKArcline *)arclineWith:(NSDictionary *)dic{
if (dic) {
BMFArclineModel *model = [BMFArclineModel bmf_modelWith:dic];
model.arclineOptions = [BMFArclineViewOptions bmf_modelWith:dic];
int _coordsCount = (int)model.coordinates.count;
if (_coordsCount < 3) {
return nil;
}
CLLocationCoordinate2D *coords = new CLLocationCoordinate2D[_coordsCount];
for (int i = 0; i < _coordsCount; i++) {
coords[i] = [model.coordinates[i] toCLLocationCoordinate2D];
}
BMKArcline *arcline = [BMKArcline arclineWithCoordinates:coords];
arcline.Id = model.Id;
arcline.arclineViewOptions = model.arclineOptions;
return arcline;
}
return nil;
}
- (NSString *)Id{
return objc_getAssociatedObject(self, IDKey);
}
- (void)setId:(NSString * _Nonnull)Id{
objc_setAssociatedObject(self, IDKey, Id, OBJC_ASSOCIATION_COPY);
}
- (BMFArclineViewOptions *)arclineViewOptions{
return objc_getAssociatedObject(self, arclineViewOptionsKey);
}
- (void)setArclineViewOptions:(BMFArclineViewOptions * _Nonnull)arclineViewOptions{
objc_setAssociatedObject(self, arclineViewOptionsKey, arclineViewOptions, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

@ -0,0 +1,30 @@
//
// BMFCircle.h
// flutter_bmfmap
//
// Created by zbj on 2020/2/15.
//
#ifndef __BMFCircle__H__
#define __BMFCircle__H__
#ifdef __OBJC__
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#endif
#endif
#import "BMFCircleModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMKCircle (BMFCircle)
/// circleView唯一id
@property (nonatomic, copy, readonly) NSString *Id;
/// circleViewOptions
@property (nonatomic, strong, readonly) BMFCircleViewOptions *circleViewOptions;
+ (BMKCircle *)circlelineWith:(NSDictionary *)dic;
@end
NS_ASSUME_NONNULL_END

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save