iPhoneのプログラム

SATCHを用いたナビアプリ(3)その4

シナリオファイル

変更したソースのみ掲載しています。

map_10F.txt
K1号館10F
|―――――――――――――――――――――――――――|
|+++++++++|・・・・・・・|+++++++++|
|+++++++++|C・・・・・C|+++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|・|*――|・|+++++++++|
|+++++++++*C・・・・・C*白++++++++|
|―――――――――|・|―――|・|―――――――――|
|+++++++++|・|+階+|・|+++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|・|+++|・|+++++++++|
|++++++++井*・|E―E|・*黒++++++++|
|―――――――――|・|+*+|・|―――――――――|
|+++井教*・+++・++・++・+++・*黒教+++|
|―――――|・・・・C・・・・・C・・・・|―――――|
|+++平教*・+++・++・++・+++・*福教+++|
|―――――――――|・|+*+|・|―――――――――|
|++++++++平*・|E―E|・*福++++++++|
|+++++++++|・|+++|・|+++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|・|+階+|・|+++++++++|
|―――――――――|・|―――|・|―――――――――|
|++++++++坂*・|―P―|・*梶++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|C・・・・・C|+++++++++|
|+++++++坂教*・|―|―|・*梶教+++++++|
|+++++++++|・*男|女*・|+++++++++|
|―――――――――――――――――――――――――――|

map_11F.txt
K1号館11F
|―――――――――――――――――――――――――――|
|+|+++|+++|・・・・・・・|+++++++++|
|+|+++|+++|・・・・・・・|+++++++++|
|+|++春|++西|C・・・・・C*小教+++++++|
|+|――*―――*|・|*|P|・|+++++++++|
|助*・・・・・・・・C・・・・・C*小++++++++|
|―――――――――|・|―――|・|―――――――――|
|+++++++++|・|+階+|・|+++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|・|+++|・|+++++++++|
|++++++++富*・|E―E|・*服++++++++|
|―――――――――|・|+*+|・|―――――――――|
|+++富教*・+++・++・++・+++・*服教+++|
|―――――|・・・・C・・・・・C・・・・|―――――|
|+++谷教*・+++・++・++・+++・*徳教+++|
|―――――――――|・|+*+|・|―――――――――|
|++++++++谷*・|E―E|・*徳++++++++|
|+++++++++|・|+++|・|+++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|・|+階+|・|+++++++++|
|―――――――――|・|―――|・|―――――――――|
|++++++++佐*・|―P―|・*速++++++++|
|+++++++++|・|―――|・|+++++++++|
|+++++++++|C・・・・・C|+++++++++|
|+++++++佐教*・|―|―|・*速教+++++++|
|+++++++++|・*男|女*・|+++++++++|
|―――――――――――――――――――――――――――|

int3d.pm
package KAIT::init3d;

*FLOOR_DATA = [ 'dummy', 'map_1F.txt', 'map_MF.txt', 'map_10F.txt', 'map_MF.txt', 'map_11F.txt', ];

*SYMBOL_PASS = { '・' => 1, 'C' => 1,};

*SYMBOL_MARKER = {'*' => 1, '@' => 1, };

*SYMBOL_CORNER = {'C' => 1, };

*ELEVATOR_MARKER = [ '15.12', '15.16', ];

*SPOTS = { 
# 1F

#入り口(K2号館側)
'1' => '19.5.1',

#入り口(マクドナルド側)
'2' => '19.23.1', 

#エレベータ(1A,1B)
'3' => '15.13.1', 

#エレベータ(1C,1D)
'4' => '15.15.1', 

# 10F

#平野教員室(1005)
'1005' => '8.15.10',

#平野研究室(1006)
'1006' => '12.17.10',

#坂内研究室(1007)
'1007' => '12.22.10',

#坂内教員室(1008)
'1008' => '12.25.10',

#梶教員室(1009)
'1009' => '18.25.10',

#梶研究室・牧研究室(1010)
'1010' => '18.22.10',

#福井研究室(1011)
'1011' => '18.17.10',

#福井教員室(1012)
'1012' => '22.15.10',

#黒川教員室(1013)
'1013' => '22.13.10',

#黒川研究室(1014)
'1014' => '18.11.10',

#エレベータ(10A,10B)
'5' => '15.13.10', 

#エレベータ(10C,10D)
'6' => '15.15.10', 

# 11F

#西村(広)教員室(1101)
'1101' => '10.6.11',

#春日教員室(1102)
'1102' => '6.6.11',

#共通教員室(1103)
'1103' => '4.6.11',

#富川研究室・山内研究室(1104)
'1104' => '12.11.11',

#富川教員室(1105)
'1105' => '8.13.11',

#谷中教員室(1106)
'1106' => '8.15.11',

#谷中研究室(1107)
'1107' => '12.17.11',

#佐藤研究室・鈴木(浩)研究室(1108)
'1108' => '12.22.11',

#佐藤教員室(1109)
'1109' => '12.25.11',

#速水教員室(1110)
'1110' => '18.25.11',

#速水研究室(1111)
'1111' => '18.22.11',

#徳弘研究室(1112)
'1112' => '18.17.11',

#徳弘教員室(1113)
'1113' => '22.15.11',

#服部(元)教員室(1114)
'1114' => '22.13.11',

#服部(元)研究室・小坂研究室(1115)
'1115' => '18.11.11',

#小島研究室(1116)
'1116' => '18.6.11',

#小島教員室(1117)
'1117' => '18.4.11',

#エレベータ(11A,11B)
'7' => '15.13.11', 

#エレベータ(11C,11D)
'8' => '15.15.11', 

};

