您的位置:首页 > 其它

随记(九)--确定两个地点的经纬度,自制驾车路线并计算其距离

2016-04-01 17:00 816 查看
使用地图,使用最多的也是百度地图API,以前使用百度地图只是表面地引用一下方法,很少点进方法或者对应属性的文件中,去查看其对应的说明与含义。

1.百度地图两点之间的距离

/**

*计算指定两点之间的距离

*@param a 第一个坐标点

*@param b 第二个坐标点

*@return 两点之间的距离,单位:米

*/

UIKIT_EXTERN CLLocationDistance BMKMetersBetweenMapPoints(BMKMapPoint a, BMKMapPoint b);


BMKMetersBetweenMapPoints方法只是两个经纬度之间的直线距离

2.路线实际距离

///此类表示一条驾车路线
@interface BMKDrivingRouteLine : BMKRouteLine{
bool                 _isSupportTraffic;//从2.7.0开始,废弃
NSArray*             _wayPoints;
}
///该路线所在区域是否含有交通流量信息,从2.7.0开始,废弃
@property (nonatomic) bool isSupportTraffic;
///路线途经点列表,成员类型为BMKPlanNode
@property (nonatomic, strong) NSArray* wayPoints;
@end


///此类表示路线数据结构的基类,表示一条路线,路线可能包括:路线规划中的换乘/驾车/步行路线
///此类为路线数据结构的基类,一般关注其子类对象即可,无需直接生成该类对象
@interface BMKRouteLine : NSObject{
int                  _distance;
BMKTime*             _duration;
BMKRouteNode*        _starting;
BMKRouteNode*        _terminal;
NSString*            _title;
NSArray*             _steps;
}
///路线长度 单位: 米
@property (nonatomic) int distance;
///路线耗时 单位: 秒
@property (nonatomic, strong) BMKTime* duration;
///路线起点信息
@property (nonatomic, strong) BMKRouteNode* starting;
///路线终点信息
@property (nonatomic, strong) BMKRouteNode* terminal;
///路线名称(预留字段,现为空)
@property (nonatomic, strong) NSString* title;
///路线中的所有路段,成员类型为BMKWalkingStep,BMKDrivingStep,BMKTransitStep
@property (nonatomic, strong) NSArray* steps;
@end


将MBKDrivingRouteLine实例化,通过distance属性获取实际驾车路线距离

长话段说,直接贴上我的代码

在XXX.h文件中

#import <UIKit/UIKit.h>
#import "BMapKit.h"

@interface XXXViewController : UIViewController

//@property (weak, nonatomic) IBOutlet BMKMapView *mapView;

@property (nonatomic, assign) CLLocationCoordinate2D startCoor;
@property (nonatomic, assign) CLLocationCoordinate2D endCoor;
@property (nonatomic, copy) NSString *addrName;

@end


在XXX.m文件中

#import "XXX.h"
#import "UIImage+Rotate.h"

#import <MapKit/MapKit.h>

#define MYBUNDLE_NAME @ "mapapi.bundle"
#define MYBUNDLE_PATH [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: MYBUNDLE_NAME]
#define MYBUNDLE [NSBundle bundleWithPath: MYBUNDLE_PATH]

@interface RouteAnnotation : BMKPointAnnotation
{
int _type; ///<0:起点 1:终点 2:公交 3:地铁 4:驾乘 5:途经点
int _degree;
}

@property (nonatomic) int type;
@property (nonatomic) int degree;
@end

@implementation RouteAnnotation

@synthesize type = _type;
@synthesize degree = _degree;
@end

@interface ServerRepairViewController () <BMKMapViewDelegate, BMKRouteSearchDelegate>
{
BMKRouteSearch* _routesearch;
BMKMapView *_mapView;
UILabel *_distanceLab;
}

@end

@implementation ServerRepairViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.title = @"外出服务";
//    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"驾车" style:UIBarButtonItemStylePlain target:self action:@selector(driveSearchAction)];

_mapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0, 0, K_ScreenWidth, K_ScreenHeight - 64)];
[self.view addSubview:_mapView];
_routesearch = [[BMKRouteSearch alloc] init];

