noteMap ルートを辿るマップ作り⑰-1 地点情報・ルート・マーカー
はじめに
ルートを辿る機能をやっと実現できました。
この機能は以下の要素にわけることができます。
地点一覧表示
マーカー表示
ルート表示
ルート修正
データ保存
データ読込・再現
今回は「地点一覧表示」「マーカー表示」「ルート表示」を解説します。
地点一覧の作成と表示
地点一覧は地図をクリックしたときのその場所の情報です(下図の赤枠)。
具体的にはその場所の経緯度と場所の名前です。
赤枠部分のhtmlは次のコードです。
地点情報(経緯度と名称)のhtmlをJavascriptのaddInputBlock関数で生成して、<div id="input-container"></div>の間に挿入する仕組みです。
<div id="input-container">
</div>
<button type="button" onclick="removeLastPoint()">最後の地点削除</button>
<input type="submit" class="btn btn-primary btn-sm" style="text-align: center;" value="保存して終了">
生成された4個の地点情報は以下です。
<div class="input-block">
<label style="width: 20px;">A</label>
<input type="text" name="lat_1" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<input type="text" name="lng_1" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<br>
<input type="text" name="comment_1" placeholder="当地点のコメント" spellcheck="false" data-ms-editor="true" style="width: 240px;">
</div>
<div class="input-block">
<label style="width: 20px;">B</label>
<input type="text" name="lat_2" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<input type="text" name="lng_2" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<br>
<input type="text" name="comment_2" placeholder="当地点のコメント" spellcheck="false" data-ms-editor="true" style="width: 240px;">
</div>
<div class="input-block">
<label style="width: 20px;">C</label>
<input type="text" name="lat_3" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<input type="text" name="lng_3" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<br>
<input type="text" name="comment_3" placeholder="当地点のコメント" spellcheck="false" data-ms-editor="true" style="width: 240px;">
</div>
<div class="input-block">
<label style="width: 20px;">D</label>
<input type="text" name="lat_4" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<input type="text" name="lng_4" spellcheck="false" data-ms-editor="true" style="width: 105px;">
<br>
<input type="text" name="comment_4" placeholder="当地点のコメント" spellcheck="false" data-ms-editor="true" style="width: 240px;">
</div>
赤枠部分のhtmlは以下のJavaScriptのaddInputBlock関数で作成されます。
function addInputBlock(latLng, comment = '') {
counter++;
if (counter > 1) document.getElementById("mapType").value = "3";
document.getElementById("content").style.display = "block";
const container = document.getElementById('input-container');
const inputBlock = document.createElement('div');
inputBlock.className = 'input-block';
const label = document.createElement('label');
label.textContent = String.fromCharCode(65 + (counter - 1));
label.style.width = '20px';
inputBlock.appendChild(label);
const latInput = document.createElement('input');
latInput.type = 'text';
latInput.name = 'lat_' + counter;
latInput.style.width = '105px';
latInput.value = latLng.lat();
inputBlock.appendChild(latInput);
const lngInput = document.createElement('input');
lngInput.type = 'text';
lngInput.name = 'lng_' + counter;
lngInput.style.width = '105px';
lngInput.value = latLng.lng();
inputBlock.appendChild(lngInput);
inputBlock.appendChild(document.createElement('br'));
const commentInput = document.createElement('input');
commentInput.type = 'text';
commentInput.name = 'comment_' + counter;
commentInput.style.width = '240px';
commentInput.placeholder = '当地点のコメント';
commentInput.value = comment;
inputBlock.appendChild(commentInput);
container.appendChild(inputBlock);
map.panTo(latLng);
const geocoder = new google.maps.Geocoder();
geocoder.geocode( {'location': latLng}, function(results, status){
if (status === 'OK' && results[0]){
var address = results[0].formatted_address.replace('日本、','');
const result = splitAddress(address);
if (result) {
const postcode = result.postalCode;
document.getElementById('postcode').value = postcode;
document.getElementById('address').value = result.address;
}
} else {
alert("住所から位置の取得ができませんでした。: " + status);
return;
}
});
};
このJavaScriptのaddInputBlock関数は以下のコードで呼び出されます。
function initMap() {
lat = 緯度の設定
lng = 経度の設定
map = new google.maps.Map(document.getElementById("map"), {
zoom: 14,
center: { lat: lat, lng: lng },
scaleControl: true,
});
// クリックした場所の情報を取得して保存する
map.addListener("click", function(e) {
addInputBlock(e.latLng);
clickedPoints.push({ lat: e.latLng.lat(), lng: e.latLng.lng() });
if (clickedPoints.length > 1) {
drawRoute();
}
});
directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
}
ルート表示
ルートの描画を行うdrawRouteは以下のコードです。
地点情報が2か所以上の場合に呼び出され、地点と地点を結びます。
このコードでは、directionsService.routeメソッドを使用して、クリックされたポイント(clickedPoints)を通るルートを描画しています。
requestオブジェクトには、出発地(origin)、目的地(destination)、および通過地点(waypoints)が含まれ、travelModeはDRIVINGとして設定されています。
// ルートを描く処理
function drawRoute() {
const waypoints = clickedPoints.slice(1, -1).map(point => ({ location: point, stopover: true }));
const origin = clickedPoints[0];
const destination = clickedPoints[clickedPoints.length - 1];
const request = {
origin: origin,
destination: destination,
waypoints: waypoints,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, (result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(result);
} else {
console.log('ルート描画に失敗しました: ' + status);
}
});
}
以下により、directionsServiceとdirectionsRendererが初期化され、地図上にルートが表示されます。
directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
マーカーの表示
下記のコードでGoogleマップ上にマーカーを表示しています。
特に以下の部分がマーカーの生成に関連しています:
new google.maps.Marker({...}): ここでマーカーが作成されます。
marker.setMap(map): ここでマーカーが地図に追加されます。
icon: これにより、マーカーのアイコンが指定されます。
let markers = [];
searchBox.addListener("places_changed", () => {
const places = searchBox.getPlaces();
if (places.length == 0) { return; }
markers.forEach((marker) => { marker.setMap(null); });
markers = [];
const bounds = new google.maps.LatLngBounds();
places.forEach((place) => {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
const icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25),
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map,
icon,
title: place.name,
position: place.geometry.location,
}));
if (place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
終わりに
処理方式について、今回は地点一覧とルート表示を説明しました。
次回以降、以下の残りを悦明します。
ルート修正
データ保存
データ読込・再現
また、他の地図のルートを描いてみて、問題点を明らかにしたいです。
参考1:GoogleMapsの来歴
Google Maps Platformはアクティブユーザーが1ヶ⽉間10億⼈と世界最大の地図プラットフォームです。
2005年から開発者向けにGoogle Maps APIがGoogle Maps 開発プラットフォームとして提供されています。
以前のサービスの名称はGoogle Maps APIでした。
2018.7.15にリニューアルされ現在のGoogle Maps Platformとなりました。
参考2:noteMapアイコン取得方法
Chreome ウェブストアを開きます。
検索ボックスに「note Map」と入力してnoteMapを捜します。
[Chrome に追加] を選択します。
右上のその他アイコン [拡張機能] [拡張機能を管理] を選択します。
ピンアイコンをクリックしてnote Mapアイコンを表示にします。
アドレスバーの右方にnote Mapアイコンが表示されます。
【あるきんぐ】
あるきんぐ 大船の切通しと高野の切通し
【人生最後のプロジェクト】
高齢者の妄想 ビットコインを自分で作ってみたが失敗
Coincheckのアカウント登録が拒否されました
これから始める 人生最後のプロジェクト①
人生最後のプロジェクト note記事と地図を連携させたい②
noteMap構想 開発するときの頭の中③
noteMapサービス 中の人と外の人④
noteMap GoogleにChrome拡張を申請⑤
noteMap Googleから申請却下の返事⑥
noteMap Googleからまたもや申請却下⑦
noteMap Chrome Web Storeに登録された⑧
noteMap これからどうする⑨
noteMap どんな言語を使って開発する?⑩
noteMap 開発を始める前にGoogleアプリやサービス全体の理解⑪
noteMap 場所検索機能を追加する⑫
noteMap 登録した場所を表示する⑬
noteMap 三連休最終日に鎌倉登山⑭-1
noteMap 三連休最終日に鎌倉登山⑭-2
noteMap 三連休最終日に鎌倉登山⑭-3
noteMap AIを使ってプログラマ引退を先延ばしする⑮
noteMap あるきんぐ 大船の切通しと高野の切通し⑯
noteMap ルートを辿れるマップ作り⑰ 概要
noteMap ルートを辿れるマップ作り⑰ー1 地点情報とルート(本記事)
noteMap ルートを辿れるマップ作り⑰ー2 地点情報の修正
noteMap ルートを辿れるマップ作り⑰ー3 地点情報の保存
noteMap ルートを辿れるマップ作り⑰ー4 地点情報の読込