dispALL4.lua
local MLTPlugin = getMLTPluginManager()
local scene = getCurrentScene()
local camera = Camera(scene:getCurrentCamera())
local vidCap = VideoCapture(scene:getObjectByName("vidcap"))
local msg = Text2D(scene:getObjectByName("msg"))

-- 方向指示用
local boussole = Entity(scene:getObjectByName("Boussole"))
local fleche = Entity(scene:getObjectByName("Fleche"))
boussole:setVisible(false)
fleche:setVisible(false)

-- 色識別用
local mainView = RenderTarget(scene:getMainView())
local targetDirectory = getUserAppDataDirectory()
local targetJpg = targetDirectory .. "c1.jpg"
local camera_mode = 1

local componentInterface = getComponentInterface()

local err_ret = eOk
local trackingIndex = -1
local targetStatus = {-1, -1, -1}
local action = {
"1101    found!", "1102    found!", "1103    found!",
"1104    found!", "1105    found!", "1106    found!",
"1107    found!", "1108    found!", "1109    found!",
"1110    found!", "1111    found!", "1112    found!",
"1113    found!", "1114    found!", "1115    found!",
"1116    found!", "1117    found!",
"1    found!", "2    found!" }
local marker_no = {
1101, 1102, 1103,
1104, 1105, 1106,
1107, 1108, 1109,
1110, 1111, 1112,
1113, 1114, 1115,
1116, 1117,
1,    2
}

local key = -1
local found = -1
local i=0
local stage = 1
local found_marker = -1
local cand = 3

local isCommand = nil
local command = nil
local mode = 1

msg:setText(" ")

err_ret, trackingIndex = MLTPlugin:startTracking("B1/tracker.xml", vidCap:getVidCapID(), camera)

function gotoStage(n)
	MLTPlugin:stopTracking(trackingIndex)
    
	stage = n

	if n == 1 then
		msg:setText("stage=1")
		err_ret, trackingIndex = 
			MLTPlugin:startTracking("B1/tracker.xml", vidCap:getVidCapID(), camera)
	elseif n == 2 then
		msg:setText("stage=2")
		err_ret, trackingIndex =
			MLTPlugin:startTracking("B2/tracker.xml", vidCap:getVidCapID(), camera)
	elseif n == 3 then
		msg:setText("stage=3")
		err_ret, trackingIndex =
			MLTPlugin:startTracking("B3/tracker.xml", vidCap:getVidCapID(), camera)
	elseif n == 4 then
		msg:setText("stage=4")
		err_ret, trackingIndex =
			MLTPlugin:startTracking("B4/tracker.xml", vidCap:getVidCapID(), camera)
	elseif n == 5 then
		msg:setText("stage=5")
		err_ret, trackingIndex =
			MLTPlugin:startTracking("B5/tracker.xml", vidCap:getVidCapID(), camera)
	elseif n == 6 then
		msg:setText("stage=6")
		err_ret, trackingIndex =
			MLTPlugin:startTracking("B6/tracker.xml", vidCap:getVidCapID(), camera)
	elseif n == 7 then
		msg:setText("stage=7")
		err_ret, trackingIndex =
			MLTPlugin:startTracking("B7/tracker.xml", vidCap:getVidCapID(), camera)
	end
end

