D28:系统地图, 高德地图

目录

一. 定位功能

iPhone手机定位(基站定位, WiFi定位, GPS定位: 定位所需时间递增, 精确度递增)

  1. 导入CoreLocation库
  2. 创建CLLocationManager对象
  3. 设置更新位置的周期(距离)
  4. 设置定位的精度
  5. 开始定位
  6. iOS8中要在Info.plist添加一组键值对, 并执行- (void)requestWhenInUseAuthorization方法
  7. 遵守协议后可以获取更新位置

二. 系统地图

  1. 导入MapKit库
  2. 创建地图对象, 设置地图类型, 地图区域(region包含中心点和半径), 显示视图
  3. 定位当前位置(除了CLLocationManager对象外, 要设置显示位置_mapView.showsUserLocation = YES)
  4. 在CLLocationManager的代理方法中, 设置将地图位置设置地图的中心点[_mapView setCenterCoordinate:loc.coordinate animated:YES]

三. 系统地图的大头针

  1. 设置地图对象
  2. 设置大头针(一般通过手势点击来添加大头针MKPointAnnotation: 需要设置其经纬度, 酌情设置大小标题和左右视图)
  3. 显示大头针: 设置地图对象的代理, 遵守MKMapViewDelegate协议- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
  4. 想要通过点击大头针的Callout视图中的UIControl对象调用方法的话, 需要遵守MKMapViewDelegate协议实现代理方法 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
  • 注意点: 如果想创建静态图片作为大头针图片的话,可以创建MKAnnotationView实例;如果想使用apple自带的大头针则创建MKPinAnnotationView

If the annotation can be represented by a static image, create an instance of the MKAnnotationView class and assign the image to its image property; see “Using the Standard Annotation Views.”
If you want to use a standard pin annotation, create an instance of the MKPinAnnotationView class; see “Using the Standard Annotation Views.”

四. 自定义大头针

  1. 自定义大头针类MyAnnotation(需要遵守MKAnnotation协议, 需要自己设标题, 副标题, 经纬度; 不需要设置左右两个视图)
  2. 显示mapView, 在mapView上添加长按手势以添加自定义Annotation, 在代理方法中- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation中显示Annotation(可以设置Annotation的图片, 添加左右CalloutAccessoryView)
  3. 之后就可以通过一些设置来弹出视图, 传参......

五. 地址解析和反地址解析

六. 高德地图

  1. 前期准备: 按照官网教程
  2. 显示地图, 搜索地点, 地址解码和反解码的示例代码

一. 定位功能

1. 导入CoreLocation的头文件, 设置定位管理对象为成员变量
{
    // 定位管理对象
    CLLocationManager *_manager;
}  
2. 设置定位管理对象
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // iOS8之前做到5步就可以
    
    // 1. 创建定位管理对象
    _manager = [[CLLocationManager alloc] init];
    // 2. 表示手机移动50米才更新定位的位置
    _manager.distanceFilter = 50;
    // 3. 表示定位的精度
    _manager.distanceFilter = kCLLocationAccuracyBest;
    // 4. 设置代理
    _manager.delegate = self;
    

    // 5. 开始定位
    [_manager startUpdatingLocation];
    
    // 6. 获取手机的方向, 去对应代理方法中获取
//    [_manager startUpdatingHeading];
    
    // iOS8需要设置Info.plist文件里面的值
    // NSLocationWhenInUseUsageDescription == YES
    // NSLocationAlwaysUsageDescription == YES
    if ([_manager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [_manager requestWhenInUseAuthorization];
    }

    if ([_manager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [_manager requestAlwaysAuthorization];
    }
    
}  
3. 在-Supporting Files文件夹下的Info.plist添加一个boolean类型的键值对NSLocationWhenInUseUsageDescription, 并设为YES, 如下图所示
D28:系统地图, 高德地图_第1张图片
示意图
4. 遵守协议, 实现代理方法
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"error:%@", error);
}

// iOS6之前
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    
}

