晴歩雨描

晴れた日は外に出て歩き、雨の日は部屋で絵を描く

神戸)再度公園、学習の森。センダイムシクイ、シジュウカラ、ヤマガラ、エナガ、ホオジロ、カワラヒワ。

5月4日。水源池前バス停→鍋蓋北谷→再度公園→仙人谷→洞川湖→学習の森→洞川湖→牛の背→神戸電鉄鈴蘭台駅。8.3km、4時間。

野鳥、センダイムシクイシジュウカラヤマガラエナガホオジロカワラヒワ

f:id:art2nd:20210504170125j:plain

f:id:art2nd:20210504170738j:plain

f:id:art2nd:20210504170742j:plain

f:id:art2nd:20210504170745j:plain

f:id:art2nd:20210504170748j:plain

f:id:art2nd:20210504170752j:plain

f:id:art2nd:20210504170755j:plain

f:id:art2nd:20210504170759j:plain

f:id:art2nd:20210504170802j:plain

f:id:art2nd:20210504170806j:plain

f:id:art2nd:20210504170810j:plain

f:id:art2nd:20210504170849j:plain

センダイムシクイ

f:id:art2nd:20210504170903j:plain

シジュウカラ

f:id:art2nd:20210504170921j:plain

ヤマガラ

f:id:art2nd:20210504170935j:plain

エナガ

f:id:art2nd:20210504170953j:plain

ホオジロ

f:id:art2nd:20210504171009j:plain

カワラヒワ

兵庫県)北雲雀きずきの森。センダイムシクイ、キジバト、マガモ。

5月3日。北雲雀きずきの森。能勢電鉄滝山駅→北雲雀きずきの森→阪急宝塚線川西能勢口駅。7km、3時間20分。

野鳥は、センダイムシクイキジバトマガモしか撮影できなかった。緑が生い茂って、野鳥撮影は難しい季節に入った。

f:id:art2nd:20210503161341j:plain

f:id:art2nd:20210503161432j:plain

f:id:art2nd:20210503161436j:plain

f:id:art2nd:20210503161440j:plain

f:id:art2nd:20210503161443j:plain

f:id:art2nd:20210503161448j:plain

f:id:art2nd:20210503161453j:plain

f:id:art2nd:20210503161504j:plain

f:id:art2nd:20210503161704j:plain

センダイムシクイ

f:id:art2nd:20210503161715j:plain

センダイムシクイ

f:id:art2nd:20210503161727j:plain

半眼のキジバト

f:id:art2nd:20210503161742j:plain

マガモ

灘五郷、京都伏見、兵庫播磨、広島西条の酒蔵マップ、甲州ワイナリーマップをLeafletで作成。Google マップ、OpenStreetMap、国土地理院、Esri World Topo Map。

過去に、灘五郷、京都伏見、兵庫播磨、広島西条の酒蔵マップ、甲州ワイナリーマップを、「Googleマイマップ」、「Google Maps API」、「Yahoo! マップAPI」で作成した。「Google Maps API」、「Yahoo! マップAPI」版はすでに使用できなくなっている。

今回、「灘五郷酒蔵マップ」「京都伏見酒蔵マップ」「兵庫播磨酒蔵マップ」「広島西条酒蔵マップ」「甲州ワイナリーマップ」を「Leaflet」を使った地図ページを作成した。

それぞれ、「Google マップ」「OpenStreetMap」「国土地理院」「Esri World Topo Map」地図を切り替えて表示できる。現在地表示機能も付けた。

【灘五郷】 西郷・御影郷・魚崎郷・西宮郷今津郷

https://ok2nd.github.io//leaflet/nada-gogou.html

f:id:art2nd:20210502114706j:plain

京都伏見:酒蔵マップ

https://ok2nd.github.io//leaflet/kyoto-fushimi.html

f:id:art2nd:20210502114717j:plain

兵庫播磨:酒蔵マップ

https://ok2nd.github.io//leaflet/hyogo-harima.html

f:id:art2nd:20210502114728j:plain

広島西条:酒蔵マップ

https://ok2nd.github.io//leaflet/hiroshima-saijo.html

f:id:art2nd:20210502114737j:plain

山梨:甲州ワイナリーマップ

https://ok2nd.github.io//leaflet/yamanashi-wine.html

f:id:art2nd:20210502114747j:plain

作成した地図の一覧。(↓)

Leaflet地図:現在地表示ボタン追加。位置情報継続的更新。サンプルソース。

地図データを扱うJavaScript ライブラリ「Leaflet」を使って、地図表示を試してきた。

Leaflet」を使って、「Google マップ」「OpenStreetMap」「国土地理院」「Esri World Topo Map」などの地図を表示できる。

今回、「Leaflet」を使った地図に「現在地表示ボタン」を追加した。

ボタンメニュー追加は以下のサイトを参考にした。

現在地表示は以下のサイトを参考にした。

ボタンのアイコンには、「Font Awesomeアイコン」を使った。

【画面イメージ】

現在地表示」、「マーカーすべて表示に戻る」ボタン追加。

f:id:art2nd:20210501094158j:plain