function recognize()

		if stage <= 5 then
			cand = 3
		else
			cand = 2
		end

		for i = 1,cand do
    	err_ret, targetStatus[i] = MLTPlugin:getTargetStatus(trackingIndex, i-1)
		end

		found = -1
		for i = 1,cand do
			if (targetStatus[i] == 1) then
				found = i
				break
			end
		end

		if (found ~= -1) then
			if (stage <= 5) then
				key = found + 3*(stage-1)
			else
				key = found + 2*(stage-6) + 15
			end
			msg:setText(action[key])
			found_marker = marker_no[key]

			if componentInterface then
    			componentInterface:executeAppFunc("setStartPosition", found_marker);
    	end
			mode = 2
		else
			if (stage == 1) then
				gotoStage(2)
			elseif (stage == 2) then
				gotoStage(3)
			elseif (stage == 3) then
				gotoStage(4)
			elseif (stage == 4) then
				gotoStage(5)
			elseif (stage == 5) then
				gotoStage(6)
			elseif (stage == 6) then
				gotoStage(7)
			elseif (stage == 7) then
				gotoStage(1)
			end

 			coroutine.yield()
		end

end

repeat
	if (mode == 1) then

		recognize()

	elseif (mode == 2) then
		msg:setText(" ")

		if componentInterface then
			isCommand, command = componentInterface:pullCommand()
			if isCommand then
				if command["CommandName"]=="sendGyro" then
					boussole:setVisible(true)
					fleche:setVisible(true)
					fleche:setOrientationEuler(0,command["arg1"],0,boussole)
					mode = 3;
				end
			end
		end

	elseif (mode == 3) then

		if componentInterface then
			isCommand, command = componentInterface:pullCommand()
			if isCommand then
				if command["CommandName"]=="sendGyro" then
					fleche:setOrientationEuler(0,command["arg1"],0,boussole)
				elseif command["CommandName"]=="prepareCamera" then
					boussole:setVisible(false)
					fleche:setVisible(false)
					camera_mode = 1
					mode = 4
				end
			end
		end

	elseif (mode == 4) then

		if camera_mode == 1 then
			if componentInterface then
				isCommand, command = componentInterface:pullCommand()
				if isCommand then
					if command["CommandName"]=="capture" then
						mainView:dump(targetJpg)
						camera_mode = 2
					end
				end
			end
		elseif camera_mode == 2 then
			if componentInterface then
				componentInterface:executeAppFunc("setCaptureFilename", targetJpg);
			end
			mode = 2
		end

	end

until coroutine.yield()

AppDelegate.mm
#import "AppDelegate.h"
#import "ViewController.h"
#import "Spot.h"
#import "URLLoader.h"
#import "NaviXMLParser.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;
@synthesize navController = _navController;
@synthesize spots = _spots;

@synthesize startSpot;
@synthesize destSpot;

@synthesize path1;
@synthesize path2;
@synthesize path;

@synthesize capName;

@synthesize elevatorSide;

