高德地图附近停车场服务

功能:

1、用户定位追踪
2、自定义用户当前位置大头针
3、添加和移除附近停车场大头针
4、跳动动画

注意事项:

1、项目使用需进行二次封装
2、用前请配置高德地图AppKey

实现过程

一、添加地图

- (void)creatMapView {
    _mapView = [[MAMapView alloc]initWithFrame:self.view.bounds];
    _mapView.delegate = self;
    _mapView.showsCompass = NO;
    _mapView.showsScale = NO;
    _mapView.rotateEnabled = NO;
    _mapView.showsUserLocation = YES;
    _mapView.userTrackingMode = MAUserTrackingModeFollow;
    _mapView.customizeUserLocationAccuracyCircleRepresentation = YES;
    [_mapView setZoomLevel:15.1 animated:NO];
    [self.view addSubview:_mapView];
}

如下两句开启定位追踪功能

_mapView.showsUserLocation = YES;
_mapView.userTrackingMode = MAUserTrackingModeFollow;

如下代码,隐藏高德SDK默认小蓝点,自定义用户头像为当前位置

_mapView.customizeUserLocationAccuracyCircleRepresentation = YES;

二、屏幕中间添加一个“针”

1、添加屏幕中间位置的“针”

- (void)setUpCenterAnnotationView {
    //添加地图中间图标
    UIImage *image = [UIImage imageNamed:@"position"];
    
    float origin_X = (self.mapView.frame.size.width - image.size.width)*0.5;
    float origin_y = self.mapView.frame.size.height*0.5 - image.size.height;
    
    centerAnnotaionView = [[UIImageView alloc]initWithFrame:CGRectMake(origin_X, origin_y, image.size.width, image.size.height)];
    centerAnnotaionView.image = image;
    centerAnnotaionView.contentMode = UIViewContentModeScaleAspectFill;
    [self.mapView addSubview:centerAnnotaionView];
}

2、给iamgeView添加跳动动画,每次请求高德地图附近停车场的时候,添加一个跳动动画,效果还是挺漂亮的。

//跳动动画
- (void)centerAnnotaionAnimation {
    UIImage *centerAnnotationImage = [UIImage imageNamed:@"position"];
    
    float origin_x = (self.view.frame.size.width - centerAnnotationImage.size.width)*0.5;
    float origin_y = self.mapView.frame.size.height*0.5 - centerAnnotationImage.size.height*2+10;
    //组动画
    CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(origin_x+centerAnnotationImage.size.width/2, origin_y+centerAnnotationImage.size.height+10)];
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(origin_x+centerAnnotationImage.size.width/2, origin_y-30+centerAnnotationImage.size.height+10)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(origin_x+centerAnnotationImage.size.width/2, origin_y+centerAnnotationImage.size.height+10)];
    anima1.values = [NSArray arrayWithObjects:value0,value1,value2, nil];
    //组动画
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    groupAnimation.animations = [NSArray arrayWithObjects:anima1, nil];
    groupAnimation.duration = 0.5f;
    groupAnimation.fillMode = kCAFillModeForwards;
    groupAnimation.removedOnCompletion = NO;
    [centerAnnotaionView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];
}

三、地图定位回调代理

1、设置_mapView.showsUserLocation = YES;用户位置或者设备方向更新后,会调用如下函数

/**
 * @brief 位置或者设备方向更新后,会调用此函数
 * @param mapView 地图View
 * @param userLocation 用户定位信息(包括位置与设备方向等数据)
 * @param updatingLocation 标示是否是location数据更新, YES:location数据更新 NO:heading数据更新
 */
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation;

2、在此方法里面我们可以时时的获取到用户当前位置信息,即使没有网络,也会有GPS定位,将维度回调回来