// 定位成功后
// iOS6之后
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    if (locations.count > 0) {
        // 获取位置信息
        CLLocation *loc = [locations lastObject];
        
        CLLocationCoordinate2D coor = loc.coordinate;
        
//        NSLog(@"%@", locations);
        NSLog(@"latitude: %lf, longitude: %lf", coor.latitude, coor.longitude);
        
        /*
         计算速度
         速度 = 位移 / 时间
         */
//        if (_lastLoc) {
//            
//            // 计算位置 将一个位置设为成员变量
//            CLLocationDistance dis = [loc distanceFromLocation:_lastLoc];
//            // 计算时间
//            NSTimeInterval time = [loc.timestamp timeIntervalSinceDate:_lastLoc.timestamp];
//            
//            CGFloat speed = dis / time;
//            
//            _lastLoc = loc;
//        }
    }
    
    // 关闭定位
    [_manager stopUpdatingLocation];
    
    // 关闭获取定位方向
    // [_manager stopUpdatingHeading];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    // 相对地理北极的方向
//    newHeading.trueHeading;
    
    // 相对磁北极的方向
//    newHeading.magneticHeading;
}

二. 系统地图

1. 导入MapKit/MapKit.h, 创建地图视图对象成员变量
@interface ViewController () 
{
   // 地图对象
   MKMapView *_mapView;
}
2. 新建地图对象, 设置属性
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 1. 创建地图对象
    _mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 20, 320, 568 - 20)];
    // 2. 地图类型
    /*
     MKMapTypeStandard,
     MKMapTypeSatellite,
     MKMapTypeHybrid
     */
    _mapView.mapType = MKMapTypeHybrid;
    // 3. 设置代理
    _mapView.delegate = self;
    // 4. 显示地图
    [self.view addSubview:_mapView];
    
    // 5. 设置地图的位置
    // 中心点
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(31, 121);
    // center = {32, 122}; 另一种创建结构体的方式
    // span 0-1
    MKCoordinateSpan span = MKCoordinateSpanMake(0.2, 0.2);
    // 区域
    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
    _mapView.region = region;
    
}  
3. 定位到所在位置: 创建定位管理对象, 遵守CLLocationManagerDelegate协议, 实现协议方法
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 开启定位功能
    _manager = [[CLLocationManager alloc] init];
    // 每隔多少距离使用位置更新数据
    _manager.distanceFilter = 50;
    // 定位的精度
    _manager.desiredAccuracy = kCLLocationAccuracyBest;
    // 代理属性
    _manager.delegate = self;
    
    [_manager startUpdatingLocation];
    
    // iOS8
    // NSLocationWhenInUseUsageDescription == YES;
    if ([_manager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [_manager requestWhenInUseAuthorization];
    }
    
    // 地图对象
    …………………………………………………………………………………………
            
    // 6. 显示定位位置
    _mapView.showsUserLocation = YES;
}

#pragma mark - CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"error:%@", error);
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    if (locations.count > 0) {
        CLLocation *loc = locations[0];
        
        // 将地图位置设置地图的中心点
        [_mapView setCenterCoordinate:loc.coordinate animated:YES];
    }
}

三. 系统地图的大头针

1. 设置好地图和大头针(大头针暂时不会显示)
#import "ViewController.h"
#import 

@interface ViewController ()
{
    MKMapView *_mapView;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 创建一个视图
    _mapView = [[MKMapView alloc] initWithFrame:CGRectMake(30, 100, 300, 500)];
    _mapView.mapType = MKMapTypeStandard;
    [self.view addSubview: _mapView];

    // 设置区域
    // 1. 中心点
    /*
    typedef struct {
        CLLocationDegrees latitude;
        CLLocationDegrees longitude;
    } CLLocationCoordinate2D;
     */
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(39, 116);
    // 2. 半径
    /*
     typedef struct {
     CLLocationDegrees latitudeDelta;
     CLLocationDegrees longitudeDelta;
     } MKCoordinateSpan;
     */
    MKCoordinateSpan span = MKCoordinateSpanMake(0.2, 0.2);
    // 3. 区域
    /*
     typedef struct {
     CLLocationCoordinate2D center;
     MKCoordinateSpan span;
     } MKCoordinateRegion;
     */
    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
    
    _mapView.region = region;
    
