iOS百度地圖畫一個(gè)矩形來顯示矩形內(nèi)的標(biāo)注的個(gè)數(shù)(經(jīng)緯度等等)

首先介紹下我們app:
由于我們是一個(gè)地圖打點(diǎn)券躁,連線的app惩坑。客戶提出一個(gè)需求也拜,在手機(jī)上畫出一個(gè)矩形以舒,要求計(jì)算矩形中的線總長度。

看到這個(gè)需求后慢哈,就去翻閱了百度sdk的文檔: http://lbsyun.baidu.com/index.php?title=iossdk/guide/map-render/ploygon
百度地圖sdk中蔓钟,存在繪制面,弧線的api卵贱,但是都是需要經(jīng)緯度之后才能繪制滥沫。 當(dāng)時(shí)就放棄了這種方法。

  • 因?yàn)橹白鯽pp的時(shí)候 我們在mapview上有過view键俱,然后轉(zhuǎn)化為百度地圖的gps坐標(biāo)兰绣。所以覺得邏輯應(yīng)該是,使用touch代理時(shí)間或者拖拽來在百度地圖上畫一個(gè)矩形view编振。然后將view的坐標(biāo)轉(zhuǎn)化為百度地圖的坐標(biāo)缀辩。這樣子來確定經(jīng)緯度范圍。

所以:最終的方案是踪央,先使用touch代理畫取矩形(我使用的touch代理臀玄,沒用拖拽手勢)。然后將view貼到mapview上畅蹂。轉(zhuǎn)化為mapview的經(jīng)緯度范圍镐牺。再進(jìn)行篩選。

一步一步實(shí)現(xiàn):

  1. 先畫一個(gè)view:
    自己做了一個(gè)小demo魁莉,通過touch的代理方法 來畫出矩睬涧。下面看代碼募胃。

先看看代碼塊顯示效果

PacView 是我自定義的一個(gè)view。 剛開始以為要用到drawrect畦浓。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = _titleStr;
    self.view.backgroundColor = [UIColor whiteColor];
    _zyqview = [[PacView alloc]initWithFrame:CGRectMake(50, 104, 80, 80)];
    [self.view addSubview:_zyqview];
    _zyqview.backgroundColor = [UIColor greenColor];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    NSSet *allTouches = [event allTouches];    //返回與當(dāng)前接收者有關(guān)的所有的觸摸對象
    UITouch *touch = [allTouches anyObject];   //視圖中的所有對象
    CGPoint point = [touch locationInView:[touch view]]; //返回觸摸點(diǎn)在視圖中的當(dāng)前坐標(biāo)
    _oriX = point.x;
    _oriY = point.y;
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    NSSet *allTouches = [event allTouches];    //返回與當(dāng)前接收者有關(guān)的所有的觸摸對象
    UITouch *touch = [allTouches anyObject];   //視圖中的所有對象
    CGPoint point = [touch locationInView:[touch view]]; //返回觸摸點(diǎn)在視圖中的當(dāng)前坐標(biāo)
    _changeX = point.x;
    _changeY = point.y;
    //    NSLog(@"2touch (x, y) is (%d, %d)", _changeX, _changeY);
    [self jisuanHeightWidth];
}
- (void)jisuanHeightWidth {
    int height = 0;
    int width = 0;
    
    if (_changeX > _oriX) {
        width = _changeX - _oriX;
    }else {
        width = _oriX - _changeX;
    }
    if (_changeY >_oriY) {
        height = _changeY - _oriY;
    }else {
        height = _oriY - _changeY;
    }
    
    CGRect rect = CGRectMake(0, 0, 0, 0);
    //右下
    if (_changeX > _oriX && _changeY >_oriY) {
        rect = CGRectMake(_oriX, _oriY, width, height);
    }
    //右上
    if (_changeX > _oriX && _changeY <_oriY) {
        rect = CGRectMake(_oriX, _changeY, width, height);
    }
    //左下
    if (_changeX < _oriX && _changeY >_oriY) {
        rect = CGRectMake(_changeX, _oriY, width, height);
    }
    //左上
    if (_changeX < _oriX && _changeY <_oriY) {
        rect = CGRectMake(_changeX, _changeY, width, height);
    }
    
    _zyqview.frame = rect;
}

以上代碼就可以畫出一個(gè)矩形了痹束。 如果是拖拽方法的話,可能jisuanHeightWidth方法里的frame獲取要改變下讶请。

  1. 接入百度地圖項(xiàng)目:

上面的畫矩形方法直接扔到項(xiàng)目里就行了祷嘶。

[self.view addSubview:_zyqview]; 這個(gè)方法的self.view 改為 mapview就行了。 因?yàn)橐粫阋D(zhuǎn)化為mapview的坐標(biāo)經(jīng)緯度

然后畫完矩形后夺溢,手指松開论巍,會走下面的方法

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    if (_isRightXY == YES) {
        [self caclulaterPacViewToMapView];

    }
    _isRightXY = NO;
    
}

