HSPでleafletを使って地図を作る(サンプル)
1.概要
地図については、Leafletで地図を作ろう - (気象庁震度観測点マップ)でJavaScriptで作成したものを
紹介していますが、今回は、このLeaflet地図をHSP言語に一部移植して見ました。JavaScript版では、外部ファイル化した定義コードやライブラリもあり、それらをHSPコード内に記述するのも
めんどうだったので、サンプルということで簡易版として再現して見ました。
2.ソースコード ソースコードは下記の通りです。HSPからHTMLコードなどを記述して生成後、起動させる方法として 良く利用される手法を使っています。具体的なコードとしては、193~197行目となります。
マーカーやポップアップの定義部分をデータベースのテーブルとして持ち、読み出して他のコードと同様に バッファに格納して一時ファイルとして保存後、ie->"Navigate"で起動させています。 該当部分は、115行~136行目の部分です。他の部分としては、ウィンドウ制御として起動時の最大化処理と リサイズ処理をWindows APIを利用して処理しています。 地図としてメインとなるHTML(Javascript)は、Leafletで地図を作ろう - (気象庁震度観測点マップ)を 参照願います。
3.ダウンロード 提供するソースコードのライセンスは、CC0 (クレジット表示不要、改変可、商用可) とします。自由に利用して頂いてかまいません。 尚、データの取得やプログラム実行において損害等が生じた場合は、筆者は一切の責任も負いません。全て自己責任でお願いします。
実行形式(exe)ファイルとソースコード一式のアーカイブは下記よりダウンロードして下さい。
ダウンロード
■関連記事
・Leafletで地図を作ろう - (気象庁震度観測点マップ)
2.ソースコード ソースコードは下記の通りです。HSPからHTMLコードなどを記述して生成後、起動させる方法として 良く利用される手法を使っています。具体的なコードとしては、193~197行目となります。
マーカーやポップアップの定義部分をデータベースのテーブルとして持ち、読み出して他のコードと同様に バッファに格納して一時ファイルとして保存後、ie->"Navigate"で起動させています。 該当部分は、115行~136行目の部分です。他の部分としては、ウィンドウ制御として起動時の最大化処理と リサイズ処理をWindows APIを利用して処理しています。 地図としてメインとなるHTML(Javascript)は、Leafletで地図を作ろう - (気象庁震度観測点マップ)を 参照願います。
;****************************************************************************************
;*
;* 気象庁震度観測点マップ (eqmpoint) Ver1.0
;*
;* <処理の概要>
;* 本プログラムは、象庁震度観測点一覧表の住所から緯度・経度を調査して
;* 整理したものから、leafletを利用してマッピングしたものである。
;*
;*
;* 出典: 気象庁震度観測点一覧表
;* URL https://www.data.jma.go.jp/svd/eqev/data/kyoshin/jma-shindo.html
;* 地図 : leaflet (オープンソースJavascript ライブラリ)
;* 地図タイル : 国土地理院タイル、オープンストリートマップ
;* URL https://maps.gsi.go.jp/development/ichiran.html
;*
;*
;****************************************************************************************
#include "sqlele.hsp"
#packopt type 0
#packopt name "eqmpoint"
#packopt runtime "hsprt"
#packopt manifest "app.manifest"
#packopt icon "SetDisp.Ico"
#packopt hide 1
#uselib "user32.dll"
#func SetWindowLong "SetWindowLongA" int,int,int
#func GetWindowLong "GetWindowLongA" int,int
#func InvalidateRect "InvalidateRect" int,int,int
#func MoveWindow "MoveWindow" sptr,sptr,sptr,sptr,sptr,sptr
#func DestroyWindow "DestroyWindow" int
#func GetWindowRect "GetWindowRect" int,var
#define DIID_DWebBrowserEvents2 "{34A715A0-6587-11D0-924A-0020AFC7AC4D}"
#define DISPID_NAVIGATECOMPLETE2 252
#define TEMP_FILE dir_cur+"/exec.tmp"
#define WS_MAXIMIZEBOX 0x00010000
#define WS_SIZEBOX 0x00040000
#define WM_SYSCOMMAND $00000112
#define WM_COMMAND $00000111
#define WM_SIZE $00000005
#define SC_MAXIMIZE $0000F030
#module
#uselib "kernel32.dll"
#cfunc CreateMutex "CreateMutexA" int,int,sptr
#cfunc GetLastError "GetLastError"
;***** 二重起動防止 *****
#deffunc wexapend str prm1
strname=prm1
;***** 名前の文字列が省略された場合 *****
if strlen(strname)==0 : strname="HSP340ONIWND" ;Default String
ret=CreateMutex(0,1,strname)
;二重起動か?
if GetLastError()==0 : return 0 ;同じジョブが起動していない
if GetLastError()==183 : return 1 ;既に起動している
return -1
#global
;***** 起動ディレクトリ取得 *****
sdim Startdir,512
if hspstat&1=0 { Startdir=dir_exe+"¥¥" : chdir dir_exe
} else {
Startdir=dir_cur+"¥¥"
}
chdir Startdir
;***** データベース存在確認 *****
exist Startdir+"setting¥¥eqmpoint.ini"
if strsize ==-1 {
dialog "データベースファイルが見つかりません。",0 : end
}
await
wexapend "eqmpoint" : if stat : end
;***** データベースオープン *****
sql_open Startdir+"setting¥¥eqmpoint.ini"
onexit goto *owari
screen 0,ginfo_dispx,ginfo_dispy,2,(ginfo_dispx-728)/2,(ginfo_dispy-600)/2,728,600
GetWindowLong hwnd, -16
SetWindowLong hwnd, -16, stat | WS_MAXIMIZEBOX | WS_SIZEBOX
color 240,240,240 : boxf
pos 0, 0 : axobj ie, "Shell.Explorer.2", ginfo_dispx+16, ginfo_dispy-26 : objIE=stat
hwndIE=objinfo(objIE, 2)
if objIE == -1 {
dialog "ActiveXコントロールの配置に失敗しました。", 1
end
}
;***** HTMLタグ生成 *****
sdim buff,10000 : sdim UPD_INFO,128,7
buff = "<!DOCTYPE html>¥n"
buff+= "<html>¥n"
buff+= "<head>¥n"
buff+= " <meta charset=¥"shift-jis¥">¥n"
buff+= " <title>気象庁震度観測点マップ</title>¥n"
buff+= " <link rel=¥"stylesheet¥" href=¥"https://unpkg.com/leaflet@1.3.0/dist/leaflet.css¥" />¥n"
buff+= " <script src=¥"https://unpkg.com/leaflet@1.3.0/dist/leaflet.js¥"></script>¥n"
buff+= " <style>¥n"
buff+= " a { font-size: 12px;text-decoration:none;color:#0000aa;font-family:Meiryo; }¥n"
buff+= " a:link { font-size: 12px;text-decoration:none;color:#0000aa;font-family:Meiryo; }¥n"
buff+= " a:hover { font-size: 12px;text-decoration:none;color:#aa0000;font-family:Meiryo; }¥n"
buff+= " body { ont-size: 12px;font-family:Meiryo; }¥n"
buff+= " </style>¥n"
buff+= " <script>¥n"
buff+= " //***** マーカーに表示したい対象の緯度経度とポップアップする名称を設定 *****¥n"
buff+= " var gmapstr = ¥"https://maps.google.co.jp/maps?q=¥";¥n"
buff+= " var markerList = [
sql_q "SELECT * FROM eqmaptbl"
count = stat
repeat count,1
UPD_INFO(1) = sql_v("Tcode")
UPD_INFO(2) = sql_v("Tfuken")
UPD_INFO(3) = sql_v("ChikiName")
UPD_INFO(4) = sql_v("MoniPoint")
UPD_INFO(5) = sql_v("MoniAdd")
UPD_INFO(6) = sql_v("Ido")
UPD_INFO(7) = sql_v("Keido")
buff+= " { pos: ["+UPD_INFO(6)+","+UPD_INFO(7)+"], name: ¥""+UPD_INFO(4)+"<br><a href=¥'¥"+gmapstr+"
buff+= "¥""+UPD_INFO(6)+","+UPD_INFO(7)+"¥' target=¥'_blank¥'>"+UPD_INFO(5)+"</a>¥" },¥n"
sql_next
loop
sql_close
buff+= " ];¥n"
buff+= " function init(){¥n"
buff+= " var map = L.map(¥'mapcontainer¥');¥n"
buff+= " //***** 座標の指定 *****¥n"
buff+= " var mpoint = [38.757436, 140.312227];¥n"
buff+= " map.setView(mpoint, 6);¥n"
buff+= " //***** 3つの地図タイルを切り替える *****¥n"
buff+= " var gsi =L.tileLayer(¥'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png¥',¥n"
buff+= " {attribution: ¥"<a href=¥'https://maps.gsi.go.jp/development/ichiran.html¥' target=¥'_blank¥'>地理院タイル</a>¥"});¥n"
buff+= " var gsipale = L.tileLayer(¥'http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png¥',¥n"
buff+= " {attribution: ¥"<a href=¥'http://portal.cyberjapan.jp/help/termsofuse.html¥' target=¥'_blank¥'>地理院タイル</a>¥"});¥n"
buff+= " var osm = L.tileLayer(¥'http://tile.openstreetmap.jp/{z}/{x}/{y}.png¥',¥n"
buff+= " { attribution: ¥"<a href=¥'http://osm.org/copyright¥' target=¥'_blank¥'>OpenStreetMap</a> contributors¥" });¥n"
buff+= " //baseMapsオブジェクトのプロパティに3つのタイルを設定¥n"
buff+= " var baseMaps = {¥n"
buff+= " ¥"地理院地図¥" : gsi,¥n"
buff+= " ¥"淡色地図¥" : gsipale,¥n"
buff+= " ¥"オープンストリートマップ¥" : osm¥n"
buff+= " };¥n"
buff+= " L.control.layers(baseMaps).addTo(map);¥n"
buff+= " gsi.addTo(map);¥n"
buff+= " //***** 画像マーカを設定 *****¥n"
buff+= " var markerIcon = L.icon({¥n"
buff+= " iconUrl: './image/ball.png',¥n"
buff+= " iconRetinaUrl: './image/ball.png',¥n"
buff+= " iconSize: [18,18],¥n"
buff+= " iconAnchor: [8,8],
buff+= " popupAnchor: [0,-16]¥n"
buff+= " });¥n"
buff+= " //***** マーカー全体が入るボックスを作る *****¥n"
buff+= " var bound = L.latLngBounds(markerList[0].pos, markerList[0].pos);¥n"
buff+= " //***** markerListの設定でマーカーを追加 *****¥n"
buff+= " for (var num in markerList) {¥n"
buff+= " var mk = markerList[num];¥n"
buff+= " var popup = L.popup().setContent(mk.name);¥n"
;***** マーカ画像がない場合は、標準マーカを使用 *****
exist Startdir+"image¥¥ball.png"
if strsize ==-1 {
buff+= " //●標準マーカ (使用しない)¥n"
buff+= " L.marker(mk.pos).bindPopup(popup).addTo(map);¥n"
}else{
buff+= " //●画像マーカ¥n"
buff+= " L.marker(mk.pos,{ icon:markerIcon }).bindPopup(popup).addTo(map);¥n"
}
buff+= " //***** マーカー全体が入るボックスを広げる *****¥n"
buff+= " bound.extend(mk.pos);¥n"
buff+= " }¥n"
buff+= " }¥n"
buff+= " </script>¥n"
buff+= "</head>¥n"
buff+= "<body onload=¥"init()¥">¥n"
buff+= " <div id=¥"mapcontainer¥" style=¥"position:absolute;top:0;left:0;right:0;bottom:0;¥"></div>¥n"
buff+= "</body>¥n"
buff+= "</html>¥n"
;***** 一時ファイルとしてセーブ *****
bsave TEMP_FILE, buff, strlen(buff)
;***** HTMLファイルを起動 *****
ie->"Navigate" "file:///"+TEMP_FILE
comevent ie_event, ie, DIID_DWebBrowserEvents2, *event
;***** ウィンドウを最大化 *****
oncmd gosub *GUIResize,WM_SIZE
sendmsg hwnd,WM_SYSCOMMAND,SC_MAXIMIZE,0
gsel 0,1
stop
*GUIResize
;***** リサイズ処理 *****
gsel 0,1
InvalidateRect hwndIE,0,1
MoveWindow hwndIE, 0, 0, ginfo_winx+16, ginfo_winy-26, 1
color 240,240,240 : boxf
color 200,200,200
line 0,ginfo_winy-26,ginfo_winx+16, ginfo_winy-26
font "Meiryo UI",11,0 : color 20,20,20
pos 10,ginfo_winy-20 : mes "出典:国土地理院 - 地理院地図、淡色地図 | OpenStreetMap - contributors"
return
*event
dispid = comevdisp(ie_event)
if dispid = DISPID_NAVIGATECOMPLETE2 : title "気象庁震度観測点マップ"
return
*owari
;***** 終了処理 *****
gsel 0,0
await
;***** 一時ファイルを削除 *****
exist TEMP_FILE
if strsize !=-1 {
delete TEMP_FILE
}
delcom ie
end
3.ダウンロード 提供するソースコードのライセンスは、CC0 (クレジット表示不要、改変可、商用可) とします。自由に利用して頂いてかまいません。 尚、データの取得やプログラム実行において損害等が生じた場合は、筆者は一切の責任も負いません。全て自己責任でお願いします。
実行形式(exe)ファイルとソースコード一式のアーカイブは下記よりダウンロードして下さい。
ダウンロード
■関連記事
・Leafletで地図を作ろう - (気象庁震度観測点マップ)


コメント
コメントを投稿