    // 添加一个长按手势, 点击后, 在这个位置加一个大头针
    // 在实际项目中, 需要去请求一个接口, 返回的数据对象中会包含每个对象的经纬度信息, 然后根据经纬度去显示一个大头针
    [_mapView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)]];
}

- (void)longPressAction:(UILongPressGestureRecognizer *)gesture
{
    // 获取经纬度信息
    CGPoint point = [gesture locationInView:_mapView];
    // 坐标转换为经纬度
    CLLocationCoordinate2D coor = [_mapView convertPoint:point toCoordinateFromView:_mapView];
    
    // 添加大头针
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    // 设置经纬度
    annotation.coordinate = coor;
    // 标题
    annotation.title = @"大标题";
    // 小标题
    annotation.subtitle = @"小标题";  
    
    [_mapView addAnnotation:annotation];

}
2. 显示大头针, 以及大头针的标题: 设置地图对象的代理, 遵守MKMapViewDelegate协议
- (void)viewDidLoad {
    …………………………………………………………………………………………
    _mapView.delegate = self;
}

#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
{
    // 重用ID
    static NSString *annotationId = @"annotationId";
    
    // 从重用队列中获取
    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationId];
    if (nil == annotationView) {
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationId];
    }
    
    // 设置属性
    annotationView.canShowCallout = YES;
    
    return annotationView;
}
3. 点击大头针, 在弹出的视图左右显示视图(如果是UIControl的子类的话, 点击调用的方法要实现代理方法 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control里面)
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
{
    …………………………………………………………………………………………
            
    // 在左边显示图片
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
    imageView.image = [UIImage imageNamed:@"blue.png"];
    annotationView.leftCalloutAccessoryView = imageView;

    // 在右边显示一个按钮
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    annotationView.rightCalloutAccessoryView = btn;
    
    return annotationView;
}  

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    NSLog(@"%s", __func__);
}

四. 自定义大头针

1. 自定义大头针类MyAnnotation(需要遵守MKAnnotation协议, 需要自己设标题, 副标题, 经纬度; 不需要设置左右两个视图)
#import 
#import 

/*
 自定义大头针类型
 title:     标题
 subtitle:  小标题
 */

@interface MyAnnotation : NSObject 

- (instancetype)initWithCoor:(CLLocationCoordinate2D)coor title:(NSString *)title subtitle:(NSString *)subTitle;

@end

#import "MyAnnotation.h"

@implementation MyAnnotation
{
    // 经纬度
    CLLocationCoordinate2D _myCoor;
    // 标题
    NSString *_myTitle;
    // 副标题
    NSString *_mySubtitle;
}

- (instancetype)initWithCoor:(CLLocationCoordinate2D)coor title:(NSString *)title subtitle:(NSString *)subtitle
{
    if (self = [super init]) {
        _myCoor = coor;
        _myTitle = title;
        _mySubtitle = subtitle;
    }
    return self;
}

#pragma mark - MKAnnotation
- (NSString *)title
{
    return _myTitle;
}

- (NSString *)subtitle
{
    return _mySubtitle;
}

- (CLLocationCoordinate2D)coordinate
{
    return _myCoor;
}

@end
2. 显示mapView, 在mapView上添加长按手势以添加自定义Annotation, 在代理方法中- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation中显示Annotation(可以设置Annotation的图片, 添加左右CalloutAccessoryView)
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
{
    static NSString *annoId = @"annoId";
    
    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:annoId];
    if (nil == annoView) {
        annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annoId];
    }
    
    annoView.image = [UIImage imageNamed:@"mark"];
    
    annoView.canShowCallout = YES;
    
    // 右边添加按钮
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    annoView.rightCalloutAccessoryView = btn;

    return annoView;
}
3. 之后就可以通过一些设置来弹出视图, 传参......

五. 系统地图的地址解析和反地址解析

地址解析: 将地址解析为经纬度
反地址解析: 将经纬度解析为地址

#import "ViewController.h"
#import "MyUtility.h"
#import 

@interface ViewController ()
{
    // 地址输入框
    UITextField *_addressTextField;
    // 经纬度
    UITextField *_latitudeTextField;
    UITextField *_longitudeTextField;
    