#pragma mark MAMapViewDelegate
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation {
    
    NSLog(@"%d",updatingLocation);
    NSLog(@"位置更新");
    NSLog(@"当前位置:%f,%f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
    
    if (!userLocation.location || !(userLocation.location.coordinate.latitude>0)) {
        return;
    }
    
    if (!_currentLocation)
    {   //第一次进入地图移动地图至用户当前位置
        _mapView.userTrackingMode = MAUserTrackingModeFollow;
        [self centerAnnotaionAnimation];
        [self POIAroundSearchRequest:[AMapGeoPoint locationWithLatitude:userLocation.location.coordinate.latitude longitude:userLocation.location.coordinate.longitude]];
    }
    
    _currentLocation = userLocation.location;
}

(1)在该方法中_currentLocation是一个全局的属性,用来保存用户当前位置的经纬度,如果项目中其他地方要用用户经纬度可以直接拿去用;
(2)如下代码是首次进入地图将地图移动至用户当前位置

_mapView.userTrackingMode = MAUserTrackingModeFollow;

(3)如下调屏幕中间的“针”,跳动动画,动画的方法我们上面已经写好了。

[self centerAnnotaionAnimation];

(4)如下是写的一个发起poi检索的方法,往下我们会看到。

[self POIAroundSearchRequest:[AMapGeoPoint locationWithLatitude:userLocation.location.coordinate.latitude longitude:userLocation.location.coordinate.longitude]];

注意啦,注意啦:到这里大家可以尝试一下,给(3)和(4)两行不同功能的代码写一个queue,异步处理这两个方法看看和这样处理有什么区别,我也是心血来潮,尝试了一下,大家也可以试试,一边做动画,一边请求高德地图附近停车场信息。

四、地图其他代理方法

直接上代码把,看看注释。- removeStopAnnotaion方法是自己写的一个移除地图上所有大头针的方法,往下我们会看到。

1、用户操作地图的代理

/**
 * @brief 地图将要发生移动时调用此接口
 */
- (void)mapView:(MAMapView *)mapView mapWillMoveByUser:(BOOL)wasUserAction {
    if (wasUserAction) {
            //地图将要移动时,移除地图上所有附近停车场的大头针
        [self removeStopAnnotaion];
    }
}

/**
 * @brief 地图移动结束后调用此接口
 */
- (void)mapView:(MAMapView *)mapView mapDidMoveByUser:(BOOL)wasUserAction {
    if (wasUserAction)
    {
        NSLog(@"滑动地图结束");
        //地图滑动结束后,用当前用户位置发起POI检索
        [self POIAroundSearchRequest:[AMapGeoPoint locationWithLatitude:mapView.centerCoordinate.latitude longitude:mapView.centerCoordinate.longitude]];
    }
}

/**
 * @brief 地图将要发生缩放时调用此接口
 */
- (void)mapView:(MAMapView *)mapView mapWillZoomByUser:(BOOL)wasUserAction {
    if (wasUserAction) {
        [self removeStopAnnotaion];
    }
}

/**
 * @brief 地图缩放结束后调用此接口
 */
- (void)mapView:(MAMapView *)mapView mapDidZoomByUser:(BOOL)wasUserAction {
    NSLog(@"地图缩放结束");
    if (wasUserAction) {
        [self POIAroundSearchRequest:[AMapGeoPoint locationWithLatitude:mapView.centerCoordinate.latitude longitude:mapView.centerCoordinate.longitude]];
    }
}

wasUserAction是指用户操作时的回调,如果wasUserAction是NO,则不做任何处理,高德地图加载过程中用户不操作也会调用如上这些方法,所以这个字段可以说明是不是用户操作。

2、添加大头针的代理

当添加大头针的时候就会执行该代理,生成大头针视图。

/**
 * @brief 根据anntation生成对应的View
 */
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation {
    
    //用户当前位置大头针
    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.canShowCallout = NO;
        annotationView.image = [UIImage imageNamed:@"heardImg_passenger_default"];
        annotationView.frame = CGRectMake(0, 0, 26, 26);
        annotationView.contentMode = UIViewContentModeScaleToFill;
        annotationView.layer.masksToBounds = YES;
        
        return annotationView;
    }
    
    //停车场位置大头针
    else if ([annotation isKindOfClass:[MAPointAnnotation class]]) {
        static NSString *stopCarReuseIndetifier = @"stopCarReuseIndetifier";
        
        MAAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:stopCarReuseIndetifier];
        
        if (annotationView == nil)
        {
            annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:stopCarReuseIndetifier];
        }

        annotationView.canShowCallout = YES;
        UIImage *image = [UIImage imageNamed:@"centerAnnotation"];
        annotationView.image = image;
        annotationView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
        annotationView.contentMode = UIViewContentModeScaleToFill;
        annotationView.layer.masksToBounds = YES;
        annotationView.centerOffset = CGPointMake(0, -0.5*image.size.height);
        
        return annotationView;
    }
    
    return nil;
}

