HSPでleafletを使って地図を作る(サンプル)

1.概要

地図については、Leafletで地図を作ろう - (気象庁震度観測点マップ)でJavaScriptで作成したものを 紹介していますが、今回は、このLeaflet地図をHSP言語に一部移植して見ました。JavaScript版では、外部ファイル化した定義コードやライブラリもあり、それらをHSPコード内に記述するのも めんどうだったので、サンプルということで簡易版として再現して見ました。

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

コメント

このブログの人気の投稿

Excelアドインで日本語形態素解析

階層構造JSONファイルの作成

HSPでコマンドプロンプトを制御する

TOP