    // 解析对象
    CLGeocoder *_geocoder;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self createView];
    
    // 初始化解析对象
    _geocoder = [[CLGeocoder alloc] init];
}

- (void)createView
{
    // 地址
    _addressTextField = [MyUtility createTextField:CGRectMake(30, 100, 200, 40) placeHolder:@"请输入地址"];
    [self.view addSubview:_addressTextField];
    
    UIButton *parserBtn = [MyUtility createButtonWithFrame:CGRectMake(240, 100, 60, 40) title:@"解析" backgroundImageName:nil target:self action:@selector(geoAction)];
    [self.view addSubview:parserBtn];
    
    // 经纬度
    _latitudeTextField = [MyUtility createTextField:CGRectMake(30, 200, 90, 40) placeHolder:@"纬度"];
    [self.view addSubview:_latitudeTextField];
    
    _longitudeTextField = [MyUtility createTextField:CGRectMake(140, 200, 90, 40) placeHolder:@"经度"];
    [self.view addSubview:_longitudeTextField];
    
    UIButton *reverseBtn = [MyUtility createButtonWithFrame:CGRectMake(240, 200, 60, 40) title:@"泛解析" backgroundImageName:nil target:self action:@selector(reverseGeoAction)];
    [self.view addSubview:reverseBtn];
}

// 地址解析
- (void)geoAction
{
    if (_addressTextField.text.length > 0) {
        // 解析
        [_geocoder geocodeAddressString:_addressTextField.text completionHandler:^(NSArray *placemarks, NSError *error) {
           
            // 解析结束时调用该block
            NSLog(@"%@", placemarks);
            
            for (CLPlacemark *placemark in placemarks) {
                // placemark 是符合条件的地址信息
                NSLog(@"ISOcountryCode:%@", placemark.ISOcountryCode);
                NSLog(@"administrativeArea:%@", placemark.administrativeArea);
                NSLog(@"addressDictionary:%@", placemark.addressDictionary);
                NSLog(@"latitude:%lf\nlongitude:%lf", placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
            }
        }];
    }
}

// 反地址解析
- (void)reverseGeoAction
{
    if (_longitudeTextField.text.length > 0 &&  _latitudeTextField.text.length > 0) {
        // 反解析
        CLLocation *loc = [[CLLocation alloc] initWithLatitude:_latitudeTextField.text.floatValue longitude:_longitudeTextField.text.floatValue];
        
        [_geocoder reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error) {
            for (CLPlacemark *placemark in placemarks) {
                NSLog(@"%@", placemark.addressDictionary);
                NSLog(@"%@", [placemark.addressDictionary objectForKey:@"City"]);
            }
        }];
    }
}

六. 高德地图

1. 前期准备: 按照官网教程
2. 显示地图, 搜索地点, 地址解码和反解码的示例代码
#import "MyUtility.h"
#import "ViewController.h"
#import 
#import 

#define kAMapKey (@"97ae63c2d20ed3b23767312e2d2ab609")

@interface ViewController () 
{
    // 地图
    MAMapView *_mapView;
    // 搜索对象(搜索, 解析都需要该对象)
    AMapSearchAPI *_searchAPI;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 设置key值
    [MAMapServices sharedServices].apiKey = kAMapKey;
    
    _searchAPI =[[AMapSearchAPI alloc] initWithSearchKey:kAMapKey Delegate:self];

    // 创建高德地图
    _mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 100, 320, 568 - 100)];
    _mapView.mapType = MAMapTypeStandard;
    _mapView.delegate = self;
    [self.view addSubview:_mapView];
    
    // 添加三个按钮
    [self createThreeButton];
}

- (void)createThreeButton
{
    UIButton *addSearchButton = [MyUtility createButtonWithFrame:CGRectMake(30, 30, 100, 40) title:@"搜地址" backgroundImageName:nil target:self action:@selector(searchPalce)];
    UIButton *geocoderButton = [MyUtility createButtonWithFrame:CGRectMake(140, 30, 100, 40) title:@"解析" backgroundImageName:nil target:self action:@selector(geocoderAction)];
    UIButton *reverseGeocoderButton = [MyUtility createButtonWithFrame:CGRectMake(250, 30, 60, 40) title:@"反解析" backgroundImageName:nil target:self action:@selector(reverseGeocoderAction)];
    [self.view addSubview:addSearchButton];
    [self.view addSubview:geocoderButton];
    [self.view addSubview:reverseGeocoderButton];
    
}

- (void)searchPalce
{
    AMapPlaceSearchRequest *request = [[AMapPlaceSearchRequest alloc] init];
    // 设置搜索的类型
    request.searchType = AMapSearchType_PlaceKeyword;
    // 城市的数组
    request.city = @[@"北京"];
    // 搜索关键字
    request.keywords = @"江南";
    
    // 搜索
    [_searchAPI AMapPlaceSearch:request];
}

// 地址解析
- (void)geocoderAction
{
    AMapGeocodeSearchRequest *request = [[AMapGeocodeSearchRequest alloc] init];
    // 类型
    request.searchType = AMapSearchType_Geocode;
    // 城市
    request.city = @[@"beijing"];
    // 地址
    request.address = @"天安门";
    
    // 搜索
    [_searchAPI AMapGeocodeSearch:request];
}

- (void)reverseGeocoderAction
{
    AMapReGeocodeSearchRequest *request = [[AMapReGeocodeSearchRequest alloc] init];
    // 类型
    request.searchType = AMapSearchType_ReGeocode;
    // 设置经纬度
    AMapGeoPoint *point = [[AMapGeoPoint alloc] init];
    point.latitude = 31;
    point.longitude = 121;
    request.location = point;
    
    // 是否返回扩展信息
    request.requireExtension = YES;
    
    [_searchAPI AMapReGoecodeSearch:request];
}

- (void)obtainBundleIdentifier
{
    NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
    NSLog(@"%@", bundleIdentifier);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - AMapSearchAPI代理
// 地址搜索
- (void)onPlaceSearchDone:(AMapPlaceSearchRequest *)request response:(AMapPlaceSearchResponse *)response
{
    NSMutableArray *array = [NSMutableArray array];
    for (AMapPOI *poi in response.pois) {
        
        // poi.location.latitude
        // 创建一个大头针对象
        MAPointAnnotation *anno = [[MAPointAnnotation alloc] init];
        anno.coordinate = CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude);
        anno.title = poi.name;
        anno.subtitle = poi.city;
        
        [array addObject:anno];
    }
    
    // 移除之前的大头针
    [_mapView removeAnnotations:_mapView.annotations];
    // 添加到地图上
    [_mapView addAnnotations:array];
}

// 地址解析
- (void)onGeocodeSearchDone:(AMapGeocodeSearchRequest *)request response:(AMapGeocodeSearchResponse *)response
{
    NSMutableArray *array = [NSMutableArray array];
    for (AMapGeocode *geoCode in response.geocodes) {
        
        // 创建大头针
        MAPointAnnotation *anno = [[MAPointAnnotation alloc] init];
        anno.coordinate = CLLocationCoordinate2DMake(geoCode.location.latitude, geoCode.location.longitude);
        anno.title = geoCode.formattedAddress;
        
        [array addObject:anno];
    }
    // 移除之前的大头针
    [_mapView removeAnnotations:_mapView.annotations];
    // 添加到地图上
    [_mapView addAnnotations:array];
}

- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
    NSLog(@"%@", response.regeocode.formattedAddress);
    
    AMapPlaceSearchRequest *request1 = [[AMapPlaceSearchRequest alloc] init];
    // 设置搜索的类型
    request1.searchType = AMapSearchType_PlaceKeyword;
    // 城市的数组
    request1.city = @[@"上海"];
    // 搜索关键字
    request1.keywords = response.regeocode.formattedAddress;
    
    // 搜索
    [_searchAPI AMapPlaceSearch:request1];

}

#pragma mark - MAMapView代理
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation
{
    static NSString *annoId = @"annoId";
    
    MAAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:annoId];
    if (nil == annoView) {
        annoView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annoId];
    }
    
    annoView.canShowCallout = YES;
    
    return annoView;
}

@end

你可能感兴趣的:(D28:系统地图, 高德地图)