HSP3Dish.jsでGPS座標を取得

目次

Geolocation APIとは?

 Geolocation APIは、ユーザーの現在地(緯度・経度)を取得するためのAPIです。ウェブブラウザで使用することができ、GPSやWi-Fi、IPアドレスなどの情報を利用して位置を推定します。

 このAPIを使用することで、地図アプリや位置情報を活用したアプリを作成できます。例えば、現在地の地図を表示したり、現在位置を利用したゲームを作るなどです。

 HSP3Dish.jsでは、execを利用することでGeolocation APIを使用することができます。本サイトでは、その具体的な方法についてちょっぴり解説してみます。

今回のテスト環境:HSP3.7β10

Geolocation APIの基本的な使い方

 navigator.geolocation.watchPosition(コールバック関数, エラー時の関数, オプション) を実行すると、位置情報が更新されるたびに最新の情報を取得するようになります。 取得した値は、第1引数として指定したコールバック関数に渡されます。 情報が更新されると勝手にコールバックしてくれるので、イベントリスナーを設定する必要がありません。

 コールバック関数には、取得した位置情報がJSON形式で渡されます。

変数内容単位
latitude 緯度deg
longitude 経度deg
accuracy 位置精度m
altitude 高度m
altitudeAccuracy 高度の精度m
heading 進行方向deg
speed 速度m/s
timestamp 取得時刻

 端末によっては対応していない値もあります。取得できない場合はnullが返されるようになっています。

 オプションで指定できる項目は以下の通りです。

enableHighAccuracy
高精度モードを有効化(true/false)
有効にするとバッテリー消費が増える場合があります。
maximumAge
位置情報の有効期限(ミリ秒)
設定値内容
0
(キャッシュを使わない)
常に最新情報を取得。(例: ランニングアプリ、ナビゲーション)
屋外(GPSが有効): 取得に 数秒(1~5秒程度) かかることが多い
屋内(GPSが弱い場合): 取得に 10秒以上かかる場合もある
Infinity
(無制限にキャッシュを使う)
キャッシュを利用し、即時表示を優先。位置情報が更新されない限り古い情報(キャッシュ)が表示され続ける。
(例: 高速なレスポンスが必要なアプリ)
任意のミリ秒数
(指定した時間以内ならキャッシュを使用)
300000(5分)などを設定して、バッテリー消費を抑える。
(例: 天気アプリ、チェックイン機能)
timeout
タイムアウト時間(ミリ秒)
タイムアウトが発生すると、error.codeerror.TIMEOUTとなり、 エラーコールバック内の処理が実行されます。

エラー処理

 エラーが発生すると、navigator.geolocation.watchPositionに指定したエラー時の関数がコールバックされます。 渡された引数の内容を確認する事でエラーの内容を判定できます。

error.PERMISSION_DENIED1ユーザーが位置情報の取得を拒否しました。
error.POSITION_UNAVAILABLE2位置情報が利用できません。
error.TIMEOUT3位置情報の取得がタイムアウトしました。
error.UNKNOWN_ERRORundefined不明なエラーが発生しました。

位置情報を取得するサンプル

 サンプルを動かしながらが理解しやすいと思うので、まずはサンプルです。
サンプル:gps01.html

 デベロッパー ツールのコンソールドロワーからセンサーを開き、場所を変更するとPCでも簡単に位置情報の動作確認ができます。サンプルのズームレベルでは海外の地図タイルがないので、Tokyoを選択しておいてください。

サンプルのJavaScript部分

 以下のスクリプトは、サンプルで使用しているJavaScriptのスクリプトです。

JavaScript