_mapView.delegate = self;
_routesearch.delegate = self;

_distanceLab = [[UILabel alloc] initWithFrame:CGRectMake(0, K_ScreenHeight - 64 - 40, K_ScreenWidth, 40)];
_distanceLab.backgroundColor = [UIColor whiteColor];
_distanceLab.textColor = [UIColor blueColor];
[self.view addSubview:_distanceLab];

// 计算两点之间直线距离
//    CLLocationDistance  distance = BMKMetersBetweenMapPoints(BMKMapPointMake(self.startCoor.latitude, self.startCoor.longitude), BMKMapPointMake(self.endCoor.latitude, self.endCoor.longitude));

}

- (void)viewWillAppear:(BOOL)animated
{
[_mapView viewWillAppear];

_mapView.delegate = self;
_routesearch.delegate = self;

[self driveSearchAction];
}

- (void)viewWillDisappear:(BOOL)animated
{

[_mapView viewWillDisappear];
_mapView.delegate = nil;
_routesearch.delegate = nil;
}

-(void)dealloc
{
if (_mapView != nil) {
_mapView = nil;
}
if (_routesearch != nil) {
_routesearch = nil;
}
}

- (void)driveSearchAction
{
//    NSLog(@"1 = %lf, %lf, %lf, %lf",self.startCoor.latitude, self.startCoor.longitude, self.endCoor.latitude, self.endCoor.longitude);

BMKPlanNode *start = [[BMKPlanNode alloc] init];
start.pt = self.startCoor;

BMKPlanNode *end = [[BMKPlanNode alloc] init];
end.pt = self.endCoor;
end.name = self.addrName;

BMKDrivingRoutePlanOption *drivingRoutePlanOption = [[BMKDrivingRoutePlanOption alloc] init];
drivingRoutePlanOption.from = start;
drivingRoutePlanOption.to = end;

BOOL flag = [_routesearch drivingSearch:drivingRoutePlanOption];
if (flag) {
NSLog(@"car检索发送成功");
} else {
NSLog(@"car检索发送失败");
}
}

#pragma mark - BMKMapViewDelegate

- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation
{
if ([annotation isKindOfClass:[RouteAnnotation class]]) {
return [self getRouteAnnotationView:view viewForAnnotation:(RouteAnnotation*)annotation];
}
return nil;
}

- (BMKOverlayView*)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay
{
if ([overlay isKindOfClass:[BMKPolyline class]]) {
BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
polylineView.fillColor = [[UIColor alloc] initWithRed:0 green:1 blue:1 alpha:1];
polylineView.strokeColor = [[UIColor alloc] initWithRed:0 green:0 blue:1 alpha:0.7];
polylineView.lineWidth = 3.0;
return polylineView;
}
return nil;
}

#pragma mark - BMKRouteSearchDelegate

- (void)onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error
{
NSArray* array = [NSArray arrayWithArray:_mapView.annotations];
[_mapView removeAnnotations:array];
array = [NSArray arrayWithArray:_mapView.overlays];
[_mapView removeOverlays:array];

if (error == BMK_SEARCH_NO_ERROR) {
BMKDrivingRouteLine* plan = (BMKDrivingRouteLine*)[result.routes objectAtIndex:0];
_distanceLab.text = [NSString stringWithFormat:@"总路线:%.2lf公里", plan.distance * 2 / 1000.0];
// 计算路线方案中的路段数目
NSInteger size = [plan.steps count];
int planPointCounts = 0;
for (int i = 0; i < size; i++) {
BMKDrivingStep* transitStep = [plan.steps objectAtIndex:i];
if(i==0){
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = plan.starting.location;
item.title = @"起点";
item.type = 0;
[_mapView addAnnotation:item]; // 添加起点标注

}else if(i==size-1){
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = plan.terminal.location;
item.title = @"终点";
item.type = 1;
[_mapView addAnnotation:item]; // 添加起点标注
}
//添加annotation节点
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = transitStep.entrace.location;
item.title = transitStep.entraceInstruction;
item.degree = transitStep.direction * 30;
item.type = 4;
[_mapView addAnnotation:item];

//轨迹点总数累计
planPointCounts += transitStep.pointsCount;
}
// 添加途经点
if (plan.wayPoints) {
for (BMKPlanNode* tempNode in plan.wayPoints) {
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item = [[RouteAnnotation alloc]init];
item.coordinate = tempNode.pt;
item.type = 5;
item.title = tempNode.name;
[_mapView addAnnotation:item];
}
}
//轨迹点
BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts];
int i = 0;
for (int j = 0; j < size; j++) {
BMKDrivingStep* transitStep = [plan.steps objectAtIndex:j];
int k=0;
for(k=0;k<transitStep.pointsCount;k++) {
temppoints[i].x = transitStep.points[k].x;
temppoints[i].y = transitStep.points[k].y;
i++;
}

}
// 通过points构建BMKPolyline
BMKPolyline* polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];
[_mapView addOverlay:polyLine]; // 添加路线overlay
delete []temppoints;
[self mapViewFitPolyLine:polyLine];
}
}

