晴歩雨描

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

Leaflet地図:「Jawg Maps」世界地図に国旗表示(1)。逆ジオコーディング「Reverse - Nominatim」使用。

先日、「Leaflet」+「Jawg Maps」を使った世界地図を作成した。

この世界地図に、国旗表示機能を追加。

緯度経度から国名検索には、「Reverse - Nominatim」の逆ジオコーディングAPIサービスを利用。

【例1】以下にように緯度経度を渡すと、

https://nominatim.openstreetmap.org/reverse?lat=34.6895&lon=135.1957

以下のようなXMLで結果が返ってくる。住所は日本語で表示される。ただ、郵便番号が間違っているなど一部信用できない。<country_code>に国コードが入ってくる。

<?xml version="1.0" encoding="UTF-8" ?>
<reversegeocode .......>
<result ......>.......</result>
<addressparts>
	<amenity>神戸市役所</amenity>
	<road>新神戸停車場線</road>
	<neighbourhood>加納町六丁目</neighbourhood>
	<suburb>中央区</suburb>
	<city>神戸市</city>
	<province>兵庫県</province>
	<postcode>650-8570</postcode>
	<country>日本</country>
	<country_code>jp</country_code>
</addressparts>
</reversegeocode>け

引数に「format=json」を追加することで、結果をJSONで返すことも可能。

https://nominatim.openstreetmap.org/reverse?lat=34.6895&lon=135.1957&format=json
{"place_id":282887460,"licence":"Data c OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":3976913,"lat":"34.68989445","lon":"135.19558801860242","display_name":"神戸市役所, 新神戸停車場線, 加納町六丁目, 中央区, 神戸市, 兵庫県, 650-8570, 日本","address":{"amenity":"神戸市役所","road":"新神戸停車場線","neighbourhood":"加納町六丁目","suburb":"中央区","city":"神戸市","province":"兵庫県","postcode":"650-8570","country":"日本","country_code":"jp"},"boundingbox":["34.6891129","34.6906589","135.1944132","135.196219"]}

【例2】日本以外の国でも国名などは日本語で返ってくる。

https://nominatim.openstreetmap.org/reverse?lat=50.4345&lon=30.5574
<addressparts>
	<amenity>キエフ・ペチェールシク大修道院</amenity>
	<road>Naberezhne Road</road>
	<neighbourhood>Берестове</neighbourhood>
	<borough>Pecherskyi district</borough>
	<city>キーウ</city>
	<postcode>01015</postcode>
	<country>ウクライナ</country>
	<country_code>ua</country_code>
	</addressparts>
</reversegeocode>

国旗アイコンは、「ASTI アマノ技研」 の「National Flags of the World(v1.0.1)」を使用。コソボのアイコン名は「xk.png」に変更。

作成した地図が以下。

マウスでクリックした場所の住所表示と合わせて、国旗をマーカーで表示する。

クリミア半島は、ウクライナのまま。

台湾は、国コードTWで台湾の国旗が表示される。

コソボは、国コードXKで国旗が表示される。

パレスチナ自治区(国コードPS)の国旗はWikipediaのものを縮小して使用。

サンプルソース

JSONを使用。

map.on('click', onMapClick);
var posMarker = null;
function onMapClick(e) {
	posMarkerRemove();
	var lat = e.latlng.lat;
	var lng = e.latlng.lng;
	if (lng > 180) {
		lng -= 360;	// 補正
	}
	// 緯度経度から国名検索:逆ジオコーディング「Reverse - Nominatim」使用
	var src = 'https://nominatim.openstreetmap.org/reverse?format=json&lat=' + lat + '&lon=' + lng;
	fetch(src)
	.then((response) => {
		return response.text();
	})
	.then((text) => {
		var results = JSON.parse(text);
		var worldFlags = L.icon({
			iconUrl: 'worldflags/80px/' + results.address.country_code + '.png', 
			iconSize: [80, 80],
			iconAnchor: [40, 48],
			popupAnchor: [0, -40],
		});
		var popStr = '<span class="country_code">' + results.address.country_code.toUpperCase() + '</span> ';
		popStr += '<span class="country">' + results.address.country + '</span><br>';
		popStr += '<span class="display_name">' + results.display_name + '</span><br>';
		popStr += '<span class="lat_lng">緯度:' + (Math.round(lat * 10000) / 10000) + ' 経度:' + (Math.round(lng * 10000) / 10000) + '</span>';
		posMarker = L.marker(e.latlng, { icon: worldFlags }).on('click', posMarkerRemove).addTo(map).bindPopup(popStr).openPopup();
	})
}
function posMarkerRemove() {
	if (posMarker) {
		map.removeLayer(posMarker);
		posMarker = null;
	}
}