Commit ed1c71ffdb2a586cd06e2f802f1ceb697d0c2ff2
1 parent
8c848bdd
提交0.1.7
Showing
1 changed file
with
206 additions
and
60 deletions
CNLiveLocationManager/Classes/CNLiveLocationManager.m
| ... | ... | @@ -9,9 +9,25 @@ |
| 9 | 9 | |
| 10 | 10 | #import "CNLiveLocationManager.h" |
| 11 | 11 | |
| 12 | -const double a = 6378245.0; | |
| 13 | -const double ee = 0.00669342162296594323; | |
| 14 | -const double pi = 3.14159265358979324; | |
| 12 | +//const double a = 6378245.0; | |
| 13 | +//const double ee = 0.00669342162296594323; | |
| 14 | +//const double pi = 3.14159265358979324; | |
| 15 | +#define LAT_OFFSET_0(x,y) -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x)) | |
| 16 | +#define LAT_OFFSET_1 (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0 | |
| 17 | +#define LAT_OFFSET_2 (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0 | |
| 18 | +#define LAT_OFFSET_3 (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0 | |
| 19 | + | |
| 20 | +#define LON_OFFSET_0(x,y) 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x)) | |
| 21 | +#define LON_OFFSET_1 (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0 | |
| 22 | +#define LON_OFFSET_2 (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0 | |
| 23 | +#define LON_OFFSET_3 (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0 | |
| 24 | + | |
| 25 | +#define RANGE_LON_MAX 137.8347 | |
| 26 | +#define RANGE_LON_MIN 72.004 | |
| 27 | +#define RANGE_LAT_MAX 55.8271 | |
| 28 | +#define RANGE_LAT_MIN 0.8293 | |
| 29 | +#define jzA 6378245.0 | |
| 30 | +#define jzEE 0.00669342162296594323 | |
| 15 | 31 | |
| 16 | 32 | @interface CNLiveLocationManager ()<CLLocationManagerDelegate> |
| 17 | 33 | |
| ... | ... | @@ -140,74 +156,203 @@ static CNLiveLocationManager *_manager = nil; |
| 140 | 156 | #pragma mark - |
| 141 | 157 | #pragma mark - CLLocationManagerDelegate |
| 142 | 158 | - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { |
| 143 | - CLLocation *loc = [locations objectAtIndex:0]; | |
| 144 | - | |
| 145 | - if (![self isLocationOutOfChina:[loc coordinate]]) { | |
| 146 | - //转换后的coord | |
| 147 | - CLLocationCoordinate2D coord = [self transformFromWGSToGCJ:[loc coordinate]]; | |
| 148 | - CLLocationDegrees lat = coord.latitude; | |
| 149 | - CLLocationDegrees lng = coord.longitude; | |
| 150 | - NSLog(@"当前更新位置: 纬度: (%lf), 经度: (%lf)", lat, lng); | |
| 151 | - | |
| 152 | - if (_coordinate2DBlock) { | |
| 153 | - _coordinate2DBlock(lat, lng); | |
| 154 | - } | |
| 155 | - }else { | |
| 156 | - CLLocation *location = locations.lastObject; | |
| 157 | - CLLocationDegrees lat = location.coordinate.latitude; | |
| 158 | - CLLocationDegrees lng = location.coordinate.longitude; | |
| 159 | - if (_coordinate2DBlock) { | |
| 160 | - _coordinate2DBlock(lat, lng); | |
| 161 | - } | |
| 159 | +// CLLocation *loc = [locations objectAtIndex:0]; | |
| 160 | + // | |
| 161 | + // if (![self isLocationOutOfChina:[loc coordinate]]) { | |
| 162 | + // //转换后的coord | |
| 163 | + // CLLocationCoordinate2D coord = [self transformFromWGSToGCJ:[loc coordinate]]; | |
| 164 | + // CLLocationDegrees lat = coord.latitude; | |
| 165 | + // CLLocationDegrees lng = coord.longitude; | |
| 166 | + // NSLog(@"当前更新位置: 纬度: (%lf), 经度: (%lf)", lat, lng); | |
| 167 | + // | |
| 168 | + // if (_coordinate2DBlock) { | |
| 169 | + // _coordinate2DBlock(lat, lng); | |
| 170 | + // } | |
| 171 | + // }else { | |
| 172 | + // CLLocation *location = locations.lastObject; | |
| 173 | + // CLLocationDegrees lat = location.coordinate.latitude; | |
| 174 | + // CLLocationDegrees lng = location.coordinate.longitude; | |
| 175 | + // if (_coordinate2DBlock) { | |
| 176 | + // _coordinate2DBlock(lat, lng); | |
| 177 | + // } | |
| 178 | + // } | |
| 179 | + CLLocation * location = [locations firstObject]; | |
| 180 | + CLLocationCoordinate2D coordinate2D = [self wgs84ToGcj02:[location coordinate]]; | |
| 181 | + CLLocationDegrees lat = coordinate2D.latitude; | |
| 182 | + CLLocationDegrees lng = coordinate2D.longitude; | |
| 183 | + if (_coordinate2DBlock) { | |
| 184 | + _coordinate2DBlock(lat, lng); | |
| 162 | 185 | } |
| 163 | 186 | |
| 164 | 187 | } |
| 165 | -- (CLLocationCoordinate2D)transformFromWGSToGCJ:(CLLocationCoordinate2D)wgsLoc | |
| 188 | + | |
| 189 | +#pragma mark - 定位转换 | |
| 190 | + | |
| 191 | +-(double)transformLat:(double)x bdLon:(double)y | |
| 192 | +{ | |
| 193 | + double ret = LAT_OFFSET_0(x, y); | |
| 194 | + ret += LAT_OFFSET_1; | |
| 195 | + ret += LAT_OFFSET_2; | |
| 196 | + ret += LAT_OFFSET_3; | |
| 197 | + return ret; | |
| 198 | +} | |
| 199 | + | |
| 200 | +-(double)transformLon:(double)x bdLon:(double)y | |
| 201 | +{ | |
| 202 | + double ret = LON_OFFSET_0(x, y); | |
| 203 | + ret += LON_OFFSET_1; | |
| 204 | + ret += LON_OFFSET_2; | |
| 205 | + ret += LON_OFFSET_3; | |
| 206 | + return ret; | |
| 207 | +} | |
| 208 | + | |
| 209 | +-(BOOL)outOfChina:(double)lat bdLon:(double)lon | |
| 210 | +{ | |
| 211 | + if (lon < RANGE_LON_MIN || lon > RANGE_LON_MAX) | |
| 212 | + return true; | |
| 213 | + if (lat < RANGE_LAT_MIN || lat > RANGE_LAT_MAX) | |
| 214 | + return true; | |
| 215 | + return false; | |
| 216 | +} | |
| 217 | + | |
| 218 | +-(CLLocationCoordinate2D)gcj02Encrypt:(double)ggLat bdLon:(double)ggLon | |
| 166 | 219 | { |
| 167 | - CLLocationCoordinate2D adjustLoc; | |
| 168 | - if([self isLocationOutOfChina:wgsLoc]){ | |
| 169 | - adjustLoc = wgsLoc; | |
| 170 | - }else{ | |
| 171 | - double adjustLat = [self transformLatWithX:wgsLoc.longitude - 105.0 withY:wgsLoc.latitude - 35.0]; | |
| 172 | - double adjustLon = [self transformLonWithX:wgsLoc.longitude - 105.0 withY:wgsLoc.latitude - 35.0]; | |
| 173 | - double radLat = wgsLoc.latitude / 180.0 * pi; | |
| 174 | - double magic = sin(radLat); | |
| 175 | - magic = 1 - ee * magic * magic; | |
| 176 | - double sqrtMagic = sqrt(magic); | |
| 177 | - adjustLat = (adjustLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); | |
| 178 | - adjustLon = (adjustLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi); | |
| 179 | - adjustLoc.latitude = wgsLoc.latitude + adjustLat; | |
| 180 | - adjustLoc.longitude = wgsLoc.longitude + adjustLon; | |
| 220 | + CLLocationCoordinate2D resPoint; | |
| 221 | + double mgLat; | |
| 222 | + double mgLon; | |
| 223 | + if ([self outOfChina:ggLat bdLon:ggLon]) { | |
| 224 | + resPoint.latitude = ggLat; | |
| 225 | + resPoint.longitude = ggLon; | |
| 226 | + return resPoint; | |
| 181 | 227 | } |
| 182 | - return adjustLoc; | |
| 228 | + double dLat = [self transformLat:(ggLon - 105.0)bdLon:(ggLat - 35.0)]; | |
| 229 | + double dLon = [self transformLon:(ggLon - 105.0) bdLon:(ggLat - 35.0)]; | |
| 230 | + double radLat = ggLat / 180.0 * M_PI; | |
| 231 | + double magic = sin(radLat); | |
| 232 | + magic = 1 - jzEE * magic * magic; | |
| 233 | + double sqrtMagic = sqrt(magic); | |
| 234 | + dLat = (dLat * 180.0) / ((jzA * (1 - jzEE)) / (magic * sqrtMagic) * M_PI); | |
| 235 | + dLon = (dLon * 180.0) / (jzA / sqrtMagic * cos(radLat) * M_PI); | |
| 236 | + mgLat = ggLat + dLat; | |
| 237 | + mgLon = ggLon + dLon; | |
| 238 | + | |
| 239 | + resPoint.latitude = mgLat; | |
| 240 | + resPoint.longitude = mgLon; | |
| 241 | + return resPoint; | |
| 183 | 242 | } |
| 184 | - | |
| 185 | -//判断是不是在中国 | |
| 186 | -- (BOOL)isLocationOutOfChina:(CLLocationCoordinate2D)location | |
| 243 | + | |
| 244 | +-(CLLocationCoordinate2D)gcj02Decrypt:(double)gjLat gjLon:(double)gjLon | |
| 187 | 245 | { |
| 188 | - if (location.longitude < 72.004 || location.longitude > 137.8347 || location.latitude < 0.8293 || location.latitude > 55.8271) | |
| 189 | - return YES; | |
| 190 | - return NO; | |
| 246 | + CLLocationCoordinate2D gPt = [self gcj02Encrypt:gjLat bdLon:gjLon]; | |
| 247 | + double dLon = gPt.longitude - gjLon; | |
| 248 | + double dLat = gPt.latitude - gjLat; | |
| 249 | + CLLocationCoordinate2D pt; | |
| 250 | + pt.latitude = gjLat - dLat; | |
| 251 | + pt.longitude = gjLon - dLon; | |
| 252 | + return pt; | |
| 191 | 253 | } |
| 192 | - | |
| 193 | -- (double)transformLatWithX:(double)x withY:(double)y | |
| 254 | + | |
| 255 | +-(CLLocationCoordinate2D)bd09Decrypt:(double)bdLat bdLon:(double)bdLon | |
| 194 | 256 | { |
| 195 | - double lat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x)); | |
| 196 | - lat += (20.0 * sin(6.0 * x * pi) + 20.0 *sin(2.0 * x * pi)) * 2.0 / 3.0; | |
| 197 | - lat += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0; | |
| 198 | - lat += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0; | |
| 199 | - return lat; | |
| 200 | -} | |
| 201 | - | |
| 202 | -- (double)transformLonWithX:(double)x withY:(double)y | |
| 257 | + CLLocationCoordinate2D gcjPt; | |
| 258 | + double x = bdLon - 0.0065, y = bdLat - 0.006; | |
| 259 | + double z = sqrt(x * x + y * y) - 0.00002 * sin(y * M_PI); | |
| 260 | + double theta = atan2(y, x) - 0.000003 * cos(x * M_PI); | |
| 261 | + gcjPt.longitude = z * cos(theta); | |
| 262 | + gcjPt.latitude = z * sin(theta); | |
| 263 | + return gcjPt; | |
| 264 | +} | |
| 265 | + | |
| 266 | +-(CLLocationCoordinate2D)bd09Encrypt:(double)ggLat bdLon:(double)ggLon | |
| 203 | 267 | { |
| 204 | - double lon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x)); | |
| 205 | - lon += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0; | |
| 206 | - lon += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0; | |
| 207 | - lon += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0; | |
| 208 | - return lon; | |
| 268 | + CLLocationCoordinate2D bdPt; | |
| 269 | + double x = ggLon, y = ggLat; | |
| 270 | + double z = sqrt(x * x + y * y) + 0.00002 * sin(y * M_PI); | |
| 271 | + double theta = atan2(y, x) + 0.000003 * cos(x * M_PI); | |
| 272 | + bdPt.longitude = z * cos(theta) + 0.0065; | |
| 273 | + bdPt.latitude = z * sin(theta) + 0.006; | |
| 274 | + return bdPt; | |
| 209 | 275 | } |
| 210 | 276 | |
| 277 | +-(CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location | |
| 278 | +{ | |
| 279 | + return [self gcj02Encrypt:location.latitude bdLon:location.longitude]; | |
| 280 | +} | |
| 281 | + | |
| 282 | +-(CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location | |
| 283 | +{ | |
| 284 | + return [self gcj02Decrypt:location.latitude gjLon:location.longitude]; | |
| 285 | +} | |
| 286 | + | |
| 287 | +-(CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location | |
| 288 | +{ | |
| 289 | + CLLocationCoordinate2D gcj02Pt = [self gcj02Encrypt:location.latitude | |
| 290 | + bdLon:location.longitude]; | |
| 291 | + return [self bd09Encrypt:gcj02Pt.latitude bdLon:gcj02Pt.longitude] ; | |
| 292 | +} | |
| 293 | + | |
| 294 | +-(CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location | |
| 295 | +{ | |
| 296 | + return [self bd09Encrypt:location.latitude bdLon:location.longitude]; | |
| 297 | +} | |
| 298 | + | |
| 299 | +-(CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location | |
| 300 | +{ | |
| 301 | + return [self bd09Decrypt:location.latitude bdLon:location.longitude]; | |
| 302 | +} | |
| 303 | + | |
| 304 | +-(CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location | |
| 305 | +{ | |
| 306 | + CLLocationCoordinate2D gcj02 = [self bd09ToGcj02:location]; | |
| 307 | + return [self gcj02Decrypt:gcj02.latitude gjLon:gcj02.longitude]; | |
| 308 | +} | |
| 309 | + | |
| 310 | +//- (CLLocationCoordinate2D)transformFromWGSToGCJ:(CLLocationCoordinate2D)wgsLoc | |
| 311 | +//{ | |
| 312 | +// CLLocationCoordinate2D adjustLoc; | |
| 313 | +// if([self isLocationOutOfChina:wgsLoc]){ | |
| 314 | +// adjustLoc = wgsLoc; | |
| 315 | +// }else{ | |
| 316 | +// double adjustLat = [self transformLatWithX:wgsLoc.longitude - 105.0 withY:wgsLoc.latitude - 35.0]; | |
| 317 | +// double adjustLon = [self transformLonWithX:wgsLoc.longitude - 105.0 withY:wgsLoc.latitude - 35.0]; | |
| 318 | +// double radLat = wgsLoc.latitude / 180.0 * pi; | |
| 319 | +// double magic = sin(radLat); | |
| 320 | +// magic = 1 - ee * magic * magic; | |
| 321 | +// double sqrtMagic = sqrt(magic); | |
| 322 | +// adjustLat = (adjustLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); | |
| 323 | +// adjustLon = (adjustLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi); | |
| 324 | +// adjustLoc.latitude = wgsLoc.latitude + adjustLat; | |
| 325 | +// adjustLoc.longitude = wgsLoc.longitude + adjustLon; | |
| 326 | +// } | |
| 327 | +// return adjustLoc; | |
| 328 | +//} | |
| 329 | +// | |
| 330 | +////判断是不是在中国 | |
| 331 | +//- (BOOL)isLocationOutOfChina:(CLLocationCoordinate2D)location | |
| 332 | +//{ | |
| 333 | +// if (location.longitude < 72.004 || location.longitude > 137.8347 || location.latitude < 0.8293 || location.latitude > 55.8271) | |
| 334 | +// return YES; | |
| 335 | +// return NO; | |
| 336 | +//} | |
| 337 | +// | |
| 338 | +//- (double)transformLatWithX:(double)x withY:(double)y | |
| 339 | +//{ | |
| 340 | +// double lat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x)); | |
| 341 | +// lat += (20.0 * sin(6.0 * x * pi) + 20.0 *sin(2.0 * x * pi)) * 2.0 / 3.0; | |
| 342 | +// lat += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0; | |
| 343 | +// lat += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0; | |
| 344 | +// return lat; | |
| 345 | +//} | |
| 346 | +// | |
| 347 | +//- (double)transformLonWithX:(double)x withY:(double)y | |
| 348 | +//{ | |
| 349 | +// double lon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x)); | |
| 350 | +// lon += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0; | |
| 351 | +// lon += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0; | |
| 352 | +// lon += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0; | |
| 353 | +// return lon; | |
| 354 | +//} | |
| 355 | + | |
| 211 | 356 | |
| 212 | 357 | |
| 213 | 358 | - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { |
| ... | ... | @@ -324,7 +469,7 @@ static CNLiveLocationManager *_manager = nil; |
| 324 | 469 | NSString *formatAddress = [NSString stringWithFormat:@"%@%@", placemark.thoroughfare ? placemark.thoroughfare : @"", |
| 325 | 470 | placemark.name ? placemark.name:@""]; |
| 326 | 471 | mark.placemark = placemark; |
| 327 | - mark.address = formatAddress; | |
| 472 | + mark.address = placemark.name?placemark.name:(placemark.thoroughfare?placemark.thoroughfare :@""); | |
| 328 | 473 | return mark; |
| 329 | 474 | } |
| 330 | 475 | |
| ... | ... | @@ -349,3 +494,4 @@ static CNLiveLocationManager *_manager = nil; |
| 349 | 494 | |
| 350 | 495 | @end |
| 351 | 496 | |
| 497 | + | ... | ... |