0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

leaflet + leaflet-kmlで表示されるpopupに緯度経度座標を表示させる

Last updated at Posted at 2023-10-28

Leafletを使った地図アプリを作る上で試行錯誤したことをメモとして書いています。その機能あるよなど、なにかあればぜひコメントください。

概要

やりたいこと

  • leafletで表示中の地図に、KMLファイルの内容を表示したい。
  • KMLファイルで表示した各要素をカスタマイズしたい。まずはポップアップの内容を編集したい。

結論

  • leaflet-kmlの中に使われている関数を一部コピーして、カスタマイズ、leaflet-kmlを上書きする。

使用するもの

0,KMLファイルを作成する

スタートゴールの2つのマーカーを立てたものを作りました。

Google Mymap Google MymapからKMLファイルを書き出し
スクリーンショット 2023-10-28 9.26.17.png スクリーンショット 2023-10-28 9.26.33.png

sample.kmlが完成。

1,KMLを表示する

単純にKMLファイルを読み込んで表示する

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Leaflet KML Example</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Leaflet CSS -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />

    <!-- Leaflet JavaScript -->
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>

    <!-- Leaflet-KML Plugin -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-plugins/3.4.0/layer/vector/KML.js"></script>
</head>
<body>
    <div id="map" style="height: 400px;"></div>

    <script>
        // Create a Leaflet map
        var map = L.map('map').setView([0, 0], 2); // Set the initial map center and zoom level.

        // Add a base layer (e.g., OpenStreetMap)
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
        }).addTo(map);

        // Load and display a KML file on the map
        var kmlURL = 'sample.kml';
        var kmlLayer = new L.KML(kmlURL, {
            async: true,
        }).addTo(map);
    </script>
</body>
</html>

表示したもの。

スクリーンショット 2023-10-28 9.27.27.png

2,ポップアップをカスタマイズ

マーカーをクリックした際に表示するポップアップに緯度経度座標を表示させます。

as-is to-be
スクリーンショット 2023-10-28 9.27.27のコピー.png スクリーンショット 2023-10-28 9.27.27.png

ポップアップを表示している関数(parsePlacemark)をコピー

Leaflet-KML Pluginのファイル、KML.jsの中でbindPopupを検索。出てきた箇所を含む関数parsePlacemarkをごっそりコピー、自分で作ったindex.htmlLeaflet-KML Pluginを読み込んだ直後に貼り付ける。

貼り付けの際、parsePlacemark:functionの部分をL.KML.parsePlacemark=functionに書き換える。

index.htmlの一部分を抜粋
// ↓こうなっていたものを
parsePlacemark:function (place, xml, style, options) { ...

// ↓ こうする
L.KML.parsePlacemark = function (place, xml, style, options) { ...

layer.bindPopupをカスタマイズ

layer.bindPopupの周辺にてGPS座標を取得、また、それらを表示するようにする。

index.htmlの一部を抜粋
var pointLatLang = layer.getLatLng(); // 追記: レイヤーから緯度経度座標を取得
var pointlatLngStr = "GPS: " + pointLatLang.lat + ", " + pointLatLang.lng; // 追記: 表示用の文字列にする

if (name) {
  layer.on('add', function () {
     layer.bindPopup('<h2>' + name + '</h2>' + descr + "<br>" + pointlatLngStr);// 編集: 表示用の文字列を文字列をポップアップに追記する
     });
}

最終形

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Leaflet KML Example</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Leaflet CSS -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />

    <!-- Leaflet JavaScript -->
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>

    <!-- Leaflet-KML Plugin -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-plugins/3.4.0/layer/vector/KML.js"></script>
    <script>
        L.KML.parsePlacemark = function (place, xml, style, options) {
		var h, i, j, k, el, il, opts = options || {};

		el = place.getElementsByTagName('styleUrl');
		for (i = 0; i < el.length; i++) {
			var url = el[i].childNodes[0].nodeValue;
			for (var a in style[url]) {
				opts[a] = style[url][a];
			}
		}
		
		il = place.getElementsByTagName('Style')[0];
		if (il) {
			var inlineStyle = this.parseStyle(place);
			if (inlineStyle) {
				for (k in inlineStyle) {
					opts[k] = inlineStyle[k];
				}
			}
		}

		var multi = ['MultiGeometry', 'MultiTrack', 'gx:MultiTrack'];
		for (h in multi) {
			el = place.getElementsByTagName(multi[h]);
			for (i = 0; i < el.length; i++) {
				return this.parsePlacemark(el[i], xml, style, opts);
			}
		}
		
		var layers = [];

		var parse = ['LineString', 'Polygon', 'Point', 'Track', 'gx:Track'];
		for (j in parse) {
			var tag = parse[j];
			el = place.getElementsByTagName(tag);
			for (i = 0; i < el.length; i++) {
				var l = this['parse' + tag.replace(/gx:/, '')](el[i], xml, opts);
				if (l) { layers.push(l); }
			}
		}

		if (!layers.length) {
			return;
		}
		var layer = layers[0];
		if (layers.length > 1) {
			layer = new L.FeatureGroup(layers);
		}

		var name, descr = '';
		el = place.getElementsByTagName('name');
		if (el.length && el[0].childNodes.length) {
			name = el[0].childNodes[0].nodeValue;
		}
		el = place.getElementsByTagName('description');
		for (i = 0; i < el.length; i++) {
			for (j = 0; j < el[i].childNodes.length; j++) {
				descr = descr + el[i].childNodes[j].nodeValue;
			}
		}

        var pointLatLang = layer.getLatLng();
        var pointlatLngStr = "GPS: " + pointLatLang.lat + ", " + pointLatLang.lng;

		if (name) {
			layer.on('add', function () {
				layer.bindPopup('<h2>' + name + '</h2>' + descr + "<br>" + pointlatLngStr);
			});
		}

		return layer;
	}
    </script>
</head>
<body>
    <div id="map" style="height: 400px;"></div>
    <script>
        // Create a Leaflet map
        var map = L.map('map').setView([0, 0], 2); // Set the initial map center and zoom level.

        // Add a base layer (e.g., OpenStreetMap)
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
        }).addTo(map);

        // Load and display a KML file on the map
        var kmlURL = 'sample.kml'; // Replace with the path to your KML file
        var kmlLayer = new L.KML(kmlURL, {
            async: true,
        }).addTo(map);
    </script>
</body>
</html>

スクリーンショット
スクリーンショット 2023-10-28 10.18.55.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?