現在地表示」ボタンクリックで現在地を中心にした地図表示に移動する。地図中央にマーカーを表示する。位置情報は継続的に更新する。現在地表示」ボタンを再度クリックすると、現在地表示機能がオフになる。「マーカーすべて表示に戻る」ボタンでも、現在地表示機能がオフになる。

f:id:art2nd:20210501094202j:plain

サンプル >>> https://ok2nd.github.io/leaflet/tokyo-06.html

サンプルソース

今回追加した部分を赤色表示している。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>東京タワー(6):Leaflet(Google Map,OpenStreetMap,国土地理院,Esri World Topo Map)</title>
<link rel="stylesheet" href="//unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
<script src="//unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<!-- Font Awesome アイコン -->
<link rel="stylesheet" href="//use.fontawesome.com/releases/v5.6.3/css/all.css"/>
<!-- メニューボタン(現在地表示、マーカーすべて表示) -->
<link rel="stylesheet" href="css/easy-button.css"/>
<script src="js/easy-button.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; right:0; left:0; }
.divicon {	/* 文字ラベル */
	display: table-cell;
	color: #f00;
	background-color: #ff4;
	opacity: 0.7;
	white-space: nowrap;
	font-size: 12px;
	font-weight: bold;
}
</style>
</head>
<body>
<div class="container"><div id="map"></div></div>
<script>
var map = L.map('map');
var tileLayer = L.tileLayer('https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}', {
	attribution: "<a href='https://developers.google.com/maps/documentation' target='_blank'>Google Map</a>"
});
tileLayer.addTo(map);
// ---------------------------
var place = [
	{
		'name': '東京タワー',
		'lat': '35.6585753263022',
		'lng': '139.7454324609718'
	},{
		'name': '増上寺',
		'lat': '35.65737629074171',
		'lng': '139.7482751425744'
	},{
		'name': '芝公園',
		'lat': '35.65548717662271',
		'lng': '139.74843437145282'
	},{
		'name': '赤羽橋駅',
		'lat': '35.65496610534149',
		'lng': '139.74394970889855'
	},{
		'name': '神谷町駅',
		'lat': '35.66307981284523',
		'lng': '139.7451975472575'
	}
]
// ---------------------------
var myIcon = L.icon({	/* アイコン */
	iconUrl: 'icon/marker-small.png',
	iconRetinaUrl: 'icon/marker-small.png',
	iconSize: [16, 27],
	iconAnchor: [7, 27],
	popupAnchor: [1, -22],
});
iconMarkers = L.featureGroup();		// 全マーカーを画面内に収めるため
for (var i = 0; i < place.length; i++) {
	// 文字ラベルを表示
	var divIcon = L.divIcon({
		html: '<div class="divicon">' + place[i].name + '</div>',
		iconSize: [0,0]
	});
	iconMarkers.addLayer( L.marker([place[i].lat, place[i].lng], {icon: myIcon}).addTo(map).bindPopup(place[i].name) );
	L.marker([place[i].lat, place[i].lng], {icon: divIcon}).addTo(map);
}
map.fitBounds(iconMarkers.getBounds());	// 全マーカーを画面内に収める
var Basic_Map = new Array();
Basic_Map[ 0 ] = L.tileLayer('https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}', {
	attribution: "<a href='https://developers.google.com/maps/documentation' target='_blank'>Google Map</a>"
});
Basic_Map[ 1 ] = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
	attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
	continuousWorld: false
});
Basic_Map[ 2 ] = 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>"
});
Basic_Map[ 3 ] = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg', {
	attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>"
});
Basic_Map[ 4 ] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
	attribution: 'Tiles © <a href="http://www.esrij.com/"> Esri Japan </a>'
});
var baseMap = {
	"Google マップ": Basic_Map[ 0 ],
	"OpenStreetMap": Basic_Map[ 1 ],
	"国土地理院 標準地図": Basic_Map[ 2 ],
	"国土地理院 写真": Basic_Map[ 3 ],
	"Esri World Topo Map": Basic_Map[ 4 ]
};
L.control.layers(baseMap).addTo(map);
// 現在地表示ボタン
var watch_id = 0;
var curMarker = null;	// 現在地マーカー
var currentWatchBtn = null;
L.easyButton({		// 現在地表示ボタン
	states: [{
		stateName: 'current-watch',
		icon:	'fas fa-map-marker-alt',
		title:	 '現在地',
		onClick: function(btn, map) {
			currentWatch();
			btn.state('current-watch-reset');
			currentWatchBtn = btn;
		}
	}, {
		stateName: 'current-watch-reset',
		icon:	'fa fa-user',
		title:	 '現在地オフ',
		onClick: function(btn, map) {
			currentWatchReset();
			btn.state('current-watch');
		}
	}]
}).addTo( map );
// マーカーすべて表示画面に戻るボタン
L.easyButton('fa fa-reply-all', function(btn, easyMap) {
	currentWatchReset();
	if (currentWatchBtn) {
		currentWatchBtn.state('current-watch');
		currentWatchBtn = null;
	}
	map.fitBounds(iconMarkers.getBounds());	// 全マーカー画面に戻る
}).addTo(map);
// クリックした地点の緯度・経度、標高を表示
map.on('click', onMapClick);
var clickMarker = null;
function onMapClick(e) {
	if (clickMarker) {
		map.removeLayer(clickMarker);
	}
	var lat = e.latlng.lat;
	var lng = e.latlng.lng;
	// 地理院地図サーバから標高を求める
	// http://maps.gsi.go.jp/development/elevation_s.html
	var src = 'https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=' + lng + '&lat=' + lat;
	fetch(src)
	.then((response) => {
		return response.text();
	})
	.then((text) => {
		var results = JSON.parse(text);
		var popStr = '緯度:' + lat + '<br>経度:' + lng + '<br>標高:' + results.elevation + 'm';
		clickMarker = L.marker(e.latlng).on('click', onMarkerClick).addTo(map).bindPopup(popStr).openPopup();
	})
	req.open("GET", src, false);
	req.send(null)
}
function onMarkerClick(e) {
	map.removeLayer(clickMarker);
}
function currentWatch() {
	function success(pos) {
		var lat = pos.coords.latitude;
		var lng = pos.coords.longitude;
		map.setView([ lat,lng ]);
		// 現在地に表示するマーカー
		if (curMarker) {
			map.removeLayer(curMarker);
		}
		var curIcon = L.icon({	/* アイコン */
			iconUrl: 'icon/hiking.png',
			iconRetinaUrl: 'icon/hiking.png',
			iconAnchor: [15, 34]
		});
		curMarker = L.marker([lat, lng], {icon: curIcon}).addTo(map);
	}
	function error(err) {
		alert('位置情報を取得できませんでした。');
	}
	var options = {
		enableHighAccuracy: true,
		timeout: 5000,
		maximumAge: 0
	};
	if (watch_id == 0) {
		watch_id = navigator.geolocation.watchPosition(success, error, options); // 現在地情報を定期的に
	}
}
function currentWatchReset() {
	if (watch_id > 0) {
		navigator.geolocation.clearWatch(watch_id);
		watch_id = 0;
	}
	if (curMarker) {
		map.removeLayer(curMarker);
		curMarker = null;
	}
}
</script>
</body>
</html>