#pragma mark - 私有
- (NSString*)getMyBundlePath1:(NSString *)filename
{
NSBundle * libBundle = MYBUNDLE ;
if ( libBundle && filename ){
NSString * s=[[libBundle resourcePath ] stringByAppendingPathComponent : filename];
return s;
}
return nil ;
}

- (BMKAnnotationView*)getRouteAnnotationView:(BMKMapView *)mapview viewForAnnotation:(RouteAnnotation*)routeAnnotation
{
BMKAnnotationView* view = nil;
switch (routeAnnotation.type) {
case 0:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"start_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"start_node"];
view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_start.png"]];
view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));
view.canShowCallout = TRUE;
}
view.annotation = routeAnnotation;
}
break;
case 1:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"end_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"end_node"];
view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_end.png"]];
view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));
view.canShowCallout = TRUE;
}
view.annotation = routeAnnotation;
}
break;
case 2:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"bus_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"bus_node"];
view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_bus.png"]];
view.canShowCallout = TRUE;
}
view.annotation = routeAnnotation;
}
break;
case 3:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"rail_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"rail_node"];
view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_rail.png"]];
view.canShowCallout = TRUE;
}
view.annotation = routeAnnotation;
}
break;
case 4:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"route_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"route_node"];
view.canShowCallout = TRUE;
} else {
[view setNeedsDisplay];
}

UIImage* image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_direction.png"]];
view.image = [image imageRotatedByDegrees:routeAnnotation.degree];
view.annotation = routeAnnotation;

}
break;
case 5:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"waypoint_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"waypoint_node"];
view.canShowCallout = TRUE;
} else {
[view setNeedsDisplay];
}

UIImage* image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_waypoint.png"]];
view.image = [image imageRotatedByDegrees:routeAnnotation.degree];
view.annotation = routeAnnotation;
}
break;
default:
break;
}

return view;
}

//根据polyline设置地图范围
- (void)mapViewFitPolyLine:(BMKPolyline *) polyLine {
CGFloat ltX, ltY, rbX, rbY;
if (polyLine.pointCount < 1) {
return;
}
BMKMapPoint pt = polyLine.points[0];
ltX = pt.x, ltY = pt.y;
rbX = pt.x, rbY = pt.y;
for (int i = 1; i < polyLine.pointCount; i++) {
BMKMapPoint pt = polyLine.points[i];
if (pt.x < ltX) {
ltX = pt.x;
}
if (pt.x > rbX) {
rbX = pt.x;
}
if (pt.y > ltY) {
ltY = pt.y;
}
if (pt.y < rbY) {
rbY = pt.y;
}
}
BMKMapRect rect;
rect.origin = BMKMapPointMake(ltX , ltY);
rect.size = BMKMapSizeMake(rbX - ltX, rbY - ltY);
[_mapView setVisibleMapRect:rect];
_mapView.zoomLevel = _mapView.zoomLevel - 0.3;
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: