init project
This commit is contained in:
41
lib/src/core/amap_flutter_platform.dart
Normal file
41
lib/src/core/amap_flutter_platform.dart
Normal file
@ -0,0 +1,41 @@
|
||||
import 'package:amap_map/src/core/method_channel_amap_map.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
/// “amap_map”平台特定实现必须扩展的接口
|
||||
abstract class AMapFlutterPlatform extends PlatformInterface {
|
||||
static final Object _token = Object();
|
||||
AMapFlutterPlatform() : super(token: _token);
|
||||
static AMapFlutterPlatform _instance = MethodChannelAMapFlutterMap();
|
||||
|
||||
/// The default instance of [AMapFlutterPlatform] to use.
|
||||
///
|
||||
/// Defaults to [MethodChannelAMapFlutterMap].
|
||||
static AMapFlutterPlatform get instance => _instance;
|
||||
|
||||
static set instance(AMapFlutterPlatform instance) {
|
||||
PlatformInterface.verifyToken(instance, _token);
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
/// /// Initializes the platform interface with [id].
|
||||
///
|
||||
/// This method is called when the plugin is first initialized.
|
||||
Future<void> init(int id) {
|
||||
throw UnimplementedError('init() has not been implemented.');
|
||||
}
|
||||
|
||||
void dispose({required int id}) {
|
||||
throw UnimplementedError('dispose() has not been implemented.');
|
||||
}
|
||||
|
||||
Widget buildView(
|
||||
Map<String, dynamic> creationParams,
|
||||
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
|
||||
PlatformViewCreatedCallback onPlatformViewCreated) {
|
||||
throw UnimplementedError('buildView() has not been implemented.');
|
||||
}
|
||||
}
|
77
lib/src/core/map_event.dart
Normal file
77
lib/src/core/map_event.dart
Normal file
@ -0,0 +1,77 @@
|
||||
import 'package:amap_map/amap_map.dart';
|
||||
import 'package:x_amap_base/x_amap_base.dart';
|
||||
|
||||
///地图事件处理
|
||||
class MapEvent<T> {
|
||||
/// 地图id
|
||||
final int mapId;
|
||||
|
||||
///返回的内容,对应的[MethodCall]中的[[arguments]]
|
||||
final T value;
|
||||
|
||||
/// 构造一个event
|
||||
///
|
||||
/// `mapId` 当前地图的id
|
||||
/// `value` 需要传输的值,可以为`null`.
|
||||
MapEvent(this.mapId, this.value);
|
||||
}
|
||||
|
||||
///定位回调接口
|
||||
class LocationChangedEvent extends MapEvent<AMapLocation> {
|
||||
LocationChangedEvent(int mapId, AMapLocation value) : super(mapId, value);
|
||||
}
|
||||
|
||||
///地图移动回调
|
||||
class CameraPositionMoveEvent extends MapEvent<CameraPosition> {
|
||||
CameraPositionMoveEvent(int mapId, CameraPosition value)
|
||||
: super(mapId, value);
|
||||
}
|
||||
|
||||
///地图移动结束回调
|
||||
class CameraPositionMoveEndEvent extends MapEvent<CameraPosition> {
|
||||
CameraPositionMoveEndEvent(int mapId, CameraPosition value)
|
||||
: super(mapId, value);
|
||||
}
|
||||
|
||||
///点击地图回调
|
||||
class MapTapEvent extends MapEvent<LatLng> {
|
||||
MapTapEvent(int mapId, LatLng value) : super(mapId, value);
|
||||
}
|
||||
|
||||
///长按地图回调
|
||||
class MapLongPressEvent extends MapEvent<LatLng> {
|
||||
MapLongPressEvent(int mapId, LatLng value) : super(mapId, value);
|
||||
}
|
||||
|
||||
/// 带位置回调的地图事件
|
||||
class _PositionedMapEvent<T> extends MapEvent<T> {
|
||||
/// 事件中带的位置信息
|
||||
final LatLng position;
|
||||
|
||||
/// 构造一个带位置的地图事件,
|
||||
///
|
||||
/// `mapId` 当前地图的id
|
||||
/// `value` 需要传输的值,可以为`null`.
|
||||
_PositionedMapEvent(int mapId, this.position, T value) : super(mapId, value);
|
||||
}
|
||||
|
||||
/// [Marker] 的点击事件
|
||||
class MarkerTapEvent extends MapEvent<String> {
|
||||
MarkerTapEvent(int mapId, String markerId) : super(mapId, markerId);
|
||||
}
|
||||
|
||||
/// [Marker] 的拖拽结束事件,附带拖拽结束时的位置信息[LatLng].
|
||||
class MarkerDragEndEvent extends _PositionedMapEvent<String> {
|
||||
MarkerDragEndEvent(int mapId, LatLng position, String markerId)
|
||||
: super(mapId, position, markerId);
|
||||
}
|
||||
|
||||
/// [Polyline] 的点击事件
|
||||
class PolylineTapEvent extends MapEvent<String> {
|
||||
PolylineTapEvent(int mapId, String polylineId) : super(mapId, polylineId);
|
||||
}
|
||||
|
||||
/// Poi点击事件
|
||||
class MapPoiTouchEvent extends MapEvent<AMapPoi> {
|
||||
MapPoiTouchEvent(int mapId, AMapPoi poi) : super(mapId, poi);
|
||||
}
|
273
lib/src/core/method_channel_amap_map.dart
Normal file
273
lib/src/core/method_channel_amap_map.dart
Normal file
@ -0,0 +1,273 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:x_amap_base/x_amap_base.dart';
|
||||
import 'package:amap_map/src/core/amap_flutter_platform.dart';
|
||||
import 'package:amap_map/src/types/types.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:stream_transform/stream_transform.dart';
|
||||
|
||||
import 'map_event.dart';
|
||||
|
||||
const VIEW_TYPE = 'com.amap.flutter.map';
|
||||
|
||||
/// 使用[MethodChannel]与Native代码通信的[AMapFlutterPlatform]的实现。
|
||||
class MethodChannelAMapFlutterMap implements AMapFlutterPlatform {
|
||||
final Map<int, MethodChannel> _channels = {};
|
||||
|
||||
MethodChannel channel(int mapId) {
|
||||
return _channels[mapId]!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> init(int mapId) {
|
||||
MethodChannel? channel = _channels[mapId];
|
||||
if (channel == null) {
|
||||
channel = MethodChannel('amap_map_$mapId');
|
||||
channel.setMethodCallHandler((call) => _handleMethodCall(call, mapId));
|
||||
_channels[mapId] = channel;
|
||||
}
|
||||
return channel.invokeMethod<void>('map#waitForMap');
|
||||
}
|
||||
|
||||
///更新地图参数
|
||||
Future<void> updateMapOptions(
|
||||
Map<String, dynamic> newOptions, {
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<void>(
|
||||
'map#update',
|
||||
<String, dynamic>{
|
||||
'options': newOptions,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 更新Marker的数据
|
||||
Future<void> updateMarkers(
|
||||
MarkerUpdates markerUpdates, {
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<void>(
|
||||
'markers#update',
|
||||
markerUpdates.toMap(),
|
||||
);
|
||||
}
|
||||
|
||||
/// 更新polyline的数据
|
||||
Future<void> updatePolylines(
|
||||
PolylineUpdates polylineUpdates, {
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<void>(
|
||||
'polylines#update',
|
||||
polylineUpdates.toMap(),
|
||||
);
|
||||
}
|
||||
|
||||
/// 更新polygon的数据
|
||||
Future<void> updatePolygons(
|
||||
PolygonUpdates polygonUpdates, {
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<void>(
|
||||
'polygons#update',
|
||||
polygonUpdates.toMap(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose({required int id}) {
|
||||
if (_channels.containsKey(id)) {
|
||||
_channels.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildView(
|
||||
Map<String, dynamic> creationParams,
|
||||
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
|
||||
void Function(int id) onPlatformViewCreated) {
|
||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
creationParams['debugMode'] = kDebugMode;
|
||||
return AndroidView(
|
||||
viewType: VIEW_TYPE,
|
||||
onPlatformViewCreated: onPlatformViewCreated,
|
||||
gestureRecognizers: gestureRecognizers,
|
||||
creationParams: creationParams,
|
||||
creationParamsCodec: const StandardMessageCodec(),
|
||||
);
|
||||
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
|
||||
return UiKitView(
|
||||
viewType: VIEW_TYPE,
|
||||
onPlatformViewCreated: onPlatformViewCreated,
|
||||
gestureRecognizers: gestureRecognizers,
|
||||
creationParams: creationParams,
|
||||
creationParamsCodec: const StandardMessageCodec(),
|
||||
);
|
||||
}
|
||||
return Text('当前平台:$defaultTargetPlatform, 不支持使用高德地图插件');
|
||||
}
|
||||
|
||||
// handleMethodCall的`broadcast`
|
||||
final StreamController<MapEvent> _mapEventStreamController =
|
||||
StreamController<MapEvent>.broadcast();
|
||||
|
||||
// 根据mapid返回相应的event.
|
||||
Stream<MapEvent> _events(int mapId) =>
|
||||
_mapEventStreamController.stream.where((event) => event.mapId == mapId);
|
||||
|
||||
//定位回调
|
||||
Stream<LocationChangedEvent> onLocationChanged({required int mapId}) {
|
||||
return _events(mapId).whereType<LocationChangedEvent>();
|
||||
}
|
||||
|
||||
//Camera 移动回调
|
||||
Stream<CameraPositionMoveEvent> onCameraMove({required int mapId}) {
|
||||
return _events(mapId).whereType<CameraPositionMoveEvent>();
|
||||
}
|
||||
|
||||
///Camera 移动结束回调
|
||||
Stream<CameraPositionMoveEndEvent> onCameraMoveEnd({required int mapId}) {
|
||||
return _events(mapId).whereType<CameraPositionMoveEndEvent>();
|
||||
}
|
||||
|
||||
Stream<MapTapEvent> onMapTap({required int mapId}) {
|
||||
return _events(mapId).whereType<MapTapEvent>();
|
||||
}
|
||||
|
||||
Stream<MapLongPressEvent> onMapLongPress({required int mapId}) {
|
||||
return _events(mapId).whereType<MapLongPressEvent>();
|
||||
}
|
||||
|
||||
Stream<MapPoiTouchEvent> onPoiTouched({required int mapId}) {
|
||||
return _events(mapId).whereType<MapPoiTouchEvent>();
|
||||
}
|
||||
|
||||
Stream<MarkerTapEvent> onMarkerTap({required int mapId}) {
|
||||
return _events(mapId).whereType<MarkerTapEvent>();
|
||||
}
|
||||
|
||||
Stream<MarkerDragEndEvent> onMarkerDragEnd({required int mapId}) {
|
||||
return _events(mapId).whereType<MarkerDragEndEvent>();
|
||||
}
|
||||
|
||||
Stream<PolylineTapEvent> onPolylineTap({required int mapId}) {
|
||||
return _events(mapId).whereType<PolylineTapEvent>();
|
||||
}
|
||||
|
||||
Future<dynamic> _handleMethodCall(MethodCall call, int mapId) async {
|
||||
switch (call.method) {
|
||||
case 'location#changed':
|
||||
try {
|
||||
_mapEventStreamController.add(LocationChangedEvent(
|
||||
mapId, AMapLocation.fromMap(call.arguments['location'])!));
|
||||
} catch (e) {
|
||||
print("location#changed error=======>" + e.toString());
|
||||
}
|
||||
break;
|
||||
|
||||
case 'camera#onMove':
|
||||
try {
|
||||
_mapEventStreamController.add(CameraPositionMoveEvent(
|
||||
mapId, CameraPosition.fromMap(call.arguments['position'])!));
|
||||
} catch (e) {
|
||||
print("camera#onMove error===>" + e.toString());
|
||||
}
|
||||
break;
|
||||
case 'camera#onMoveEnd':
|
||||
try {
|
||||
_mapEventStreamController.add(CameraPositionMoveEndEvent(
|
||||
mapId, CameraPosition.fromMap(call.arguments['position'])!));
|
||||
} catch (e) {
|
||||
print("camera#onMoveEnd error===>" + e.toString());
|
||||
}
|
||||
break;
|
||||
case 'map#onTap':
|
||||
_mapEventStreamController.add(
|
||||
MapTapEvent(mapId, LatLng.fromJson(call.arguments['latLng'])!));
|
||||
break;
|
||||
case 'map#onLongPress':
|
||||
_mapEventStreamController.add(MapLongPressEvent(
|
||||
mapId, LatLng.fromJson(call.arguments['latLng'])!));
|
||||
break;
|
||||
|
||||
case 'marker#onTap':
|
||||
_mapEventStreamController.add(MarkerTapEvent(
|
||||
mapId,
|
||||
call.arguments['markerId'],
|
||||
));
|
||||
break;
|
||||
case 'marker#onDragEnd':
|
||||
_mapEventStreamController.add(MarkerDragEndEvent(
|
||||
mapId,
|
||||
LatLng.fromJson(call.arguments['position'])!,
|
||||
call.arguments['markerId']));
|
||||
break;
|
||||
case 'polyline#onTap':
|
||||
_mapEventStreamController
|
||||
.add(PolylineTapEvent(mapId, call.arguments['polylineId']));
|
||||
break;
|
||||
case 'map#onPoiTouched':
|
||||
try {
|
||||
_mapEventStreamController.add(MapPoiTouchEvent(
|
||||
mapId, AMapPoi.fromJson(call.arguments['poi'])!));
|
||||
} catch (e) {
|
||||
print('map#onPoiTouched error===>' + e.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///移动镜头到一个新的位置
|
||||
Future<void> moveCamera(
|
||||
CameraUpdate cameraUpdate, {
|
||||
required int mapId,
|
||||
bool animated = true,
|
||||
int duration = 0,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<void>('camera#move', <String, dynamic>{
|
||||
'cameraUpdate': cameraUpdate.toJson(),
|
||||
'animated': animated,
|
||||
'duration': duration
|
||||
});
|
||||
}
|
||||
|
||||
///设置地图每秒渲染的帧数
|
||||
Future<void> setRenderFps(int fps, {required int mapId}) {
|
||||
return channel(mapId)
|
||||
.invokeMethod<void>('map#setRenderFps', <String, dynamic>{
|
||||
'fps': fps,
|
||||
});
|
||||
}
|
||||
|
||||
///截屏
|
||||
Future<Uint8List?> takeSnapshot({
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<Uint8List>('map#takeSnapshot');
|
||||
}
|
||||
|
||||
//获取地图审图号(普通地图)
|
||||
Future<String?> getMapContentApprovalNumber({
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<String>('map#contentApprovalNumber');
|
||||
}
|
||||
|
||||
//获取地图审图号(卫星地图)
|
||||
Future<String?> getSatelliteImageApprovalNumber({
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId)
|
||||
.invokeMethod<String>('map#satelliteImageApprovalNumber');
|
||||
}
|
||||
|
||||
Future<void> clearDisk({
|
||||
required int mapId,
|
||||
}) {
|
||||
return channel(mapId).invokeMethod<void>('map#clearDisk');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user