IOS开发中地图实现国内高德地图、国外Google地图逻辑

App需求如下:
1,App连接蓝牙设备,此时App端开始记录GPS位置信息;
2,App蓝牙连接断开,此时App端统计GPS位置轨迹,并绘制在地图上显示

使用2种地图原因:高德地图国外显示不了、Google地图国内显示不了
注:还有一个原因是因为通过手机系统SDK获取得到的GPS位置有偏移
系统SDK得到的位置为国际标准WGS-84
国内的位置标准为GCJ-02(火星坐标)

由于业务需求,我在App启动的时候,就做了判断当前位置是否在国内,然后统计数据保存一个(国内、外)状态至数据库。
逻辑如下:
1,App启动,使用CLLocationManager获取到location
2,使用CLGeocoder *geocoder = [[CLGeocoder alloc] init];

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
        BOOL isChina = NO;
        if (placemarks.count > 0) {
            CLPlacemark * placemark = placemarks[0];
            //通过该判断是为CN,还有HK,TW等,自行判断吧
            isChina = [placemark.ISOcountryCode isEqualToString:@"CN"];
        }        
    }];

3,当isChina为YES时,使用高德地图来获取位置更新
当isChina为NO时,使用系统SDK来获取位置更新
(代码就不贴粗来了,应该难不到谁吧?)
4,这个时候就是贴代码的时候了【Google地图轨迹绘制】

        //默认显示【北京】也可以不设置默认
        GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:39.7072013727
                                                                longitude:116.5429835110
                                                                     zoom:12];
        _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
   //创建轨迹路径集合
   GMSMutablePath *path = [GMSMutablePath path];
    for(MALocationModel *m in locations){
        [path addLatitude:m.latitude longitude:m.longitude];        
    }
    //轨迹线图对象
    _polyline = [GMSPolyline polylineWithPath:path];
    _polyline.strokeWidth = 5;
    _polyline.map = _mapView;
    //设置地图轨迹屏幕可视区域
    GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithPath:path];
    GMSCameraPosition *position = [_mapView cameraForBounds:bounds insets:UIEdgeInsetsZero];
    _mapView.camera = position;

到了这里,地图轨迹基本就出来了(上面insets:UIEdgeInsetsZero可以自行设置)。
4.1添加起点图标【自定义View】

    CLLocationCoordinate2D position_start = CLLocationCoordinate2DMake(latitude,longitude);
    GMSMarker *start = [GMSMarker markerWithPosition:position_start];
    start.title = nil;
    start.icon = [UIImage imageNamed:@"record_map_start_icon"];
    start.map = _mapView;

注意问题:有可能轨迹地图显示的zoomlevel需要手动调整下
[_mapView animateToZoom:[self levelWithMileage:10]];【如下】


image.png

5,高德地图轨迹绘制【上代码】

self.mapView = [[MAMapView alloc] initWithFrame:self.bounds];
        self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        self.mapView.delegate = self;
        self.mapView.showsCompass = NO;
        self.mapView.showsScale = NO;
        self.mapView.zoomLevel = 17;
//显示轨迹
-(void)showDefaultMap
{
    NSMutableArray *arr = [NSMutableArray array];
    for(MALocationModel *m in self.recordInfo.locations){
        MATracePoint *point = [[MATracePoint alloc] init];
        point.latitude = m.latitude;
        point.longitude = m.longitude;
        [arr addObject:point];
    }
    
    CLLocationCoordinate2D start = CLLocationCoordinate2DMake(((MATracePoint *)[arr firstObject]).latitude, ((MATracePoint *)[arr firstObject]).longitude);
    CLLocationCoordinate2D end = CLLocationCoordinate2DMake(((MATracePoint *)[arr lastObject]).latitude, ((MATracePoint *)[arr lastObject]).longitude);
    
    [self addAnnotationWithCooordinate:start title:@"start"];
    [self addAnnotationWithCooordinate:end title:@"end"];
    
    self.processedOverlays = [NSMutableArray array];
    [self addFullTrace:arr toMapView:self.mapView];
}

