Leafletで地図を作ろう - (四国遍路巡礼マップ)
1.四国遍路巡礼マップ
作品例として、四国遍路巡礼マップを作成します。この題材は弘法大師空海のゆかりの地を地図上で巡ります。
八十八ヶ所の寺院などを選び四国八十八ヶ所霊場を開創された空海の御跡である八十八ヶ所霊場にアイコンマーカーを配置しました。
マーカーをクリックするとポップアップに寺院名や場所などを表示します。
ソースコードの大部分は、すでに公開している「気象庁震度観測点マップ」からの流用です。内容が重複するので「気象庁震度観測点マップ」で説明していない
追加、変更部分のみを中心に説明していきます。
ポップアップ内で利用しているお坊さんの画像素材は、下記サイト様にて提供されているものを利用させて頂きました。 取得先 : イラストポップ(出典:illpop) お坊さんのイラスト 2.ソースコードの説明 四国遍路巡礼マップのメインとなる(henro.html)コードです。各実装部品の定義ファイル類は外部ファイルとしています。 leaflet.css、all.css、henro.css、leaflet.js、SlideMenu.js、henrodef.js、henro88.jsライブラリ等をヘッダー部分に指定しています。 henro.cssとhenrodef.js、henro88.jsは筆者が作成したものです。 DEMO
マーカーの配置やポップアップのコード部分は、「気象庁震度観測点マップ」と同じです。コードの説明は「気象庁震度観測点マップ」を参照して下さい。
大量のアイコンマーカーの配置とポップアップ(吹き出し)を指定した座標(緯度、経度)の位置に展開します。
種類の違う複数の任意アイコン画像のマーカーを指定した位置に配置するために外部ファイルとしてhenro88.jsとして作成します。
henro88.jsも「気象庁震度観測点マップ」の構成と相違ありません。データ内容が違うだけです。
※リスト表示にsyntaxhighlighterを利用していますが、スクリプト中に<br>タグを含んでいる
箇所が何箇所かあり、henro88.jsコード表示が正しく表示されないため掲載していません。コードは一部分のみのサンプルですが、下記から確認して下さい。
henro88.jsファイル確認
3.ソースコードについて 掲載しているソースコードのライセンスは、CC0 (クレジット表示不要、改変可、商用可) とします。自由に利用して頂いてかまいません。 作品で利用しているアイコンマーカー画像ファイル等は提供していませんので、お手数ですが各自で準備して下さい。尚、ソースコードは予告なく修正を加えて 更新することがあります。予めご了承願います。また、ブラウザのソースコード表示などで表示して確認やコピー、URLから直接ダウンロードするなども自由に行ってもかまいません。 全て自己責任でお願いします。 ■関連記事
・Leafletで地図を作ろう - (イントロダクション)
・Leafletで地図を作ろう - (気象庁震度観測点マップ)
・Leafletで地図を作ろう - (都道府県別人口統計マップ)
・Leafletで地図を作ろう - (東海道五十三次ルートマップ)
・Leafletで地図を作ろう - (富嶽三十六景浮世絵マップ)
ポップアップ内で利用しているお坊さんの画像素材は、下記サイト様にて提供されているものを利用させて頂きました。 取得先 : イラストポップ(出典:illpop) お坊さんのイラスト 2.ソースコードの説明 四国遍路巡礼マップのメインとなる(henro.html)コードです。各実装部品の定義ファイル類は外部ファイルとしています。 leaflet.css、all.css、henro.css、leaflet.js、SlideMenu.js、henrodef.js、henro88.jsライブラリ等をヘッダー部分に指定しています。 henro.cssとhenrodef.js、henro88.jsは筆者が作成したものです。 DEMO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" > < meta http-equiv = "X-UA-Compatible" content = "ie=edge" > < title >四国遍路巡礼マップ</ title > < link rel = "stylesheet" href = "https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity = "sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin = "" /> < script src = "https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity = "sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin = "" > </script> < link rel = "stylesheet" type = "text/css" media = "screen" href = "./css/henro.css" > < link rel = "stylesheet" href = "./css/L.Control.SlideMenu.css" /> < link rel = "stylesheet" href = "https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity = "sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin = "anonymous" > <script src="./jsscr/L.Control.SlideMenu.js"> </script> <script src='./jsscr/henro88.js'> </script> <script src='./jsscr/henrodef.js'> </script> <script> var markers=[]; function init(){ //***** 中心基準座標の指定 ***** var mpoint = [33.561995, 133.670654]; var map = L.map( 'mapcontainer' ).setView(mpoint, 9); //***** 3つの地図タイルを設定 ***** var gsi =L.tileLayer( 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png' , { attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>" }); var gsipale = L.tileLayer( 'http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png' , { attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>" }); var osm = L.tileLayer( 'http://tile.openstreetmap.jp/{z}/{x}/{y}.png' , { attribution: "<a href='http://osm.org/copyright' target='_blank'>OpenStreetMap</a> contributors" }); //***** baseMapsオブジェクトのプロパティに3つのタイルを設定 ***** var baseMaps = { "地理院地図" : gsi, "淡色地図" : gsipale, "オープンストリートマップ" : osm }; L.control.layers(baseMaps).addTo(map); osm.addTo(map); //***** Slide Menu Content html ***** var header1 = '<span class="cstm-slidmenu-header" style=" background-color: #0033aa">巡礼所名を選択</span>' ; var contents1 = '<select class="combinfo-set" name="select" onchange="selText(this);">' ; for ( var i=0;i< selbox.length ;i++){ if (i==0) { contents1 += '<option disabled selected value=' + selbox[i].val + '>' + selbox[i].name + '</option>' ; } else { contents1 += '<option value=' + selbox[i].val + '>' + selbox[i].name + '</option>' ; } } contents1 += '</select>' ; var contents2 = '<br><br>' ; var header3 = '<span class="cstm-slidmenu-header" style="background-color: #dd3366">XXXXXXXXXX</span>' ; var contents3 = '<table width=180 border=0 cellspacing=0 cellpadding=0 bgcolor="#303040" ' + 'onMouseOver="cellbgcolor(¥' ' + "#805080" + ' ¥ ');" ' + 'onMouseOut="bgrecover(¥' ' + "#303040" + ' ¥ ')">' ; for ( var i = 0; i < SlideMenu_ma.length ; i++) { var smenuDef = SlideMenu_ma [i]; var text = smenuDef .title; contents3 += '<tr><td width=15 align="right"><img src=' + smenuDef.img + '></td>' + '<td width=165 height=20 align="left" class="menustr" onClick="JumpURL(¥' ' + smenuDef.url+ ' ¥ ')">' + text + '</td></tr>' ; } contents3 += '</table>' ; // ***** SlideMenu Option ***** var options = { width: '200px' , height: '230px' } L.control.slideMenu(header1+contents1+contents2+header3+contents3, options).addTo(map); //***** 凡例を右下に追加(1) ***** var legend = L.control({position: 'bottomright' }); legend.onAdd = function (map) { var div = L.DomUtil.create( 'div' , 'info legend' ); var labels = []; for ( var i = 0; i < colorDefs.length ; i++) { var colorDef = colorDefs [i]; var text = '' ; text = colorDef .title; if (i >= 5) { labels.push( '<span class="legend-item" style="color:#0033c1"><span class="legend-item-color" style="background:' + colorDef.color + '">' + '</span> ' + text + '</span>' ); } else { labels.push( '<span class="legend-item"><span class="legend-item-color" style="background:' + colorDef.color + '">' + '</span> ' + text + '</span>' ); } } div.innerHTML = labels.join( '' ); return div; }; legend.addTo(map); //***** 画像を右下に追加(2) ***** var img = L.control({position: 'bottomright' }); img .onAdd = function (map) { this ._div = L.DomUtil.create( 'div' , 'imglinfo' ); this .update(); return this ._div; }; img.update = function () { this ._div.innerHTML = '<img src="./image/henro88.png" width=190 height=165>' }; img.addTo(map); //***** スケールの表示 ***** L.control.scale({imperial: false }).addTo(map); //***** マーカー全体が入るボックスを作る ***** var bound = L.latLngBounds(markerList[0].pos, markerList[0].pos); //***** markerListの設定でマーカーを展開 ***** for ( var num in markerList) { var mk = markerList[num]; var popup = L.popup().setContent(mk.name); //***** ツールチップ付加でアイコン色分け表示 ***** var mIcon = L.icon({ iconUrl: mk.iconUrl, iconSize: mk.iconSize }); markers[num]=L.marker(mk.pos,{ icon:mIcon }).bindPopup(popup).bindTooltip(mk.title).addTo(map); //***** マーカー全体が入るボックスを広げる ***** bound.extend(mk.pos); } } //***** コンボボックスの巡礼所名を選択するとポップアップ ***** function selText(obj){ var idx = obj.selectedIndex; var value = obj.options[idx].value; markers[value].openPopup(); } </script> </ head > < body onload = "init()" > < div id = "mapcontainer" style = "position:absolute;top:0;left:0;right:0;bottom:0;" ></ div > </ body > </ html > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | //***** 巡礼所名配列 ***** var selbox= [ { val: "" ,name: "巡礼所名" },{val: "0" ,name: "01.霊山寺 (りょうぜんじ)" },{val: "1" ,name: "02.極楽寺 (ごくらくじ)" },{val: "2" ,name: "03.金泉寺 (こんせんじ)" }, { val: "3" ,name: "04.大日寺 (だいにちじ)" },{val: "4" ,name: "05.地蔵寺 (じぞうじ)" },{val: "5" ,name: "06.安楽寺 (あんらくじ)" },{val: "6" ,name: "07.十楽寺 (じゅうらくじ)" }, { val: "7" ,name: "08.熊谷寺 (くまだにじ)" },{val: "8" ,name: "09.法輪寺 (ほうりんじ)" },{val: "9" ,name: "10.切幡寺 (きりはたじ)" },{val: "10" ,name: "11.藤井寺 (ふじいでら)" }, { val: "11" ,name: "12.焼山寺 (しょうざんじ)" },{val: "12" ,name: "13.大日寺 (だいにちじ)" },{val: "13" ,name: "14.常楽寺 (じょうらくじ)" },{val: "14" ,name: "15.国分寺 (こくぶんじ)" }, { val: "15" ,name: "16.観音寺 (かんおんじ)" },{val: "16" ,name: "17.井戸寺 (いどじ)" },{val: "17" ,name: "18.恩山寺 (おんざんじ)" },{val: "18" ,name: "19.立江寺 (たつえじ)" }, { val: "19" ,name: "20.鶴林寺 (かくりんじ)" },{val: "20" ,name: "21.太龍寺 (たいりゅうじ)" },{val: "21" ,name: "22.平等寺 (びょうどうじ)" },{val: "22" ,name: "23.薬王寺 (やくおうじ)" }, { val: "23" ,name: "24.最御崎寺 (ほつみさきじ)" },{val: "24" ,name: "25.津照寺 (しんしょうじ)" },{val: "25" ,name: "26.金剛頂寺 (こんごうちょうじ)" },{val: "26" ,name: "27.神峯寺 (こうのみねじ)" }, { val: "27" ,name: "28.大日寺 (だいにちじ)" },{val: "28" ,name: "29.国分寺 (こくぶんじ)" },{val: "29" ,name: "30.善楽寺 (ぜんらくじ)" },{val: "30" ,name: "31.竹林寺 (ちくりんじ)" }, { val: "31" ,name: "32.禅師峰寺 (ぜんじぶじ)" },{val: "32" ,name: "33.雪蹊寺 (せっけいじ)" },{val: "33" ,name: "34.種間寺 (たねまじ)" },{val: "34" ,name: "35.清瀧寺 (きよたきじ)" }, { val: "35" ,name: "36.青龍寺 (しょうりゅうじ)" },{val: "36" ,name: "37.岩本寺 (いわもとじ)" },{val: "37" ,name: "38.金剛福寺 (こんごうふくじ)" },{val: "38" ,name: "39.延光寺 (えんこうじ)" }, { val: "39" ,name: "40.観自在寺 (かんじざいじ)" },{val: "40" ,name: "41.龍光寺 (りゅうこうじ)" },{val: "41" ,name: "42.仏木寺 (ぶつもくじ)" },{val: "42" ,name: "43.明石寺 (めいせきじ)" }, { val: "43" ,name: "44.大寶寺 (だいほうじ)" },{val: "44" ,name: "45.岩屋寺 (いわやじ)" },{val: "45" ,name: "46.浄瑠璃寺 (じょうるりじ)" },{val: "46" ,name: "47.八坂寺 (やさかじ)" }, { val: "47" ,name: "48.西林寺 (さいりんじ)" },{val: "48" ,name: "49.浄土寺 (じょうどじ)" },{val: "49" ,name: "50.繁多寺 (はんたじ)" },{val: "50" ,name: "51.石手寺 (いしてじ)" }, { val: "51" ,name: "52.太山寺 (たいさんじ)" },{val: "52" ,name: "53.圓明寺 (えんみょうじ)" },{val: "53" ,name: "54.延命寺 (えんめいじ)" },{val: "54" ,name: "55.南光坊 (なんこうぼう)" }, { val: "55" ,name: "56.泰山寺 (たいさんじ)" },{val: "56" ,name: "57.栄福寺 (いふくじ)" },{val: "57" ,name: "58.仙遊寺 (せんゆうじ)" },{val: "58" ,name: "59.国分寺 (こくぶんじ)" }, { val: "59" ,name: "60.横峰寺 (よこみねじ)" },{val: "60" ,name: "61.香園寺 (こうおんじ)" },{val: "61" ,name: "62.宝寿寺 (ほうじゅじ)" },{val: "62" ,name: "63.吉祥寺 (きちじょうじ)" }, { val: "63" ,name: "64.前神寺 (まえがみじ)" },{val: "64" ,name: "65.三角寺 (さんかくじ)" },{val: "65" ,name: "66.雲辺寺 (うんぺんじ)" },{val: "66" ,name: "67.大興寺 (だいこうじ)" }, { val: "67" ,name: "68.神恵院 (じんねいん)" },{val: "68" ,name: "69.観音寺 (かんのんじ)" },{val: "69" ,name: "70.本山寺 (もとやまじ)" },{val: "70" ,name: "71.弥谷寺 (いやだにじ)" }, { val: "71" ,name: "72.曼荼羅寺 (まんだらじ)" },{val: "72" ,name: "73.出釈迦寺 (しゅっしゃかじ)" },{val: "73" ,name: "74.甲山寺 (こうやまじ)" },{val: "74" ,name: "75.善通寺 (ぜんつうじ)" }, { val: "75" ,name: "76.金倉寺 (こんぞうじ)" },{val: "76" ,name: "77.道隆寺 (どうりゅうじ)" },{val: "77" ,name: "78.郷照寺 (ごうしょうじ)" },{val: "78" ,name: "79.天皇寺 (てんのうじ)" }, { val: "79" ,name: "80.國分寺 (こくぶんじ)" },{val: "80" ,name: "81.白峯寺 (しろみねじ)" },{val: "81" ,name: "82.根香寺 (ねごろじ)" },{val: "82" ,name: "83.一宮寺 (いちのみやじ)" }, { val: "83" ,name: "84.屋島寺 (やしまじ)" },{val: "84" ,name: "85.八栗寺 (やくりじ)" },{val: "85" ,name: "86.志度寺 (しどじ)" },{val: "86" ,name: "87.長尾寺 (ながおじ)" }, { val: "87" ,name: "88.大窪寺 (おおくぼじ)" } ]; //***** 簡易マイ・メニュー定義( SlideMenu) ***** var SlideMenu_ma = [ { title: 'XXXXXXXXXXX' , url: 'XXXXXXXXXXXXXXXX' ,img: '"./image/ball3.png" width=8 height=8 align="absmiddle"' }, { title: 'XXXXXXXXXXX' , url: 'XXXXXXXXXXXXXXXX' ,img: '"./image/ball3.png" width=8 height=8 align="absmiddle"' }, { title: 'XXXXXXXXXXX' , url: 'XXXXXXXXXXXXXXXX' ,img: '"./image/ball3.png" width=8 height=8 align="absmiddle"' } ]; //***** 凡例:色定義 (地域別)***** var colorDefs = [ { title: '徳島県:阿波 (発心の道場)(24)' , color: '#ff5891' }, { title: '高知県:土佐 (修行の道場)(16)' , color: '#0061c1' }, { title: '愛媛県:伊予 (菩提の道場)(23)' , color: '#1a883a' }, { title: '香川県:讃岐 (涅槃の道場)(22)' , color: '#ff7f27' }, { title: '合計: (88箇所)' , color: '#ffffff' }, { title: '(*注)37.岩本寺の本尊:五仏' , color: '#ffffff' }, { title: '・不動明王' , color: '#ffffff' }, { title: '・聖観世音菩薩' , color: '#ffffff' }, { title: '・阿弥陀如来' , color: '#ffffff' }, { title: '・薬師如来' , color: '#ffffff' }, { title: '・地蔵菩薩である。' , color: '#ffffff' } ]; // ****** 背景色変更 ****** var obj,evobj; function bgrecover(bg) { evobj.style.backgroundColor=bg; } function setColor(obj,col) { obj.style.backgroundColor = col; } // ****** 'table' , 'tr'タグ部分を避ける制御 ***** function cellbgcolor(bg) { evobj=event.srcElement; if (evobj.tagName== "TABLE" ) { return } while (evobj.tagName!= "TR" ) { evobj=evobj.parentElement; } evobj.style.backgroundColor=bg; } // ****** 別のHTMLに切替 (target="_blank") ****** function JumpURL(URL) { window.open(URL, '_blank' , "directories=no,location=yes,menubar=yes,resizable=yes,scrollbars=yes,status=yes,toolbar=yes" ); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | a { font-size : 12px ; text-decoration : none ; font-family :Meiryo UI; } a:link { color : #0033aa ; } a:hover { color : #aa0000 ; } a:visited { color : #0000ff ; } body { font-size : 12px ; font-family :Meiryo; margin : 0 ; padding : 0 ; } .info { padding : 10px 10.5px ; background : white ; border-radius: 3px ; } .legend-item { display : flex; font-family : Meiryo UI; font-size : 10.5px ; color : #555555 ; width : 165px ; align-items: center ; } .legend-item-color { display : block ; width : 15px ; height : 15px ; margin-right : 5px ; } .cstm-slidmenu-header { display : block ; margin : 0 ; font-size : 14px ; font-weight : bold ; width : 180px ; color : #ffffff ; text-align : center ; } .menustr { font-size : 11px ; font-family : Meiryo UI; padding-left : 6px ; color : #ffffff ; cursor : pointer ; } .combinfo-set { font-size : 11px ; font-family :Meiryo; color : #000000 ; width : 180px ; height : 20px ; margin-top : 1px ; margin-bottom : 1px ; background : #fefcc8 ; cursor : pointer ; } |
3.ソースコードについて 掲載しているソースコードのライセンスは、CC0 (クレジット表示不要、改変可、商用可) とします。自由に利用して頂いてかまいません。 作品で利用しているアイコンマーカー画像ファイル等は提供していませんので、お手数ですが各自で準備して下さい。尚、ソースコードは予告なく修正を加えて 更新することがあります。予めご了承願います。また、ブラウザのソースコード表示などで表示して確認やコピー、URLから直接ダウンロードするなども自由に行ってもかまいません。 全て自己責任でお願いします。 ■関連記事
・Leafletで地図を作ろう - (イントロダクション)
・Leafletで地図を作ろう - (気象庁震度観測点マップ)
・Leafletで地図を作ろう - (都道府県別人口統計マップ)
・Leafletで地図を作ろう - (東海道五十三次ルートマップ)
・Leafletで地図を作ろう - (富嶽三十六景浮世絵マップ)
コメント
コメントを投稿