前言
我们的APP是做房地产类,所以用户有在地图中根据区域,不同商圈,地铁线路站牌来查看楼盘的需求。我们的功能就是在用户进入地图页时按区域显示新楼盘或者二手房数量,用户根据需要点击区域进入二级商圈显示商圈内楼盘数量,用户点击某个商圈进入该商圈内的楼盘位置视图,楼盘标注显示楼盘信息,价格信息,点击楼盘标签进入详情页,功能效果可参考房天下的地图模式。
地铁模式:用户选择地铁线或者站点,在地图上显示地铁线路标注,站点标注。点击某个站点显示附近楼盘标注信息。
![Uploading 33C948F3F2B44F1084ED64A77BA8A4CE_098266.png . . .]
功能实现
1、准备
地图:我们的APP是基于百度地图的
后台:需要分别返回区域,商圈,楼盘的接口。
2、实现
创建自定义的annotationview继承于BMKAnnotationView
创建好对应的model,存储后台返回的数据
刚进入地铁时默认加载区域的标注。
//添加区域标注
-(void)addAreaAnnotation{
[_mapView removeAnnotations:self.mapViewAnnotations];
NSMutableArray *annotations= [NSMutableArray new];
for (AreaModel *model in self.areaArray) {
AreaAnnotation *areaAnnotation = [AreaAnnotation new];
areaAnnotation.coordinate = model.location;
areaAnnotation.areaModel = model;
[annotations addObject:areaAnnotation];
}
self.mapViewAnnotations = [annotations copy];
[_mapView addAnnotations:self.mapViewAnnotations];
}
实现百度地图的代理方法
// 根据anntation生成对应的View
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation{
//普通annotation
if ([annotation isKindOfClass:[AreaAnnotation class]]) {
static NSString *AreaAnnotationViewID = @"AreaAnnotationViewID";
AreaAnnotationView *annotationView = (AreaAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AreaAnnotationViewID];
if (annotationView == nil) {
annotationView = [[AreaAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AreaAnnotationViewID];
annotationView.delegate = self;
}
annotationView.titleLabel.text = ((AreaAnnotation *)annotation).areaModel.areaName;
annotationView.subTitleLabel.text = ((AreaAnnotation *)annotation).areaModel.houseNums;
return annotationView;
}
}
区域的标注AreaAnnotationView 自定义视图继承于BMKAnnotationView
这样区域的标注就已经加载完成。
下面实现点击区域加载商圈的功能:
这里在区域标注的点击代理里实现
- (void)didSelectAreaAnnotationView:(UIView *)view{
//当当前的选择点移到最前
UIView *tapDetectingView = view.superview;
[tapDetectingView bringSubviewToFront:view];
if([view isKindOfClass:[AreaAnnotationView class]]){
if (_isNewhouse) {
//统计
[MobClick event:@"searchNewHouseOnMap_bubble_arecaClickEvent"];
}else {
//统计
[MobClick event:@"searchNewHouseOnMap_bubble_houseClickEvent"];
}
AreaAnnotationView *areaAnnotationView = (AreaAnnotationView *)view;
AreaAnnotation *annotation= (AreaAnnotation *)areaAnnotationView.annotation;
[_mapView setMapStatus:[BMKMapStatus statusWithCenterCoordinate:annotation.coordinate zoomLevel:15] withAnimation:YES];
[self.searchMenuForHouseView setCurrentSelectLocationModel:annotation.areaModel];
}
}
这里没有做网络请求的方法,因为被下面这个方法中替代了,这个下面说
[_mapView setMapStatus:[BMKMapStatus statusWithCenterCoordinate:annotation.coordinate zoomLevel:15] withAnimation:YES];
商圈的加载和区域是一样的,这里就不再赘述了
这是mapView的代理方法,当mapView的zoomLevel改变或者mapView的region发生改变是会调用,我们的加载数据请求是放在这里做的,不同的地图zoomlevel显示不同标注:
一般区域的标注在地图上显示缩放水平为12、13级
商圈的标注在地图上显示缩放水平为14、15级
楼盘,学校在地图上显示缩放水平为17级
据此我们可以根据不同的缩放水平来进行不同的网络请求
-(void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
if (mapView.zoomLevel <= 13 && !_inModalStatus ){
if(self.areaArray.count>0){
[self addAreaAnnotation];
}else {
[self loadAreaAnnotation];
}
}else if (mapView.zoomLevel >13 && mapView.zoomLevel <17 && !_inModalStatus){
self.areaArray = nil;
[self loadTradingAnnotationWith:mapView.region.center fromMenuChoosed:animated];
}else if (mapView.zoomLevel >= 17){
self.areaArray = nil;
[self loadVillageAnnotationWith:mapView.region.center fromMenuChoosed:animated];
}else {
if (!animated){
[self resetArea:@"地图位置"];
}
[self.mapView removeAnnotations:self.mapViewAnnotations];
}
}
这里我们再来说下这个方法
[_mapView setMapStatus:[BMKMapStatus statusWithCenterCoordinate:annotation.coordinate zoomLevel:15] withAnimation:YES];
进到这个方法的定义内:
/**
- 设置地图状态
- @param [in] mapStatus 地图状态信息
- @param [in] bAnimation 是否需要动画效果,true:需要做动画
*/
这是百度地图提供的方法
我们需要做的是计算BMKMapStatus;这个类包含这些属性:
///缩放级别:[3~19]
@property (nonatomic, assign) float fLevel;
///旋转角度
@property (nonatomic, assign) float fRotation;
///俯视角度:[-45~0]
@property (nonatomic, assign) float fOverlooking;
///屏幕中心点坐标:在屏幕内,超过无效
@property (nonatomic) CGPoint targetScreenPt;
///地理中心点坐标:经纬度
@property (nonatomic) CLLocationCoordinate2D targetGeoPt;
///当前地图范围,采用直角坐标系表示,向右向下增长
@property (nonatomic, assign, readonly) BMKMapRect visibleMapRect;
这里我们需要的就是缩放级别和地理中心点坐标:经纬度
我们这里对做了一个类别并提供这个方法来计算这2个属性
+ (BMKMapStatus *)statusWithCenterCoordinate:(CLLocationCoordinate2D )centerCoordinate
zoomLevel:(NSUInteger)zoomLevel;
这样就可以当地图位置和缩放发生改变时被获取到,去执行代理方法。
这样地图3级显示区域、商业、楼盘的功能就实现了。
下面再简单说下在地图上画地铁的方法:
//画地铁
-(void)addSubWayAnnotationAndDrawSubWayLine{
[_mapView removeAnnotations:self.modalAnimations];
NSArray* arrayForOverlays = [NSArray arrayWithArray:_mapView.overlays];
[_mapView removeOverlays:arrayForOverlays];
CLLocationCoordinate2D *coords = malloc([self.subWayArray count] * sizeof(CLLocationCoordinate2D));
NSMutableArray *annotations= [NSMutableArray new];
for (int i = 0; i<self.subWayArray.count; i++) {
SubWayStationModel *model = self.subWayArray[i];
SubWayStationAnnotation *station = [SubWayStationAnnotation new];
station.subWayStationModel = model;
station.coordinate = model.location;
[annotations addObject:station];
//point
coords[i] = model.location;
}
self.modalAnimations = [annotations copy];
[_mapView addAnnotations:self.modalAnimations];
//构建BMKPolyline
BMKPolyline* polyline = [BMKPolyline polylineWithCoordinates:coords count:self.subWayArray.count];
//添加分段纹理绘制折线覆盖物
[self.mapView addOverlay:polyline];
//设置地图位置
[self mapViewFitPolyLine];
}
//根据地铁点设置地图位置
- (void)mapViewFitPolyLine{
CLLocationCoordinate2D center;
if (self.searchModel.stationCoordinate.latitude>0) {
center = self.searchModel.stationCoordinate;
}else {
if (self.subWayArray.count>0) {
NSInteger index = self.subWayArray.count/2;
SubWayStationModel *model = self.subWayArray[index];
center = model.location;
}
}
[_mapView setMapStatus:[BMKMapStatus statusWithCenterCoordinate:center zoomLevel:15] withAnimation:YES];
}
- (BMKOverlayView*)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay{
if ([overlay isKindOfClass:[BMKPolyline class]]) {
BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
polylineView.lineWidth = 4.0;
polylineView.fillColor = [UIColor colorWithHex:0xfb3534];
polylineView.strokeColor = [UIColor colorWithHex:0xfb3534];
return polylineView;
}
return nil;
}
就是简单的拿数据显示,并没有什么需要说的。地铁站的标注跟区域商圈一样显示。
感觉说的比较乱,如果有朋友做这方面的可以留言或者加我QQ聊。