{

let watchId = null;
let position_coords = {
    latitude:  null,
    longitude: null,
    accuracy:  null,
    altitude:  null,
    altitudeAccuracy: null,
    heading:   null,
    speed:     null,
    timestamp: ""
};
let errorGeolocation = { code: 0, message: "" };

// geolocation取得開始
// highAccuracy  高精度モードを有効化 (true/false)
// maximumAge    位置情報の有効期限 [msec]
// timeout       タイムアウト [msec]
function startTracking(highAccuracy = false, maximumAge = 0, timeout = Infinity){
    if (navigator.geolocation) {
        const options = {
            enableHighAccuracy: highAccuracy,
            maximumAge: maximumAge,
            timeout: timeout
        };
        
        let position;
        watchId = navigator.geolocation.watchPosition(showPosition, showError, options);

    } else {
        errorGeolocation.code = 4;
        errorGeolocation.message = "このブラウザは位置情報取得をサポートしていません。";
    }
}

function showPosition(position) {
    errorGeolocation = { code: 0, message: "" };
    position_coords = {
        latitude:  position.coords.latitude,  // 緯度 [deg]
        longitude: position.coords.longitude, // 経度 [deg]
        accuracy:  position.coords.accuracy,  // 位置精度 [m]
        altitude:  position.coords.altitude,  // 高度 [m]
        altitudeAccuracy: position.coords.altitudeAccuracy, // 高度の精度 [m]
        heading:   position.coords.heading,   // 進行方向 [deg]
        speed:     position.coords.speed,     // 速度 [m/s]
        timestamp: new Date(position.timestamp).toLocaleTimeString() // 取得時刻
    };
}

// geolocation取得停止
function stopTracking(){
    if (watchId !== null) {
        navigator.geolocation.clearWatch(watchId);
        watchId = null;
        errorGeolocation.code = 5;
        errorGeolocation.message = "位置情報の監視を停止しました。";
    }
}

// 取得した値をまとめてHSP3に渡す
function updateGeolocation(
        ptrLatitude, 
        ptrLongitude, 
        ptrAccuracy, 
        ptrAltitude, 
        ptrAltitudeAccuracy, 
        ptrHeading, 
        ptrSpeed,
        ptrTimestamp,
        ptrErrorCode,
        ptrErrorMessage ) {
    if (watchId === null) { return };
    passStringToHsp3( ptrLatitude         , position_coords.latitude        , 7);
    passStringToHsp3( ptrLongitude        , position_coords.longitude       , 7);
    passStringToHsp3( ptrAccuracy         , position_coords.accuracy        , 2);
    passStringToHsp3( ptrAltitude         , position_coords.altitude        , 3);
    passStringToHsp3( ptrAltitudeAccuracy , position_coords.altitudeAccuracy, 3);
    passStringToHsp3( ptrHeading          , position_coords.heading         , 3);
    passStringToHsp3( ptrSpeed            , position_coords.speed           , 3);
    passStringToHsp3( ptrTimestamp        , position_coords.timestamp);

    passStringToHsp3( ptrErrorCode   , errorGeolocation.code);
    passStringToHsp3( ptrErrorMessage, errorGeolocation.message);
}

// HSP3に値を渡す
// fix : 0以上の整数
function passStringToHsp3(ptr, value=null, fix=0){
    if(!ptr){ return; };
    
    if(typeof value === 'string'){
        stringToUTF8Array(value, Module.HEAP8, ptr, 64);
    } else if (typeof value === 'number'){
        if(fix < 0){fix = 0;}
        stringToUTF8Array(value.toFixed(fix), Module.HEAP8, ptr, 64);
    } else if (typeof value === 'boolean'){
        let v = "0";
        if(value){ v = "1";};
        stringToUTF8Array(v, Module.HEAP8, ptr, 64);
    } else {
        stringToUTF8Array("", Module.HEAP8, ptr, 64);
    }
}


// エラー処理
function showError(error) {
    let message = '';
    switch (error.code) {
        case error.PERMISSION_DENIED: // 1
            message = "ユーザーが位置情報の取得を拒否しました。";
            break;
        case error.POSITION_UNAVAILABLE: // 2
            message = "位置情報が利用できません。";
            break;
        case error.TIMEOUT: // 3
            message = "位置情報の取得がタイムアウトしました。";
            break;
        case error.UNKNOWN_ERROR: // undefined
            message = "不明なエラーが発生しました。";
            break;
    }
    errorGeolocation.code = error.code;
    errorGeolocation.message = message;
}

}

