前言
我們的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聊。