Geometry Libraryを使ってPathをエンコード/デコードする方法
今回は、緯度/経度の配列である「MVCArray」型をエンコードして、文字列に変換する方法、そして、そのエンコード文字列からデコードして「MVCArray」型のデータを取得する方法を紹介します。
なお、Google Maps関連の記事についてはこちらにまとめてありますので、ご覧ください。
Contents
Geometry Libraryを使ってPathをエンコード/デコードする方法
Geometry Libraryとは、Google Mapsで使うオブジェクトを利用した計算や判定、変換する関数群を提供するライブラリになっています。
Pathをエンコード/デコードするには「google.maps.geometry.encoding」を利用します。
Geometry Libraryを利用するには
Geometry Libraryを利用するには、Google Maps APIをロードする際に、Geometry Libraryを利用できるようなパラメータを設定しなければなりません。以下のようなコードが必要になります。
<script src="https://maps.googleapis.com/maps/api/js?key=(APIキー)&libraries=geometry">
PolylineのPath(緯度/経度の集合体)をエンコードする/エンコード文字列からPolylineを描画する
サンプル
マップを複数回、クリックし、PolyLineを描画してください。
手順1
まず、マップを複数回数クリックし、Polylineを描画してください。
手順2
「↓エンコードする」ボタンを押して、Polylineの各緯度/経度情報をエンコードしてください。
手順3
「線を消す」ボタンを押して、Polylineやマーカーを削除させてみてください。
手順4
「↑デコードする」ボタンを押してみてください。エンコード文字列をもとに、消す前に描画させていた、Polylineとマーカーを再描画させています。
HTMLコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<title>Sample Map</title>
<script defer
src="https://maps.googleapis.com/maps/api/js?key=(APIキー)&callback=initMap&libraries=geometry" >
</script>
<style type="text/css">
#map_canvas {
width: 100%;
height:70%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script type="text/javascript">
var map;
var clickedLines;
var marker;
function initMap() {
var myLatlng = new google.maps.LatLng(35.68517826190777,139.7528236934712);
var mapOptions = {
zoom: 15,
center: myLatlng
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
clickedLines = new google.maps.Polyline({
geodesic: true,
strokeColor: "#3333FF",
strokeOpacity: 1.0,
strokeWeight: 3
});
// マップにクリックイベントを設定
google.maps.event.addListener(map, 'click', function(event) {
// クリック時の位置を渡す
drawOneLine(event.latLng);
});
}
function drawOneLine(latLng) {
var path = clickedLines.getPath();
if ( path.length == 0 ) {
createMarker(latLng);
document.getElementById('txtLatLng').value = latLng;
} else {
document.getElementById('txtLatLng').value = document.getElementById('txtLatLng').value + "\n" + latLng;
}
path.push(latLng);
clickedLines.setMap(map);
}
function createMarker(latLng) {
marker = new google.maps.Marker({
position: latLng,
map: map,
title: '最初の位置'
});
}
function deleteAllLines() {
var path = clickedLines.getPath();
if ( path != undefined ) {
if ( path.length >= 0 ){
do {
if ( path.length == 0 ) break;
path.pop();
} while(1);
}
}
document.getElementById('txtLatLng').value = "";
if ( marker != undefined ) {
marker.setMap(null);
}
if ( clickedLines != undefined ) {
clickedLines.setMap(null);
}
}
function encodePath() {
var path = clickedLines.getPath();
var encodedPath = google.maps.geometry.encoding.encodePath(path);
document.getElementById('txtEncoded').value = encodedPath;
}
function decodePath() {
var sEncodedPath = document.getElementById('txtEncoded').value;
if ( sEncodedPath.length > 0 ) {
deleteAllLines();
var path = google.maps.geometry.encoding.decodePath(sEncodedPath);
document.getElementById('txtLatLng').value = path[0];
marker.setPosition(path[0]);
marker.setMap(map);
for ( var i=1 ; i < path.length; i++ ) {
document.getElementById('txtLatLng').value = document.getElementById('txtLatLng').value + "\n" + path[i];
}
clickedLines.setPath(path);
clickedLines.setMap(map);
}
}
</script>
</head>
<body>
<div id="map_canvas"></div>
<br />
<textarea style="height:50px;width:80%;margin-left:20px;margin-bottom:10px;" id="txtLatLng"></textarea>
<br />
<input type="button" value="線を消す" onclick="deleteAllLines();" style="margin-left:20px;"/>
<input type="button" value="↓エンコードする" onclick="encodePath();" style="margin-left:20px;"/><input type="button" value="↑デコードする" onclick="decodePath();" style="margin-left:20px;"/>
<br />
<textarea style="height:50px;width:80%;margin-left:20px;margin-top:10px;" id="txtEncoded"></textarea>
</body>
</html>
デモ
エンコード/デコードする
エンコードする
「↓エンコードする」ボタンを押すと、エンコード処理が呼び出されます。
function encodePath() {
var path = clickedLines.getPath();
var encodedPath = google.maps.geometry.encoding.encodePath(path);
document.getElementById('txtEncoded').value = encodedPath;
}
まず、PolylineオブジェクトのgetPath()メソッドを実行することで、描画されているPolylineの位置情報(path)を取得します。そのpathは「MVCArray<LatLng>」型で、位置情報を複数配列で保持している型になります。
その「MVCArray<LatLng>」型、または、「Array<LatLng>」型の値をencodePathメソッド渡すことで、位置情報の配列をエンコードし、文字列に変換することができます。
デコードする
「↑デコードする」ボタンを押すと、エンコード文字列から、デコードし、位置情報の配列を取得します。それをもとにマーカーを設定し、Polylineを描画するようにしてあります。
function decodePath() {
var sEncodedPath = document.getElementById('txtEncoded').value;
if ( sEncodedPath.length > 0 ) {
deleteAllLines();
var path = google.maps.geometry.encoding.decodePath(sEncodedPath);
document.getElementById('txtLatLng').value = path[0];
marker.setPosition(path[0]);
marker.setMap(map);
for ( var i=1 ; i < path.length; i++ ) {
document.getElementById('txtLatLng').value = document.getElementById('txtLatLng').value + "\n" + path[i];
}
clickedLines.setPath(path);
clickedLines.setMap(map);
}
}
まず、「deleteAllLines()」ですべての線(Polylineとマーカー)をいったん削除します。その後、decodePath()にエンコード文字列を渡すことで、緯度/経度の配列型「MVCArray<LatLng>」型の変数に変換します。
配列の一つ目の緯度/経度にマーカーを設定、その後、テキストボックスに緯度/経度の配列文字列を設定し、PolylineのsetPath()メソッドに緯度/経度の配列型変数を渡すことで、Polylineを描画させることができます。最後にsetMap()でMapオブジェクトと紐づけて描画終了です。
ご参考
関連ページ