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で地図を作ろう - (気象庁震度観測点マップ)
コメント
コメントを投稿