五、自定义的一些私有方法

1、移除地图上所有的停车场大头针的方法

要注意同时访问self.dataSource,会造成数据错乱,有些大头针移除不掉的问题。所以需要先创建一个数组接收需要移除的大头针,self.dataSource只存储最新需要显示的大头针数据。

//移除地图上所有的停车场大头针
- (void)removeStopAnnotaion {
    [UIView animateWithDuration:.5 animations:^{
        //用一个数组去接收需要移除的大头针
        NSMutableArray *removeAnnotations = [[NSMutableArray alloc]init];
        //除了当前位置的大头针,其余的都需要移除
        [removeAnnotations addObjectsFromArray:self.mapView.annotations];
        [removeAnnotations removeObject:self.mapView.userLocation];
        //移除需要移除的大头针
        [self.mapView removeAnnotations:removeAnnotations];
        
    } completion:^(BOOL finished) {
        [self centerAnnotaionAnimation];
    }];
}

2、发起poi检索的方法

//发起poi检索
- (void)POIAroundSearchRequest:(AMapGeoPoint *)point {
    //取消所有未回调的请求,防止多次叠加请求,防止造成数据源错乱
    [self.searchAPI cancelAllRequests];
    //地图移动结束,请求高德地图附近停车场信息
    AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc]init];
    request.keywords = @"停车库";
    request.radius = 3000;
    request.location = point;
    /*发起搜索*/
    [self.searchAPI AMapPOIAroundSearch:request];
}

self.searchAPI是一个全局的高德地图POI搜索类

3、跳动动画

屏幕中间“针”的跳动动画,上面已说过了。

六、高德地图POI检索回调

#pragma mark AMapSearchDelegate
/**
 * @brief POI查询回调函数
 */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
    if (response.pois.count == 0) {
        NSLog(@"暂无停车场信息");
        return;
    }

    //清空数据源
    [self.dataSource removeAllObjects];
    
    for (AMapPOI *poi in response.pois) {
        NSLog(@"%@",poi.name);
        NSLog(@"%@",poi.address);
        
        MAPointAnnotation *anotation = [[MAPointAnnotation alloc]init];
        anotation.title = poi.name;
        anotation.subtitle = poi.address;
        anotation.coordinate = CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude);
        [self.dataSource addObject:anotation];
    }
    //添加附近车库大头针
    [self.mapView addAnnotations:self.dataSource];
}

self.dataSource是一个全局的可变数组,用户存储数据源,有了数据源我们可以做我们想做的操作。
通过此数据源你也可以将附近的停车场信息显示在一个tableView上,提供用户选择,大多数项目多有这样做的,都是大同小异,只要有了数据,其他只是展示数据、刷新数据了。

最后附上效果图和github地址大家可以克隆下来看看,有不多的地方请多多指教。
此外提醒大家看demo的时候不要忘了配置自己的AppKey哦,这玩意我就不给你提供了。

附近停车场.PNG

https://github.com/Mexiang/GaoDeMapParkService

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容