AMapViewController.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. //
  2. // AMapViewController.m
  3. // amap_flutter_map
  4. //
  5. // Created by lly on 2020/10/29.
  6. //
  7. #import "AMapViewController.h"
  8. #import "AMapJsonUtils.h"
  9. #import "AMapCameraPosition.h"
  10. #import "MAMapView+Flutter.h"
  11. #import "MAAnnotationView+Flutter.h"
  12. #import "AMapMarkerController.h"
  13. #import "MAPointAnnotation+Flutter.h"
  14. #import "AMapPolylineController.h"
  15. #import "MAPolyline+Flutter.h"
  16. #import "AMapPolyline.h"
  17. #import "MAPolylineRenderer+Flutter.h"
  18. #import <CoreLocation/CoreLocation.h>
  19. #import "AMapPolygonController.h"
  20. #import "MAPolygon+Flutter.h"
  21. #import "MAPolygonRenderer+Flutter.h"
  22. #import "AMapPolygon.h"
  23. #import <AMapFoundationKit/AMapFoundationKit.h>
  24. #import "AMapLocation.h"
  25. #import "AMapJsonUtils.h"
  26. #import "AMapConvertUtil.h"
  27. #import "FlutterMethodChannel+MethodCallDispatch.h"
  28. @interface AMapViewController ()<MAMapViewDelegate>
  29. @property (nonatomic,strong) MAMapView *mapView;
  30. @property (nonatomic,strong) FlutterMethodChannel *channel;
  31. @property (nonatomic,assign) int64_t viewId;
  32. @property (nonatomic,strong) NSObject<FlutterPluginRegistrar>* registrar;
  33. @property (nonatomic,strong) AMapMarkerController *markerController;
  34. @property (nonatomic,strong) AMapPolylineController *polylinesController;
  35. @property (nonatomic,strong) AMapPolygonController *polygonsController;
  36. @property (nonatomic,copy) FlutterResult waitForMapCallBack;//waitForMap的回调,仅当地图没有加载完成时缓存使用
  37. @property (nonatomic,assign) BOOL mapInitCompleted;//地图初始化完成,首帧回调的标记
  38. @property (nonatomic,assign) MAMapRect initLimitMapRect;//初始化时,限制的地图范围;如果为{0,0,0,0},则没有限制
  39. @end
  40. @implementation AMapViewController
  41. - (instancetype)initWithFrame:(CGRect)frame
  42. viewIdentifier:(int64_t)viewId
  43. arguments:(id _Nullable)args
  44. registrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  45. if (self = [super init]) {
  46. NSAssert([args isKindOfClass:[NSDictionary class]], @"传参错误");
  47. //构建methedChannel
  48. NSString* channelName =
  49. [NSString stringWithFormat:@"amap_flutter_map_%lld", viewId];
  50. _channel = [FlutterMethodChannel methodChannelWithName:channelName
  51. binaryMessenger:registrar.messenger];
  52. NSDictionary *dict = args;
  53. NSDictionary *apiKey = dict[@"apiKey"];
  54. if (apiKey && [apiKey isKindOfClass:[NSDictionary class]]) {
  55. NSString *iosKey = apiKey[@"iosKey"];
  56. if (iosKey && iosKey.length > 0) {//通过flutter传入key,则再重新设置一次key
  57. [AMapServices sharedServices].apiKey = iosKey;
  58. }
  59. }
  60. //这里统一检查key的设置是否生效
  61. NSAssert(([AMapServices sharedServices].apiKey != nil), @"没有设置APIKey,请先设置key");
  62. NSDictionary *cameraDict = [dict objectForKey:@"initialCameraPosition"];
  63. AMapCameraPosition *cameraPosition = [AMapJsonUtils modelFromDict:cameraDict modelClass:[AMapCameraPosition class]];
  64. _viewId = viewId;
  65. if ([dict objectForKey:@"privacyStatement"] != nil) {
  66. [self updatePrivacyStateWithDict:[dict objectForKey:@"privacyStatement"]];
  67. }
  68. self.mapInitCompleted = NO;
  69. _mapView = [[MAMapView alloc] initWithFrame:frame];
  70. if (_mapView == nil && (MAMapVersionNumber) >= 80100) {
  71. NSAssert(_mapView,@"MAMapView初始化失败,地图SDK8.1.0及以上,请务必确保调用SDK任何接口前先调用更新隐私合规updatePrivacyShow:privacyInfo、updatePrivacyAgree两个接口");
  72. }
  73. _mapView.delegate = self;
  74. _mapView.accessibilityElementsHidden = NO;
  75. [_mapView setCameraPosition:cameraPosition animated:NO duration:0];
  76. _registrar = registrar;
  77. [self.mapView updateMapViewOption:[dict objectForKey:@"options"] withRegistrar:_registrar];
  78. self.initLimitMapRect = [self getLimitMapRectFromOption:[dict objectForKey:@"options"]];
  79. if (MAMapRectIsEmpty(self.initLimitMapRect) == NO) {//限制了显示区域,则添加KVO监听
  80. [_mapView addObserver:self forKeyPath:@"frame" options:0 context:nil];
  81. }
  82. _markerController = [[AMapMarkerController alloc] init:_channel
  83. mapView:_mapView
  84. registrar:registrar];
  85. _polylinesController = [[AMapPolylineController alloc] init:_channel
  86. mapView:_mapView
  87. registrar:registrar];
  88. _polygonsController = [[AMapPolygonController alloc] init:_channel
  89. mapView:_mapView
  90. registrar:registrar];
  91. id markersToAdd = args[@"markersToAdd"];
  92. if ([markersToAdd isKindOfClass:[NSArray class]]) {
  93. [_markerController addMarkers:markersToAdd];
  94. }
  95. id polylinesToAdd = args[@"polylinesToAdd"];
  96. if ([polylinesToAdd isKindOfClass:[NSArray class]]) {
  97. [_polylinesController addPolylines:polylinesToAdd];
  98. }
  99. id polygonsToAdd = args[@"polygonsToAdd"];
  100. if ([polygonsToAdd isKindOfClass:[NSArray class]]) {
  101. [_polygonsController addPolygons:polygonsToAdd];
  102. }
  103. [self setMethodCallHandler];
  104. }
  105. return self;
  106. }
  107. - (UIView*)view {
  108. return _mapView;
  109. }
  110. - (void)dealloc {
  111. if (MAMapRectIsEmpty(_initLimitMapRect) == NO) {//避免没有开始渲染,frame监听还存在时,快速销毁
  112. [_mapView removeObserver:self forKeyPath:@"frame"];
  113. }
  114. }
  115. - (void)updatePrivacyStateWithDict:(NSDictionary *)dict {
  116. if ((MAMapVersionNumber) < 80100) {
  117. NSLog(@"当前地图SDK版本没有隐私合规接口,请升级地图SDK到8.1.0及以上版本");
  118. return;
  119. }
  120. if (dict == nil || [dict isKindOfClass:[NSDictionary class]] == NO) {
  121. return;
  122. }
  123. if (dict[@"hasContains"] != nil && dict[@"hasShow"] != nil) {
  124. [MAMapView updatePrivacyShow:[dict[@"hasShow"] integerValue] privacyInfo:[dict[@"hasContains"] integerValue]];
  125. }
  126. if (dict[@"hasAgree"] != nil) {
  127. [MAMapView updatePrivacyAgree:[dict[@"hasAgree"] integerValue]];
  128. }
  129. }
  130. - (MAMapRect)getLimitMapRectFromOption:(NSDictionary *)dict {
  131. NSArray *limitBounds = dict[@"limitBounds"];
  132. if (limitBounds) {
  133. return [AMapConvertUtil mapRectFromArray:limitBounds];
  134. } else {
  135. return MAMapRectMake(0, 0, 0, 0);
  136. }
  137. }
  138. - (void)observeValueForKeyPath:(NSString*)keyPath
  139. ofObject:(id)object
  140. change:(NSDictionary*)change
  141. context:(void*)context {
  142. if (MAMapRectIsEmpty(self.initLimitMapRect) == YES ) {//初始化时,没有设置显示范围,则不再监听frame的变化
  143. [_mapView removeObserver:self forKeyPath:@"frame"];
  144. return;
  145. }
  146. if (object == _mapView && [keyPath isEqualToString:@"frame"]) {
  147. CGRect bounds = _mapView.bounds;
  148. if (CGRectEqualToRect(bounds, CGRectZero)) {
  149. // 忽略初始化时,frame为0的情况,仅当frame更新为非0时,才设置limitRect
  150. return;
  151. }
  152. //监听到一次,就直接移除KVO
  153. [_mapView removeObserver:self forKeyPath:@"frame"];
  154. if (MAMapRectIsEmpty(self.initLimitMapRect) == NO) {
  155. //加0.1s的延迟,确保地图的frame和内部引擎都已经更新
  156. MAMapRect tempLimitMapRect = self.initLimitMapRect;
  157. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  158. self.mapView.limitMapRect = tempLimitMapRect;
  159. });
  160. //避免KVO短时间触发多次,造成多次延迟派发
  161. self.initLimitMapRect = MAMapRectMake(0, 0, 0, 0);
  162. }
  163. } else {
  164. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  165. }
  166. }
  167. - (void)setMethodCallHandler {
  168. __weak __typeof__(self) weakSelf = self;
  169. [self.channel addMethodName:@"map#update" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  170. [weakSelf.mapView updateMapViewOption:call.arguments[@"options"] withRegistrar:weakSelf.registrar];
  171. result(nil);
  172. }];
  173. [self.channel addMethodName:@"map#waitForMap" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  174. if (weakSelf.mapInitCompleted) {
  175. result(nil);
  176. } else {
  177. weakSelf.waitForMapCallBack = result;
  178. }
  179. }];
  180. [self.channel addMethodName:@"camera#move" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  181. [weakSelf.mapView setCameraUpdateDict:call.arguments];
  182. result(nil);
  183. }];
  184. [self.channel addMethodName:@"map#takeSnapshot" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  185. [weakSelf.mapView takeSnapshotInRect:weakSelf.mapView.frame withCompletionBlock:^(UIImage *resultImage, NSInteger state) {
  186. if (state == 1 && resultImage) {
  187. NSData *data = UIImagePNGRepresentation(resultImage);
  188. result([FlutterStandardTypedData typedDataWithBytes:data]);
  189. } else if (state == 0) {
  190. NSLog(@"takeSnapsShot 载入不完整");
  191. }
  192. }];
  193. }];
  194. [self.channel addMethodName:@"map#setRenderFps" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  195. NSInteger fps = [call.arguments[@"fps"] integerValue];
  196. [weakSelf.mapView setMaxRenderFrame:fps];
  197. result(nil);
  198. }];
  199. [self.channel addMethodName:@"map#contentApprovalNumber" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  200. NSString *approvalNumber = [weakSelf.mapView mapContentApprovalNumber];
  201. result(approvalNumber);
  202. }];
  203. [self.channel addMethodName:@"map#satelliteImageApprovalNumber" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  204. NSString *sateApprovalNumber = [weakSelf.mapView satelliteImageApprovalNumber];
  205. result(sateApprovalNumber);
  206. }];
  207. [self.channel addMethodName:@"map#clearDisk" withHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  208. [weakSelf.mapView clearDisk];
  209. result(nil);
  210. }];
  211. }
  212. //MARK: MAMapViewDelegate
  213. //MARK: 定位相关回调
  214. - (void)mapView:(MAMapView *)mapView didChangeUserTrackingMode:(MAUserTrackingMode)mode animated:(BOOL)animated {
  215. NSLog(@"%s,mapView:%@ mode:%ld",__func__,mapView,(long)mode);
  216. }
  217. /**
  218. * @brief 在地图View将要启动定位时,会调用此函数
  219. * @param mapView 地图View
  220. */
  221. - (void)mapViewWillStartLocatingUser:(MAMapView *)mapView {
  222. NSLog(@"%s,mapView:%@",__func__,mapView);
  223. }
  224. /**
  225. * @brief 在地图View停止定位后,会调用此函数
  226. * @param mapView 地图View
  227. */
  228. - (void)mapViewDidStopLocatingUser:(MAMapView *)mapView {
  229. NSLog(@"%s,mapView:%@",__func__,mapView);
  230. }
  231. /**
  232. * @brief 位置或者设备方向更新后,会调用此函数
  233. * @param mapView 地图View
  234. * @param userLocation 用户定位信息(包括位置与设备方向等数据)
  235. * @param updatingLocation 标示是否是location数据更新, YES:location数据更新 NO:heading数据更新
  236. */
  237. - (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation {
  238. if (updatingLocation && userLocation.location) {
  239. AMapLocation *location = [[AMapLocation alloc] init];
  240. [location updateWithUserLocation:userLocation.location];
  241. NSDictionary *jsonObjc = [AMapJsonUtils jsonObjectFromModel:location];
  242. NSArray *latlng = [AMapConvertUtil jsonArrayFromCoordinate:location.latLng];
  243. NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:jsonObjc];
  244. [dict setValue:latlng forKey:@"latLng"];
  245. [_channel invokeMethod:@"location#changed" arguments:@{@"location" : dict}];
  246. }
  247. }
  248. /**
  249. * @brief 当plist配置NSLocationAlwaysUsageDescription或者NSLocationAlwaysAndWhenInUseUsageDescription,并且[CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined,会调用代理的此方法。
  250. 此方法实现调用后台权限API即可( 该回调必须实现 [locationManager requestAlwaysAuthorization] ); since 6.8.0
  251. * @param locationManager 地图的CLLocationManager。
  252. */
  253. - (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager {
  254. if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
  255. [locationManager requestAlwaysAuthorization];
  256. }
  257. }
  258. /**
  259. * @brief 定位失败后,会调用此函数
  260. * @param mapView 地图View
  261. * @param error 错误号,参考CLError.h中定义的错误号
  262. */
  263. - (void)mapView:(MAMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
  264. NSLog(@"%s,mapView:%@ error:%@",__func__,mapView,error);
  265. }
  266. /**
  267. * @brief 地图加载成功
  268. * @param mapView 地图View
  269. */
  270. - (void)mapViewDidFinishLoadingMap:(MAMapView *)mapView {
  271. NSLog(@"%s,mapView:%@",__func__,mapView);
  272. }
  273. - (void)mapInitComplete:(MAMapView *)mapView {
  274. NSLog(@"%s,mapView:%@",__func__,mapView);
  275. self.mapInitCompleted = YES;
  276. if (self.waitForMapCallBack) {
  277. self.waitForMapCallBack(nil);
  278. self.waitForMapCallBack = nil;
  279. }
  280. }
  281. //MARK: Annotation相关回调
  282. - (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation {
  283. if ([annotation isKindOfClass:[MAPointAnnotation class]] == NO) {
  284. return nil;
  285. }
  286. MAPointAnnotation *fAnno = annotation;
  287. if (fAnno.markerId == nil) {
  288. return nil;
  289. }
  290. AMapMarker *marker = [_markerController markerForId:fAnno.markerId];
  291. // TODO: 这里只实现基础AnnotationView,不再根据marker的数据差异,区分是annotationView还是pinAnnotationView了;
  292. MAAnnotationView *view = [mapView dequeueReusableAnnotationViewWithIdentifier:AMapFlutterAnnotationViewIdentifier];
  293. if (view == nil) {
  294. view = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AMapFlutterAnnotationViewIdentifier];
  295. }
  296. [view updateViewWithMarker:marker];
  297. return view;
  298. }
  299. /**
  300. * @brief 当mapView新添加annotation views时,调用此接口
  301. * @param mapView 地图View
  302. * @param views 新添加的annotation views
  303. */
  304. - (void)mapView:(MAMapView *)mapView didAddAnnotationViews:(NSArray *)views {
  305. for (MAAnnotationView *view in views) {
  306. if ([view.annotation isKindOfClass:[MAAnnotationView class]] == NO) {
  307. return;
  308. }
  309. MAPointAnnotation *fAnno = view.annotation;
  310. if (fAnno.markerId == nil) {
  311. return;
  312. }
  313. AMapMarker *marker = [_markerController markerForId:fAnno.markerId];
  314. [view updateViewWithMarker:marker];
  315. }
  316. }
  317. /**
  318. * @brief 标注view的calloutview整体点击时,触发该回调。只有使用默认calloutview时才生效。
  319. * @param mapView 地图的view
  320. * @param view calloutView所属的annotationView
  321. */
  322. //- (void)mapView:(MAMapView *)mapView didAnnotationViewCalloutTapped:(MAAnnotationView *)view {
  323. // MAPointAnnotation *fAnno = view.annotation;
  324. // if (fAnno.markerId == nil) {
  325. // return;
  326. // }
  327. // [_markerController onInfoWindowTap:fAnno.markerId];
  328. //}
  329. /**
  330. * @brief 标注view被点击时,触发该回调。(since 5.7.0)
  331. * @param mapView 地图的view
  332. * @param view annotationView
  333. */
  334. - (void)mapView:(MAMapView *)mapView didAnnotationViewTapped:(MAAnnotationView *)view {
  335. MAPointAnnotation *fAnno = view.annotation;
  336. if (fAnno.markerId == nil) {
  337. return;
  338. }
  339. [_markerController onMarkerTap:fAnno.markerId];
  340. }
  341. /**
  342. * @brief 拖动annotation view时view的状态变化
  343. * @param mapView 地图View
  344. * @param view annotation view
  345. * @param newState 新状态
  346. * @param oldState 旧状态
  347. */
  348. - (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view didChangeDragState:(MAAnnotationViewDragState)newState
  349. fromOldState:(MAAnnotationViewDragState)oldState {
  350. if (newState == MAAnnotationViewDragStateEnding) {
  351. MAPointAnnotation *fAnno = view.annotation;
  352. if (fAnno.markerId == nil) {
  353. return;
  354. }
  355. [_markerController onMarker:fAnno.markerId endPostion:fAnno.coordinate];
  356. }
  357. }
  358. /**
  359. * @brief 根据overlay生成对应的Renderer
  360. * @param mapView 地图View
  361. * @param overlay 指定的overlay
  362. * @return 生成的覆盖物Renderer
  363. */
  364. - (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay {
  365. if ([overlay isKindOfClass:[HSTCusPolyline class]]){
  366. HSTCusPolyline *polyLine = (HSTCusPolyline *)overlay;
  367. // NSLog(@"overlay == %@ polyLine.polyLineType == %ld",overlay,(long)polyLine.polyLineType);
  368. //绘制单色 - 还可绘制多彩色
  369. MAMultiColoredPolylineRenderer * polylineRenderer = [[MAMultiColoredPolylineRenderer alloc]initWithMultiPolyline:polyLine];
  370. polylineRenderer.lineWidth = polyLine.lineWidth;
  371. polylineRenderer.lineJoinType = polyLine.joinType;
  372. polylineRenderer.lineCapType = polyLine.capType;
  373. polylineRenderer.lineDashType = polyLine.dashLineType;
  374. polylineRenderer.gradient = YES;
  375. polylineRenderer.strokeColors = polyLine.colorsArr;
  376. return polylineRenderer;
  377. }else if ([overlay isKindOfClass:[MAPolyline class]]) {
  378. MAPolyline *polyline = overlay;
  379. if (polyline.polylineId == nil) {
  380. return nil;
  381. }
  382. AMapPolyline *fPolyline = [_polylinesController polylineForId:polyline.polylineId];
  383. MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
  384. [polylineRenderer updateRenderWithPolyline:fPolyline];
  385. return polylineRenderer;
  386. } else if ([overlay isKindOfClass:[MAPolygon class]]) {
  387. MAPolygon *polygon = overlay;
  388. if (polygon.polygonId == nil) {
  389. return nil;
  390. }
  391. AMapPolygon *fPolygon = [_polygonsController polygonForId:polygon.polygonId];
  392. MAPolygonRenderer *polygonRenderer = [[MAPolygonRenderer alloc] initWithPolygon:polygon];
  393. [polygonRenderer updateRenderWithPolygon:fPolygon];
  394. return polygonRenderer;
  395. } else {
  396. return nil;
  397. }
  398. }
  399. /**
  400. * @brief 单击地图回调,返回经纬度
  401. * @param mapView 地图View
  402. * @param coordinate 经纬度
  403. */
  404. - (void)mapView:(MAMapView *)mapView didSingleTappedAtCoordinate:(CLLocationCoordinate2D)coordinate {
  405. NSArray *latLng = [AMapConvertUtil jsonArrayFromCoordinate:coordinate];
  406. [_channel invokeMethod:@"map#onTap" arguments:@{@"latLng":latLng}];
  407. NSArray *polylineRenderArray = [mapView getHittedPolylinesWith:coordinate traverseAll:NO];
  408. if (polylineRenderArray && polylineRenderArray.count > 0) {
  409. MAOverlayRenderer *render = polylineRenderArray.firstObject;
  410. MAPolyline *polyline = render.overlay;
  411. if (polyline.polylineId) {
  412. [_polylinesController onPolylineTap:polyline.polylineId];
  413. }
  414. }
  415. }
  416. /**
  417. * @brief 长按地图,返回经纬度
  418. * @param mapView 地图View
  419. * @param coordinate 经纬度
  420. */
  421. - (void)mapView:(MAMapView *)mapView didLongPressedAtCoordinate:(CLLocationCoordinate2D)coordinate {
  422. NSArray *latLng = [AMapConvertUtil jsonArrayFromCoordinate:coordinate];
  423. [_channel invokeMethod:@"map#onLongPress" arguments:@{@"latLng":latLng}];
  424. }
  425. /**
  426. * @brief 当touchPOIEnabled == YES时,单击地图使用该回调获取POI信息
  427. * @param mapView 地图View
  428. * @param pois 获取到的poi数组(由MATouchPoi组成)
  429. */
  430. - (void)mapView:(MAMapView *)mapView didTouchPois:(NSArray *)pois {
  431. MATouchPoi *poi = pois.firstObject;
  432. NSDictionary *dict = [AMapConvertUtil dictFromTouchPOI:poi];
  433. if (dict) {
  434. [_channel invokeMethod:@"map#onPoiTouched" arguments:@{@"poi":dict}];
  435. }
  436. }
  437. /**
  438. * @brief 地图区域改变过程中会调用此接口 since 4.6.0
  439. * @param mapView 地图View
  440. */
  441. - (void)mapViewRegionChanged:(MAMapView *)mapView {
  442. // TODO: 这里消息回调太多,channel可能有性能影响
  443. AMapCameraPosition *cameraPos = [mapView getCurrentCameraPosition];
  444. NSDictionary *dict = [cameraPos toDictionary];
  445. if (dict) {
  446. [_channel invokeMethod:@"camera#onMove" arguments:@{@"position":dict}];
  447. }
  448. }
  449. /**
  450. * @brief 地图区域改变完成后会调用此接口
  451. * @param mapView 地图View
  452. * @param animated 是否动画
  453. */
  454. - (void)mapView:(MAMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
  455. AMapCameraPosition *cameraPos = [mapView getCurrentCameraPosition];
  456. NSDictionary *dict = [cameraPos toDictionary];
  457. if (dict) {
  458. [_channel invokeMethod:@"camera#onMoveEnd" arguments:@{@"position":dict}];
  459. }
  460. }
  461. @end