Leaflet地図:クリックした地点の緯度・経度、標高を表示。サンプルソース。

昨日から「Leaflet」を使って「Google マップ」「OpenStreetMap」「国土地理院」「Esri World Topo Map」の地図表示を試している。

この地図に以下の機能を追加。

  1. 地図上の任意の地点をクリックしてマーカー表示
  2. 地点をクリックし直したら、先のマーカーは削除
  3. マーカーにポップアップを表示
  4. ポップアップにクリックした地点の緯度・経度を表示
  5. ポップアップにクリックした地点の標高を表示

f:id:art2nd:20210429143245j:plain

緯度経度は、国土地理院のサーバーから取得する。

JavaScriptに以下のコードを追加。

・・・・・
map.on('click', onMapClick);
var clickMarker = null;
function onMapClick(e) {
	if (clickMarker) {
		map.removeLayer(clickMarker);
	}
	var lat = e.latlng.lat;
	var lng = e.latlng.lng;
	// 地理院地図サーバから標高を求める
	// http://maps.gsi.go.jp/development/elevation_s.html
	var src = 'https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=' + lng + '&lat=' + lat ;
	var req = new XMLHttpRequest();
	req.onreadystatechange = function() {
		if(req.readyState == 4 && req.status == 200) {
			var json = req.responseText;
			var results = JSON.parse(json);
			var popStr = '緯度:' + lat + '<br>経度:' + lng + '<br>標高:' + results.elevation + 'm';
			clickMarker = L.marker(e.latlng).on('click', onMarkerClick).addTo(map).bindPopup(popStr).openPopup();
		}
	};
	req.open("GET", src, false);
	req.send(null)
}
function onMarkerClick(e) {
	map.removeLayer(clickMarker);
}

【後日追記】

XMLHttpRequest()が非推奨なのでFetch APIに変更。

・・・・・
map.on('click', onMapClick);
var clickMarker = null;
function onMapClick(e) {
	if (clickMarker) {
		map.removeLayer(clickMarker);
	}
	var lat = e.latlng.lat;
	var lng = e.latlng.lng;
	// 地理院地図サーバから標高を求める
	// http://maps.gsi.go.jp/development/elevation_s.html
	var src = 'https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=' + lng + '&lat=' + lat;
	fetch(src)
	.then((response) => {
		return response.text();
	})
	.then((text) => {
		var results = JSON.parse(text);
		var popStr = '緯度:' + lat + '<br>経度:' + lng + '<br>標高:' + results.elevation + 'm';
		clickMarker = L.marker(e.latlng).on('click', onMarkerClick).addTo(map).bindPopup(popStr).openPopup();
	})
}
function onMarkerClick(e) {
	map.removeLayer(clickMarker);
}

f:id:art2nd:20210429141857j:plain

サンプル >>> https://ok2nd.github.io/leaflet/fujisan-05.html