自定义添加标注(大头针)样式,并使其适应屏幕

来源:互联网 发布:大学生网络理财产品 编辑:程序博客网 时间:2024/06/05 18:21

前提:
在高德地图上添加自定义标注,并在一个屏幕上自适应显示所有的标注。
因为使用的是高德地图,需引入高德地图sdk

一、先解决自定义标注样式的问题
如果仅仅只是更换自己自定义的大头针图片,那么在高德地图开放平台(开发-ios地图SDK-开发指南-地图功能)自定义标注图片中就有讲述如何更换自定义大头针的图片。但这不够用,我所需要的是在地图上有多种标注,每个标注的样式都不一样,且每个标注所属的属性也不一样。在这里我只更改每个标注的样式不同;不做内容的不同(比如,每个标注携带语音,文字信息等),但如果要做内容的不同,可以参考图片的不同,我这里有给每种标注使用不同的背景图片。
自定义标注样式时,需要继承MAAnnotationView类,这个类主要是用来描述标注样式。
创建一个类HeadPicAnnotation继承自MAAnnotationView;
在.h文件中:定义一个NSString *imageName属性。方便给标注设置图片;
在.m文件中:自定义标注的样式。但这时使用的init方法就不是

- (instancetype)initWithFrame:(CGRect)frame{    if (self = [super initWithFrame:frame]{        …自定义标注样式代码…    }    return self;}

而是使用高德的方法

-(instancetype)initWithAnnotation:(id<MAAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier{       if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]){              …自定义标注样式代码…      }      return self;}

同时,还需要给在.h文件的属性写setter方法,将传递过来的图片名添加到自定义标注里的imageView属性中去。

二、解决每个自定义标注所携带的内容的不同
我们自定义标注时,或背景图片不同,或样式不同,或自携带的内容不同(语音,下标)等
需创建一个类CustomMAPointAnnotation继承自MAPointAnnotation类,该类用于指定标注的位置。
在.h文件中:定义一个标注的类别NSinteger pointTypedef(因为有多种标注)
定义一个用来当做中间人传递NSString *imageName的属性

三、将自定义标注添加到地图上
1.先创建标注实例

CustomMAPointAnnotation *headAnnotation = [[CustomMAPointAnnotation alloc]init];headAnnotation.coordinate = CLLocationCoordinate2DMake(latitude,longitude);//latitude和longitude就是经纬度//在创建标注实例时,需要给标注一个经纬度位置点。同时,也是在创建标注实例时就给标注设置属性,比如他的类别(每种标注是一种类别)、图片名等,我前面说的语音、下标文字信息等都是在这里设置headAnnotation.pointType = 5;headAnnotation.imageName = @"图片名";[_mapView addAnnotation:headAnnotation];//高德方法,将标注添加到地图上

2.将标注显示到地图上

- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnotation>)annotation{    if ([annotation isKindOfClass:[CustomMAPointAnnotation class]]){        if (point.pointType == 5){            static NSString *reuseIndetifier = @"annotationReuseIndetifier5";            headPicAnnotation *headAnnotation = (headPicAnnotation *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier];            if (!headAnnotation){                headAnnotation = [[headPicAnnotation alloc]initWithAnnotation:annotation reuseIdentifier:reuseIndetifier];            }            //在这里,给每个标注匹配相对应的值            headAnnotation.imageName = point.imageName;            //设置中心点偏移,使得标注底部中间点成为经纬度对应点            headAnnotation.centerOffsest = CGPointMake(-18,0);            //annotationArray用来保存标注的可变数组,最终用来把数组里的标注全部显示到地图上            [_annotationArray addObject:headAnnotation];            return headAnnotation;        }else if(point.pointType == 6){             …其他类别的标注,以此类推…        }else if([annotation isKindOfClass:[MAUserLocation class]]){            //这是用户定位点            static NSString *userLocationStyleReuseIndetifier = @"userLocationStyleReuseIndetifier";            MAAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:userLocationStyleReuseIndetifier];            if (annotationView == nil){                annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:userLocationStyleReuseIndetifier];            }               annotationView.image = [UIImage imageName:@"图片名"];            self.userLocationAnnotationView = annotationView;            return annotationView;        }    }    return nil;}

剩下的就是怎么把所有的标注显示到地图上

//要将所有的标注显示到地图上,需要使用高德方法showAnnotations[_mapView showAnnotations:_annotationArray animated:YES];//annotatinArray是可变数组,存的是所有的标注

好了,标注问题基本就是这样了。接下来解决标注在一屏幕上自适应的问题
思路是:找出中心点,并以此作为屏幕(地图)的中心点。然后通过计算求出距离中心点纬度最远的标注点和经度上最远的标注点,得出一个可以显示所有标注的地图矩形区域。在这里需要分清屏幕矩形区域和地图矩形区域。屏幕区域是一个二维的很直观的去油,但地图区域不同,他是一个立体,虽然没有谷歌那样真正意义上的地图式的地图。想象下,地球上有高山,有大海,有高楼等等。再比如,地球仪和纸质平铺地图。好了不多说,这里以死数据做标注的位置点,pointArray数组,pointArray存储的数据是这样的 @[ @[@{@”latitude”:@”30”,@”longitude”:@”120”}], @[@{@”latitude”:@”30”,@”longitude”:@”120”}], @[@{@”latitude”:@”30”,@”longitude”:@”120”}], @[@{@”latitude”:@”30”,@”longitude”:@”120”}], @[@{@”latitude”:@”30”,@”longitude”:@”120”}]]。

if (!Empty_Array(_pointArray)) {        for (int i=0; i<[_pointArray count]; i++) {            if (i == 0) {                minLat = [_pointArray[0][0][@"latitude"] doubleValue];                maxLat = [_pointArray[0][0][@"latitude"] doubleValue];                minLon = [_pointArray[0][0][@"longitude"] doubleValue];                maxLon = [_pointArray[0][0][@"longitude"] doubleValue];            }else{                minLat = MIN(minLat, [_pointArray[i][0][@"latitude"] doubleValue]);                maxLat = MAX(maxLat, [_pointArray[i][0][@"latitude"] doubleValue]);                minLon = MIN(minLon, [_pointArray[i][0][@"longitude"] doubleValue]);                maxLon = MAX(maxLon, [_pointArray[i][0][@"longitude"] doubleValue]);            }        }    }    //获取区域中心点    CLLocationCoordinate2D centCoor;    centCoor.latitude = (CLLocationDegrees)((maxLat + minLat) *0.5f);    centCoor.longitude = (CLLocationDegrees)((maxLon + minLon) *0.5f);    //获取最远的纬度距离和经度距离(将两个经纬度点转换成投影点,然后计算距离)    MAMapPoint point1 = MAMapPointForCoordinate(CLLocationCoordinate2DMake(maxLat, centCoor.longitude));    MAMapPoint point2 = MAMapPointForCoordinate(CLLocationCoordinate2DMake(centCoor.latitude, maxLon));    MAMapPoint centPoint = MAMapPointForCoordinate(centCoor);    CLLocationDistance horizontalDistance = MAMetersBetweenMapPoints(point1,centPoint);    CLLocationDistance verticalDistance = MAMetersBetweenMapPoints(point2,centPoint);    //根据中心点和距离形成一个区域    MACoordinateRegion region = MACoordinateRegionMakeWithDistance(centCoor, verticalDistance*2, horizontalDistance*2);    //    [_mapView setRegion:region animated:YES];    [_mapView setVisibleMapRect:MAMapRectForCoordinateRegion(region) animated:YES];    [self startConcentrate];

到这里,基本结束!
申明一下,如果有某些地方有侵犯别人版权的,请联系我!
不过我想应该也没有,毕竟这是我一个一个字敲出来的,
同时,如果有某些地方出现错误,欢迎您的指出,我收到消息会更改!谢谢!!!

0 0