@interface ViewController ()<CLLocationManagerDelegate,MKMapViewDelegate>
/**
* 定位管理器
*/
@property (nonatomic,strong) CLLocationManager *locationManager
/**
* 地理位置解码编码器
*/
@property (nonatomic,strong) CLGeocoder *geocoder
/**
* 地图控件
*/
@property (nonatomic,strong) MKMapView *mapView
/**
* 大头针
*/
@property (nonatomic,strong) MKPointAnnotation *pointAnnotation
@end
@implementation ViewController
- (CLLocationManager *)locationManager
{
if (!_locationManager) {
//创建定位管理器对象,作用是定位当前用户的经度和纬度
_locationManager = [[CLLocationManager alloc] init]
_locationManager.delegate = self
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
[_locationManager requestAlwaysAuthorization]
_locationManager.distanceFilter = 10.f
}
return _locationManager
}
- (CLGeocoder *)geocoder
{
if (!_geocoder) {
_geocoder = [[CLGeocoder alloc] init]
}
return _geocoder
}
- (MKMapView *)mapView
{
if (!_mapView) {
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]
//设置地图的类型
_mapView.maskView = MKMapTypeStandard
//显示当前用户的位置
_mapView.showsUserLocation = YES
}
return _mapView
}
- (MKPointAnnotation *)pointAnnotation
{
if (!_pointAnnotation) {
_pointAnnotation = [[MKPointAnnotation alloc] init]
}
return _pointAnnotation
}
- (void)viewDidLoad {
[super viewDidLoad]
//info.plist文件添加以下两条(或者其中一条):
//NSLocationWhenInUseUsageDescription 在使用应用期间
//NSLocationAlwaysUsageDescription 始终
[self.view addSubview:self.mapView]
if(![CLLocationManager locationServicesEnabled]||[CLLocationManager authorizationStatus]!=kCLAuthorizationStatusAuthorizedWhenInUse){
[_locationManager requestWhenInUseAuthorization]
}
[self.locationManager startUpdatingLocation]
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
[self.locationManager stopUpdatingLocation]
CLLocation *newLocation = locations[0]
CLLocationCoordinate2D oCoordinate = newLocation.coordinate
CLLocationCoordinate2D gcjPt = [JZLocationConverter wgs84ToGcj02:oCoordinate]
//定义地图的缩放比例
MKCoordinateSpan coordinateSpan
coordinateSpan.longitudeDelta = 0.1
coordinateSpan.latitudeDelta = 0.1
//为地图添加定义的内容
MKCoordinateRegion coordinateRegion
coordinateRegion.center = gcjPt
coordinateRegion.span = coordinateSpan
//添加到地图上
[self.mapView setRegion:coordinateRegion animated:YES]
[self.geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
for (CLPlacemark *place in placemarks) {
NSDictionary *location = [place addressDictionary]
//设置大头针坐标
self.pointAnnotation.coordinate = gcjPt
self.pointAnnotation.title = [location objectForKey:@"State"]
self.pointAnnotation.subtitle = [location objectForKey:@"SubLocality"]
//添加大头针对象
[self.mapView addAnnotation:self.pointAnnotation]
NSLog(@"国家:%@",[location objectForKey:@"Country"])
NSLog(@"城市:%@",[location objectForKey:@"State"])
NSLog(@"区:%@",[location objectForKey:@"SubLocality"])
}
}]
}
@end
@interface MSManageLocation : NSObject
/**
* @brief 世界标准地理坐标(WGS-84) 转换成 中国国测局地理坐标(GCJ-02)<火星坐标>
*
*
*
* @param location 世界标准地理坐标(WGS-84)
*
* @return 中国国测局地理坐标(GCJ-02)<火星坐标>
*/
+ (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location
/**
* @brief 中国国测局地理坐标(GCJ-02) 转换成 世界标准地理坐标(WGS-84)
*
*
*
* @param location 中国国测局地理坐标(GCJ-02)
*
* @return 世界标准地理坐标(WGS-84)
*/
+ (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location
/**
* @brief 世界标准地理坐标(WGS-84) 转换成 百度地理坐标(BD-09)
*
* @param location 世界标准地理坐标(WGS-84)
*
* @return 百度地理坐标(BD-09)
*/
+ (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location
/**
* @brief 中国国测局地理坐标(GCJ-02)<火星坐标> 转换成 百度地理坐标(BD-09)
*
* @param location 中国国测局地理坐标(GCJ-02)<火星坐标>
*
* @return 百度地理坐标(BD-09)
*/
+ (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location
/**
* @brief 百度地理坐标(BD-09) 转换成 中国国测局地理坐标(GCJ-02)<火星坐标>
*
* @param location 百度地理坐标(BD-09)
*
* @return 中国国测局地理坐标(GCJ-02)<火星坐标>
*/
+ (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location
/**
* @brief 百度地理坐标(BD-09) 转换成 世界标准地理坐标(WGS-84)
*
*
*
* @param location 百度地理坐标(BD-09)
*
* @return 世界标准地理坐标(WGS-84)
*/
+ (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location
@end
// jzA = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2
@implementation MSManageLocation
+ (double)transformLat:(double)x bdLon:(double)y
{
double ret = LAT_OFFSET_0(x, y)
ret += LAT_OFFSET_1
ret += LAT_OFFSET_2
ret += LAT_OFFSET_3
return ret
}
+ (double)transformLon:(double)x bdLon:(double)y
{
double ret = LON_OFFSET_0(x, y)
ret += LON_OFFSET_1
ret += LON_OFFSET_2
ret += LON_OFFSET_3
return ret
}
+ (BOOL)outOfChina:(double)lat bdLon:(double)lon
{
if (lon < RANGE_LON_MIN || lon > RANGE_LON_MAX)
return true
if (lat < RANGE_LAT_MIN || lat > RANGE_LAT_MAX)
return true
return false
}
+ (CLLocationCoordinate2D)gcj02Encrypt:(double)ggLat bdLon:(double)ggLon
{
CLLocationCoordinate2D resPoint
double mgLat
double mgLon
if ([self outOfChina:ggLat bdLon:ggLon]) {
resPoint.latitude = ggLat
resPoint.longitude = ggLon
return resPoint
}
double dLat = [self transformLat:(ggLon - 105.0)bdLon:(ggLat - 35.0)]
double dLon = [self transformLon:(ggLon - 105.0) bdLon:(ggLat - 35.0)]
double radLat = ggLat / 180.0 * M_PI
double magic = sin(radLat)
magic = 1 - jzEE * magic * magic
double sqrtMagic = sqrt(magic)
dLat = (dLat * 180.0) / ((jzA * (1 - jzEE)) / (magic * sqrtMagic) * M_PI)
dLon = (dLon * 180.0) / (jzA / sqrtMagic * cos(radLat) * M_PI)
mgLat = ggLat + dLat
mgLon = ggLon + dLon
resPoint.latitude = mgLat
resPoint.longitude = mgLon
return resPoint
}
+ (CLLocationCoordinate2D)gcj02Decrypt:(double)gjLat gjLon:(double)gjLon {
CLLocationCoordinate2D gPt = [self gcj02Encrypt:gjLat bdLon:gjLon]
double dLon = gPt.longitude - gjLon
double dLat = gPt.latitude - gjLat
CLLocationCoordinate2D pt
pt.latitude = gjLat - dLat
pt.longitude = gjLon - dLon
return pt
}
+ (CLLocationCoordinate2D)bd09Decrypt:(double)bdLat bdLon:(double)bdLon
{
CLLocationCoordinate2D gcjPt
double x = bdLon - 0.0065, y = bdLat - 0.006
double z = sqrt(x * x + y * y) - 0.00002 * sin(y * M_PI)
double theta = atan2(y, x) - 0.000003 * cos(x * M_PI)
gcjPt.longitude = z * cos(theta)
gcjPt.latitude = z * sin(theta)
return gcjPt
}
+(CLLocationCoordinate2D)bd09Encrypt:(double)ggLat bdLon:(double)ggLon
{
CLLocationCoordinate2D bdPt
double x = ggLon, y = ggLat
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * M_PI)
double theta = atan2(y, x) + 0.000003 * cos(x * M_PI)
bdPt.longitude = z * cos(theta) + 0.0065
bdPt.latitude = z * sin(theta) + 0.006
return bdPt
}
+ (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location
{
return [self gcj02Encrypt:location.latitude bdLon:location.longitude]
}
+ (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location
{
return [self gcj02Decrypt:location.latitude gjLon:location.longitude]
}
+ (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location
{
CLLocationCoordinate2D gcj02Pt = [self gcj02Encrypt:location.latitude
bdLon:location.longitude]
return [self bd09Encrypt:gcj02Pt.latitude bdLon:gcj02Pt.longitude]
}
+ (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location
{
return [self bd09Encrypt:location.latitude bdLon:location.longitude]
}
+ (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location
{
return [self bd09Decrypt:location.latitude bdLon:location.longitude]
}
+ (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location
{
CLLocationCoordinate2D gcj02 = [self bd09ToGcj02:location]
return [self gcj02Decrypt:gcj02.latitude gjLon:gcj02.longitude]
}
@end