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

//
// 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