自定義室內地圖以及路徑規劃
阿新 • • 發佈:2019-02-03
最近做到一個專案,設計到室內地圖路徑規劃,其實一般的專案也很少設計到室內路徑規劃,室內也就那麼點大。
但是上面怎麼說我們就怎麼做吧,或者是人性化,或者是多此一舉的專案,既然寫了就分享出來吧。
先說下大致思想流程吧,語言表達不是很好,有不懂的可以加我的qq24272779詢問!
上圖例子:
基本思路把上圖建築區域全部用座標扣選出來,也就是不能走到的地方,藍色區域和灰色區域。
座標點以畫素為單位。
扣選出來以後把整個圖片地圖分成由好多小方格組成的!
選擇兩個點,用A*演算法求出需要經過非藍色和灰色區域的最短路徑。
(A*演算法不懂的可以百度)。
程式碼:
//新增地圖圖片
//長安選擇起點和終點SKIndoorMapView *indoorMap = [[SKIndoorMapView alloc]initWithIndoorMapImageName:@"WHTerminalBD.png" Frame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; [self.view addSubview:indoorMap];
#pragma mark - Zoom methods -(void)longRequired:(UIGestureRecognizer*)gesture { if (gesture.state == UIGestureRecognizerStateBegan) { if (Points.count == 0 || Points.count >= 2) { [Points removeAllObjects]; for (UIView *view in [self.mapView subviews]) { [view removeFromSuperview]; } //座標 CGPoint touchPoint = [gesture locationInView:self.mapView]; UIImage *Img = [UIImage imageNamed:@"startPoint"]; UIImageView *imgView = [[UIImageView alloc]initWithImage:Img]; [imgView setFrame:CGRectMake(touchPoint.x - (Img.size.width / (self.zoomScale*2)), touchPoint.y - (Img.size.width / (self.zoomScale)), Img.size.width / self.zoomScale, Img.size.height / self.zoomScale)]; [self.mapView addSubview:imgView]; [Points addObject:NSStringFromCGPoint(touchPoint)]; } else if (Points.count == 1) { //座標 CGPoint touchPoint = [gesture locationInView:self.mapView]; UIImage *Img = [UIImage imageNamed:@"endPoint"]; UIImageView *imgView = [[UIImageView alloc]initWithImage:Img]; [imgView setFrame:CGRectMake(touchPoint.x - (Img.size.width / (self.zoomScale*2)), touchPoint.y - (Img.size.width / (self.zoomScale)), Img.size.width / self.zoomScale, Img.size.height / self.zoomScale)]; [self.mapView addSubview:imgView]; [Points addObject:NSStringFromCGPoint(touchPoint)]; [self RoadRecevied:Points]; } } }
#pragma 路徑 -(void)RoadRecevied:(NSMutableArray *)Arr { /* 路徑規劃 */ AStar *astar = [[AStar alloc]init]; data = [astar findPath:CGPointFromString(Arr[0]).x curY:CGPointFromString(Arr[0]).y aimX:CGPointFromString(Arr[1]).x aimY:CGPointFromString(Arr[1]).y]; /* size——同UIGraphicsBeginImageContext opaque—透明開關,如果圖形完全不用透明,設定為YES以優化點陣圖的儲存。 scale—–縮放因子 */ UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 480), NO, [UIScreen mainScreen].scale); UIBezierPath *path = [UIBezierPath bezierPath]; [[UIColor redColor] setStroke]; [path setLineWidth:0.5]; [path setLineJoinStyle:kCGLineJoinRound]; [path setLineCapStyle:kCGLineCapRound]; BOOL isfirst = YES; if (data && [data count] > 0) { for (id obj in data) { if (isfirst) { isfirst = NO; [path moveToPoint:CGPointMake([obj id_col], [obj id_row])];//設定起始路徑的點 } [path addLineToPoint:CGPointMake([obj id_col], [obj id_row])]; } } [path stroke]; UIImage *img =UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIImageView *imgV = [[UIImageView alloc]initWithImage:img]; [_mapView addSubview:imgV]; [self setNeedsDisplay]; }
//這裡我們來看看怎麼扣選出藍色區域和灰色非路徑規劃區域吧
<pre name="code" class="objc">- (bool)checkMap:(int)col row:(int)row
{
CGPoint point = CGPointMake(col, row);
/*
150,45,180,45,180,70,150,70 值班室
200,10,225,10,225,50,180,50,180,45,200,45 不明區域
160,75,180,75,180,150,150,150,150,135,120,135,120,145,195,150,95,125,120,110,140,110,160,95 包裹打包區
100,165,125,65,125,270,140,270,140,280,85,280,85,260,95,260, 候機大廳
150,170,170,170,170,260,150,260 安檢區
10,310,60,280,150,290,150,275,180,275,180,305,150,305,150,360,170,360,170,390,200,405,200,475,150,475,150,380 休息區
*/
/*
180,350,220,250,220,370,180,380 不明區域
0,0,200,0,200,45,150,45,150,75,10,145,60,170,70,28010,310,150,380,150,420,190,425,150,480,0,480 左邊灰色
230,0,320,0,320,480,230,480 右邊灰色
*/
NSString *obstacle00 = @"150,45,180,45,180,70,150,70";
NSString *obstacle01 = @"200,10,225,10,225,50,180,50,180,45,200,45";
NSString *obstacle02 = @"160,75,180,75,180,150,150,150,150,135,120,135,120,145,195,150,95,125,120,110,140,110,160,95";
NSString *obstacle03 = @"100,165,125,65,125,270,140,270,140,280,85,280,85,260,95,260";
NSString *obstacle04 = @"150,170,170,170,170,260,150,260 ";
NSString *obstacle05 = @"10,310,60,280,150,290,150,275,180,275,180,305,150,305,150,360,170,360,170,390,200,405,200,475,150,475,150,380";
NSString *obstacle06 = @"180,350,220,250,220,370,180,380";
UIBezierPath *path00 = [Utils bezierPathFromCoordinateString:obstacle00];
UIBezierPath *path01 = [Utils bezierPathFromCoordinateString:obstacle01];
UIBezierPath *path02 = [Utils bezierPathFromCoordinateString:obstacle02];
UIBezierPath *path03 = [Utils bezierPathFromCoordinateString:obstacle03];
UIBezierPath *path04 = [Utils bezierPathFromCoordinateString:obstacle04];
UIBezierPath *path05 = [Utils bezierPathFromCoordinateString:obstacle05];
UIBezierPath *path06 = [Utils bezierPathFromCoordinateString:obstacle06];
// NSString *str110 = @"10,145,65,170,65,280,10,310,150,385,150,423,190,425,190,475,230,475,230,5,200,5,200,45,150,45,150,75";
if (CGPathContainsPoint(path00.CGPath,NULL,point,false))
{
return NO;
}
else if (CGPathContainsPoint(path01.CGPath,NULL,point,false))
{
return NO;
}
else if (CGPathContainsPoint(path02.CGPath,NULL,point,false))
{
return NO;
}
else if (CGPathContainsPoint(path03.CGPath,NULL,point,false))
{
return NO;
}
else if (CGPathContainsPoint(path04.CGPath,NULL,point,false))
{
return NO;
}
else if (CGPathContainsPoint(path05.CGPath,NULL,point,false))
{
return NO;
}
else if (CGPathContainsPoint(path06.CGPath,NULL,point,false))
{
return NO;
}
return YES;
}
我們來看下最終效果!