// 1. 长按屏幕得到触摸点 转为地理信息坐标
// 2. 通过转化得到的地理信息坐标得到该地理坐标的信息
// 3. 添加标注和覆盖物
// 4. 重写代理方法
#import "ViewController.h"
#import <MapKit/MapKit.h>
@interface ViewController () <MKMapViewDelegate>
/** 地图显示类 */
@property (nonatomic, strong) MKMapView *mapView;
@end
@implementation ViewController
#pragma mark - 懒加载
- (MKMapView *)mapView {
if (_mapView == nil) {
MKMapView *mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
CLLocationCoordinate2D coordinate = {39.9087607478,116.3975780499};
MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.01);
MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, span);
[mapView setRegion:region];
mapView.delegate = self;
// 获取用户当前位置
mapView.showsUserLocation = YES;
[self.view addSubview:mapView];
_mapView = mapView;
// 修改当前位置的文字
// 1. 获取用户当前的位置对象 前提是必须把showUserLocation设置为YES
MKUserLocation *userLocation = mapView.userLocation;
userLocation.title = @"当前位置";
}
return _mapView;
}
/**
* 地理编码和地理反编码
* 1. 地理编码 根据具体地理信息编码为经纬度
* 2. 地理反编码 根据经纬度反编码为地理位置
*/
- (void)viewDidLoad {
[super viewDidLoad];
[self mapView];
[self addLongPressGestToMapView];
}
#pragma mark - 手势
/**
* 添加长按手势
*/
- (void)addLongPressGestToMapView {
UILongPressGestureRecognizer *longPressGest = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestAction:)];
[self.mapView addGestureRecognizer:longPressGest];
}
- (void)longPressGestAction:(UILongPressGestureRecognizer *)longPressGest {
// 长按开始
if (longPressGest.state == UIGestureRecognizerStateBegan) {
// 0. 移除所有的标注和覆盖物
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView removeOverlays:self.mapView.overlays];
// 1. 获取手指点击在mapView上的点
CGPoint point = [longPressGest locationInView:self.mapView];
// 2. 将 手指点击的点 转化为 地理坐标信息
CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
/**
2.5 地理反编码 经纬度->具体地理信息
*/
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { // 回调说明地理编码完成
if (error == nil) {
// CLPlacemark -> 保存地理位置 详细的信息 而 CLLocation 海平面等
CLPlacemark *placemark = placemarks[0];
NSLog(@"名字 %@",placemark.name);
NSLog(@"街道 %@",placemark.thoroughfare);
NSLog(@"市 %@",placemark.locality);
NSLog(@"区 %@",placemark.subLocality);
NSLog(@"省 %@",placemark.administrativeArea);
// 地理编码成功
// 3. 创建大头针
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init];
pointAnnotation.coordinate = coordinate;
pointAnnotation.title = placemark.name;
// 4. 添加大头针 -> 这个方法会走到代理方法
[self.mapView addAnnotation:pointAnnotation];
// 5. 覆盖物 Overlay 以coordinate为中心点 500为半径的圆
MKCircle *circle = [MKCircle circleWithCenterCoordinate:coordinate radius:100.0f]; // 这样覆盖物不显示,需要重写代理方法,找返回覆盖物的线条颜色
[self.mapView addOverlay:circle];
}
}];
#if 0
/**
* 4.5 地理编码
*/
[geocoder geocodeAddressString:@"天安门" completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil) {
CLPlacemark *placemark = placemarks[0];
CLLocationCoordinate2D coordinate = placemark.location.coordinate;
NSLog(@"纬度:%f 经度: %f", coordinate.latitude,coordinate.longitude);
}
}];
#endif
}
}
/**
* 添加标注或者是添加覆盖物都是和代理方法分不开的。
*/
#pragma mark - MKMapView 代理方法
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
// 如果是用户当前位置 不定制标注
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
MKPinAnnotationView *pin = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"annotation"];
if (pin == nil) {
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotation"];
pin.canShowCallout = YES;
// 大头针从天上掉下来的动画
pin.animatesDrop = YES;
}
return pin;
}
/**
* 添加覆盖物的时候会触发 只要一调用addOverlay就会调到这里来
*/
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
// 覆盖物有三种
/**
* 1. MKCircle 圆形覆盖物
* 2. MKPolygon 多边形覆盖物
* 3. MKPolyline 线的覆盖物
*/
if ([overlay isKindOfClass:[MKCircle class]]) {
// MKCircleRenderer -> MKOverlayPathRenderer -> MKOverlayRenderer
MKCircleRenderer *circleRenderer = [[MKCircleRenderer alloc] initWithCircle:overlay];
// 线条颜色
circleRenderer.strokeColor = [UIColor redColor];
// 线条宽度
circleRenderer.lineWidth = 5.0f;
// 填充颜色
circleRenderer.fillColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3]; // 颜色的设置 带着透明度
return circleRenderer;
} else if ([overlay isKindOfClass:[MKPolygon class]]) {
MKPolygonRenderer *polygonRenderer = [[MKPolygonRenderer alloc] initWithPolygon:overlay];
// 线条颜色
polygonRenderer.strokeColor = [UIColor redColor];
// 线条宽度
polygonRenderer.lineWidth = 5.0f;
// 填充颜色
polygonRenderer.fillColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3];
} else if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineRenderer *polylineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
// 线条颜色
polylineRenderer.strokeColor = [UIColor redColor];
// 线条宽度
polylineRenderer.lineWidth = 5.0f;
// 填充颜色
polylineRenderer.fillColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3];
}
return nil;
}
@end
导航地图4_地理编码和反编码
最新推荐文章于 2020-07-31 16:36:58 发布