leaflet.js を使った Web地図
  ここでは leaflet.js を使った Web地図の例を示します。  他のWeb地図
  1. 地図例一覧
    1. 基本的なコード・・・・・・・・・・・・・・・国土地理院地図タイルを利用した基本地図  具体例  参考
    2. ベースレイヤの切替・・・・・・・・・・・ベース地図タイルを切替えて利用する  具体例  参考
    3. マーカを設置する・・・・・・・・・・・・・色々なマーカを設置する    具体例  参考
    4. レイヤを切替・・・・・・・・・・・・・・・・・レイヤの表示を切替える    具体例  参考
    5. ライン&マーカを追加・・・・・・・・・クリック点にライン&マーカを追加/削除する  具体例  参考
    6. JSON マーカを追加・・・・・・・・・・・マーカ情報を持つ JSON を読込んでマーカを追加  具体例  参考
    7. google mapも表示・・・・・・・・・・・・ Leaflet に google mapも表示する  具体例  参考  例2
    8. 住所検索を追加・・・・・・・・・・・・・・・Leaflet で住所検索を行う  具体例  参考  例2  (*google geo を推奨)
    9. 緯度・経度を指定・・・・・・・・・・・・・緯度・経度を指定して map を表示  具体例
    10. 現在地を表示・・・・・・・・・・・・・・・・・現在地をWeb地図上に表示   具体例
  2. 具体的コード例
    1. 基本的なコード 例表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>Leaflet の基本的な記述</title>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css" />
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <script>
          function init() {
            var mapobj = L.map('mapDiv'); // 'mapDiv' に表示する地図を変数 mapobj で指定
            mapobj.setView([35.36063,138.72731],10); //地図の中心位置とズームレベルを指定
            //表示するタイルレイヤと Attribution の記述を指定し、地図に追加
            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>"}
            ).addTo(mapobj);
          }
        </script>
      </head>
      <body onload="init()">
        <div id="mapDiv" style="width:900px;height:540px;margin:0 auto;"></div>
      </body>
      </html>
       【基本サンプルを表示
      ( 6,7行目)  Leafletを使うための cssとJavaScriptを読込
      (10行目) 'mapDiv' に表示する地図を変数 mapobj で L.mapオブジェクトに設定 参考
      (11行目) setViewメソッドで地図中心の緯経度とズームレベルを指定 参考
      (13行目) 地図データとして地理院タイルレイヤし、
      (14行目) それが地理院のタイルであることを表記して、
      (15行目) addToメソッドで地図mapobj に取り込みます
      (19行目) ページを読み込んだらinit()を実行します
      (20行目) divタグに idを設定 'mapDiv' としました

    2. ベースレイヤを切替える例 例表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>ベースレイヤを切り替える</title>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css" />
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <script>
          function init(){
            var mapobj = L.map('mapDiv',{zoomControl:false});
            mapobj.setView([35.36063,138.72731],10);
            L.control.scale({maxWidth:200,position:'bottomright',imperial:false}).addTo(mapobj);
            L.control.zoom({position:'bottomleft'}).addTo(mapobj);
            var gsi =L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', 
              {minZoom:2,maxZoom:18,attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>"});   //地理院地図の標準地図タイル
            var gsiphoto = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg',
              {minZoom:2,maxZoom:18,attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>地理院タイル</a>"});  //地理院地図の写真タイル
            var gsipho78 = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/gazo1/{z}/{x}/{y}.jpg',
              {minZoom:10,maxZoom:17,attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>地理院タイル</a>"});  //地理院地図の写真タイル-78
            var relief = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png',
              {minZoom:5,maxZoom:15,attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>地理院タイル</a>「海域部は海上保安庁海洋情報部の資料を使用して作成」"}); //地理院地図の色別標高図
            var gsipale = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
              {minZoom:2,maxZoom:18,attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.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オブジェクトに複数のタイルを設定
            var baseMaps = {
              "地理院地図" : gsi,
              "地理院写真" : gsiphoto,
              "院写真-78" : gsipho78,
              "色別標高図" : relief,
              "淡色地図" : gsipale,
              "O.S.Map"  : osm
            };
            // layersコントロールにbaseMapsオブジェクトを設定して地図に追加
            L.control.layers(baseMaps).addTo(mapobj);
            gsiphoto.addTo(mapobj);   // 初期表示地図を設定
          }
        </script>
        <style>
          #mapDiv{position:absolute;top:5px;left:5px;right:5px;bottom:5px;}
        </style>
      </head>
      <body onload="init()">
        <header style="text-align:center;">ベースレイヤを切り替える(右上アイコン)</header>
        <div id="mapDiv"></div>
      </body>
      </html>
       【ベースレイヤ切替え例を表示
      ( 6,7行目)  Leafletを使うための cssとJavaScriptを読込
      (10行目) 'mapDiv' に表示する地図を変数 mapobj で L.mapオブジェクトに設定。zoomControl を一旦削除(false)
      (11行目) setViewメソッドで地図中心の緯経度とズームレベルを指定
      (12行目) scale control を右下に設置 参考
      (13行目) zoom control を左下に設置 参考
      (14-36行) 地図データとして利用するベースタイルをそれぞれ定義し、layersコントロールを設置します。ベースレイヤ切替ボタンは右上に設置されます 参考
      (37行目) 初期のベースタイルはgsiphotoにしました
      (41行目) css で地図表示域のスタイルを設定します
      (44行目) ページを読み込んだらinit()を実行します
      (46行目) 地図表示域の idを 'mapDiv' と設定しました

    3. マーカを設置する例 例表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>マーカの設置</title>
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css"/>
        <style>
          #mapDiv{position:absolute;top:5px;left:5px;right:5px;bottom:5px;}
        </style>
        <script>
          var mapobj; var myIcon2;
          function init(){ 
            var mypoint = [35.196262,139.026013];  // 図中心:恩賜公園 
            mapobj = L.map('mapDiv',{zoomControl:true}).setView(mypoint,14); //中心&ズーム値
            L.control.scale({imperial:false}).addTo(mapobj);  // スケール(mのみ)を追加
            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>"
            }).addTo(mapobj);
            var myIcon1 = L.icon({
              iconUrl: '../img/mkg.gif',
              iconSize: [27, 45],
              iconAnchor: [14, 44]
            });
            myIcon2 = L.icon({
              iconUrl: '../img/mkr.gif',
              iconSize: [27, 45],
              iconAnchor: [14, 44]
            });
            var myIcon3 = L.icon({
              iconUrl: '../img/mkb.gif',
              iconSize: [27, 45],
              iconAnchor: [14, 44]
            });
            // ポップアップする文字(HTML可、ここでは画像を表示)
            var sucontents = "ここは恩賜箱根公園です<br><img src='http://kurage.ready.jp/jfuji/fj1674s.jpg' width='200' height='125'>"
            // ポップアップオブジェクトを作成
            var popup1 = L.popup({ maxWidth:300,maxHeight:150 }).setContent(sucontents);
            var popup4 = L.popup().setContent("箱根関所跡です<br>ドラッグは不可です");
            // マーカにポップアップを紐付けする。同時にbindTooltipでツールチップも追加
            L.marker(mypoint,{draggable:true,icon:myIcon1}).bindPopup(popup1).bindTooltip("クリックで popup します<br>ドラッグ可能です").addTo(mapobj);
            L.marker([35.204794,139.025357],{icon:myIcon2}).bindTooltip("箱根神社です<br>クリックで削除可能").on('click', onMkClick).addTo(mapobj); 
            L.marker([35.189311,139.024623],{draggable:true,icon:myIcon3}).bindTooltip("箱根駅伝 goal・start<br>ドラッグ可、クリックで不動").addTo(mapobj);
            L.marker([35.192362,139.026346],{title:"箱根関所跡 クリック可"}).bindPopup(popup4).addTo(mapobj);// マーカを追加
            // 地図のclickイベントでonMapClick関数を呼び出し
            mapobj.on('click', onMapClick);
          }; // init()  -----------------------
          function onMapClick(e) {
            // クリック地点にマーカを追加、マーカのclickイベントでonMkClick関数を呼び出し
            var mk = L.marker(e.latlng,{icon:myIcon2}).bindTooltip(e.latlng+"<br>クリックで削除可能").on('click',onMkClick).addTo(mapobj);
          }
          function onMkClick(e) { // クリックされたマーカを地図のレイヤから削除
            mapobj.removeLayer(e.target);
          }; // onMkClick(e)  -----------------------
        </script>
      </head>
      <body onload="init()">
        
        <header style="text-align:center;">マーカを設置する(クリックで追加・消去等)</header>
        <div id="mapDiv"></div>
      </body>
      </html>
       【マーカを設置する例を表示
      ( 6,7行目)  Leafletを使うための JavaScriptとcssを読込み
      ( 9行目) css で地図表示域 'mapDiv' のスタイルを設定
      (15行目) 'mapDiv' に表示する地図を変数 mapobj で L.mapオブジェクトに設定 参考 setViewメソッドで地図中心の緯経度とズームレベルを指定 参考
      (16行目) 地図の距離スケールを追加 参考
      (17行目) 地図データとして地理院タイルレイヤし、
      (18行目) それが地理院のタイルであることを表記して、
      (19行目) addToメソッドで地図mapobj に取り込みます
      (20-34行) 後で使う3個のアイコンを定義します 参考
      (36-39行) popup1,popup4 の定義をします 参考
      (41行目) 図中心mypointにpopup1を持つmyIcon1 のマーカを Tooltip を付与して設置します 参考
      (42行目) クリック時に onMkClick 動作する myIcon2 マーカを設置します
      (43行目) ドラッグ可能な myIcon3 マーカ を設置します
      (44行目) アイコンを指定せず default の popup4 を付与したマーカを設置します
      (46,50行) 地図クリック点に myIcon2 マーカを設置します
      (52-54行) クリックされたマーカを削除する関数を設置
      (57行目) ページを読み込んだらinit()を実行します
      (58行目) divタグに idを設定 'mapDiv' としました

    4. レイヤを切替える例 例(雨雲レイヤ)を表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>各レイヤを描く</title>
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css"/>
        <style>
          #mapDiv{ position:absolute;top:35px;left:5px;right:5px;bottom:5px; }
        </style>
        <script>
          function init() {
            var mapobj = L.map('mapDiv', { zoomControl: false });
            var mypoint = [35.196262,139.026013];   // 図中心:恩賜箱根公園 
            mapobj.setView(mypoint, 14);            // 図中心とズームレベルを設定
            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>"           // 地理院タイルの出典の表示&リンク
            }).addTo(mapobj);               // 地理院タイルを貼付け
            var gsiphoto = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg',
              {attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>地理院タイル</a>"});       //地理院地図の写真タイルの設定
            var osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
              {  attribution: "c<a href='http://osm.org/copyright' target='_blank'>OpenStreetMap</a> contributors" }); // オープンストリートマップのタイルの設定
            var ClsGroup = L.layerGroup();  // 同心円群を layerGroupオブジェクトに纒める
            var Clscenter = [35.192362,139.026346]; // 同心円中心 箱根関所跡
            for (var i =0; i <5; i++) {             // 4同心円描画
              var r = i * 1000;
              ClsGroup.addLayer(L.circle(Clscenter,{ radius:r,color:"#e55",fill:false,weight:2 }));
            }
      //      var circleMarker = L.circleMarker([35.189311,139.024623], { radius:30,color:"#5555ff",weight:2, fill:true, fillColor:"#0000ff", opacity:0.5 }).addTo(mapobj); // 円マーカを地図に付加
            var roadPts = [ [35.189311,139.024623],[35.189052,139.025025],[35.191502,139.027394],[35.192102,139.026511],[35.192273,139.026372],[35.192358,139.026340],[35.193125,139.026308],[35.193779,139.026731],[35.193893,139.026474],[35.194046,139.026544],[35.194112,139.026367],[35.194198,139.026276],[35.194754,139.025702],[35.195276,139.025837],[35.195386,139.025815],[35.195523,139.025654],[35.195637,139.025412],[35.195913,139.025756],[35.196005,139.025627],[35.196073,139.025627],[35.196358,139.025815],[35.196262,139.026013]];
            var polyline = L.polyline(roadPts,{color:"#2b2",weight:5}).addTo(mapobj); // 配列データ roadPts の polyline を mapobj に追加
            var arealatlons = [[35.1952632,139.0275431],[35.1955350,139.0276289],[35.1961312,139.0277040],[35.1960961,139.0279025],[35.1961882,139.0279669],[35.1962890,139.0278381],[35.1963855,139.0278167],[35.1965652,139.0278381],[35.1966529,139.0278167],[35.1969860,139.0279400],[35.1971482,139.0279454],[35.1972666,139.0279239],[35.1973849,139.0279186],[35.1976830,139.0277791],[35.1978759,139.0276074],[35.1979986,139.0275216],[35.1982529,139.0275323],[35.1983756,139.0275216],[35.1985334,139.0274143],[35.1986825,139.0273607],[35.1988666,139.0271998],[35.1990156,139.0270066],[35.1990419,139.0267921],[35.1989981,139.0265238],[35.1989367,139.0263414],[35.1988491,139.0261912],[35.1987702,139.0261376],[35.1986211,139.0260732],[35.1984019,139.0258050],[35.1981652,139.0256333],[35.1979022,139.0252364],[35.1977269,139.0251613],[35.1974989,139.0249145],[35.1973586,139.0248823],[35.1971044,139.0249682],[35.1968940,139.0249038],[35.1967011,139.0245926],[35.1964030,139.0243566],[35.1962539,139.0240455],[35.1962101,139.0237773],[35.1961575,139.0235949],[35.1956928,139.0231979],[35.1954386,139.0232408],[35.1951668,139.0234447],[35.1950353,139.0235305],[35.1949213,139.0237236],[35.1949213,139.0238309],[35.1949476,139.0239167],[35.1949038,139.0240455],[35.1949125,139.0244210],[35.1949564,139.0246677],[35.1949038,139.0250218],[35.1947898,139.0251184],[35.1945618,139.0251935],[35.1943777,139.0252686],[35.1942286,139.0253437],[35.1941936,139.0254188],[35.1941410,139.0257835],[35.1940270,139.0259123],[35.1939568,139.0259338],[35.1938516,139.0259445],[35.1939656,139.0261912],[35.1939656,139.0264165],[35.1946320,139.0270281]];
            var polygon = L.polygon(arealatlons,{ color:'#2b2',weight:3,fill:true,fillColor: 'green',opacity:0.5 }); // 配列データ arealatlons の polygon を追加
            L.YimgTileLayer = L.TileLayer.extend({   // 雨雲画像をオーバーレイ作業
              getTileUrl: function (coords) {
                //雨雲リクエスト日付の作成
                var now = new Date();
                var year = now.getFullYear();
                var month = now.getMonth() + 1;
                var day = now.getDate();
                var hours = now.getHours();
                var minutes = now.getMinutes();
                if (month < 10) month = '0' + month;
                if (day < 10) day = '0' + day;
                if (hours < 10) hours = '0' + hours;
                minutes *= 0.1;
                minutes = Math.floor(minutes);
                minutes *= 10;
                if (minutes < 10) minutes = '0' + minutes;
                date = "" + year + month + day + hours + minutes;
                return L.Util.template(this._url, L.extend({
                  d: date,
                  x: coords.x,
                  y: Math.pow(2, this._getZoomForUrl() - 1) - 1 - coords.y,
                  z: this._getZoomForUrl() + 1
                }, this.options));
              }
            });
            // 雨雲画像をオーバーレイとしてマップに追加
            var rainmap = new L.YimgTileLayer('http://weather.map.c.yimg.jp/weather?x={x}&y={y}&z={z}&size=256&date={d}', {
              attribution: 'Rain map',
              maxZoom: 18,
              opacity: 0.6
            }).addTo(mapobj);
            var baseMaps = {        // 各ベースレイヤをオブジェクト baseMaps に設定
              "地理院地図" : gsi,
              "地理院写真" : gsiphoto,
              "O.S.Map"  : osm
            };
            var overlay = {         // 各ベクタレイヤをオブジェクト overlay に設定
              "polyline": polyline,
      //        "円マーカ": circleMarker,  // 今回これは layersコントロールには含めず
              "等距離円": ClsGroup,
              "雨雲マップ": rainmap,
              "polygon": polygon
            }
            L.control.layers(baseMaps,overlay).addTo(mapobj); // layersコントロールを mapobj に追加
          }; // init() -----------------------------------
        </script>
      </head>
      <body onload="init()">
        <header style="text-align:center;">オーバーレイ(雨雲マップ等)を追加</header>
        <div id="mapDiv"></div>
      </body>
      </html>
       【レイヤを切替える例を表示
      ( 6,7行目)  Leafletを使うための JavaScriptとcssを読込み
      ( 9行目) css で地図表示域 'mapDiv' のスタイルを設定
      (13行目) 'mapDiv' に表示する mapobj を L.mapオブジェクトに設定。zoomControl は不使用(false)とした
      (15行目) 地図変数 mapobj に setViewで地図中心の緯経度(mypoint)とズームレベルを指定 参考
      (16行目) 地図データとして地理院タイルレイヤし、
      (17行目) それが地理院のタイルであることを表記して、
      (18行目) addToメソッドで地図mapobj に取り込みます
      (19-20行) 地図データとして航空写真タイルレイヤを著作表示して定義します 参考
      (21-22行) 地図データとしてオープンストリートマップの地図レイヤを著作表示して定義します
      (23-28行) 同心円群用にlayerGroupを定義し、中心点Clscenterより半径の異なる円群を記述します
      (29行目) 円形のマーカを定義して設置します
      (30-31行) 配列roadPtsをpolylineとしてmapobjに貼付け、
      (32-33行) 配列arealatlonsをpolygonとしてmapobjに貼付け、
      (34-58行) さらに雨雲レイヤを作成し、 参考
      (60-64行) 雨雲レイヤ(rainmap)をmapobjに貼付けて、
      (65-69行) まずベースレイヤ群(baseMaps)を作成し、
      (70-76行) オーバーレイヤ群をoverlayとして定義します
      (77行目) baseMapsとoverlayのレイヤ選択controlとを設置
      (81行目) ページを読み込んだらinit()を実行します
      (83行目) divタグのidを地図領域 'mapDiv'に設定

    5. ライン&マーカを追加する例 例を表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>マーカの追加・削除</title>
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css"/>
        <style>
          #mapDiv{position:absolute;top:5px;left:5px;right:5px;bottom:5px;}
        </style>
        <script>
          var mapobj; var pline;
          function init() {
            mapobj = L.map('mapDiv', { zoomControl: false });
            var mypoint = [35.192362,139.026346];  // 図中心: 箱根関所跡
            mapobj.setView(mypoint, 15);
            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>"    // 地理院タイルを使い、出典表示を記載
            }).addTo(mapobj);
            mapobj.on('click', onMapClick); // 地図のclickイベントでonMapClick関数を呼出す
            // plineをpolylineオブジェクトとし空座標を入れて地図に追加。bubblingMouseEvents属性をfalseに設定して、イベントがmapobjオブジェクトに連鎖するのを防ぐ
            pline = L.polyline([],{color:'blue',weight:5,bubblingMouseEvents:false}).addTo(mapobj);
            pline.on('click', onLineClick); // clickイベントでonLineClick関数を呼出す
          }; // init() -----------------------
          
          function onMapClick(e) {
            pline.addLatLng(e.latlng);      // plineにクリック地点の座標を追加
            var mk = L.marker(e.latlng).bindTooltip(e.latlng+"<br>クリックで削除可能").on('click',onMkClick).addTo(mapobj);
          }; // onMapClick(e) ----------------------- 
          
          function onLineClick(e) {         // plineのclickイベントで呼出し、
            pline.setLatLngs([]);           // plineに空座標を入れて非表示にする
          }; // onLineClick(e)  -----------------------
          
          function onMkClick(e) { 
            var dots = pline.getLatLngs();
            dots.pop();                  // クリックされたマーカ位置を位置配列から削除
            pline.setLatLngs(dots);      // 縮小された位置配列をplineデータに再設定
            mapobj.removeLayer(e.target);// クリックされたマーカを地図レイヤから削除
          }; // onMkClick(e)  -----------------------
        </script>
      </head>
      <body onload="init()">
        <header style="text-align:center;">クリック点にマーカ(クリックで消去)、ラインを追加</header>
        <div id="mapDiv"></div>
      </body>
      </html>
       【ライン&マーカを追加する例を表示
      ( 6,7行目)  Leafletを使うための cssとJavaScriptを読込み
      ( 9行目) 地図表示域 'mapDiv' のスタイルを設定
      (14行目) 'mapDiv' に表示する mapobj を L.mapオブジェクトに設定。zoomControl は不使用(false)
      (16行目) 地図変数 mapobj に setViewで地図中心の緯経度mypointとズームレベルを指定 参考
      (17行目) 地図データとして地理院タイルレイヤし、
      (18行目) それが地理院のタイルであることを表記して、
      (19行目) addToメソッドで地図変数mapobj に取込み
      (20行目) 地図のclickでonMapClick関数を呼出します
      (22行目) polyline plineを定義します
      (23行目) plineのclickでonLineClick関数を呼出します
      (26-29行) 動作時に plineの座標を追加し、onMkClick動作を有するマーカを追加する関数onMapClickを定義します
      (31-33行) plineを消去する関数onLineClickを定義します
      (34-40行) マーカクリックで該マーカを削除し、plineを短縮する関数onMkClickを定義します
      (43行目) ページを読み込んだらinit()を実行します
      (45行目) divタグのidを地図領域 'mapDiv'に設定

    6. JSON を読込んでマーカを追加する例 例を表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>JSON マーカの設置</title>
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css"/>
        <style>
          body { line-height:1.5em; }
          .page { width:1400px; height:95vh; margin: 0 auto; padding:5px; background:#efe; display:flex; }
            #main{ width:400px; margin-right:8px; }
              #drop { height:50px; margin:5px 35px; padding: 8px; border:3px #aaa dotted; }
              #disp { height:400px; margin:3px; padding:5px; border:1px #3d3 solid; overflow:auto; }
            #mapDiv{ flex:3; }
            #txt{ margin-top:8px; }
        </style>
      </head>
      <body onload="init()">
        <div class="page" >
          <section id="main">
              <h3> マーカー指定 json を読込む</h3>
              <div id="drop" ondragover="onDragOver(event)">
                  ここにマーカーファイル(<a href="datah.json">datah.json</a>) をドロップします。
              </div>
              <div id="disp" >ここにドロップしたファイルの内容を表示します。</div>
              <div id="txt">
                【 datah.json サンプル 】<br>
                { "marker":[ {"lat":35.204794,"lng":139.025357,"name":"箱根神社"}, {"lat":35.192362,"lng":139.026346,"name":"箱根関所跡"}, {"lat":35.182194,"lng":139.014074,"name":"箱根峠"} ] }
              </div>
          </section>
          <section id="mapDiv">ここに地図を表示</section>
        </div>
        
        <script>
          var mapobj; var myIcon2;
          if (window.File) {
                  //    window.alert("File APIが実装されてます。");
                      document.getElementById("drop").addEventListener("drop", onDrop, false);
          } else {
                      window.alert("本ブラウザではFile APIが使えません");
          }
              
              // Drop領域にドロップした際のファイルのプロパティ情報読み取り処理
          function onDrop(event){
             var files = event.dataTransfer.files;
             var disp = document.getElementById("disp");
             var encode_type = "utf-8";     // 'utf-8' 'shift-jis' ・・・・・
             disp.innerHTML ="";
             // 複数のファイルから1つずつファイルを選択
             for(var i=0; i< files.length; i++){
                var f = files[i];
                // ①FileReaderオブジェクトの生成
                var reader = new FileReader();
                // ②ファイルの種別を確認
                if( !f.type.match('application.json')  ){
                   alert("jsonファイル以外は表示できません。");
                   continue;
                }
                // ③エラー発生時の処理
                reader.onerror = function (evt) {
                    disp.innerHTML = "読み取り時にエラーが発生しました。";
                }
                // ファイル読取が完了した際に呼ばれる処理
                reader.onload = function (evt) {
                   // FileReaderが取得したテキストをそのままdivタグに出力
                      disp.innerHTML ="[ "+ f.name+" ]<br>"+reader.result;
                      let mks = JSON.parse( reader.result ).marker;
                      bound = L.latLngBounds( [ mks[0].lat, mks[0].lng ], [ mks[0].lat, mks[0].lng ] );
                      for ( let i = 0; i < mks.length; i++ ){  
                         L.marker([ mks[i].lat, mks[i].lng ],{title:mks[i].name }).on('click',onMkClick).addTo(mapobj);// マーカを追加
                         bound.extend( [ mks[i].lat, mks[i].lng ] ); //マーカー全体が入るボックスを広げる
                      }   
                      mapobj.fitBounds(bound); //マーカー全体が入るように地図範囲を設定する
                }
                // readAsTextメソッドでファイル内容の取得を実行
                reader.readAsText(f, encode_type);    // 'utf-8' 'shift-jis' ・・・・・
             }
             // ⑥ブラウザ上でファイルを展開する挙動を抑止
             event.preventDefault();
          }; // onDrop(event  -----------------------
      
          function onDragOver(event){ 
                 // ⑥ブラウザ上でファイルを展開する挙動を抑止
                 event.preventDefault(); 
          }; // onDragOver(event)  -----------------------
          
          function init(){ 
            var mypoint = [35.196262,139.026013];  // 図中心:恩賜公園 
            mapobj = L.map('mapDiv',{zoomControl:true}).setView(mypoint,14); //中心&ズーム値
            L.control.scale({imperial:false}).addTo(mapobj);  // スケール(mのみ)を追加
            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>"
            }).addTo(mapobj);
          }; // init()  -----------------------
      
          function onMkClick(e) { // クリックされたマーカを地図のレイヤから削除
            mapobj.removeLayer(e.target);
          }; // onMkClick(e)  --------------------
        </script>
        
      </body>
      </html>
       【JSON マーカを追加する例を表示
      ( 6,7行目)  Leafletを使う為、JavaScriptとcssを読込み
      (14行目) 地図表示域 'mapDiv' のスタイルを設定
      (22行目) マーカを指定する JSON ファイル(datah.json)をドロップするエリアを設定
      (25行目) ドロップしたJSON の内容をここに表示
      (31行目) divタグのidを地図領域 'mapDiv'に設定
      (36行目) File オブジェクトの利用確認をします
      (38行目) JSON がドロップされると、onDrop()を発火します
      (44行目) function onDrop()を定義します
      (50行目) 複数のファイルがドロップ可能なのでその対応をします
      (55行目) ファイルの種別を確認
      (60行目) エラー時の処理
      (64行目) ファイル読取後の処理
      (67行目) 読取後、JSON の merker 配列部分を取出し、設定
      (68行目) 地図表示領域拡大用に、bound を定義しておく
      (70行目) 取出した配列をマーカの位置と、title に入力します
      (76行目) ファイル内容の取得を実行
      (79行目) ブラウザ上のファイル展開を抑止
      (84行目) ドラッグ時のファイル展開を抑止
      (87行~) ロード時 L.mapを表示します
      (89行目) 'mapDiv' に表示する mapobj を L.mapオブジェクトに設定。zoomControl は不使用(false)
      (90行目) 地図 mapobj に mスケールを表示 参考
      (91行目) 地図データとして地理院タイルレイヤし、
      (92行目) それが地理院のタイルであることを表記して、
      (93行目) addToメソッドで地図変数mapobj に取込みます
      (96行目) マーカの clickで消去する関数 onMkClickを定義

    7. Leaflet に google mapも表示する例 例を表示
      <!DOCTYPE html>
      <html lang="ja">
      <head>
        <meta charset="utf-8">
        <title>GoogleMap も表示</title>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" >
        <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet-src.js"  integrity="sha512-I5Hd7FcJ9rZkH7uD01G3AjsuzFy3gqz7HIJvzFZGFt2mrCS4Piw9bYZvCgUE0aiJuiZFYIJIwpbNnDIM6ohTrg==" crossorigin=""></script>
      <!-- Google Maps API を利用 -->
         <script src="https://maps.googleapis.com/maps/api/js?key=【google API キー】" async defer></script>
         <script src="https://unpkg.com/leaflet.gridlayer.googlemutant@latest/dist/Leaflet.GoogleMutant.js"></script>
      <style>
          html, body, #mapDiv { width: 100%; height: 100%; padding: 0px; margin: 0px; }
      </style>
      </head>
      <body>
        <div id="mapDiv"></div>
              
        <script>
            mapobj = L.map('mapDiv', { zoomControl: true });
            mapobj.setView( [35.36063,138.72731],10 );  // 図中心 富士山
            L.control.scale({maxWidth:300,position:'topright',imperial:false}).addTo(mapobj);  // スケールを表示
            var gsiattr = "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>";
            var gsi = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { minZoom:5, attribution: gsiattr });
            var gsiphot = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg', { minZoom:5, attribution: gsiattr });
            var osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
                { minZoom:5, attribution: "©<a href='http://osm.org/copyright' target='_blank'>OpenStreetMap</a> contributors" });
            var GmapsHYB = L.gridLayer.googleMutant({ minZoom:5, type:'hybrid' });     // 航空写真&ラベル
            var GmapsTER  = L.gridLayer.googleMutant({ minZoom:5, type:'terrain' });    // 地形地図
            // オーバーレイ用のタイルレイヤ
            // opacityで透過度を設定、maxNativeZoom以上のズームレベルのタイルは、指定レベルのタイル画像を拡大表示
            var gsirelief = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png', { opacity: 0.4, maxNativeZoom: 15, minZoom:5, attribution: gsiattr });
            var gsirehillshademap = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/hillshademap/{z}/{x}/{y}.png', { opacity: 0.35, maxNativeZoom: 16, attribution: gsiattr });
            var baseMaps = {
              "地理院地図": gsi,
              "地理院写真": gsiphot,
              "O.S.Map": osm,
              'Google Hybrid':GmapsHYB,
              'Google Terrain':GmapsTER
            };
            var overlayMaps = {
              "色別標高図": gsirelief,
              "陰影起伏図": gsirehillshademap
            };
            L.control.layers(baseMaps,overlayMaps,{maxWidth:200,position:'topleft',imperial:false}).addTo(mapobj); 
            GmapsHYB.addTo(mapobj);  // 初期設定でgoogleHYBを表示
      </script>
      </body>
      </html>
       【google mapも表示する例
      (6,7行目)  Leafletを使う為、JavaScriptとcssを読込み
      ( 9行目) google mapも使う為、googleの【API キー】を書込む
      (10行目) Leaflet.GridLayer.GoogleMutantプラグインを読込む
      (12行目) 地図表示域 'mapDiv' のスタイルを設定
      (16行目) 地図表示域の idを 'mapDiv' としました
      (19行目) 表示地図を変数 mapobj で L.mapオブジェクトに設定
      (21行目) scaleの表示位置などを設定
      (23,24行) 地理院タイルと写真を指定
      (25行目) openstreetmapタイルを指定
      (27行目) google mapの写真を指定
      (28行目) google mapの地形地図を指定
      (31行目) オーバーレイ用の色別標高図を指定
      (32行目) オーバーレイ用の陰影起伏図を指定
      (33-39行) 基盤図のセレクタを設定
      (40-43行) オーバーレイ用のセレクタを設定
      (44行目) 基盤図のセレクタをセット
      (45行目) 初期設定でgoogleHYBを表示します

    8. 住所検索する例 例を表示
      <!DOCTYPE html>
      <html lang="ja">
        <head>
          <title>Leaflet Geocoder</title>
          <meta charset="utf-8">
          <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css">
          <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
          <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css">
          <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
      <style>
         html, body, #mapDiv { width: 100%; height: 100%; padding: 0px; margin: 0px; }
      </style>
      </head>
      <body>
        <div id="mapDiv"></div>
          <script>
            mapobj = L.map('mapDiv', { zoomControl: true });
            mapobj.setView( [35.36063,138.72731],11 );  // 図中心 富士山
            L.control.scale({maxWidth:300,position:'topright',imperial:false}).addTo(mapobj);  // スケールを表示
            var gsiattr = "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>";
            var gsi = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { minZoom:5, attribution: gsiattr });
            var gsiphot = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg', { minZoom:5, attribution: gsiattr });
            var osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
                { minZoom:5, attribution: "©<a href='http://osm.org/copyright' target='_blank'>OpenStreetMap</a> contributors" });
            var gsirelief = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png', { opacity: 0.4, maxNativeZoom: 15, minZoom:5, attribution: gsiattr });
            var gsirehillshademap = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/hillshademap/{z}/{x}/{y}.png', { opacity: 0.35, maxNativeZoom: 16, attribution: gsiattr });
            var baseMaps = {
              "地理院地図": gsi,
              "地理院写真": gsiphot,
              "O.S.Map": osm
            };
            var overlayMaps = {
              "色別標高図": gsirelief,
              "陰影起伏図": gsirehillshademap
            };
            L.control.layers(baseMaps,overlayMaps,{maxWidth:200,position:'topleft',imperial:false}).addTo(mapobj); 
            osm.addTo(mapobj);  // 初期設定で osm を表示
            L.Control.geocoder({ // 地点検索を行う
              geocoder: L.Control.Geocoder.nominatim()
            }).addTo(mapobj);
          </script>
        </body>
      </html>
       【住所検索する例
      (6,7行目)  Leafletを使う為、cssとJavaScriptを読込み
      (8,9行目)  Geocoderを使う為、cssとJavaScriptを読込み
      (11行目) 地図表示域 'mapDiv' のスタイルを設定
      (15行目) 地図表示域の idを 'mapDiv' としました
      (17行目) 表示地図を変数 mapobj で L.mapオブジェクトに設定
      (19行目) scaleの表示位置などを設定
      (20-24行) 各タイル(地理院、osm 地図等)とその変数を設定
      (25,26行) 各オーバーレイ(色別標高図等)とその変数を設定
      (27-31行) 各タイルのセレクタの表示名を設定
      (32-35行) オーバーレイのセレクタの表示名を設定
      (36行目) 基盤図、オーバーレイ、各コントローラをセット
      (37行目) 初期設定で osm を表示します
      (38-40行) 地点検索コントローラをセット

    9. 緯度経度を指定する例 例を表示
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>緯度・経度位置を表示</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css" />
        <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
        <script>
            var mapobj; var Pset = []; 
            function init() {
              mapobj = L.map('mapDiv', { zoomControl:true });
              mapobj.setView([35.360631,138.727307], 11);  //初期中心 富士山
              L.control.scale({maxWidth:200,position:'bottomleft',imperial:false}).addTo(mapobj);  // 右下にスケールを表示
              var gsiattr = "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>";
              var gsi = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { attribution: gsiattr });
              var gsiphot = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg', { attribution: gsiattr });
              var osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
                { attribution: "<a href='http://osm.org/copyright' target='_blank'>OpenStreetMap</a> contributors" });
              var baseMaps = {
                "地理院地図": gsi,
                "地理院写真": gsiphot,
                "O.S.Map": osm
              };
              L.control.layers(baseMaps).addTo(mapobj);
              osm.addTo(mapobj);
            }; // init()  ==============
            
            function set(){  // 中心位置変更
              var input = document.getElementById('latlng').value;
              var latlngStr = input.split(',', 2);
              var zm = document.getElementById('zom').value; 
              zm = parseInt (zm);
              let Pset = new L.LatLng( parseFloat(latlngStr[0]),parseFloat(latlngStr[1]) );
              mapobj.setView(Pset, zm); // 中心位置変更
              marker= L.marker(Pset).bindTooltip( latlngStr+"").addTo(mapobj); // 中心にマーカー
            }; // set() =============
            
        </script>
        <style>
           html, body{ height:100%; margin:0; padding:0; }
           #mapDiv {position:absolute;top:64px;left:3px;right:3px;bottom:3px;}
            section{ width:98%; margin: 0 auto; text-align:center; padding: 5px; }
            article{ font-size:20px; }
            #link{ position:absolute; top:8px; left:10px; }
            #latlng { width:220px; }
            #zom { width:30px; }
        </style>
      </head>
      <body onload="init()" background="../img/p_bcg007.gif">
          <div id="link"><a href="../ex-opn.html">leaflet地図</a></div>
          <section>
            <article>緯度,経度を入力して地図を表示</article>
            <div>
              北緯,東経:<input id="latlng" type="text" value="35.68,139.76">  
              Zoom:<input id="zom" type="textbox" value="13" size=2> 
              <input id="submit" type="button" value="セット" onclick="set()">
            </div>
          </section>
          <div id="mapDiv">ここに地図を表示</div>
      </body>
      </html>
       【緯度経度を指定する例
      (7,8行目)  Leafletを使う為、cssとJavaScriptを読込み
      (12行目) 表示地図を変数 mapobj で L.mapオブジェクトに設定
      (13行目) 初期地図で富士山を表示
      (14行目) scaleの表示位置などを設定
      (15-24行) 各タイル(地理院、osm 地図等)とその変数を設定
      (25-26行) 初期設定で osm 地図を表示します
      (29-37行) 中心位置変更のための function を記述
      (35行目) 変更中心位置をセット
      (36行目) その中心位置に Tooltip 付きマーカーをセット
      (40-48行) 各スタイルを設定
      (55-57行) 中心位置変更のための入力要素を記述
      (60行目) 地図表示域の idを 'mapDiv' としました

  3. 関連サイト
    1. reference  使い方  Leaflet 使い方  Leaflet入門  リファレンス  Leaflet 1.8  地図を表示  逆引き  API リファレンス
    2. Plugins  おすすめ  プラグイン  プラグインまとめ  Web地図  距離計測系  色マーカ
    3. Overlay表示  雨雲レーダ  GoogleMapに雨雲  天気を表示  雲等を表示  Windy.com  地理院タイル  MapFan API
    4. removeLayer  あれこれ描く  Leaflet Drawプラグイン  サンプル
    5. CRS  地図以外の画像  平面図
    6. OSRMで経路探索  住所検索  古地図  マーカークラスター
    7. 地図タイルの仕組み  タイル地図入門  地理院タイル  QGISマニュアル  Leafletの使い方  地図タイル
    8. Bing Maps   チュートリアル  Bing Mapsを使う  サンプルコード