- (void)caclulaterPacViewToMapView {
    if (_jisuanButton.selected == YES) {
        
        //百度地圖
        BMKCoordinateRegion  region = [_mapView convertRect:_zyqview.frame toRegionFromView:_mapView];
//        region.span.latitudeDelta //緯度范圍 是指總長,類似寬高风响。
//        region.span.longitudeDelta 經(jīng)度范圍
//        CLLocationCoordinate2D center;    ///< 中心點(diǎn)經(jīng)緯度坐標(biāo)
        double leftLat = region.center.latitude - region.span.latitudeDelta/2;
        double rightLat = region.center.latitude + region.span.latitudeDelta/2;
        double topLog = region.center.longitude - region.span.longitudeDelta/2;//最小
        double bootomLog = region.center.longitude + region.span.longitudeDelta/2;//最大
//        113.615697,34.745975;113.611570,34.750439  long嘉汰,lat;long状勤,lat
        
        
        //另一種計(jì)算方法
//        左下 右上 最小最大
        CGPoint mixPoint = CGPointMake(CGRectGetMinX(_zyqview.frame), CGRectGetMinY(_zyqview.frame)+CGRectGetHeight(_zyqview.frame));
        CGPoint maxPoint = CGPointMake(CGRectGetMinX(_zyqview.frame) + CGRectGetWidth(_zyqview.frame), CGRectGetMinY(_zyqview.frame));
        CLLocationCoordinate2D mixCoordinate = [_mapView convertPoint:mixPoint toCoordinateFromView:_mapView];

        CLLocationCoordinate2D maxCoordinate = [_mapView convertPoint:maxPoint toCoordinateFromView:_mapView];
        leftLat = mixCoordinate.latitude;
        rightLat = maxCoordinate.latitude;
        topLog = mixCoordinate.longitude;
        bootomLog = maxCoordinate.longitude;
        
        
        
        NSLog(@"圈圈圈%f,%f,%f,%f",topLog,bootomLog,leftLat,rightLat);
        NSMutableArray * counArray = [NSMutableArray new];
        for (TYBMKPolyline * line in _mapView.overlays) {
            if ([line isKindOfClass:[TYBMKPolyline class]]) {
                NSArray * latAndLogArray = [line.slnInfo.line_Longitude_Latitude componentsSeparatedByString:@";"];
                NSString * firstCor = latAndLogArray[0];//第一個(gè)coors
                NSString * secCor = latAndLogArray[1];//第2個(gè)coors
                
                double firstLog = [[firstCor componentsSeparatedByString:@","][0] doubleValue];
                double firstLat = [[firstCor componentsSeparatedByString:@","][1] doubleValue];
                double secLog = [[secCor componentsSeparatedByString:@","][0] doubleValue];
                double sectLat = [[secCor componentsSeparatedByString:@","][1] doubleValue];
                
                
                CLLocationCoordinate2D coors[2] = {0};
                coors[0].latitude = firstLat;
                coors[0].longitude = firstLog;
                coors[1].latitude = sectLat;
                coors[1].longitude = secLog;

                CLLocationCoordinate2D converTos[2] = {0};
                
                converTos[0] = [TYTool baiduLocationFromGPSCoordinate2D:coors[0]];
                converTos[1] = [TYTool baiduLocationFromGPSCoordinate2D:coors[1]];
                
                
                firstLat = converTos[0].latitude;
                firstLog = converTos[0].longitude;
                sectLat = converTos[1].latitude;
                secLog = converTos[1].longitude;
                
                double minLog = MIN(firstLog, secLog);
                double minLat = MIN(firstLat, sectLat);
                double maxLog = MAX(firstLog, secLog);
                double maxLat = MAX(firstLat, sectLat);
                NSLog(@"%f,%f,%f,%f \n ---%f",minLog,maxLog,minLat,maxLat,line.slnInfo.line_Distance);

                if (minLog>topLog && maxLog<bootomLog && minLat>leftLat && maxLat<rightLat) {//最大的和最大的比鞋怀,最小的和最小的比
//                    NSLog(@"%f,%f,%f,%f ---%f",minLog,maxLog,minLat,maxLat,line.slnInfo.line_Distance);
                    [counArray addObject:line];
                }
                
            }

        }
//        NSLog(@"%ld",counArray.count);
        if (counArray.count != 0) {
            double allLineDis = 0.0;
            for (TYBMKPolyline * line in counArray) {
                allLineDis = allLineDis + line.slnInfo.line_Distance;
            }
            _tipsLabel.text = [NSString stringWithFormat:@"長度為%.f 米",allLineDis];
            
//            UIAlertController * ac = [UIAlertController alertControllerWithTitle:@"提示" message:[NSString stringWithFormat:@"%f",allLineDis] preferredStyle:UIAlertControllerStyleAlert];
//            UIAlertAction * deleteAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
////                _zyqview.hidden = YES;
//            }];
//            [ac addAction:deleteAction];
//            [self presentViewController:ac animated:YES completion:nil];

        }else {
            [[TYNotification share] showPromptView:@"沒有符合要求的線"];
            _tipsLabel.text = @"請劃線";
//            _zyqview.hidden = YES;
        }
        
    }
}