- (void)dealloc
{
    [_window release];
    [_viewController release];
    [_spots release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    numPath = 1;
    countPath = 0;
    curDirect = 1;
    
    Spot *s1 = [[[Spot alloc] init] autorelease];
    s1.spotID = @"1";
    s1.spotName = @"入り口(K2号館側)";
    
    Spot *s2 = [[[Spot alloc] init] autorelease];
    s2.spotID = @"2";
    s2.spotName = @"入り口(マクドナルド側)";
    
    Spot *s1101 = [[[Spot alloc] init] autorelease];
    s1101.spotID = @"1101";
    s1101.spotName = @"西村(広)教員室(1101)";
    
    Spot *s1102 = [[[Spot alloc] init] autorelease];
    s1102.spotID = @"1102";
    s1102.spotName = @"春日教員室(1102)";
    
    Spot *s1103 = [[[Spot alloc] init] autorelease];
    s1103.spotID = @"1103";
    s1103.spotName = @"共通教員室(1103)";
    
    Spot *s1104 = [[[Spot alloc] init] autorelease];
    s1104.spotID = @"1104";
    s1104.spotName = @"富川研究室・山内研究室(1104)";
    
    Spot *s1105 = [[[Spot alloc] init] autorelease];
    s1105.spotID = @"1105";
    s1105.spotName = @"富川教員室(1105)";
    
    Spot *s1106 = [[[Spot alloc] init] autorelease];
    s1106.spotID = @"1106";
    s1106.spotName = @"谷中教員室(1106)";
    
    Spot *s1107 = [[[Spot alloc] init] autorelease];
    s1107.spotID = @"1107";
    s1107.spotName = @"谷中研究室(1107)";
    
    Spot *s1108 = [[[Spot alloc] init] autorelease];
    s1108.spotID = @"1108";
    s1108.spotName = @"佐藤研究室・鈴木(浩)研究室(1108)";
    
    Spot *s1109 = [[[Spot alloc] init] autorelease];
    s1109.spotID = @"1109";
    s1109.spotName = @"佐藤教員室(1109)";

    Spot *s1110 = [[[Spot alloc] init] autorelease];
    s1110.spotID = @"1110";
    s1110.spotName = @"速水教員室(1110)";

    Spot *s1111 = [[[Spot alloc] init] autorelease];
    s1111.spotID = @"1111";
    s1111.spotName = @"速水研究室(1111)";

    Spot *s1112 = [[[Spot alloc] init] autorelease];
    s1112.spotID = @"1112";
    s1112.spotName = @"徳弘研究室(1112)";
    
    Spot *s1113 = [[[Spot alloc] init] autorelease];
    s1113.spotID = @"1113";
    s1113.spotName = @"徳弘教員室(1113)";

    Spot *s1114 = [[[Spot alloc] init] autorelease];
    s1114.spotID = @"1114";
    s1114.spotName = @"服部(元)教員室(1114)";

    Spot *s1115 = [[[Spot alloc] init] autorelease];
    s1115.spotID = @"1115";
    s1115.spotName = @"服部(元)・小坂研究室(1115)";

    Spot *s1116 = [[[Spot alloc] init] autorelease];
    s1116.spotID = @"1116";
    s1116.spotName = @"小島研究室(1116)";

    Spot *s1117 = [[[Spot alloc] init] autorelease];
    s1117.spotID = @"1117";
    s1117.spotName = @"小島教員室(1117)";

    self.spots = [[NSMutableArray alloc] 
                  initWithObjects:s1, s2, 
                  s1101, s1102, s1103, s1104, s1105,
                  s1106, s1107, s1108, s1109, s1110,
                  s1111, s1112, s1113, s1114, s1115,
                  s1116, s1117, nil];
    
    // ジャイロ関係
    motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 1.0f/4.0f; // ジャイロのサンプリング間隔[s]    
    isCaptured = NO;
    referenceAttitude = nil;
    
    self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];
    self.navController = [[UINavigationController alloc] 
                          initWithRootViewController:self.viewController];
    self.window.rootViewController = self.navController;
    
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

- (void)gotoNaviMode
{
    self.viewController.txtMsg.text = [NSString stringWithFormat:@"出発地:%@, 目的地:%@",
                                       startSpot.spotName, destSpot.spotName];
    
    NSLog(@"%@ -> %@", startSpot.spotID, destSpot.spotID);
    
    NSString *url = [NSString 
                     stringWithFormat:@"http://www.tosiyama.jp/personal/cgi/navitest8.cgi?start=%@&target=%@",
                     startSpot.spotID, destSpot.spotID];
    
    URLLoader *loader = [[[URLLoader alloc] init] autorelease];
    
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(loadNaviDataDidEnd:) 
                                                 name:@"connectionDidFinishNotification"
                                               object:loader];
    
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(loadNaviDataFailed:) 
                                                 name:@"connectionDidFailWithError" 
                                               object:loader];
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [loader loadFromUrl:url method:@"GET"];
}

- (void)loadNaviDataDidEnd:(NSNotification *)notification
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    URLLoader *loader = (URLLoader *)[notification object];
    NSData *xmlData = loader.data;
    
    NaviXMLParser *parser = [[[NaviXMLParser alloc] init] autorelease];
    
    NSArray *naviData = [parser parseNaviData:xmlData];
    numPath = [naviData count];
    self.path1 = [naviData objectAtIndex:0];
    self.path2 = nil;
    if (numPath == 2) {
        self.path2 = [naviData objectAtIndex:1];
    }
    self.path = path1;
    
    self.viewController.btnCorner.enabled = YES;
    [self stepNext];
    [self startGyro:NO];
}

- (int)adjustDirection:(int)dir prev:(int)prevDir
{
    int total = ((prevDir-1) + (dir-1)) % 8;
    return (total + 1);
}

