美文网首页
flutter 高德地图路线规划插件IOS版

flutter 高德地图路线规划插件IOS版

作者: 西北傻狍子 | 来源:发表于2019-08-01 20:04 被阅读0次

    前言

    在引入高德库的前提下,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
    

    相关文章

      网友评论

          本文标题:flutter 高德地图路线规划插件IOS版

          本文链接:https://www.haomeiwen.com/subject/wiqxdctx.html