1. 程式人生 > >自定義室內地圖以及路徑規劃

自定義室內地圖以及路徑規劃


最近做到一個專案,設計到室內地圖路徑規劃,其實一般的專案也很少設計到室內路徑規劃,室內也就那麼點大。

但是上面怎麼說我們就怎麼做吧,或者是人性化,或者是多此一舉的專案,既然寫了就分享出來吧。

先說下大致思想流程吧,語言表達不是很好,有不懂的可以加我的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;
}



我們來看下最終效果!