- (void)stepNext
{
    if (countPath < [self.path count]) {
        
        int cmd = [[[self.path objectAtIndex:countPath] objectForKey:@"command"] intValue];
        NSString *msg = [[self.path objectAtIndex:countPath] objectForKey:@"msg"];
        
        if (curDirect == 0) {
            curDirect = 1;
            if (self.elevatorSide != -cmd) {
                self.path = self.path2;
            }
            countPath++;
            
            cmd = [[[self.path objectAtIndex:countPath] objectForKey:@"command"] intValue];
            msg = [NSString stringWithFormat:@"エレベータを降りたら、%@",
                   [[self.path objectAtIndex:countPath] objectForKey:@"msg"]];
            [self.viewController.btnCorner setTitle:@"角" forState:UIControlStateNormal];
            self.viewController.btnCorner.enabled = YES;
            [self startGyro:NO];
        }
        
        if (cmd > 10) {
            curDirect = [self adjustDirection:(cmd % 10) prev:curDirect];
            [self.viewController.btnCorner setTitle:@"確認" forState:UIControlStateNormal];
        }
        else if (cmd == 0) {
            [motionManager stopDeviceMotionUpdates];
            curDirect = 0;
            [self.viewController.btnCorner setTitle:@"撮影" forState:UIControlStateNormal];
            [self.viewController enqueueCommand:@"prepareCamera" args:nil];
        }
        else if (cmd > 0) {
            curDirect = [self adjustDirection:cmd prev:curDirect];
        }
        
        if (msg != nil) {
            self.viewController.txtMsg.text = msg;
        }
        countPath++;
        if (countPath == [self.path1 count]) 
        {
            self.viewController.btnCorner.enabled = NO;
        }
    }
}

- (void)startGyro:(BOOL)restart
{
    // デバイスのハードウェアチェック
    if (!motionManager.deviceMotionAvailable)
    {
        NSLog(@"DeviceMotion is not available.");
        return;
    }
    
    isCaptured = restart;
    
    // モーションデータ更新時のハンドラを作成
    void (^handler)(CMDeviceMotion *, NSError *) = ^(CMDeviceMotion *motion, NSError *error)
    {
        if (isCaptured == NO) {
            referenceAttitude = [motion.attitude retain];
            isCaptured = YES;
        }
        else {
            // ジャイロデータの記録
            [self recordGyroData:motion];
        }
    };
    
    // モーションデータの測定を開始
    NSOperationQueue *queue = [NSOperationQueue currentQueue];
    [motionManager startDeviceMotionUpdatesToQueue:queue withHandler:handler];
}

- (BOOL)isCameraMode
{
    if (curDirect == 0) { 
        return YES;
    }
    
    return NO;
}

- (void)recordGyroData:(CMDeviceMotion *)motion
{    
    CMAttitude *currentAttitude = motion.attitude;
    
    if (referenceAttitude != nil) {
        [currentAttitude multiplyByInverseOfAttitude: referenceAttitude];
    }
    
    // 角度を度数に変換
    float rollDegree = 180 * currentAttitude.roll / M_PI;
    NSNumber *direct = [self calcDirection:rollDegree mode:curDirect];
    
    NSString *_roll = [NSString stringWithFormat:@"%.4f", rollDegree];
    NSString *_roll2 = [NSString stringWithFormat:@"%.4f", [direct floatValue]];    
    NSArray *para = [NSArray arrayWithObjects:_roll, _roll2, nil];
    
    [direct release];
    [self.viewController enqueueCommand:@"sendGyro" args:para];
}

- (NSNumber *)calcDirection:(float)roll mode:(int)num
{
    float _direct = 0.0;
    switch (num) {
        case NAVI_DIRECT_FORWARD:
            _direct = roll;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_RIGHT:
            _direct = roll + 90.0;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_LEFT:
            _direct = roll - 90.0;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_BACKWARD:
            _direct = roll - 180;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_RIGHT_FORWARD:
            _direct = roll + 45.0;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_LEFT_FORWARD:
            _direct = roll - 45.0;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_RIGHT_BACKWARD:
            _direct = roll + 135.0;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
        case NAVI_DIRECT_LEFT_BACKWARD:
            _direct = roll - 135.0;
            if (_direct <= 0) {
                _direct = -_direct;
            }
            else {
                _direct = 360.0 - _direct;
            }
            break;
            
    }
    
    NSNumber *direct = [[NSNumber alloc] initWithFloat:_direct];
    return direct;
}

- (void)loadNaviDataFailed:(NSNotification *)notification
{
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"エラー" 
                          message:@"xmlデータの取得に失敗しました!" 
                          delegate:self 
                          cancelButtonTitle:@"閉じる" 
                          otherButtonTitles:nil];
    [alert show];
    [alert release];
}

@end