前言
在引入高德库的前提下,Flutter笔记-调用原生IOS高德地图sdk
以下贴上全部代码配置
Flutter参数配置
child: UiKitView(viewType: "com.flutter_to_path_planning.amap",
creationParams: <String,dynamic>{
"latitude":39.9088230000, //配置地图显示中心位置点
"longitude":116.3974700000,
"origin_destination":[39.9088230000,116.3974700000,39.8683,116.56078],//路线规划配置 起点--终点
"routeType":"1", //1驾车路线规划 2步行出行
},
creationParamsCodec: new StandardMessageCodec(),
),
ios端注册插件
AppDelegate.m
[FlutterMapPlugin registerWithRegistrar:[self registrarForPlugin:@"FlutterMapPlugin"]];
FlutterMapPlugin.m
//路径规划
[registrar registerViewFactory:[[PathPlanningFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.flutter_to_path_planning.amap"];
PathPlanningFactory.m
#import "PathPlanningFactory.h"
#import "MapPathPlanningView.h"
@implementation PathPlanningFactory {
NSObject<FlutterBinaryMessenger>*_messenger;
}
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger> *)messager{
self = [super init];
if (self) {
_messenger = messager;
}
return self;
}
//设置参数的编码方式
-(NSObject<FlutterMessageCodec> *)createArgsCodec{
return [FlutterStandardMessageCodec sharedInstance];
}
//用来创建 ios 原生view
- (nonnull NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {
//args 为flutter 传过来的参数
MapPathPlanningView *mapView = [[MapPathPlanningView alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
return mapView;
}
@end
MapPathPlanningView.m
#import "MapPathPlanningView.h"
#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapSearchKit/AMapSearchKit.h>
static const NSString *RoutePlanningViewControllerStartTitle = @"起点";
static const NSString *RoutePlanningViewControllerDestinationTitle = @"终点";
static const NSInteger RoutePlanningPaddingEdge = 20;
@interface MapPathPlanningView ()<MAMapViewDelegate,AMapSearchDelegate>
@property (nonatomic, strong) MAAnnotationView *userLocationAnnotationView;
/* 起始点经纬度. */
@property (nonatomic) CLLocationCoordinate2D startCoordinate;
/* 终点经纬度. */
@property (nonatomic) CLLocationCoordinate2D destinationCoordinate;
@property (nonatomic, strong) MAPointAnnotation *startAnnotation;
@property (nonatomic, strong) MAPointAnnotation *destinationAnnotation;
@end
@implementation MapPathPlanningView {
//创建后的标识
int64_t _viewId;
MAMapView *_mapView;
AMapSearchAPI *_search;
//消息回调
FlutterMethodChannel* _channel;
UIButton *gpsButton;
}
//在这里只是创建了一个UILabel
-(instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject<FlutterBinaryMessenger> *)messenger{
if ([super init]) {
//double atitu2de = args[@"latitude"];
//NSInteger _latitude = args[@"latitude"];
NSNumber *latitude = args[@"latitude"];
NSNumber *longitude = args[@"longitude"];
NSArray *origin_destination = args[@"origin_destination"];
NSLog(@"接受数组:%@", origin_destination);
NSLog(@"接数组:%@", [origin_destination objectAtIndex:0]);
NSString *routeType =args[@"routeType"];
///地图需要v4.5.0及以上版本才必须要打开此选项(v4.5.0以下版本,需要手动配置info.plist)
[AMapServices sharedServices].enableHTTPS = YES;
_mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
_viewId = viewId;
// 显示比例尺
_mapView.showsScale = NO;
// 显示指南针
_mapView.showsCompass = NO;
// 显示定位蓝点
_mapView.showsUserLocation = YES;
// 用户定位模式
_mapView.userTrackingMode = MAUserTrackingModeFollow;
// 设置缩放级别
[_mapView setZoomLevel:15];
// 设置当前地图的中心点:例如默认地图中心显示坐标为(39.9088230000, 116.3974700000)
_mapView.centerCoordinate = CLLocationCoordinate2DMake([latitude doubleValue],[longitude doubleValue]);
_mapView.delegate = self;
UIView *zoomPannelView = [self makeZoomPannelView];
zoomPannelView.center = CGPointMake(self.view.bounds.size.width - CGRectGetMidX(zoomPannelView.bounds) - 10,
self.view.bounds.size.height - CGRectGetMidY(zoomPannelView.bounds) - 255);
zoomPannelView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
[_mapView addSubview:zoomPannelView];
gpsButton = [self makeGPSButtonView];
gpsButton.center = CGPointMake(_mapView.bounds.size.height - CGRectGetMidX(gpsButton.bounds) - 10,
_mapView.bounds.size.height - CGRectGetMidY(gpsButton.bounds) + 50);
[_mapView addSubview:gpsButton];
gpsButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
_search = [[AMapSearchAPI alloc] init];
_search.delegate = self;
self.startCoordinate = CLLocationCoordinate2DMake( [[origin_destination objectAtIndex:0] doubleValue], [[origin_destination objectAtIndex:1] doubleValue]);
self.destinationCoordinate = CLLocationCoordinate2DMake( [[origin_destination objectAtIndex:2] doubleValue], [[origin_destination objectAtIndex:3] doubleValue]);
[self addDefaultAnnotations];
if ([routeType isEqualToString:@"1"]){
AMapDrivingRouteSearchRequest *navi = [[AMapDrivingRouteSearchRequest alloc] init];
navi.requireExtension = YES;
navi.strategy = 5;
/* 出发点. */
navi.origin = [AMapGeoPoint locationWithLatitude:self.startCoordinate.latitude
longitude:self.startCoordinate.longitude];
/* 目的地. */
navi.destination = [AMapGeoPoint locationWithLatitude:self.destinationCoordinate.latitude
longitude:self.destinationCoordinate.longitude];
[_search AMapDrivingRouteSearch:navi];
} else if([routeType isEqualToString:@"2"]){
AMapWalkingRouteSearchRequest *navi = [[AMapWalkingRouteSearchRequest alloc] init];
navi.origin = [AMapGeoPoint locationWithLatitude:self.startCoordinate.latitude
longitude:self.startCoordinate.longitude];
navi.destination = [AMapGeoPoint locationWithLatitude:self.destinationCoordinate.latitude
longitude:self.destinationCoordinate.longitude];
[_search AMapWalkingRouteSearch:navi];
}
}
return self;
}
//实现路径搜索的回调函数
- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response
{
if(response.route == nil)
{
return;
}
AMapPath *path = response.route.paths[0]; //选择一条路径
AMapStep *step = path.steps[0]; //这个路径上的导航路段数组
NSLog(@"%@",step.polyline); //此路段坐标点字符串
MAPolyline *_polyline;
if (response.count > 0)
{
// //直接取第一个方案
AMapPath *path = response.route.paths[0];
//移除旧折线对象
[_mapView removeOverlay:_polyline];
//构造折线对象
_polyline = [self polylinesForPath:path];
//添加新的遮盖,然后会触发代理方法(- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay)进行绘制
[_mapView addOverlay:_polyline];
}
}
//路线解析
- (MAPolyline *)polylinesForPath:(AMapPath *)path{
if (path == nil || path.steps.count == 0){
return nil;
}
NSMutableString *polylineMutableString = [@"" mutableCopy];
for (AMapStep *step in path.steps) {
[polylineMutableString appendFormat:@"%@;",step.polyline];
}
NSUInteger count = 0;
CLLocationCoordinate2D *coordinates = [self coordinatesForString:polylineMutableString
coordinateCount:&count
parseToken:@";"];
MAPolyline *polyline = [MAPolyline polylineWithCoordinates:coordinates count:count];
free(coordinates),coordinates = NULL;
return polyline;
}
//解析经纬度
- (CLLocationCoordinate2D *)coordinatesForString:(NSString *)string
coordinateCount:(NSUInteger *)coordinateCount
parseToken:(NSString *)token{
if (string == nil){
return NULL;
}
if (token == nil){
token = @",";
}
NSString *str = @"";
if (![token isEqualToString:@","]){
str = [string stringByReplacingOccurrencesOfString:token withString:@","];
}else{
str = [NSString stringWithString:string];
}
NSArray *components = [str componentsSeparatedByString:@","];
NSUInteger count = [components count] / 2;
if (coordinateCount != NULL){
*coordinateCount = count;
}
CLLocationCoordinate2D *coordinates = (CLLocationCoordinate2D*)malloc(count * sizeof(CLLocationCoordinate2D));
for (int i = 0; i < count; i++){
coordinates[i].longitude = [[components objectAtIndex:2 * i] doubleValue];
coordinates[i].latitude = [[components objectAtIndex:2 * i + 1] doubleValue];
}
return coordinates;
}
//绘制遮盖时执行的代理方法
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
{
/* 自定义定位精度对应的MACircleView. */
//画路线
if ([overlay isKindOfClass:[MAPolyline class]])
{
//初始化一个路线类型的view
MAPolylineRenderer *polygonView = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
//设置线宽颜色等
polygonView.lineWidth = 8.f;
polygonView.strokeColor = [UIColor colorWithRed:0.015 green:0.658 blue:0.986 alpha:1.000];
polygonView.fillColor = [UIColor colorWithRed:0.940 green:0.771 blue:0.143 alpha:0.800];
polygonView.lineJoinType = kMALineJoinRound;//连接类型
//返回view,就进行了添加
return polygonView;
}
return nil;
}
- (UIView *)makeZoomPannelView
{
UIView *ret = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 53, 98)];
UIButton *incBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 53, 49)];
[incBtn setImage:[UIImage imageNamed:@"increase"] forState:UIControlStateNormal];
[incBtn sizeToFit];
[incBtn addTarget:self action:@selector(zoomPlusAction) forControlEvents:UIControlEventTouchUpInside];
UIButton *decBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 49, 53, 49)];
[decBtn setImage:[UIImage imageNamed:@"decrease"] forState:UIControlStateNormal];
[decBtn sizeToFit];
[decBtn addTarget:self action:@selector(zoomMinusAction) forControlEvents:UIControlEventTouchUpInside];
[ret addSubview:incBtn];
[ret addSubview:decBtn];
return ret;
}
- (void)zoomPlusAction
{
CGFloat oldZoom = _mapView.zoomLevel;
[_mapView setZoomLevel:(oldZoom + 1) animated:YES];
_mapView.showsScale = YES;
}
- (void)zoomMinusAction
{
CGFloat oldZoom = _mapView.zoomLevel;
[_mapView setZoomLevel:(oldZoom - 1) animated:YES];
_mapView.showsScale = NO;
}
- (UIButton *)makeGPSButtonView {
UIButton *ret = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
ret.backgroundColor = [UIColor whiteColor];
ret.layer.cornerRadius = 4;
[ret setImage:[UIImage imageNamed:@"gpsStat1"] forState:UIControlStateNormal];
[ret addTarget:self action:@selector(gpsAction) forControlEvents:UIControlEventTouchUpInside];
return ret;
}
- (void)gpsAction {
if(_mapView.userLocation.updating && _mapView.userLocation.location) {
[_mapView setCenterCoordinate:_mapView.userLocation.location.coordinate animated:YES];
[gpsButton setSelected:YES];
}
}
/**
* @brief 根据anntation生成对应的View
* @param mapView 地图View
* @param annotation 指定的标注
* @return 生成的标注View
*/
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation {
if ([annotation isKindOfClass:[MAUserLocation class]]) {//定位蓝点
static NSString *reuseIndetifier = @"annotationReuseIndetifier";
MAAnnotationView *annotationView = (MAAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier];
if (annotationView == nil) {
annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:reuseIndetifier];
}
// 设置标记点的图片
annotationView.image = [UIImage imageNamed:@"userPosition"];
annotationView.canShowCallout= YES; //设置气泡可以弹出,默认为NO
return annotationView;
}
else if ([annotation isKindOfClass:[MAPointAnnotation class]])
{
static NSString *routePlanningCellIdentifier = @"RoutePlanningCellIdentifier";
MAAnnotationView *poiAnnotationView = (MAAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:routePlanningCellIdentifier];
if (poiAnnotationView == nil)
{
poiAnnotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:routePlanningCellIdentifier];
}
poiAnnotationView.canShowCallout = YES;
poiAnnotationView.image = nil;
/* 起点. */
if ([[annotation title] isEqualToString:(NSString*)RoutePlanningViewControllerStartTitle])
{
poiAnnotationView.image = [UIImage imageNamed:@"startPoint"];
}
/* 终点. */
else if([[annotation title] isEqualToString:(NSString*)RoutePlanningViewControllerDestinationTitle])
{
poiAnnotationView.image = [UIImage imageNamed:@"endPoint"];
}
return poiAnnotationView;
}
return nil;
}
- (void)addDefaultAnnotations
{
MAPointAnnotation *startAnnotation = [[MAPointAnnotation alloc] init];
startAnnotation.coordinate = self.startCoordinate;
startAnnotation.title = (NSString*)RoutePlanningViewControllerStartTitle;
startAnnotation.subtitle = [NSString stringWithFormat:@"{%f, %f}", self.startCoordinate.latitude, self.startCoordinate.longitude];
self.startAnnotation = startAnnotation;
MAPointAnnotation *destinationAnnotation = [[MAPointAnnotation alloc] init];
destinationAnnotation.coordinate = self.destinationCoordinate;
destinationAnnotation.title = (NSString*)RoutePlanningViewControllerDestinationTitle;
destinationAnnotation.subtitle = [NSString stringWithFormat:@"{%f, %f}", self.destinationCoordinate.latitude, self.destinationCoordinate.longitude];
self.destinationAnnotation = destinationAnnotation;
[_mapView addAnnotation:startAnnotation];
[_mapView addAnnotation:destinationAnnotation];
}
- (nonnull UIView *)view {
return _mapView;
}
@end