关于定位打卡
公司需求
给全国67家分公司的员工在APP上做一个打卡签到的功能,之前考虑用苹果原生定位进行实现,发现准确度有问题,后来想了想,决定做成以公司为圆心半径300米范围内可以打卡,结合一些查找的资料,决定使用高德地图进行实现。
效果如图
文章图片
这是武汉的一个分公司,但是我是在北京的,所以我的位置不在圆圈范围内 界面计较简单,当个人位置在圆圈内时,可以签到,否则不可以。
主要代码如下:
首先项目中需要导入高德的sdk,在高德地图开放平台申请自己APP的key
文章图片
这样的,安卓和iOS都有 首先pod 高德sdk
pod'AMap3DMap'
pod'AMapSearch'
然后在APPdelegate里面注册一下
[AMapServices sharedServices].apiKey = @"你的应用的key";
然后就是代码环节了:
#define kUIColorFromRGBAlpha(rgbValue) [UIColor \
colorWithRed:((float)((rgbValue &0xFF0000) >>16))/255.0\
green:((float)((rgbValue &0xFF00) >>8))/255.0\
blue:((float)(rgbValue &0xFF))/255.0alpha:0.4]
#import "RXSignViewController.h"
#import
#import
@interface RXSignViewController ()
CLLocationManager *_manager;
}
// 高德地图
@property (nonatomic, strong)MAMapView *mapView;
// 有多少个打卡范围(可拓展不同地方打卡)
@property (nonatomic, copy)NSArray *circles;
// 经纬度
@property (nonatomic,copy)NSString *userLongitude;
@property (nonatomic,copy)NSString *userLatitude;
@property(nonatomic ,copy) NSString *position;
@end
@implementation RXSignViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
// 进入界面就以定位点为地图中心
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(self.latitude, self.longitude) animated:NO];
// 将绘制的图形添加到地图上
[self.mapView addOverlays:self.circles];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.leftBarButtonItem.tintColor = [UIColor whiteColor];
self.title=self.signTitle;
// 初始化地图
[self initMapView];
// 初始化 MAUserLocationRepresentation 对象
[self initUserLocationRepresentation];
// 创建按钮
[self initMapButton];
_manager = [[CLLocationManager alloc]init];
[_manager requestAlwaysAuthorization];
}
- (void)initMapView {
// https配置
[AMapServices sharedServices].enableHTTPS = YES;
// 初始化地图
self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT )];
self.mapView.delegate = self;
// 显示定位小蓝点
self.mapView.showsUserLocation = YES;
self.mapView.showsCompass = NO;
// 追踪用户的location更新
self.mapView.userTrackingMode = MAUserTrackingModeFollow;
// 放大等级
[self.mapView setZoomLevel:16 animated:YES];
[self.viewaddSubview:self.mapView];
}
- (void)initUserLocationRepresentation {
// 初始化小蓝点
MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init];
r.showsAccuracyRing = YES;
// 精度圈是否显示,默认YES
r.enablePulseAnnimation = YES;
// 内部蓝色圆点是否使用律动效果, 默认YES
r.locationDotFillColor = [UIColor redColor];
r.lineWidth = 2;
// 精度圈 边线宽度,默认0
[self.mapView updateUserLocationRepresentation:r];
}
- (void)initMapButton {
UIButton*signBtn = [[UIButtonalloc]initWithFrame:CGRectMake(20,SCREEN_HEIGHT-144,SCREEN_WIDTH-40,44)];
[signBtnsetTitle:self.signTitle forState:UIControlStateNormal];
[signBtnsetTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[signBtncornerRadius:5];
[signBtnsetBackgroundColor:APP_MAIN_C];
[signBtnaddTarget:self action:@selector(signWork) forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:signBtn];
// 定位按钮
UIButton*searchBtn = [[UIButtonalloc]initWithFrame:CGRectMake(SCREEN_WIDTH-20-37,20,37,37)];
[searchBtnsetBackgroundImage:[UIImage imageNamed:@"locationPoint"] forState:UIControlStateNormal];
[searchBtnsetBackgroundImage:[UIImage imageNamed:@"locationPoint_select"] forState:UIControlStateHighlighted];
[searchBtnaddTarget:selfaction:@selector(locationClick)forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:searchBtn];
UIButton*zoomUpBtn = [[UIButtonalloc]initWithFrame:CGRectMake(signBtn.right-37, signBtn.top-67-30,37,37)];
[zoomUpBtnsetBackgroundImage:[UIImage imageNamed:@"up"] forState:UIControlStateNormal];
[zoomUpBtnsetBackgroundImage:[UIImage imageNamed:@"up_select"] forState:UIControlStateHighlighted];
[zoomUpBtnaddTarget:self action:@selector(zoomUp) forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:zoomUpBtn];
UIButton*zoomDownBtn = [[UIButtonalloc]initWithFrame:CGRectMake(signBtn.right-37, signBtn.top-30-30,37,37)];
[zoomDownBtnsetBackgroundImage:[UIImage imageNamed:@"down"] forState:UIControlStateNormal];
[zoomDownBtnsetBackgroundImage:[UIImage imageNamed:@"down_select"] forState:UIControlStateHighlighted];
[zoomDownBtnaddTarget:selfaction:@selector(zoomDown)forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:zoomDownBtn];
[self setAddress];
}
- (void)setAddress {
NSMutableArray *arr = [NSMutableArray array];
MACircle *circle1 = [MACircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(self.latitude, self.longitude) radius:300];
[arraddObject:circle1];
self.circles= [NSArrayarrayWithArray:arr];
}
// 放大
- (void)zoomUp{
[self.mapView setZoomLevel:(self.mapView.zoomLevel + 1) animated:YES];
}
// 缩小
- (void)zoomDown {
[self.mapView setZoomLevel:(self.mapView.zoomLevel - 1) animated:YES];
}
// 签到
- (void)signWork {
BOOL isOpen = [self RX_Device_Permission_LocationAuth];
if(!isOpen) {
NSString*appName =[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
NSString*message = [NSStringstringWithFormat:@"应用没有位置权限,请修改 \"设置-%@-位置\"",appName];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"无位置权限" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction*cancelAction = [UIAlertActionactionWithTitle:@"取消"style:UIAlertActionStyleCancelhandler:^(UIAlertAction*_Nonnullaction) {
}];
UIAlertAction*doneAction = [UIAlertActionactionWithTitle:@"去设置"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*_Nonnullaction) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if([[UIApplication sharedApplication] canOpenURL:url]){
if(@available(iOS10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
}];
}else{
[[UIApplicationsharedApplication]openURL:url];
}
}else{
NSLog(@"打开设置失败");
}
}];
[alertControlleraddAction:cancelAction];
[alertControlleraddAction:doneAction];
[self presentViewController:alertController animated:YES completion:nil];
return;
}
// 半径在500米以内就在范围内
doubler =300;
double distance = [self distanceBetweenCenterLatitude:self.latitude centerLongitude:self.longitude userLatitude:[self.userLatitude doubleValue]userLongitude:[self.userLongitude doubleValue]];
if(distance <= r) {
// 在范围内的提示
//[MBProgressHUD showError:@"在签到范围内"];
[selfgetAddress];
}else{
// 不在范围内的提示
//[MBProgressHUD showError:@"不在签到范围内"];
[RXErrorShowViewshowRXErrorShowViewWithMessage:@"您不在签到范围内,请在公司300米范围内操作"view:self.view block:nil];
}
}
// 定位按钮
-(void)locationClick {
// 设置地图中心位置
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake([self.userLatitude floatValue], [self.userLongitude floatValue]) animated:YES];
[self.mapView setZoomLevel:18 animated:YES];
}
- (void)mapView:(MAMapView*)mapViewdidUpdateUserLocation:(MAUserLocation*)userLocationupdatingLocation:(BOOL)updatingLocation {
// 获取用户位置的经纬度
self.userLongitude= [NSStringstringWithFormat:@"%f",userLocation.location.coordinate.longitude];
self.userLatitude= [NSStringstringWithFormat:@"%f",userLocation.location.coordinate.latitude];
NSLog(@"%@------%@",self.userLongitude,self.userLatitude);
}
- (void)getAddress{
CGFloatlongitude = [self.userLongitudefloatValue];
//经度
CGFloatlatitude = [self.userLatitudefloatValue];
//纬度
CLLocation*location = [[CLLocationalloc]initWithLatitude:latitudelongitude:longitude];
CLGeocoder*geocoder = [[CLGeocoderalloc]init];
[geocoderreverseGeocodeLocation:locationcompletionHandler:^(NSArray*placemark,NSError*error){
CLPlacemark*mark = [placemarkobjectAtIndex:0];
//NSLog(@"%@%@%@%@%@",mark.subLocality,mark.thoroughfare,mark.name,mark.locality,mark.subLocality);
//NSLog(@"%@%@%@",mark.locality,mark.subLocality,mark.name);
在这里提交签到请求
}];
}
// 高德地图delegate
#pragma mark - MAMapViewDelegate
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id
if([overlayisKindOfClass:[MACircleclass]])
{
MACircleRenderer*circleRenderer = [[MACircleRendereralloc]initWithCircle:(MACircle*)overlay];
circleRenderer.lineWidth=1.f;
circleRenderer.strokeColor= [UIColorblueColor];
circleRenderer.lineDashType=NO;
NSIntegerindex = [self.circlesindexOfObject:overlay];
if(index ==0) {
circleRenderer.fillColor=kUIColorFromRGBAlpha(0x24b7eb);
}elseif(index ==1) {
circleRenderer.fillColor= [[UIColorgreenColor]colorWithAlphaComponent:0.3];
}elseif(index ==2) {
circleRenderer.fillColor= [[UIColorblueColor]colorWithAlphaComponent:0.3];
}else{
circleRenderer.fillColor= [[UIColoryellowColor]colorWithAlphaComponent:0.3];
}
returncircleRenderer;
}
return nil;
}
// 计算两个经纬度点的距离
- (double)distanceBetweenCenterLatitude:(double)centerLatitudecenterLongitude:(double)centerLongitudeuserLatitude:(double)userLatitudeuserLongitude:(double)userLongitude{
doubledd =M_PI/180;
doublex1 = centerLatitude * dd,x2 = userLatitude * dd;
doubley1 = centerLongitude * dd,y2 = userLongitude * dd;
doubleR =6371004;
doubledistance = (2* R *asin(sqrt(2-2*cos(x1) *cos(x2) *cos(y1 - y2) -2*sin(x1) *sin(x2)) /2));
//返回 m
returndistance;
}
- (BOOL)RX_Device_Permission_LocationAuth {
if (![CLLocationManager locationServicesEnabled]) {
returnNO;
}
CLAuthorizationStatus CLstatus = [CLLocationManager authorizationStatus];
if (CLstatus == kCLAuthorizationStatusDenied || CLstatus == kCLAuthorizationStatusRestricted || CLstatus == kCLAuthorizationStatusNotDetermined) {
returnNO;
}
return YES;
}
- (void)dealloc{
if(_manager) {
_manager=nil;
}
}
【关于定位打卡】基本就这样,不想写了,来bug了
推荐阅读
- Ⅴ爱阅读,亲子互动——打卡第178天
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- 四首关于旅行记忆的外文歌曲
- 2018-3-24
- 醒不来的梦
- 日志打卡
- 以读攻“毒”唤新活动曹彦斌打卡第二天
- 关于自我为中心的一点感想
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- 关于Ruby的杂想