關(guān)于百度sdk的這個(gè)方法:

BMKCoordinateRegion  region = [_mapView convertRect:_zyqview.frame toRegionFromView:_mapView];
//        region.span.latitudeDelta //緯度范圍 是指總長,類似寬高持搜。
//        region.span.longitudeDelta 經(jīng)度范圍
//        CLLocationCoordinate2D center;    ///< 中心點(diǎn)經(jīng)緯度坐標(biāo)
        double leftLat = region.center.latitude - region.span.latitudeDelta/2;
        double rightLat = region.center.latitude + region.span.latitudeDelta/2;
        double topLog = region.center.longitude - region.span.longitudeDelta/2;//最小
        double bootomLog = region.center.longitude + region.span.longitudeDelta/2;//最大
//        113.615697,34.745975;113.611570,34.750439  long密似,lat;long葫盼,lat

api上給的是 將view坐標(biāo) 轉(zhuǎn)化為經(jīng)緯度残腌。 region.span.longitudeDelta 經(jīng)度范圍,這個(gè)經(jīng)度范圍最開始 我當(dāng)成是寬/2來計(jì)算贫导。
double leftLat = region.center.latitude - region.span.latitudeDelta
后來發(fā)現(xiàn)根本不正確废累,精確度錯(cuò)的太多,后來web同事提醒脱盲,是不是region.span.longitudeDelta是寬度的一半邑滨,就改成了這樣
double leftLat = region.center.latitude - region.span.latitudeDelta/2
后來發(fā)現(xiàn)還是不行,雖然精確度提高了钱反,但是還是誤差很大很大掖看。
最后曲線救國吧

//        左下 右上 最小最大
        CGPoint mixPoint = CGPointMake(CGRectGetMinX(_zyqview.frame), CGRectGetMinY(_zyqview.frame)+CGRectGetHeight(_zyqview.frame));
        CGPoint maxPoint = CGPointMake(CGRectGetMinX(_zyqview.frame) + CGRectGetWidth(_zyqview.frame), CGRectGetMinY(_zyqview.frame));
        CLLocationCoordinate2D mixCoordinate = [_mapView convertPoint:mixPoint toCoordinateFromView:_mapView];

        CLLocationCoordinate2D maxCoordinate = [_mapView convertPoint:maxPoint toCoordinateFromView:_mapView];
        leftLat = mixCoordinate.latitude;
        rightLat = maxCoordinate.latitude;
        topLog = mixCoordinate.longitude;
        bootomLog = maxCoordinate.longitude;

將左下,右上的點(diǎn)提出來轉(zhuǎn)化為經(jīng)緯度面哥,最后就ok了哎壳。

以上就是這次需求開發(fā)的坑。尚卫。

第一次用markdown寫企孩。gif不知道怎么上傳=- =

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怔蚌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子患整,更是在濱河造成了極大的恐慌诊胞,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡盅蝗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門姆蘸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墩莫,“玉大人,你說我怎么就攤上這事逞敷】袂兀” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵推捐,是天一觀的道長裂问。 經(jīng)常有香客問我,道長玖姑,這世上最難降的妖魔是什么愕秫? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任慨菱,我火速辦了婚禮焰络,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘符喝。我一直安慰自己闪彼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布协饲。 她就那樣靜靜地躺著畏腕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茉稠。 梳的紋絲不亂的頭發(fā)上描馅,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音而线,去河邊找鬼铭污。 笑死,一個(gè)胖子當(dāng)著我的面吹牛膀篮,可吹牛的內(nèi)容都是我干的嘹狞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼誓竿,長吁一口氣:“原來是場噩夢啊……” “哼磅网!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起筷屡,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涧偷,失蹤者是張志新(化名)和其女友劉穎簸喂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嫂丙,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娘赴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跟啤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诽表。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖隅肥,靈堂內(nèi)的尸體忽然破棺而出竿奏,到底是詐尸還是另有隱情,我是刑警寧澤腥放,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布泛啸,位于F島的核電站,受9級特大地震影響秃症,放射性物質(zhì)發(fā)生泄漏候址。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一种柑、第九天 我趴在偏房一處隱蔽的房頂上張望岗仑。 院中可真熱鬧,春花似錦聚请、人聲如沸荠雕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炸卑。三九已至,卻和暖如春煤傍,著一層夾襖步出監(jiān)牢的瞬間盖文,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工蚯姆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留五续,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓蒋失,卻偏偏與公主長得像返帕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子篙挽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容