位置情報の取得開始 (startTracking)

 startTracking 関数を呼び出すことで、位置情報の取得が開始されます。 この関数では、オプション(高精度モード・位置情報の有効期限・タイムアウト時間)を指定し、navigator.geolocation.watchPosition を使って位置情報を監視します。 位置情報の取得は、バッテリー消費が増えることがあるためON/OFF機能を付けています。

位置情報の更新 (showPosition)

 位置情報が取得されるたびに showPosition が呼び出され、取得した緯度・経度などのデータが更新されます。

位置情報の取得停止 (stopTracking)

 stopTracking 関数を呼び出すことで、位置情報の監視を停止できます。これにより、watchPosition の監視が解除され、不要な処理を防ぎバッテリー消費を抑えることができます。 また、位置情報取得のオプションを変更するには、navigator.geolocationを一度停止する必要があります。

位置情報のHSP3への受け渡し (updateGeolocation)

 取得した位置情報は、updateGeolocation を通じてHSP3に渡されます。この関数では、位置情報など各データをHSP3のメモリに格納します。

エラー処理 (showError)

 位置情報の取得中にエラーが発生した場合、showError が呼び出され、エラーメッセージが記録されます。

HSP3のメモリにデータを渡す(passStringToHsp3)

 HSP3に渡す値を文字列に成型する下処理を実施してから、stringToUTF8Arrayで値を渡します。

サンプルのHSP3部分

 以下のスクリプトは、サンプルで使用しているHSP3のスクリプトです。

HSP3

; スマホ向けHSP3Dishのサンプル
#include "hsp3dish.as"

;-------------------------------------------------------------------------------

; プラットフォームを確認
getreq idPlatform, SYSREQ_PLATFORM

sdim strLatitude , 64
sdim strLongitude, 64
sdim strAccuracy , 64
sdim strAltitude , 64
sdim strAltitudeA, 64
sdim strHeading  , 64
sdim strSpeed    , 64
sdim strTimestamp, 64
sdim strErrorCode, 64
sdim strErrorMessage, 64

exec_text = ""
watchId = 0


button gosub "スタート", *l_gpsStart
button gosub "停止", *l_gpsStop

;-------------------------------------------------------------------------------
*main
	redraw 1
	if idPlatform = PLATFORM_WEBGL {
		exec exec_text	; hsp3dish.js(WebGL/JavaScript)版
	} else {
		await 16	; Windows版など他環境
	}
	exec_text = ""
	redraw 0 : color 255, 255, 255 : boxf : color 10,10,10 : pos 0,0

	; GPS座標の監視状態をON/OFF
	if watchId = 1 {
		exec_text += "startTracking(true, 0, 5000);"
		watchId = 2	; 監視中
	}
	if watchId = 3 {
		exec_text += "stopTracking();"
		watchId = 0	; 停止中
	}

	; 座標を取得
	gosub *l_getGeo

	pos 10, 80
	mes strf("(err: %d)\n%s", errorCode, strErrorMessage)
	mes strf("   緯度 %f [deg]", latitude )
	mes strf("   経度 %f [deg]", longitude)
	mes strf(" 位置精度 ±%f [m]", accuracy )
	mes strf("   高度 %f [m]",   altitude )
	mes strf("高度の精度 ±%f [m]", altitudeA)
	mes strf(" 進行方向 %f [deg]", heading  )
	mes strf("   速度 %f [m/s]", speed    )
	mes strf("取得時刻 %s", strTimestamp )

	goto *main

;-------------------------------------------------------------------------------

