flutter 高德地圖路線規(guī)劃插件IOS版

前言

在引入高德庫的前提下帚戳,Flutter筆記-調(diào)用原生IOS高德地圖sdk

以下貼上全部代碼配置

Flutter參數(shù)配置
     child: UiKitView(viewType: "com.flutter_to_path_planning.amap",
          creationParams: <String,dynamic>{
            "latitude":39.9088230000, //配置地圖顯示中心位置點(diǎn)
            "longitude":116.3974700000,
            "origin_destination":[39.9088230000,116.3974700000,39.8683,116.56078],//路線規(guī)劃配置 起點(diǎn)--終點(diǎn)
            "routeType":"1", //1駕車路線規(guī)劃  2步行出行
          },
          creationParamsCodec: new StandardMessageCodec(),
        ),
ios端注冊插件

AppDelegate.m

[FlutterMapPlugin registerWithRegistrar:[self registrarForPlugin:@"FlutterMapPlugin"]];

FlutterMapPlugin.m

  //路徑規(guī)劃
 [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;
}

//設(shè)置參數(shù)的編碼方式
-(NSObject<FlutterMessageCodec> *)createArgsCodec{
    return [FlutterStandardMessageCodec sharedInstance];
}

//用來創(chuàng)建 ios 原生view
- (nonnull NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {
    //args 為flutter 傳過來的參數(shù)
    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       = @"起點(diǎn)";
static const NSString *RoutePlanningViewControllerDestinationTitle = @"終點(diǎn)";
static const NSInteger RoutePlanningPaddingEdge                    = 20;

@interface MapPathPlanningView ()<MAMapViewDelegate,AMapSearchDelegate>
@property (nonatomic, strong) MAAnnotationView *userLocationAnnotationView;

/* 起始點(diǎn)經(jīng)緯度. */
@property (nonatomic) CLLocationCoordinate2D startCoordinate;
/* 終點(diǎn)經(jīng)緯度. */
@property (nonatomic) CLLocationCoordinate2D destinationCoordinate;

@property (nonatomic, strong) MAPointAnnotation *startAnnotation;
@property (nonatomic, strong) MAPointAnnotation *destinationAnnotation;


@end

@implementation MapPathPlanningView {
    
    //創(chuàng)建后的標(biāo)識
    int64_t _viewId;
    
    MAMapView *_mapView;
    
    AMapSearchAPI *_search;
    //消息回調(diào)
    FlutterMethodChannel* _channel;
    
    UIButton *gpsButton;
    
}

//在這里只是創(chuàng)建了一個(gè)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(@"接受數(shù)組:%@", origin_destination);
          NSLog(@"接數(shù)組:%@",   [origin_destination objectAtIndex:0]);
        
         NSString *routeType =args[@"routeType"];
        
        ///地圖需要v4.5.0及以上版本才必須要打開此選項(xiàng)(v4.5.0以下版本玷或,需要手動配置info.plist)
        [AMapServices sharedServices].enableHTTPS = YES;
        
        
        _mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
        _viewId = viewId;
        
        // 顯示比例尺
        _mapView.showsScale = NO;
        // 顯示指南針
        _mapView.showsCompass = NO;
        // 顯示定位藍(lán)點(diǎn)
        _mapView.showsUserLocation = YES;
        // 用戶定位模式
        _mapView.userTrackingMode = MAUserTrackingModeFollow;
        // 設(shè)置縮放級別
        [_mapView setZoomLevel:15];
        // 設(shè)置當(dāng)前地圖的中心點(diǎn):例如默認(rèn)地圖中心顯示坐標(biāo)為(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;
            
            /* 出發(fā)點(diǎn). */
            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;
}

//實(shí)現(xiàn)路徑搜索的回調(diào)函數(shù)
- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response
{
    if(response.route == nil)
    {
        return;
    }
    
    AMapPath *path = response.route.paths[0]; //選擇一條路徑
    AMapStep *step = path.steps[0]; //這個(gè)路徑上的導(dǎo)航路段數(shù)組
    NSLog(@"%@",step.polyline);   //此路段坐標(biāo)點(diǎn)字符串
    
    
    MAPolyline *_polyline;
    
    if (response.count > 0)
    {
        //      //直接取第一個(gè)方案
        AMapPath *path = response.route.paths[0];
        //移除舊折線對象
        [_mapView removeOverlay:_polyline];
        //構(gòu)造折線對象
        _polyline = [self polylinesForPath:path];
        //添加新的遮蓋,然后會觸發(fā)代理方法(- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay)進(jìn)行繪制
        [_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;
}

//解析經(jīng)緯度
- (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;
}

//繪制遮蓋時(shí)執(zhí)行的代理方法
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
{
    /* 自定義定位精度對應(yīng)的MACircleView. */
    
    //畫路線
    if ([overlay isKindOfClass:[MAPolyline class]])
    {
        //初始化一個(gè)路線類型的view
        MAPolylineRenderer *polygonView = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
        //設(shè)置線寬顏色等
        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片任,就進(jìn)行了添加
        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 根據(jù)anntation生成對應(yīng)的View
 * @param mapView 地圖View
 * @param annotation 指定的標(biāo)注
 * @return 生成的標(biāo)注View
 */
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation {
    if ([annotation isKindOfClass:[MAUserLocation class]]) {//定位藍(lán)點(diǎn)
        static NSString *reuseIndetifier = @"annotationReuseIndetifier";
        MAAnnotationView *annotationView = (MAAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier];
        if (annotationView == nil) {
            annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation
                                                          reuseIdentifier:reuseIndetifier];
        }
        // 設(shè)置標(biāo)記點(diǎn)的圖片
        annotationView.image = [UIImage imageNamed:@"userPosition"];
        annotationView.canShowCallout= YES;       //設(shè)置氣泡可以彈出偏友,默認(rèn)為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;
        
        /* 起點(diǎn). */
        if ([[annotation title] isEqualToString:(NSString*)RoutePlanningViewControllerStartTitle])
        {
            poiAnnotationView.image = [UIImage imageNamed:@"startPoint"];
        }
        /* 終點(diǎn). */
        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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蚂踊,隨后出現(xiàn)的幾起案子约谈,更是在濱河造成了極大的恐慌犁钟,老刑警劉巖涝动,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件醋粟,死亡現(xiàn)場離奇詭異重归,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)育苟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門椎木,熙熙樓的掌柜王于貴愁眉苦臉地迎上來违柏,“玉大人漱竖,你說我怎么就攤上這事畜伐。” “怎么了万矾?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵勤众,是天一觀的道長。 經(jīng)常有香客問我们颜,道長,這世上最難降的妖魔是什么努溃? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任梧税,我火速辦了婚禮称近,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凳谦。我一直安慰自己衡未,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布如失。 她就那樣靜靜地躺著褪贵,像睡著了一般葫督。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上橄镜,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天洽胶,我揣著相機(jī)與錄音裆馒,去河邊找鬼喷好。 笑死读跷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的无切。 我是一名探鬼主播丐枉,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼瘦锹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弯院?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤识补,失蹤者是張志新(化名)和其女友劉穎辫红,沒想到半個(gè)月后贴妻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝙斜,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年娩鹉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弯予。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片个曙。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呼寸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情河狐,我是刑警寧澤瑟捣,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站丈钙,受9級特大地震影響交汤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜星岗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一俏橘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寥掐,春花似錦磷蜀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至固惯,卻和暖如春掉伏,著一層夾襖步出監(jiān)牢的瞬間澳窑,已是汗流浹背供常。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工栈暇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人源祈。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓香缺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锋拖。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360