-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCLLocation+LXLocation.m
156 lines (136 loc) · 5.48 KB
/
CLLocation+LXLocation.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// CLLocation+LXLocation.m
// CLLocation+LXLocation
//
// Created by 丿Love_wcx丶灬丨 紫軒 on 2017/11/1.
// Copyright © 2017年 丿Love_wcx丶灬丨若兮. All rights reserved.
//
#import "CLLocation+LXLocation.h"
void transform_earth_from_mars(double lat, double lng, double* tarLat, double* tarLng);
void transform_mars_from_baidu(double lat, double lng, double* tarLat, double* tarLng);
void transform_baidu_from_mars(double lat, double lng, double* tarLat, double* tarLng);
@implementation CLLocation (LXLocation)
/**
从地图坐标转化到火星坐标
@return CLLocation
*/
- (CLLocation *)lxLocationMarsFromEarth {
double lat = 0.0;
double lng = 0.0;
transform_earth_from_mars(self.coordinate.latitude, self.coordinate.longitude, &lat, &lng);
return [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
altitude:self.altitude
horizontalAccuracy:self.horizontalAccuracy
verticalAccuracy:self.verticalAccuracy
course:self.course
speed:self.speed
timestamp:self.timestamp];
}
/**
从火星坐标转化到百度坐标
@return CLLocation
*/
- (CLLocation *)lxLocationBaiduFromMars {
double lat = 0.0;
double lng = 0.0;
transform_mars_from_baidu(self.coordinate.latitude, self.coordinate.longitude, &lat, &lng);
return [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
altitude:self.altitude
horizontalAccuracy:self.horizontalAccuracy
verticalAccuracy:self.verticalAccuracy
course:self.course
speed:self.speed
timestamp:self.timestamp];
}
/**
从百度坐标到火星坐标
@return CLLocation
*/
- (CLLocation *)lxLocationMarsFromBaidu {
double lat = 0.0;
double lng = 0.0;
transform_baidu_from_mars(self.coordinate.latitude, self.coordinate.longitude, &lat, &lng);
return [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
altitude:self.altitude
horizontalAccuracy:self.horizontalAccuracy
verticalAccuracy:self.verticalAccuracy
course:self.course
speed:self.speed
timestamp:self.timestamp];
}
@end
/**
--- transform_earth_from_mars ---
参考来源:https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936
Krasovsky 1940
a = 6378245.0, 1/f = 298.3
b = a * (1 - f)
ee = (a^2 - b^2) / a^2;
*/
const double a = 6378245.0;
const double ee = 0.00669342162296594323;
bool transform_sino_out_china(double lat, double lon)
{
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
}
double transform_earth_from_mars_lat(double x, double y)
{
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x));
ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;
ret += (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0;
return ret;
}
double transform_earth_from_mars_lng(double x, double y)
{
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x));
ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;
ret += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0;
return ret;
}
void transform_earth_from_mars(double lat, double lng, double* tarLat, double* tarLng)
{
if (transform_sino_out_china(lat, lng))
{
*tarLat = lat;
*tarLng = lng;
return;
}
double dLat = transform_earth_from_mars_lat(lng - 105.0, lat - 35.0);
double dLon = transform_earth_from_mars_lng(lng - 105.0, lat - 35.0);
double radLat = lat / 180.0 * M_PI;
double magic = sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * M_PI);
*tarLat = lat + dLat;
*tarLng = lng + dLon;
}
/**
--- transform_earth_from_mars end ---
--- transform_mars_vs_bear_paw ---
参考来源:http://blog.woodbunny.com/post-68.html
*/
const double x_pi = M_PI * 3000.0 / 180.0;
void transform_mars_from_baidu(double gg_lat, double gg_lon, double *bd_lat, double *bd_lon)
{
double x = gg_lon, y = gg_lat;
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);
*bd_lon = z * cos(theta) + 0.0065;
*bd_lat = z * sin(theta) + 0.006;
}
void transform_baidu_from_mars(double bd_lat, double bd_lon, double *gg_lat, double *gg_lon)
{
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);
*gg_lon = z * cos(theta);
*gg_lat = z * sin(theta);
}