*l_getGeo
	ptrLatitude  = varptr( strLatitude  )
	ptrLongitude = varptr( strLongitude )
	ptrAccuracy  = varptr( strAccuracy  )
	ptrAltitude  = varptr( strAltitude  )
	ptrAltitudeA = varptr( strAltitudeA )
	ptrHeading   = varptr( strHeading   )
	ptrSpeed     = varptr( strSpeed     )
	ptrTimestamp = varptr( strTimestamp )
	ptrErrorCode = varptr( strErrorCode )
	ptrErrorMessage = varptr( strErrorMessage )
	exec_text += "updateGeolocation(" + ptrLatitude  + "," + ptrLongitude + "," + ptrAccuracy  + "," + ptrAltitude  + "," + ptrAltitudeA + "," + ptrHeading   + "," + ptrSpeed + "," + ptrTimestamp + "," + ptrErrorCode + "," + ptrErrorMessage + ");"

	; 文字列→数値
	latitude  = double( strLatitude  )
	longitude = double( strLongitude )
	accuracy  = double( strAccuracy  )
	altitude  = double( strAltitude  )
	altitudeA = double( strAltitudeA )
	heading   = double( strHeading   )
	speed     = double( strSpeed     )
	errorCode = int( strErrorCode )
	return


*l_gpsStart
	watchId = 1	; 開始する
	return

*l_gpsStop
	watchId = 3	; 停止する
	return

 navigator.geolocationでの位置情報取得開始(スタート)と位置情報の取得停止ボタン(停止)をつけています。 スタートボタンを押すと位置の取得を開始します。

 *l_getGeo サブルーチンで、現在の位置情報を受け取る処理を行っています。

 *l_gpsStart*l_gpsStopは、ボタンのジャンプ先です。 ボタンがジャンプをするタイミングは、awaitexecの直後なので、ボタンのジャンプ先でexec_textにコマンドを追記してもexecで実行する前に消えてしまいます。 そこで、watchIdを使って他の場所でコマンドを追記しています。

 JavaScript側で実装してしまったので、ほとんどやることがありません。 位置情報の監視条件を変更する場合は、stopTrackingで停止してから、startTrackingのオプションを変更したものを実行します。

取得値の意味

 取得した値の意味は理解していないと適切な利用ができません。とりあえず必要そうな情報を少し書いておきます。詳しくは調べてください。

緯度、経度(latitude、longitude)と精度(accuracy)
 緯度、経度(latitude、longitude)の単位は度(degree)で、精度(accuracy)の方はメートル(m)です。 測定精度はスマホでは±5~10mが一般的。高性能スマホの場合でも3m程度のようです。 精度の意味についての資料が見つからなかったので、「この数値の範囲内に実際の位置があると考えられるが保証はできない」程度の理解をしておいたほうがいいようです。
 小数点以下のケタ数と誤差の関係は、おおよそ以下のようにな感じです。
小数点以下4桁で誤差10m
小数点以下5桁で誤差1m
小数点以下6桁で誤差10cm
小数点以下7桁で誤差1cm
測位できる位置精度を考慮すると、小数点以下6桁まで使えば十分だとわかります。
高度(Altitude)と精度(altitudeAccuracy)
 単位はメートル。
 精度に関する信頼できる情報は得られませんでした。緯度経度よりも誤差が大きく、±数m~数十mの誤差があると思っていいと思います。 この値は楕円体高であり、ジオイド高を除いた標高ではない点に注意が必要です。
進行方向(Heading)
 移動方向(北が0度、東が90度、南が180度、西が270度)を示す値で、単位は度(degree)です。
 静止中は磁気センサーに依存するため、磁気干渉の影響を受けやすく精度が低下します。 移動中はGPSベースのため精度はよくなりますが、移動速度が遅いと精度も悪くなります。
速度(Speed)
 移動速度を示す値で単位は m/s です。
 自動車の速度は高精度となりますが、歩行や自転車では精度が低くなります。 測定した緯度と経度から算出するので、測定誤差の影響を受けます。