//添加图标
-(void)addAnnotationWithCooordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title
{
    MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init];
    annotation.coordinate = coordinate;
    annotation.title    = title;
    annotation.subtitle = @"CustomAnnotationView2";
    
    [self.mapView addAnnotation:annotation];
}



- (void)addFullTrace:(NSArray *)tracePoints toMapView:(MAMapView *)mapView
{
    [self.mapView hiddenHUD];
    
    //此类用于定义一个由多个点相连的多段线
    MAMultiPolyline *polyline = [self makePolyLineWith:tracePoints];
    if(!polyline) {
        return;
    }
    
    [self.processedOverlays addObject:polyline];
    [mapView addOverlays:self.processedOverlays];
    
    UIEdgeInsets edge = UIEdgeInsetsMake(20, 20, 20, 20);
    if (_showSetting) {
        edge = UIEdgeInsetsMake(50, 30, 50, 30);
    }
    [mapView setVisibleMapRect:polyline.boundingMapRect edgePadding:edge animated:NO];
    
    [mapView setZoomLevel:[self levelWithMileage:self.recordInfo.distance/1000.f] animated:NO];
}

//划线
- (MAMultiPolyline *)makePolyLineWith:(NSArray *)tracePoints {
    if(tracePoints.count == 0) {
        return nil;
    }
    CLLocationCoordinate2D *pCoords = malloc(sizeof(CLLocationCoordinate2D) * tracePoints.count);
    if(!pCoords) {
        return nil;
    }
    for(int i = 0; i < tracePoints.count; ++i) {
        MATracePoint *p = [tracePoints objectAtIndex:i];
        CLLocationCoordinate2D *pCur = pCoords + i;
        pCur->latitude = p.latitude;
        pCur->longitude = p.longitude;
    }
    //分段绘制,根据经纬度坐标数据生成多段线
    MAMultiPolyline *polyline = [MAMultiPolyline polylineWithCoordinates:pCoords count:tracePoints.count drawStyleIndexes:@[@10, @60]];
    if(pCoords) {
        free(pCoords);
    }
    return polyline;
}

//绘制覆盖物
#pragma mark - MAMapViewDelegate
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id )overlay
{
    if ([overlay isKindOfClass:[MAMultiPolyline class]])
    {
        MAPolylineRenderer *polylineView = [[MAPolylineRenderer alloc] initWithPolyline:(MAPolyline *)overlay];
        
        polylineView.lineWidth   = 6.f;
        polylineView.strokeColor = RGB(0, 182, 249);
        //路线填充图片
        polylineView.strokeImage = [UIImage imageNamed:@"icon_map_arrow"];
        polylineView.lineJoinType = kCGLineJoinRound;//连接类型
        polylineView.lineCapType = kCGLineCapRound;//端点类型
        
        
        return polylineView;
    }
    
    return nil;
}

- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation
{
    if ([annotation isKindOfClass:[MAPointAnnotation class]]) {
        static NSString *ident = @"pointIdent";
        MAAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:ident];
        
        if (annotationView == nil)
        {
            annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ident];
            // must set to NO, so we can show the custom callout view.
            annotationView.canShowCallout = NO;
            annotationView.draggable = YES;
        }
        
        if ([annotation.title isEqualToString:@"start"]) {
            annotationView.image = [UIImage imageNamed:@"record_map_start_icon"];
        }else if ([annotation.title isEqualToString:@"end"]){
            annotationView.image = [UIImage imageNamed:@"record_map_end_icon"];
        }
        
        return annotationView;
    }
    return nil;
}


-(int)levelWithMileage:(CGFloat)mileage
{
    int level = 15;
    if (mileage > 1000) {
        level = 3;
    }else if (mileage > 500){
        level = 4;
    }else if (mileage > 200){
        level = 5;
    }else if (mileage > 100){
        level = 6;
    }else if (mileage > 50){
        level = 7;
    }else if (mileage > 30){
        level = 8;
    }else if (mileage > 20){
        level = 9;
    }else if (mileage > 10){
        level = 10;
    }else if (mileage > 5){
        level = 11;
    }else if (mileage > 1){
        level = 13;
    }else{
        level = 14;
    }
    
    return level;
}

你可能感兴趣的:(IOS开发中地图实现国内高德地图、国外Google地图逻辑)