You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
370 lines
14 KiB
370 lines
14 KiB
// |
|
// GDMapView.m |
|
// LekangGuard |
|
// |
|
// Created by ecell on 2022/11/18. |
|
// |
|
|
|
#import "GDMapView.h" |
|
#import "CustomAnnotationView.h" |
|
#import "UserAnnotationView.h" |
|
|
|
//默认的定位位置 北京 |
|
#define DefineLocate CLLocationCoordinate2DMake(39.9086828351,116.3980865479) |
|
@interface GDMapView ()<CLLocationManagerDelegate,MKMapViewDelegate,AMapSearchDelegate> |
|
|
|
@property (nonatomic ,strong) MKMapView *mapView; |
|
|
|
@property (strong, nonatomic) CLLocationManager *locationManager; |
|
|
|
@property (strong, nonatomic) CLLocation *userLocate;// 用户当前的 位置 |
|
@property (strong, nonatomic) MKPointAnnotation *curPointAnnotation; //设备 View |
|
@property (strong, nonatomic) MKPointAnnotation *userPointAnnotation; //用户 View |
|
|
|
@property (nonatomic, strong) AMapSearchAPI *searchAPI; |
|
|
|
@end |
|
|
|
@implementation GDMapView |
|
|
|
- (instancetype)initWithFrame:(CGRect)frame |
|
{ |
|
self = [super initWithFrame:frame]; |
|
if (self) |
|
{ |
|
self.backgroundColor = KKClearColor; |
|
[self subViews]; |
|
} |
|
return self; |
|
} |
|
|
|
- (void)setLaloModel:(LatestLocationModel *)laloModel |
|
{ |
|
_laloModel = laloModel; |
|
//先移动 到 设备的定位处 |
|
if([laloModel.latitude doubleValue] == 0 |
|
&& [laloModel.longitude doubleValue] == 0) |
|
{ |
|
[self setMapZoom:DefineLocate]; |
|
} |
|
else |
|
{ |
|
self.curPointAnnotation.coordinate = CLLocationCoordinate2DMake([laloModel.latitude doubleValue], |
|
[laloModel.longitude doubleValue]); |
|
[self setMapZoom:CLLocationCoordinate2DMake([laloModel.latitude doubleValue], [laloModel.longitude doubleValue])]; |
|
} |
|
} |
|
|
|
- (void)subViews |
|
{ |
|
[self initLocationManager]; |
|
self.laloModel = APIManager.sharedManager.laloModel; |
|
[self addSubview:self.mapView]; |
|
self.curPointAnnotation = [[MKPointAnnotation alloc] init]; |
|
self.userPointAnnotation = [[MKPointAnnotation alloc] init]; |
|
[self showCurPiont]; |
|
[self mapView:self.mapView didSelectAnnotationView:[CustomAnnotationView new]]; |
|
|
|
|
|
self.searchAPI = [[AMapSearchAPI alloc] init]; |
|
self.searchAPI.delegate = self; |
|
|
|
|
|
} |
|
|
|
-(void)showCurPiont |
|
{ |
|
//要在地图上显示的点的数组 |
|
NSMutableArray *pointArr = [NSMutableArray array]; |
|
CLLocationCoordinate2D coordinate2D = DefineLocate; |
|
if (self.laloModel) |
|
{ |
|
//设置新的地图信息 |
|
coordinate2D = CLLocationCoordinate2DMake([self.laloModel.latitude doubleValue], |
|
[self.laloModel.longitude doubleValue]); |
|
//删除原来的点 |
|
if ([self.mapView.annotations containsObject:self.curPointAnnotation]) { |
|
// NSInteger index = [self.mapView.annotations indexOfObject:curPointAnnotation]; |
|
[self.mapView removeAnnotation:self.curPointAnnotation]; |
|
} |
|
self.curPointAnnotation.coordinate = coordinate2D; |
|
|
|
// 设备的 范围框 |
|
if (self.laloModel.radius) |
|
{ |
|
CLLocationDistance radius = [self.laloModel.radius doubleValue]; |
|
MKCircle *circle = [MKCircle circleWithCenterCoordinate:coordinate2D |
|
radius:radius]; |
|
[self.mapView removeOverlays:self.mapView.overlays]; |
|
[self.mapView addOverlay:circle]; |
|
} |
|
[pointArr addObject:self.curPointAnnotation]; |
|
} |
|
|
|
if(pointArr.count > 0) |
|
{ |
|
//如果 设备的位置存在则显示 设备的位置 |
|
[self.mapView addAnnotations:pointArr]; |
|
[self setMapZoom:coordinate2D]; |
|
} |
|
else |
|
{ |
|
//调整位置 |
|
//设置中心点为当前地图范围的中心点 |
|
CLLocationCoordinate2D center = DefineLocate; |
|
//不存在 则 显示用户的位置 |
|
if(self.mapView.userLocation.isUpdating){ |
|
center = self.mapView.userLocation.coordinate; |
|
}else if(self.userLocate){ |
|
center = self.userLocate.coordinate; |
|
} |
|
[self setMapZoom:center]; |
|
} |
|
} |
|
|
|
|
|
- (MKMapView *)mapView |
|
{ |
|
if (!_mapView) |
|
{ |
|
_mapView = [[MKMapView alloc] initWithFrame:self.bounds]; |
|
// //设置用户的跟踪模式 |
|
// _mapView.userTrackingMode = MKUserTrackingModeFollow; |
|
// //设置标准地图 |
|
// _mapView.mapType = MKMapTypeStandard; |
|
// // 不显示罗盘和比例尺 |
|
// if (@available(iOS 9.0, *)) { |
|
// _mapView.showsCompass = NO; |
|
// _mapView.showsScale = NO; |
|
// } |
|
// 开启定位 |
|
//_mapView.showsUserLocation = YES; |
|
_mapView.delegate = self; |
|
MKCoordinateSpan span = MKCoordinateSpanMake(0.021251, 0.016093); |
|
CLLocationCoordinate2D center = self.mapView.region.center; |
|
[_mapView setRegion:MKCoordinateRegionMake(center, span) animated:YES]; |
|
} |
|
return _mapView; |
|
} |
|
|
|
#pragma 定位 |
|
- (void)initLocationManager |
|
{ |
|
self.locationManager = [[CLLocationManager alloc] init]; |
|
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; |
|
self.locationManager.delegate = self; |
|
|
|
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) |
|
{ |
|
[self.locationManager requestWhenInUseAuthorization]; |
|
} |
|
} |
|
|
|
|
|
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status |
|
{ |
|
switch (status) |
|
{ |
|
case kCLAuthorizationStatusNotDetermined: |
|
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) |
|
{ |
|
[self.locationManager requestWhenInUseAuthorization]; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
|
|
#pragma 缩小地图 |
|
- (void)setMapZoom:(CLLocationCoordinate2D)centerCoordinate |
|
{ |
|
@try { |
|
if (CLLocationCoordinate2DIsValid(centerCoordinate)) { |
|
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(centerCoordinate, 2000, 2000); |
|
[self.mapView setRegion:region animated:YES]; |
|
} |
|
} @catch (NSException *exception) { |
|
|
|
} @finally { |
|
|
|
} |
|
} |
|
|
|
#pragma mark - 地图控件代理方法 |
|
#pragma mark 显示大头针时调用,注意方法中的annotation参数是即将显示的大头针对象 |
|
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation |
|
{ |
|
if([annotation isEqual:self.curPointAnnotation]) |
|
{ |
|
//由于当前位置的标注也是一个大头针,所以此时需要判断,此代理方法返回nil使用默认大头针视图 |
|
static NSString *key1=@"CustomAnnotationView"; |
|
CustomAnnotationView *annotationView = (CustomAnnotationView*)[_mapView dequeueReusableAnnotationViewWithIdentifier:key1]; |
|
//如果缓存池中不存在则新建 |
|
if (!annotationView) |
|
{ |
|
annotationView =[[CustomAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1]; |
|
annotationView.canShowCallout = NO;//不允许交互点击 |
|
|
|
} |
|
else |
|
{ |
|
//重新设置此类大头针视图的大头针模型(因为有可能是从缓存池中取出来的,位置是放到缓存池时的位置) |
|
annotationView.annotation = annotation; |
|
} |
|
//修改大头针视图 设置成头像 |
|
[annotationView setImageWithURLString:APIManager.sharedManager.deviceModel.image]; |
|
//设置大小 |
|
annotationView.frame = CGRectMake(0, 0, Adapted(50), Adapted(60)); |
|
//设置中心偏移量 |
|
annotationView.centerOffset = CGPointMake(0, -26); |
|
//定义详情视图偏移量 |
|
annotationView.calloutOffset=CGPointMake(0, 12); |
|
return annotationView; |
|
} |
|
else if([annotation isKindOfClass:[MKUserLocation class]] && self.laloModel.latitude.doubleValue == 0) |
|
{ |
|
//由于当前位置的标注也是一个大头针,所以此时需要判断,此代理方法返回nil使用默认大头针视图 |
|
static NSString *key1=@"UserAnnotationView"; |
|
UserAnnotationView *annotationView = (UserAnnotationView*)[_mapView dequeueReusableAnnotationViewWithIdentifier:key1]; |
|
//如果缓存池中不存在则新建 |
|
if (!annotationView) { |
|
annotationView =[[UserAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1]; |
|
annotationView.canShowCallout = NO;//不允许交互点击 |
|
|
|
}else{ |
|
//重新设置此类大头针视图的大头针模型(因为有可能是从缓存池中取出来的,位置是放到缓存池时的位置) |
|
annotationView.annotation = annotation; |
|
} |
|
//修改大头针视图 设置成头像 |
|
[annotationView setImageWithURLString:APIManager.sharedManager.deviceModel.image]; |
|
//设置大小 |
|
annotationView.frame = CGRectMake(0, 0, Adapted(50), Adapted(60)); |
|
//设置中心偏移量 |
|
annotationView.centerOffset = CGPointMake(0, -26); |
|
//定义详情视图偏移量 |
|
annotationView.calloutOffset=CGPointMake(0, 12); |
|
return annotationView; |
|
} |
|
return nil; |
|
} |
|
|
|
//MARK: 点击地图 中的 标点 触发的方法 |
|
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view |
|
{ |
|
if([view isKindOfClass:[CustomAnnotationView class]]) |
|
{ |
|
// 设备点 |
|
// self.locationTypeLabel.text = self.curLocate.loc_type; |
|
// if ([self.curLocate.loc_type isEqualToString:@"LBS"]) { |
|
// self.locationTypeImageView.image = [UIImage imageNamed:@"icon_base_station"]; |
|
// }else if([self.curLocate.loc_type isEqualToString:@"GPS"]){ |
|
// self.locationTypeImageView.image = [UIImage imageNamed:@"icon_positioning_g"]; |
|
// }else if([self.curLocate.loc_type isEqualToString:@"WIFI"]){ |
|
// self.locationTypeImageView.image = [UIImage imageNamed:@"icon_home_wifi"]; |
|
// }else{ |
|
// //是空的 LBS |
|
// self.locationTypeImageView.image = [UIImage imageNamed:@"icon_base_station"]; |
|
// self.locationTypeLabel.text = @"LBS"; |
|
// } |
|
// if(self.laloModel) |
|
// { |
|
// NSString *dateStr = [myHelper distanceTimeWithBeforeTime:[self.curLocate.timestamp doubleValue]]; |
|
// self.locationTimeLabel.text = dateStr; |
|
// self.locationAddressLabel.text = @"位置解析中..."; |
|
// } |
|
|
|
AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init]; |
|
|
|
regeo.location = [AMapGeoPoint locationWithLatitude:[self.laloModel.latitude floatValue] longitude:[self.laloModel.longitude floatValue]]; |
|
[self.searchAPI AMapReGoecodeSearch:regeo]; |
|
|
|
}else{ |
|
// // 用户点 |
|
// xLog(@""); |
|
// self.locationAddressLabel.text = @"解析位置..."; |
|
// //看看是否 开启定位权限 |
|
// if (![CLLocationManager locationServicesEnabled]) { |
|
// //LBS |
|
// self.locationTypeImageView.image = [UIImage imageNamed:@"icon_base_station"]; |
|
// }else{ |
|
// //GPS |
|
// self.locationTypeImageView.image = [UIImage imageNamed:@"icon_positioning_g"]; |
|
// } |
|
// |
|
// if(!userLocate){return;} |
|
// //地理位置编码解析 |
|
// CLGeocoder *geocoder = [[CLGeocoder alloc]init]; |
|
// WEAKSELF |
|
// [geocoder reverseGeocodeLocation:userLocate completionHandler:^(NSArray *placemarks, NSError *error) { |
|
// CLPlacemark *placemark = [placemarks firstObject]; |
|
// |
|
// NSString *state = placemark.locality; |
|
// if (!state) { |
|
// //四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市) |
|
// state = placemark.administrativeArea; |
|
// } |
|
// NSString *name = [NSString stringWithFormat:@"%@ %@ %@",state,placemark.subLocality,placemark.name]; |
|
// |
|
// NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@",name,@"刚刚"]]; |
|
// [att addAttribute:NSForegroundColorAttributeName |
|
// value:mainColor |
|
// range:NSMakeRange(att.length-2,2)]; |
|
// weakSelf.locationAddressLabel.attributedText = att; |
|
// weakSelf.locationTitleLabel.text = @"我的位置"; |
|
// }]; |
|
} |
|
} |
|
|
|
|
|
|
|
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay |
|
{ |
|
if ([overlay isKindOfClass:[MKCircle class]]) |
|
{ |
|
MKCircleRenderer *circle = [[MKCircleRenderer alloc] initWithOverlay:overlay]; |
|
circle.strokeColor = [UIColor clearColor]; |
|
|
|
circle.fillColor = [[UIColor blueColor] colorWithAlphaComponent:0.1]; |
|
|
|
// circle.lineWidth = 1; |
|
return circle; |
|
} |
|
|
|
return nil; |
|
} |
|
|
|
#pragma mark ====高德地图位置解析回调==== |
|
|
|
-(void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response{ |
|
if (response.regeocode != nil) |
|
{ |
|
NSString *name = response.regeocode.formattedAddress; |
|
//解析response获取地址描述,具体解析见 Demo |
|
//获取市 |
|
// NSString *city = response.regeocode.addressComponent.city; |
|
// NSString *province = response.regeocode.addressComponent.province; |
|
// if(city && city.length>0){ |
|
// name = [name componentsSeparatedByString:city].lastObject; |
|
// if([city isEqualToString:province]){ |
|
// //直辖市 |
|
// name = [NSString stringWithFormat:@"%@ %@",name,city]; |
|
// }else{ |
|
// //普通市 |
|
// name = [NSString stringWithFormat:@"%@ %@ %@",name,city,province]; |
|
// } |
|
// } |
|
|
|
//self.locationAddressLabel.text = name; |
|
} |
|
} |
|
|
|
/* |
|
// Only override drawRect: if you perform custom drawing. |
|
// An empty implementation adversely affects performance during animation. |
|
- (void)drawRect:(CGRect)rect { |
|
// Drawing code |
|
} |
|
*/ |
|
|
|
@end
|
|
|