取得時刻
位置が取得された日時。

地図アプリ

 ここまでくると地図アプリとか作ってみたいですね。地図アプリには地図の画像データが必要です。 地図の画像データを提供している所としてはGoogleMapがメジャーですが、APIキーの取得が必要な点が面倒です。 ちょっと試しに作ってみた個人開発アプリでそこまでやるのはハードル高すぎです。

 他にも地図画像を提供しているサイトがあり、OpenStreetMapが有名なようです。 国内最大手は国土地理院で、こちらは通常の道路地図の外に航空写真(年代別)や標高地形図、宅地利用動向調査成果など様々な種類の情報が取得できます。 本当に無料で使っていいのか不安になるレベルの精度と物量にあふれています。せっかくタダなので存分に利用しましょう。(※利用規約には従いましょう。)

 ちょうどこちらのモジュールで、緯度経度から地図データ(地図タイルといいます)を取得するための関数とサンプルを作ったのでこれを利用してみます。

Home > アプリ > mod経緯度

地図アプリのサンプル

サンプル:gps02.html

 実行すると取得した緯度経度の情報を使って、地図の上に現在位置をピンで表示します。 地図タイルは地理院タイル(https://maps.gsi.go.jp/development/ichiran.html)を利用しています。

 地図タイルの読み込みと取り扱いをうまく処理できれば、地図アプリができてしまいそうですね。

HSP3

; 地図アプリのサンプル
;
; 現在の緯度経度情報から地図を表示し、現在位置をピンで表示します。
; 画像の出典:https://maps.gsi.go.jp/development/ichiran.html
#include "hsp3dish.as"
#include "modKeiido.hsp"

;------------------------------
;	初期値
;------------------------------
;	地図表示位置
pxMapPosX = 10
pxMapPosY = 60

; ズームレベル
; 0で世界地図、数値が大きいほど詳細な地図
; タイルサーバーによって提供されるズームレベルの範囲は異なります。
zoom_level = 15	; 0~

; タイル座標の初期値
tx = 0.0
ty = 0.0

; celloadのウィンドウID
widImg = 1

; 読み込み結果メッセージ
; 主にエラーメッセージ用
message = ""

; 地図タイルの読み込み状態
; 0 初期状態
; 1 ロード中
; 2 ロードが正常終了した
; 3 ロードが異常終了した
stateLoad = 0

; 位置情報取得変数(文字列)
sdim strLatitude , 64
sdim strLongitude, 64
sdim strAccuracy , 64
sdim strAltitude , 64
sdim strAltitudeA, 64
sdim strHeading  , 64
sdim strSpeed    , 64
sdim strTimestamp, 64
sdim strErrorCode, 64
sdim strErrorMessage, 64

; 地図タイルのタイルサーバー
base_url = "https://cyberjapandata.gsi.go.jp/xyz/std"	; 地理院タイル
url = ""

; GPS測位の状態
; 0 測位停止中
; 1 測位開始
; 2 測位監視中
watchId = 1

; プラットフォームを確認
getreq idPlatform, SYSREQ_PLATFORM

; JavaScriptコマンド
exec_text = ""

;===============================================================================
;
;	メインループ
;
;===============================================================================
*main
	redraw 1
	if idPlatform = PLATFORM_WEBGL {
		exec exec_text	; hsp3dish.js(WebGL/JavaScript)版
	} else {
		await 16	; Windows版など他環境
	}
	exec_text = ""
	redraw 0 : color 255, 255, 255 : boxf : color 10,10,10 : pos 0,0

	;------------------------------
	;	GPS座標の監視状態をON/OFF
	;------------------------------
	if watchId = 1 {
		exec_text += "startTracking(true, 0, 5000);"
		watchId = 2	; 監視中
	}
	if watchId = 3 {
		exec_text += "stopTracking();"
		watchId = 0	; 停止中
	}

	; 座標を取得
	if watchId = 2 {
		gosub *l_getGeo
		gosub *l_get_map
	}

	;	結果待ちのためのループ
	if stateLoad = 1 {
		httpinfo res, HTTPINFO_MODE
		if res = HTTPMODE_NONE     : logmes "通信初期化エラー "   + HTTPMODE_NONE    
		if res = HTTPMODE_READY    : logmes "通信可能状態 "       + HTTPMODE_READY   
		if res = HTTPMODE_REQUEST  : logmes "リクエスト通信準備 " + HTTPMODE_REQUEST 
		if res = HTTPMODE_SEND     : logmes "リクエスト送信 "     + HTTPMODE_SEND    
		if res = HTTPMODE_DATAWAIT : logmes "通信結果待機中 "     + HTTPMODE_DATAWAIT
		if res = HTTPMODE_DATAEND  : logmes "通信終了 "           + HTTPMODE_DATAEND 
		if res = HTTPMODE_ERROR    : logmes "エラー発生 "         + HTTPMODE_ERROR   
		if res = HTTPMODE_READY : gosub *comp
		if res <= HTTPMODE_NONE : gosub *bad
	}

	;	ロードが正常終了した
	if stateLoad = 2 {
		;	読み込み完了後
		; 地図を表示
		pos pxMapPosX, pxMapPosY
		celput widImg, 0
		
		; 地図画像内の座標
		x = int( (tx - int(tx)) * 256.0 + pxMapPosX )
		y = int( (ty - int(ty)) * 256.0 + pxMapPosY )
		
		; マーカーを表示
		color 234, 67, 53
		r = 13 : z = 24
		gx = x, x-r, x+r, x
		gy = y, y-z, y-z, y
		gsquare -1, gx, gy
		circle x-r, y-r-z, x+r, y+r-z, 1
		r = 5
		color 179, 20, 18
		circle x-r, y-r-z, x+r, y+r-z, 1
	}

	pos 10, 10
	color
	mes message

	; タイル座標から緯度経度を逆算
	pos pxMapPosX, pxMapPosY+256
	webmercator2lla tx, ty, zoom_level, lat, lon
	mes "緯度:" + lat + "度"
	mes "経度:" + lon + "度"


	goto *main

;===============================================================================
;
;	サブルーチン
;
;===============================================================================

;------------------------------
;	位置情報の取得
;------------------------------
*l_getGeo
	ptrLatitude  = varptr( strLatitude  )
	ptrLongitude = varptr( strLongitude )
	ptrAccuracy  = varptr( strAccuracy  )
	ptrAltitude  = varptr( strAltitude  )
	ptrAltitudeA = varptr( strAltitudeA )
	ptrHeading   = varptr( strHeading   )
	ptrSpeed     = varptr( strSpeed     )
	ptrTimestamp = varptr( strTimestamp )
	ptrErrorCode = varptr( strErrorCode )
	ptrErrorMessage = varptr( strErrorMessage )
	exec_text += "updateGeolocation(" + ptrLatitude  + "," + ptrLongitude + "," + ptrAccuracy  + "," + ptrAltitude  + "," + ptrAltitudeA + "," + ptrHeading   + "," + ptrSpeed + "," + ptrTimestamp + "," + ptrErrorCode + "," + ptrErrorMessage + ");"

	; 文字列→数値
	latitude  = double( strLatitude  )	; 緯度 [deg]
	longitude = double( strLongitude )	; 経度 [deg]
	accuracy  = double( strAccuracy  )	; 位置精度 [m]
	altitude  = double( strAltitude  )	; 高度 [m]
	altitudeA = double( strAltitudeA )	; 高度の精度 [m]
	heading   = double( strHeading   )	; 進行方向 [deg]
	speed     = double( strSpeed     )	; 速度 [m/s]
	errorCode = int( strErrorCode )	; エラーコード
	; strTimestamp    位置情報の取得時刻
	; strErrorMessage エラーメッセージ

	return
	
;------------------------------
;	地図タイルを読み込み
;------------------------------
*l_get_map
	;------------------------------
	;	タイル座標を算出
	;------------------------------
	; 指定された緯度経度からタイル座標を算出します。
	; 整数部分がタイル座標、小数部分がタイル地図の画像内の位置です。
	; 左上が原点となっています。
	zoom_level0 = zoom_level : tx0 = tx : ty0 = ty
	lla2webmercator latitude, longitude, zoom_level, tx, ty
	if absf(latitude) < gd_func(M_PI) : return

	; latitude, longitude または tx, tyが地球を1周以上している場合
	tmax = powf(2, zoom_level)
	if tx >= 0 {
		tx = tx \ (tmax + 1)
	} else {
		tx = tmax + ((tx + 1) \ (tmax + 1))
	}
	if tx >= 0 {
		ty = ty \ (tmax + 1)
	} else {
		ty = tmax + ((ty + 1) \ (tmax + 1))
	}

	;------------------------------
	;	新しい地図タイルのダウンロード
	;------------------------------
	if stateLoad = 1 : return
	url0 = url
	url = strf("%s/%d/%d/%d.png", base_url, zoom_level, tx, ty)
	if url = url0 : return
	stateLoad = 1
	httpload url
	if stat : gosub *bad	; 正しくリクエストができなかった
	return
	
;------------------------------
;	エラー処理
;------------------------------
; エラーメッセージと意味
; 「Error:無効なサーバーが指定されました」
;	https:以外が指定された。
;
; 「Error:リクエストができませんでした」
;	存在しないサーバーが指定された。
; 
*bad
	stateLoad = 3
	httpinfo estr, HTTPINFO_ERROR
	message = "Error: 正しくリクエストができませんでした。\n" + estr + "\n" + url
	message += "\nエラーから復旧できません。\nアプリを再読み込みしてください。"
	exec_text += "console.log('" + url + "');"
	return

;------------------------------
;	ダウンロード完了
;------------------------------
*comp
	stateLoad = 3
	httpinfo buf,  HTTPINFO_DATA	; PGN画像
	httpinfo size, HTTPINFO_SIZE

	if size <= 0 {
		message = "Error:地図データがありません。"
		return
	}
	if (peek(buf, 0) ! 0x89) & (peek(buf, 1) ! 0x50) & (peek(buf, 2) ! 0x4E) {	; PNG
		message = "Error:画像がありません。"
		return
	}
	stateLoad = 2

	; メモリストリームで読み込む
	memfile buf, 0, size
	celload "MEM:.png", widImg

	; 読み込みに成功したら、画像のファイルサイズを表示
	message = "読み込み完了(" + size + " byte)"
	
	return

 地図の画像(地図タイル)は、外部サイトから取得するので、httpload命令、httpinfo命令の使い方がポイントになります。 画像がない地域を参照するとエラーになります。一度エラーになると復帰できないので再読み込みが必要です。 httpload命令、httpinfo命令は使用例が少ないので、回避方法がわかりませんでした。

最後に

 HSP3Dish.jsで現在位置の取得と地図への表示をやってみました。 JavaScript側での実装とHSP3側のモジュール化をすることで、ほとんどやることはなく実装作業としては簡単です。

 しかし、数値の意味をちゃんと理解して使おうとするとちょっと大変そうですね。 とりあえず作ってみて、使いながら数値の意味を体感するという方法での開発でもいいと思います。 それでも行き詰ったら、ググれば大抵のことは国土地理院が丁寧に解説してくれています。

関連記事

  1. HSP3Dish.jsでJavaScript 対象環境 execでJavaScriptを実行する HSP3Dish.jsにおけるスクリプトの最小構...
  2. HSP3Dish.jsでセンサー値を取得 今回やること センサ値の取得(JavaScript) stringToUTF8Array関数を使った...