map_controller.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:flutter_map/flutter_map.dart';
  6. import 'package:flutter_map/src/consts/map_constants.dart';
  7. import 'package:flutter_map/src/entity/camera_position.dart';
  8. import 'package:flutter_map/src/entity/codable.dart';
  9. import 'package:flutter_map/src/entity/lat_lng.dart';
  10. import 'package:flutter_map/src/entity/marker.dart';
  11. import 'package:flutter_map/src/entity/polyline.dart';
  12. import 'package:flutter_map/src/interface/map_fun_interface.dart';
  13. import 'package:flutter_map/src/interface/map_marker_interface.dart';
  14. import 'package:flutter_map/src/interface/map_polyline_interface.dart';
  15. import '../entity/map_padding.dart';
  16. class MapController
  17. implements MapMarkerInterface, MapFunInterface, MapPolylineInterface {
  18. final _pendingOperations = <Map<String, dynamic>>[];
  19. MethodChannel? _channel;
  20. bool _isDisposed = false;
  21. void setChannel(MethodChannel channel) {
  22. if (_isDisposed) return;
  23. _channel = channel;
  24. for (final op in _pendingOperations) {
  25. _executeMethod(op);
  26. }
  27. _pendingOperations.clear();
  28. }
  29. void _executeMethod(Map<String, dynamic> op) {
  30. _channel?.invokeMethod(op['method'], op['args']).catchError((e) {
  31. debugPrint('Method ${op['method']} failed: $e');
  32. });
  33. }
  34. void dispose() {
  35. _isDisposed = true;
  36. _pendingOperations.clear();
  37. _channel?.setMethodCallHandler(null);
  38. _channel = null;
  39. }
  40. @override
  41. void updateOrAddMarkers(List<Marker> markers) {
  42. if (_isDisposed || markers.isEmpty) return;
  43. final serialized = _encodeJson(markers);
  44. final params = {
  45. 'method': MapConstants.methodUpdateOrAddMarkers,
  46. 'args': serialized
  47. };
  48. debugPrint("updateOrAddMarkers...params==>$params");
  49. if (_channel != null) {
  50. _executeMethod(params);
  51. } else {
  52. _pendingOperations.add(params);
  53. }
  54. }
  55. @override
  56. void moveCamera(CameraPosition cameraPosition) {
  57. if (_isDisposed) return;
  58. final serialized = cameraPosition.toJson();
  59. final params = {
  60. 'method': MapConstants.methodMapMoveCamera,
  61. 'args': serialized
  62. };
  63. debugPrint("moveCamera...params==>$params");
  64. if (_channel != null) {
  65. _executeMethod(params);
  66. } else {
  67. _pendingOperations.add(params);
  68. }
  69. }
  70. @override
  71. void animateCamera(CameraPosition cameraPosition) {
  72. if (_isDisposed) return;
  73. final serialized = cameraPosition.toJson();
  74. final params = {
  75. 'method': MapConstants.methodMapAnimateCamera,
  76. 'args': serialized
  77. };
  78. debugPrint("animateCamera...params==>$params");
  79. if (_channel != null) {
  80. _executeMethod(params);
  81. } else {
  82. _pendingOperations.add(params);
  83. }
  84. }
  85. @override
  86. void updateOrAddMarker(Marker marker) {
  87. updateOrAddMarkers([marker]);
  88. }
  89. @override
  90. void replaceAllMarkers(List<Marker> markers) {
  91. if (_isDisposed) return;
  92. final serialized = _encodeJson(markers);
  93. final params = {
  94. 'method': MapConstants.methodReplaceAllMarkers,
  95. 'args': serialized
  96. };
  97. debugPrint("replaceAllMarkers...params==>$params");
  98. if (_channel != null) {
  99. _executeMethod(params);
  100. } else {
  101. _pendingOperations.add(params);
  102. }
  103. }
  104. @override
  105. void clearAllMarkers() {
  106. replaceAllMarkers([]);
  107. }
  108. @override
  109. void addPolyline(Polyline polyline,
  110. {bool isAnimateCamera = true, MapPadding? mapPadding}) {
  111. if (_isDisposed || polyline.points.isEmpty) return;
  112. Map<String, dynamic> map = {};
  113. map['lineId'] = polyline.lineId;
  114. map['points'] = _encodeJson(polyline.points);
  115. map['isAnimateCamera'] = isAnimateCamera;
  116. map['lineType'] = polyline.lineType.value;
  117. if (polyline.color != null) {
  118. map['color'] = polyline.color;
  119. }
  120. if (polyline.width != null) {
  121. map['width'] = polyline.width;
  122. }
  123. if (mapPadding != null) {
  124. map['mapPadding'] = _encodeJson(mapPadding);
  125. }
  126. final params = {'method': MapConstants.methodAddPolyline, 'args': map};
  127. debugPrint("addPolyline...params==>$params");
  128. if (_channel != null) {
  129. _executeMethod(params);
  130. } else {
  131. _pendingOperations.add(params);
  132. }
  133. }
  134. @override
  135. void clear() {
  136. if (_isDisposed) return;
  137. clearAllMarkers();
  138. final params = {'method': MapConstants.methodMapClear, 'args': ''};
  139. debugPrint("clear...params==>$params");
  140. if (_channel != null) {
  141. _executeMethod(params);
  142. } else {
  143. _pendingOperations.add(params);
  144. }
  145. }
  146. @override
  147. void moveToSuitableLocation(List<LatLng> points, {MapPadding? mapPadding}) {
  148. if (_isDisposed || points.isEmpty) return;
  149. Map<String, dynamic> map = {};
  150. map['points'] = _encodeJson(points);
  151. if (mapPadding != null) {
  152. map['mapPadding'] = _encodeJson(mapPadding);
  153. }
  154. final params = {
  155. 'method': MapConstants.methodMoveToSuitableLocation,
  156. 'args': map
  157. };
  158. debugPrint("moveToSuitableLocation...params==>$params");
  159. if (_channel != null) {
  160. _executeMethod(params);
  161. } else {
  162. _pendingOperations.add(params);
  163. }
  164. }
  165. @override
  166. void removeMarker(String markerId) {
  167. if (_isDisposed) return;
  168. final params = {
  169. 'method': MapConstants.methodMarkerRemoveMarker,
  170. 'args': {'markerId': markerId}
  171. };
  172. debugPrint("removeMarker...params==>$params");
  173. if (_channel != null) {
  174. _executeMethod(params);
  175. } else {
  176. _pendingOperations.add(params);
  177. }
  178. }
  179. @override
  180. void removePolyline(String lineId) {
  181. if (_isDisposed) return;
  182. final params = {
  183. 'method': MapConstants.methodRemovePolyline,
  184. 'args': {'lineId': lineId}
  185. };
  186. debugPrint("removePolyline...params==>$params");
  187. if (_channel != null) {
  188. _executeMethod(params);
  189. } else {
  190. _pendingOperations.add(params);
  191. }
  192. }
  193. @override
  194. void clearAllPolylines() {
  195. if (_isDisposed) return;
  196. final params = {'method': MapConstants.methodClearAllPolylines, 'args': ''};
  197. debugPrint("clearAllPolylines...params==>$params");
  198. if (_channel != null) {
  199. _executeMethod(params);
  200. } else {
  201. _pendingOperations.add(params);
  202. }
  203. }
  204. @override
  205. void setMapInteractionEnabled(bool enabled) {
  206. if (_isDisposed) return;
  207. final params = {
  208. 'method': MapConstants.methodInteractionEnabled,
  209. 'args': {'enabled': enabled}
  210. };
  211. debugPrint("setMapInteractionEnabled...params==>$params");
  212. if (_channel != null) {
  213. _executeMethod(params);
  214. } else {
  215. _pendingOperations.add(params);
  216. }
  217. }
  218. @override
  219. void setMapLogoVisible(bool visible) {
  220. if (_isDisposed) return;
  221. final params = {
  222. 'method': MapConstants.methodMapLogoVisible,
  223. 'args': {'visible': visible}
  224. };
  225. debugPrint("setMapLogoVisible...params==>$params");
  226. if (_channel != null) {
  227. _executeMethod(params);
  228. } else {
  229. _pendingOperations.add(params);
  230. }
  231. }
  232. /// iOS 需要一个Map 而不是json string
  233. dynamic _encodeJson(dynamic object) {
  234. // iOS平台直接返回对象或转换为JSON对象
  235. if (Platform.isIOS) {
  236. if (object is List) {
  237. return object
  238. .map((item) => item is Codable ? item.toJson() : item)
  239. .toList();
  240. }
  241. return object is Codable ? object.toJson() : object;
  242. }
  243. // 其他平台序列化为JSON字符串
  244. return jsonEncode(object);
  245. }
  246. }