#追加-1、デバイスの位置を地図上に表示する
Qiitaで『Geolocation APIでPCやスマホの位置情報を取得する』 という記事がありましたので、記事内容を利用してスマホ等の位置を地図上に表示させてみました。 さらに、任意の時間間隔で連続して地図上に位置をトレースし表示するプログラムを作成してみました。 これらのプログラムは、PCでの動作は確認できましたが、スマホでは通信が暗号化された『https://』以外のホームページからでは位置情報が使用できないようです。
##1-1、自分のPC等の位置を地図に表示させてみる
『Leaflet_Tutrial_101.html』を元にPC等の位置を地図上に表示させてみました。 プログラムを実行すると「位置情報を使うことを許可するか」の確認メッセージが表示されますので、「はい」か「許可する」をクリックして下さい。(ブラウザによってメッセージが異なります) 使用しているデバイスの現在地がマーカーで表示され、その地点が地図の中心になります。 表示されたマーカーをクリックすると取得時刻と位置誤差がポップアップで表示されます。 なお、「Safari」では動作しませんでした。 以下にその表示例とソースファイルの内容を示します。 ソースファイルの内容で25~31行目と48~79行目が『Leaflet_Tutrial_101.html』に追加した部分です。 実際の表示を確認したい方は、こちらをクリックしてください。
『 Leaflet_Tutrial_Additional_001.html 』のソースファイル内容
<!DOCTYPE html>
<html>
<head>
<title>Leaflet_Tutrial_Additional_001.html 2019/5/5 by T. Fujita</title>
<meta charset="utf-8" />
<link rel = "stylesheet" href = "https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" />
<script src = "https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
<script>
function init() {
var Layer_A001 = new Array();
var Current_Lat = 0;
var Current_Lon = 0;
var Accuracy = 0;
var Current_Time = "";
var zoom = 8;
var map_A001 = L.map('map_A001').setView([35.65809922, 139.74135747], 8);
mapLink = '<a href="https://openstreetmap.org">OpenStreetMap</a>';
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © ' + mapLink,
maxZoom: 18
}).addTo(map_A001);
// Geolocation APIに対応している場合
if (navigator.geolocation) {
getPosition();
// Geolocation APIに対応していない場合
} else {
alert("この端末では位置情報が取得できません");
}
function Leaflet_Marker_A001() // マーカー設置
{
var Markers_shape = new Array();
var Markers_shape_pos = new Array();
var Markers_shape_nam = new Array();
var Markers_shape_lnk = new Array();
Markers_shape_pos[ 0 ] = [Current_Lat, Current_Lon];
Markers_shape_nam[ 0 ] = Current_Time;
Markers_shape_lnk[ 0 ] = "";
Markers_shape[ 0 ] = L.marker([ Markers_shape_pos[ 0 ][ 0 ], Markers_shape_pos[ 0 ][ 1 ] ]);
Markers_shape[ 0 ].bindPopup(Markers_shape_nam[ 0 ] + "<BR> 位置誤差:" + Accuracy + " (m)").openPopup();
Layer_A001[ 0 ] = Markers_shape[ 0 ];
Layer_A001[ 0 ].addTo(map_A001);
}
// 現在地取得処理
function getPosition() {
navigator.geolocation.getCurrentPosition(
// 取得成功した場合
function(position) {
Current_Lat = position.coords.latitude;
Current_Lon = position.coords.longitude;
Accuracy = position.coords.accuracy;
Current_Time = new Date(position.timestamp);
zoom = map_A001.getZoom();
Leaflet_Marker_A001();
map_A001.setView(new L.LatLng(Current_Lat, Current_Lon), zoom, {animation: true} );
},
// 取得失敗した場合
function(error) {
switch(error.code) {
case 1: //PERMISSION_DENIED
alert("位置情報の利用が許可されていません");
break;
case 2: //POSITION_UNAVAILABLE
alert("現在位置が取得できませんでした");
break;
case 3: //TIMEOUT
alert("タイムアウトになりました");
break;
default:
alert("その他のエラー(エラーコード:"+error.code+")");
break;
}
}
);
}
}
</script>
</head>
<body onload="init()">
<div id="map_A001" style="width: 100%; height: 400px; border: solid 1px"></div>
</body>
</html>
##1-2、連続して位置をトレースしてみる
次に『Leaflet_Tutrial_404.html』を元にデバイスの位置を地図上に表示・トレースさせてみました。 画面上部のメニューに「本デバイスの位置」を追加し、クリックすると次のサブ・メニューが表示されるようにしています。 実際の表示を確認したい方は、こちらをクリックしてください。
(1)本デバイスの位置表示: 上記1-1項と同一
(2)位置トレース開始・終了:
トレースを開始・終了するためのダイアログ・ボックスが表示されます。 また、トレースのインターバル・タイムを設定できるようにしました。
(3)トレース表示消去:
本デバイスの位置表示及びトレース結果の表示を全て消去します。
(4)トレース保存(CSV形式):
トレース結果をCSV形式でローカルファイルとして保存します。 保存したCSVファイルは、『Leaflet_Tutrial_404.html』、『Leaflet_Tutrial_505.html』、『Leaflet_Tutrial_601.html』と共通していますので、直線や円を表示することができます。
(5)トレース読込(CSV形式):
ローカルファイルからトレースデータを選択するダイアログ・ボックスを表示します。 マーカーの読込みと同一ですが、ファイル選択後にトレース表示が選択できます。
『Leaflet_Tutrial_404.html』から追加した箇所は、47~63行目、419~635行目及び654~662行目です。 以下に 表示例とそのソースファイルの内容を示します。
『 Leaflet_Tutrial_Additional_002.html 』のソースファイル内容
<!DOCTYPE html>
<html>
<head>
<title>Leaflet_Tutrial_Additional_002.html 2019/5/6 by T. Fujita</title>
<meta charset = "utf-8" />
<link rel = "stylesheet" href = "https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" />
<link rel = "stylesheet" href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<link rel = "stylesheet" href = "./Plugins/ms-Dropdown-master/css/msdropdown/dd.css" />
<link rel = "stylesheet" href = "./CSS/scroll_menu.css" />
<link rel = "stylesheet" href = "./CSS/Original_Style_404.css" />
<style>
html, body {
width: 99%;
height: 98%;
font-size: 14px;
z-index: 0;
}
</style>
<script src = "https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src = "./Plugins/ms-Dropdown-master/js/msdropdown/jquery.dd.js"></script>
<script src = "./JS/Dialog_Additional_002.js" ></script>
<script>
var Marker_LAT = new Array();
var Marker_LON = new Array();
var Marker_NAM = new Array();
var Marker_LNK = new Array();
var Marker_ICN = new Array();
var Marker_ID = new Array();
var Marker_Drag_flag = new Array();
var Marker_Drag_info = new Array();
var ClickLat = null;
var ClickLon = null;
var Marker_count = 0;
var Marker_ID_count = 0;
var SelectedID;
var Marker_flag = 0;
var Temp_shape, Temp_shape_clone;
var Temp, Temp_LAT, Temp_LON, Temp_NAM, Temp_LNK, Temp_ICN, Temp_ID, Temp_ACC;
var Temp_Drag_flag, Temp_Drag_info;
var Layer_404 = new Array();
var Layer_404_clone = new Array();
var Dialog_flag_001 = 0;
var Trace_LAT = new Array();
var Trace_LON = new Array();
var Trace_NAM = new Array();
var Trace_LNK = new Array();
var Trace_ACC = new Array();
var Trace_ICN = new Array();
var Trace_ID = new Array();
var Trace_Drag_flag = new Array();
var Trace_Drag_info = new Array();
var Trace_count = 0;
var Trace_ID_count = 0;
var Layer_AD_002 = new Array();
var Layer_AD_002_clone = new Array();
var Accuracy = 0;
var Time_Stamp = "";
var Interval_flag = 0;
var zoom = 6;
var map_AD_002;
function init() {
map_AD_002 = L.map('map_AD_002').setView([35.0, 137.0], 6);
mapLink = '<a href="https://openstreetmap.org">OpenStreetMap</a>';
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © ' + mapLink,
maxZoom: 18
}).addTo(map_AD_002);
map_AD_002.on('click', function(e) {
ClickLat = e.latlng.lat;
ClickLon = e.latlng.lng;
if ( Marker_flag == 1 ) { Leaflet_Marker_401(); }
if ( Marker_flag == 2 ) { Leaflet_Marker_403(); }
});
}
function Leaflet_Marker_400() { // 初期設定(マーカー単独設置)
ClickLat = null;
ClickLon = null;
Marker_flag = 1;
}
function Leaflet_Marker_401() { // マーカー単独設置
if(Marker_flag == 1) {
Marker_LAT[ Marker_count ] = ClickLat;
Marker_LON[ Marker_count ] = ClickLon;
Marker_NAM[ Marker_count ] = Set_Text;
Marker_LNK[ Marker_count ] = " ";
Marker_ICN[ Marker_count ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
Marker_ID[ Marker_count ] = "Marker" + Marker_ID_count;
Marker_Drag_flag[ Marker_count ] = true;
Marker_Drag_info[ Marker_count ] = "マウスで移動出来ます。";
Temp = Marker_count;
Marker_setting();
Marker_set();
Layer_404[ Temp ] = Temp_shape;
Layer_404[ Temp ].addTo(map_AD_002);
Layer_404_clone[ Temp ] = Temp_shape_clone;
Layer_404_clone[ Temp ].addTo(map_AD_002);
Marker_count = Marker_count + 1;
Marker_ID_count = Marker_ID_count + 1;
Marker_flag = 0;
}
}
function Leaflet_Marker_402() { // 初期設定(マーカー連続設置)
ClickLat = null;
ClickLon = null;
Marker_flag = 2;
}
function Leaflet_Marker_403() { // マーカー連続設置
if(Marker_flag == 2) {
Marker_LAT[ Marker_count ] = ClickLat;
Marker_LON[ Marker_count ] = ClickLon;
Marker_NAM[ Marker_count ] = Set_Text;
Marker_LNK[ Marker_count ] = " ";
Marker_ICN[ Marker_count ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
Marker_ID[ Marker_count ] = "Marker" + Marker_ID_count;
Marker_Drag_flag[ Marker_count ] = true;
Marker_Drag_info[ Marker_count ] = "マウスで移動出来ます。";
Temp = Marker_count;
Marker_setting();
Marker_set();
Layer_404[ Temp ] = Temp_shape;
Layer_404[ Temp ].addTo(map_AD_002);
Layer_404_clone[ Temp ] = Temp_shape_clone;
Layer_404_clone[ Temp ].addTo(map_AD_002);
Marker_count = Marker_count + 1;
Marker_ID_count = Marker_ID_count + 1;
}
}
function Leaflet_Marker_404() { // マーカー連続設置終了
Marker_flag = 0;
}
function Leaflet_Marker_405() { // マーカー全消去
var j = Layer_404.length - 1;
for(i = 0; i <= j; i++) {
if(Layer_404[i] != null) {
map_AD_002.removeLayer(Layer_404[i]);
map_AD_002.removeLayer(Layer_404_clone[ i ]);
}
}
Marker_count = 0;
Marker_LAT = new Array();
Marker_LON = new Array();
Marker_NAM = new Array();
Marker_LNK = new Array();
Marker_ICN = new Array();
}
function Leaflet_Marker_406() { // マーカー保存(CSV形式)
for (i = 0; i <= (Marker_LON.length - 1); i++) {
if( !isNaN(Marker_LON[ i ]) ) {
while( (Marker_LON[ i ] * 1.0) < -180) {
Marker_LON[ i ] = (Marker_LON[ i ] * 1.0) + 360;
}
while( (Marker_LON[ i ] * 1.0) > 180) {
Marker_LON[ i ] = (Marker_LON[ i ] * 1.0) - 360;
}
}
}
if(Marker_LAT[ 0 ] == "LAT(deg.)") {
var CSV_content = [];
} else {
var CSV_content = "LAT(deg.),LONG(deg.),Name(by utf-8),Link,\r\n";
}
const aTag = document.createElement('a');
aTag.download = "CSV_Data.csv";
var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
Temp = Marker_LAT.length;
for ( i = 0; i < Temp; i++ ) {
if( Marker_LAT[ i ] != "" && Marker_LON[ i ] != "" ) {
CSV_content = CSV_content + Marker_LAT[ i ] + "," + Marker_LON[ i ] + "," + Marker_NAM[ i ] + "," + Marker_LNK[ i ] + ",\r\n";
}
}
var blob = new Blob([ bom, CSV_content ], { "type": "text/csv"});
if(window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, aTag.download); // for IE
} else if (window.URL && window.URL.createObjectURL) {
aTag.href = window.URL.createObjectURL(blob); // for FireFox
document.body.appendChild(aTag);
aTag.click();
document.body.removeChild(aTag);
} else if (window.webkitURL && window.webkitURL.createObject) {
aTag.href = (window.URL || window.webkitURL).createObjectURL(blob); // for Chrome
aTag.click();
} else {
alert("保存に失敗しました!");
}
}
function Leaflet_Marker_407() { // マーカー読込(CSV形式)
Dialog_002();
}
function Marker_setting() { // マーカー設定
Temp_LAT = Marker_LAT[ Temp ] * 1.0;
Temp_LON = Marker_LON[ Temp ] * 1.0;
Temp_NAM = Marker_NAM[ Temp ];
Temp_LNK = Marker_LNK[ Temp ];
Temp_ICN = Marker_ICN[ Temp ];
Temp_ID = Marker_ID[ Temp ];
Temp_Drag_flag = Marker_Drag_flag[ Temp ]
Temp_Drag_info = Marker_Drag_info[ Temp ]
Set_Link =" ";
if(Temp_LNK != undefined ) {
if( String( Temp_LNK ).length > 5 ) {
Set_Link = "<a href= '" + Temp_LNK + "' target='_blank'> " + Temp_NAM + "情報にリンク</a>";
}
}
}
function Marker_set() { // マーカー設置
if( !isNaN( Temp_LAT ) && !isNaN( Temp_LON ) ) {
if( (Temp_LAT !== undefined) || (Temp_LAT !== "") ) {
if( ((Temp_LAT * 1.0) != 0) || ((Temp_LON * 1.0) != 0) ) {
Temp_shape = L.marker([ Temp_LAT, Temp_LON ],
{icon: Temp_ICN, id: Temp_ID, draggable: Temp_Drag_flag}).bindPopup( Temp_NAM + "<BR>" + Temp_Drag_info + "<BR>" +
"<p> <input type='button' value='Change this Marker' class='marker-change-button'/></p>" +
Set_Link + "<p> <input type='button' value='Delete this Marker' class='marker-delete-button'/></p>");
Temp_shape.on('popupopen', onMarkerOpen ).on('dragend', Dragging);
if(Temp_LON >= 0) {
Temp_shape_clone = L.marker([ Temp_LAT, (Temp_LON - 360) ],
{icon: Temp_ICN, id: Temp_ID, draggable: Temp_Drag_flag}).bindPopup( Temp_NAM + "<BR>" + Temp_Drag_info + "<BR>" +
"<p> <input type='button' value='Change this Marker' class='marker-change-button'/></p>" +
Set_Link + "<p> <input type='button' value='Delete this Marker' class='marker-delete-button'/></p>");
Temp_shape_clone.on('popupopen', onMarkerOpen ).on('dragend', Dragging);
} else {
Temp_shape_clone = L.marker([ Temp_LAT, (Temp_LON + 360) ],
{icon: Temp_ICN, id: Temp_ID, draggable: Temp_Drag_flag}).bindPopup( Temp_NAM + "<BR>" + Temp_Drag_info + "<BR>" +
"<p> <input type='button' value='Change this Marker' class='marker-change-button'/></p>" +
Set_Link + "<p> <input type='button' value='Delete this Marker' class='marker-delete-button'/></p>");
Temp_shape_clone.on('popupopen', onMarkerOpen ).on('dragend', Dragging);
}
}
}
}
}
function onMarkerOpen() { // マーカーをクリックした時に表示する削除ボタンと変更ボタン
var tempMarker = this;
SelectedID = tempMarker.options.id;
$(".marker-delete-button:visible").click(function () {
Marker_DEL(tempMarker);
});
$(".marker-change-button:visible").click(function () {
Dialog_001();
});
}
function Change_Marker() { // 変更ボタン押下時の処理
for(i = 0; i <= Marker_count; i++) {
if(SelectedID == Marker_ID[ i ] ) {
Marker_NAM[ i ] = Set_Text;
Marker_ICN[ i ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
}
}
for(i = 0; i <= Trace_count; i++) {
if(SelectedID == Trace_ID[ i ] ) {
Trace_ICN[ i ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
}
}
Marker_Refresh();
}
function Marker_DEL(tempMarker) { // 削除ボタン押下時の処理
var k = 0;
Marker_flag = 0;
Marker_LAT[ Marker_count + 1 ] = "";
Marker_LON[ Marker_count + 1 ] = "";
Marker_NAM[ Marker_count + 1 ] = "";
Marker_LNK[ Marker_count + 1 ] = "";
Marker_ICN[ Marker_count + 1 ] = "";
Marker_ID[ Marker_count + 1 ] = "";
SelectedID = tempMarker.options.id;
for(i = 0; i <= Marker_count; i++) {
if(SelectedID == Marker_ID[ i ] ) {
for(k = i; k <= Marker_count; k++) {
Marker_LAT[ k ] = Marker_LAT[ k + 1 ];
Marker_LON[ k ] = Marker_LON[ k + 1 ];
Marker_NAM[ k ] = Marker_NAM[ k + 1 ];
Marker_LNK[ k ] = Marker_LNK[ k + 1 ];
Marker_ICN[ k ] = Marker_ICN[ k + 1 ];
Marker_ID[ k ] = Marker_ID[ k + 1 ];
Marker_Drag_flag[ k ] = Marker_Drag_flag[ k + 1 ];
Marker_Drag_info[ k ] = Marker_Drag_info[ k + 1 ];
}
}
}
SelectedID = null;
Marker_count = Marker_count - 1;
Marker_Refresh();
}
function Marker_Refresh() { // マーカー再表示
var j = Layer_404.length - 1;
for(i = 0; i <= j; i++) {
if(Layer_404[ i ] != null) {
map_AD_002.removeLayer(Layer_404[ i ]);
map_AD_002.removeLayer(Layer_404_clone[ i ]);
}
}
var j = Layer_AD_002.length - 1;
for(i = 0; i <= j; i++) {
if(Layer_AD_002[ i ] != null) {
map_AD_002.removeLayer(Layer_AD_002[ i ]);
map_AD_002.removeLayer(Layer_AD_002_clone[ i ]);
}
}
for (i = 0; i <= Marker_count - 1; i++)
{
Temp = i;
Marker_setting();
Marker_set();
Layer_404[ Temp ] = Temp_shape;
Layer_404[ Temp ].addTo(map_AD_002);
Layer_404_clone[ Temp ] = Temp_shape_clone;
Layer_404_clone[ Temp ].addTo(map_AD_002);
}
for (i = 0; i <= Trace_count - 1; i++)
{
Temp = i;
Trace_setting();
Trace_set();
Layer_AD_002[ Temp ] = Temp_shape;
Layer_AD_002[ Temp ].addTo(map_AD_002);
Layer_AD_002_clone[ Temp ] = Temp_shape_clone;
Layer_AD_002_clone[ Temp ].addTo(map_AD_002);
}
}
function Dragging() { // マーカーをドラッグ時の位置取得
ClickLat = this._latlng.lat;
ClickLon = this._latlng.lng;
SelectedID = this.options.id;
for(i = 0; i <= Marker_count; i++) {
if(SelectedID == Marker_ID[ i ] ) {
Marker_LAT[ i ] = ClickLat;
Marker_LON[ i ] = ClickLon;
}
}
Marker_Refresh();
SelectedID = null;
}
function CSV_Markers() { // CSVデータを表示
for (i = 0; i <= (Data_CSV.length - 1); i++) {
if((Data_CSV[i][0] * 1.0) > 90) {
Data_CSV[i][0] = 90;
}
if((Data_CSV[i][0] * 1.0) < -90) {
Data_CSV[i][0] = -90;
}
while( (Data_CSV[i][1] * 1.0) < -180) {
Data_CSV[i][1] = Data_CSV[i][1] * 1.0 + 360;
}
while( (Data_CSV[i][1] * 1.0) > 180) {
Data_CSV[i][1] = Data_CSV[i][1] * 1.0 - 360;
}
}
for (i = 0; i <= (Data_CSV.length - 1); i++) {
Marker_LAT[ Marker_count ] = Data_CSV[i][0];
Marker_LON[ Marker_count ] = Data_CSV[i][1];
Marker_NAM[ Marker_count ] = Data_CSV[i][2];
Marker_LNK[ Marker_count ] = Data_CSV[i][3];
Marker_ICN[ Marker_count ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
Marker_ID[ Marker_count ] = "Marker" + Marker_ID_count;
Marker_Drag_flag[ Marker_count ] = false;
Marker_Drag_info[ Marker_count ] = "移動出来ません。";
if( Data_CSV[i][0] != "" ) {
if( !isNaN( Data_CSV[i][0] ) ) {
Temp = Marker_count;
Marker_setting();
Marker_set();
Layer_404[ Temp ] = Temp_shape;
Layer_404[ Temp ].addTo(map_AD_002);
Layer_404_clone[ Temp ] = Temp_shape_clone;
Layer_404_clone[ Temp ].addTo(map_AD_002);
}
}
Marker_count = Marker_count + 1;
Marker_ID_count = Marker_ID_count + 1;
}
}
function Leaflet_Position_AD001() { // デバイスの位置表示
if (navigator.geolocation) { // Geolocation APIに対応している場合
getPosition();
} else { // Geolocation APIに対応していない場合
alert("この端末では位置情報が取得できません");
}
}
function Leaflet_Trace_AD002() { // トレース開始/終了
Dialog_AD_001();
}
function Leaflet_Trace_AD003() { // トレース消去
var j = Layer_AD_002.length - 1;
for(i = 0; i <= j; i++) {
if(Layer_AD_002[i] != null) {
map_AD_002.removeLayer(Layer_AD_002[i]);
map_AD_002.removeLayer(Layer_AD_002_clone[ i ]);
}
}
Trace_count = 0;
Trace_LAT = new Array();
Trace_LON = new Array();
Trace_NAM = new Array();
Trace_LNK = new Array();
Trace_ACC = new Array();
Trace_ICN = new Array();
}
function Leaflet_Trace_AD004() { // トレースデータ保存
for (i = 0; i <= (Trace_LON.length - 1); i++) {
if( !isNaN(Trace_LON[ i ]) ) {
while( (Trace_LON[ i ] * 1.0) < -180) {
Trace_LON[ i ] = (Trace_LON[ i ] * 1.0) + 360;
}
while( (Trace_LON[ i ] * 1.0) > 180) {
Trace_LON[ i ] = (Trace_LON[ i ] * 1.0) - 360;
}
}
}
if(Trace_LAT[ 0 ] == "LAT(deg.)") {
var CSV_content = [];
} else {
var CSV_content = "LAT(deg.),LONG(deg.),Time Stamp,Link,Accuracy(m),\r\n";
}
const aTag = document.createElement('a');
aTag.download = "CSV_Trace_Data.csv";
var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
Temp = Trace_LAT.length;
for ( i = 0; i < Temp; i++ ) {
if( Trace_LAT[ i ] != "" && Trace_LON[ i ] != "" ) {
CSV_content = CSV_content + Trace_LAT[ i ] + "," + Trace_LON[ i ] + "," + Trace_NAM[ i ] + "," + Trace_LNK[ i ] + "," + Trace_ACC[ i ] + ",\r\n";
}
}
var blob = new Blob([ bom, CSV_content ], { "type": "text/csv"});
if(window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, aTag.download); // for IE
} else if (window.URL && window.URL.createObjectURL) {
aTag.href = window.URL.createObjectURL(blob); // for FireFox
document.body.appendChild(aTag);
aTag.click();
document.body.removeChild(aTag);
} else if (window.webkitURL && window.webkitURL.createObject) {
aTag.href = (window.URL || window.webkitURL).createObjectURL(blob); // for Chrome
aTag.click();
} else {
alert("保存に失敗しました!");
}
}
function getPosition() { // 現在地取得処理
navigator.geolocation.getCurrentPosition(
function(position) { // 取得成功した場合
Trace_LAT[ Trace_count ] = position.coords.latitude;
Trace_LON[ Trace_count ] = position.coords.longitude;
Trace_NAM[ Trace_count ] = new Date(position.timestamp);
Trace_ACC[ Trace_count ] = position.coords.accuracy;
Trace_LNK[ Trace_count ] = " ";
Trace_ICN[ Trace_count ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
Trace_ID[ Trace_count ] = "Trace" + Trace_ID_count;
Trace_Drag_flag[ Trace_count ] = false;
Trace_Drag_info[ Trace_count ] = "マウスで移動出来ません。";
Temp = Trace_count;
Trace_setting();
Trace_set();
Layer_AD_002[ Temp ] = Temp_shape;
Layer_AD_002[ Temp ].addTo(map_AD_002);
Layer_AD_002_clone[ Temp ] = Temp_shape_clone;
Layer_AD_002_clone[ Temp ].addTo(map_AD_002);
zoom = map_AD_002.getZoom();
map_AD_002.setView(new L.LatLng(Trace_LAT[ Temp ], Trace_LON[ Temp ]), zoom, {animation: true} );
Trace_count = Trace_count + 1;
Trace_ID_count = Trace_ID_count + 1;
},
function(error) { // 取得失敗した場合
switch(error.code) {
case 1: //PERMISSION_DENIED
alert("位置情報の利用が許可されていません");
break;
case 2: //POSITION_UNAVAILABLE
alert("現在位置が取得できませんでした");
break;
case 3: //TIMEOUT
alert("タイムアウトになりました");
break;
default:
alert("その他のエラー(エラーコード:"+error.code+")");
break;
}
}
);
}
function Trace_setting() { // トレース用マーカー設定
Temp_LAT = Trace_LAT[ Temp ] * 1.0;
Temp_LON = Trace_LON[ Temp ] * 1.0;
Temp_NAM = Trace_NAM[ Temp ];
Temp_LNK = Trace_LNK[ Temp ];
Temp_ACC = Trace_ACC[ Temp ];
Temp_ICN = Trace_ICN[ Temp ];
Temp_ID = Trace_ID[ Temp ];
Temp_Drag_flag = Trace_Drag_flag[ Temp ]
Temp_Drag_info = Trace_Drag_info[ Temp ]
Set_Link =" ";
if(Temp_LNK != undefined ) {
if( String( Temp_LNK ).length > 5 ) {
Set_Link = "<a href= '" + Temp_LNK + "' target='_blank'> " + Temp_NAM + "情報にリンク</a>";
}
}
}
function Trace_set() { // トレース用マーカー設置
if( !isNaN( Temp_LAT ) && !isNaN( Temp_LON ) ) {
if( (Temp_LAT !== undefined) || (Temp_LAT !== "") ) {
if( ((Temp_LAT * 1.0) != 0) || ((Temp_LON * 1.0) != 0) ) {
Temp_shape = L.marker([ Temp_LAT, Temp_LON ],
{icon: Temp_ICN, id: Temp_ID, draggable: Temp_Drag_flag}).bindPopup( Temp_NAM + "<BR> 位置誤差:" + Temp_ACC + " (m) <BR>" +
"<p> <input type='button' value='Change this Marker' class='marker-change-button'/></p>" );
Temp_shape.on('popupopen', onMarkerOpen ).on('dragend', Dragging);
if(Temp_LON >= 0) {
Temp_shape_clone = L.marker([ Temp_LAT, (Temp_LON - 360) ],
{icon: Temp_ICN, id: Temp_ID, draggable: Temp_Drag_flag}).bindPopup( Temp_NAM + "<BR> 位置誤差:" + Temp_ACC + " (m) <BR>" +
"<p> <input type='button' value='Change this Marker' class='marker-change-button'/></p>");
Temp_shape_clone.on('popupopen', onMarkerOpen ).on('dragend', Dragging);
} else {
Temp_shape_clone = L.marker([ Temp_LAT, (Temp_LON + 360) ],
{icon: Temp_ICN, id: Temp_ID, draggable: Temp_Drag_flag}).bindPopup( Temp_NAM + "<BR> 位置誤差:" + Temp_ACC + " (m) <BR>" +
"<p> <input type='button' value='Change this Marker' class='marker-change-button'/></p>");
Temp_shape_clone.on('popupopen', onMarkerOpen ).on('dragend', Dragging);
}
}
}
}
}
function Start_Trace() {
Interval_flag = 1;
var POS_Data = setInterval( function() {
Leaflet_Position_AD001();
if(Interval_flag != 1) {
clearInterval(POS_Data);
}}, Interval * 60 * 1000 );
}
function Stop_Trace() {
Inteval_flag = 0;
}
function CSV_Trace() {
for (i = 0; i <= (Data_CSV.length - 1); i++) {
if((Data_CSV[i][0] * 1.0) > 90) {
Data_CSV[i][0] = 90;
}
if((Data_CSV[i][0] * 1.0) < -90) {
Data_CSV[i][0] = -90;
}
while( (Data_CSV[i][1] * 1.0) < -180) {
Data_CSV[i][1] = Data_CSV[i][1] * 1.0 + 360;
}
while( (Data_CSV[i][1] * 1.0) > 180) {
Data_CSV[i][1] = Data_CSV[i][1] * 1.0 - 360;
}
}
for (i = 0; i <= (Data_CSV.length - 1); i++) {
Trace_LAT[ Trace_count ] = Data_CSV[i][0];
Trace_LON[ Trace_count ] = Data_CSV[i][1];
Trace_NAM[ Trace_count ] = Data_CSV[i][2];
Trace_LNK[ Trace_count ] = Data_CSV[i][3];
Trace_ACC[ Trace_count ] = Data_CSV[i][4];
Trace_ICN[ Trace_count ] = L.icon({
iconUrl: Icon_Url,
iconSize: [Icon_W, Icon_H],
iconAnchor : [Icon_AW, Icon_AH],
popupAnchor: [Icon_PW, Icon_PH]
});
Trace_ID[ Trace_count ] = "Trace" + Trace_ID_count;
Trace_Drag_flag[ Trace_count ] = false;
Trace_Drag_info[ Trace_count ] = "移動出来ません。";
if( Data_CSV[i][0] != "" ) {
if( !isNaN( Data_CSV[i][0] ) ) {
Temp = Trace_count;
Trace_setting();
Trace_set();
Layer_AD_002[ Temp ] = Temp_shape;
Layer_AD_002[ Temp ].addTo(map_AD_002);
Layer_AD_002_clone[ Temp ] = Temp_shape_clone;
Layer_AD_002_clone[ Temp ].addTo(map_AD_002);
}
}
Trace_count = Trace_count + 1;
Trace_ID_count = Trace_ID_count + 1;
}
}
</script>
</head>
<body onload="init()">
<nav id="menu-wrap" style="z-index: 1000;">
<ul id="menu" style="width: 98%;">
<li><a href="#">マーカー設定</a>
<ul>
<li><a href="#" onclick = "Dialog_001()">マーカーのスタイル設定</a></li>
<li><a href="#" onclick = "Leaflet_Marker_400()">マーカー単独設置 </a></li>
<li><a href="#" onclick = "Leaflet_Marker_402()">マーカー連続設置 </a></li>
<li><a href="#" onclick = "Leaflet_Marker_404()">マーカー連続設置終了 </a></li>
<li><a href="#" onclick = "Leaflet_Marker_405()">マーカー全消去 </a></li>
<li><a href="#" onclick = "Leaflet_Marker_406()">マーカー保存(CSV形式) </a></li>
<li><a href="#" onclick = "Leaflet_Marker_407()">マーカー読込(CSV形式) </a></li>
</ul>
</li>
<li><a href="#">本デバイスの位置</a>
<ul>
<li><a href="#" onclick = "Leaflet_Position_AD001()">本デバイスの位置表示 </a></li>
<li><a href="#" onclick = "Leaflet_Trace_AD002()">位置トレース開始/終了 </a></li>
<li><a href="#" onclick = "Leaflet_Trace_AD003()">トレース表示消去 </a></li>
<li><a href="#" onclick = "Leaflet_Trace_AD004()">トレース保存(CSV形式) </a></li>
<li><a href="#" onclick = "Leaflet_Marker_407()">トレースー読込(CSV形式) </a></li>
</ul>
</li>
</ul>
</nav>
<div id="map_Layer">
<div id="map_AD_002" style="width: 100%; height: 95%; border: solid 1px"></div>
ここで使用しているアイコン素材は、<A HREF = "http://flat-icon-design.com/" target="_blank"> FLAT ICON DESIGN </A>および
<A HREF = "http://icooon-mono.com/" target="_blank"> ICOON MONO </A>から取得しており、これらアイコン素材データの著作権は TopeconHeroes が保持しています。
</div>
</body>
</html>
『 Dialog_Additional_002.js 』は、『Dialog_404.js』に位置をトレースするインターバルとトレースの開始/終了を指定する箇所を追加した JavaScriptファイルです。 追加した箇所は、15~17行目、141~144行目、151~178行目、187行目、209~216行目及び226~228行目です。 インターバルは、1分から120分の間でスライダーにより指定できます。
『 Dialog_Additional_002.js 』のソースファイル内容
// Dialog_Additional_002.js 2019/5/6 by T. Fujita
var Set_Text = "";
var Set_Link = " ";
var Icon_Url = "../ICONS/BW_Icon/BW_Icons_64/icon_000200_64.png";
var Icon_W = 24;
var Icon_H = 24;
var Icon_AW = Math.round(Icon_W / 2);
var Icon_AH = Math.round(Icon_H / 2);
var Icon_PW = 0;
var Icon_PH = Math.round(Icon_H / 2) * -1;
var Max_M_Size = 64;
var Min_M_Size = 8;
var Data_CSV = new Array();
var Interval = 1;
var Max_Interval = 120;
var Min_Interval = 1;
$(document).ready( function() {
$("body").append('<div id="dialog_001" style="z-index: 2000;"><p><form name="Form_001"> Title: '+
'<input type="text" style="width: 230px;" name="txt_mk" value=""></form><BR>'+
'<div>Marker Select:<BR>'+
'<select id="Marker_Samples" name="Marker_Samples" style="width:150px;">'+
'<option value="1" title="../ICONS/BW_Icon/BW_Icons_64/icon_000200_64.png">001</option>'+
'<option value="2" title="../ICONS/BW_Icon/BW_Icons_64/icon_127890_64.png">002</option>'+
'<option value="3" title="../ICONS/BW_Icon/BW_Icons_64/icon_114880_64.png">003</option>'+
'<option value="4" title="../ICONS/BW_Icon/BW_Icons_64/icon_109890_64.png">004</option>'+
'<option value="5" title="../ICONS/BW_Icon/BW_Icons_64/icon_001050_64.png">005</option>'+
'<option value="6" title="../ICONS/BW_Icon/BW_Icons_64/icon_119170_64.png">006</option>'+
'<option value="7" title="../ICONS/BW_Icon/BW_Icons_64/icon_122590_64.png">007</option>'+
'<option value="8" title="../ICONS/BW_Icon/BW_Icons_64/icon_000220_64.png">008</option>'+
'<option value="9" title="../ICONS/BW_Icon/BW_Icons_64/icon_133000_64.png">009</option>'+
'<option value="10" title="../ICONS/BW_Icon/BW_Icons_64/icon_115740_64.png">010</option>'+
'<option value="11" title="../ICONS/BW_Icon/BW_Icons_64/icon_115710_64.png">011</option>'+
'<option value="12" title="../ICONS/BW_Icon/BW_Icons_64/icon_115750_64.png">012</option>'+
'<option value="13" title="../ICONS/BW_Icon/BW_Icons_64/icon_115720_64.png">013</option>'+
'<option value="14" title="../ICONS/BW_Icon/BW_Icons_64/icon_147060_64.png">014</option>'+
'<option value="15" title="../ICONS/BW_Icon/BW_Icons_64/icon_127900_64.png">015</option>'+
'<option value="16" title="../ICONS/BW_Icon/BW_Icons_64/icon_109850_64.png">016</option>'+
'<option value="17" title="../ICONS/BW_Icon/BW_Icons_64/icon_111050_64.png">017</option>'+
'<option value="18" title="../ICONS/BW_Icon/BW_Icons_64/icon_111060_64.png">018</option>'+
'<option value="19" title="../ICONS/BW_Icon/BW_Icons_64/icon_111520_64.png">019</option>'+
'<option value="20" title="../ICONS/BW_Icon/BW_Icons_64/icon_127100_64.png">020</option>'+
'<option value="21" title="../ICONS/BW_Icon/BW_Icons_64/icon_127110_64.png">021</option>'+
'<option value="22" title="../ICONS/BW_Icon/BW_Icons_64/icon_127120_64.png">022</option>'+
'<option value="23" title="../ICONS/BW_Icon/BW_Icons_64/icon_127130_64.png">023</option>'+
'<option value="24" title="../ICONS/BW_Icon/BW_Icons_64/icon_127140_64.png">024</option>'+
'<option value="25" title="../ICONS/BW_Icon/BW_Icons_64/icon_127150_64.png">025</option>'+
'<option value="26" title="../ICONS/BW_Icon/BW_Icons_64/icon_127160_64.png">026</option>'+
'<option value="27" title="../ICONS/BW_Icon/BW_Icons_64/icon_001720_64.png">027</option>'+
'<option value="28" title="../ICONS/BW_Icon/BW_Icons_64/icon_100590_64.png">028</option>'+
'<option value="29" title="../ICONS/BW_Icon/BW_Icons_64/icon_100600_64.png">029</option>'+
'<option value="30" title="../ICONS/BW_Icon/BW_Icons_64/icon_102040_64.png">030</option>'+
'<option value="31" title="../ICONS/BW_Icon/BW_Icons_64/icon_104940_64.png">031</option>'+
'<option value="32" title="../ICONS/BW_Icon/BW_Icons_64/icon_107470_64.png">032</option>'+
'<option value="33" title="../ICONS/BW_Icon/BW_Icons_64/icon_108510_64.png">033</option>'+
'<option value="34" title="../ICONS/BW_Icon/BW_Icons_64/icon_108730_64.png">034</option>'+
'<option value="35" title="../ICONS/BW_Icon/BW_Icons_64/icon_111960_64.png">035</option>'+
'<option value="36" title="../ICONS/BW_Icon/BW_Icons_64/icon_111970_64.png">036</option>'+
'<option value="37" title="../ICONS/BW_Icon/BW_Icons_64/icon_112440_64.png">037</option>'+
'<option value="38" title="../ICONS/BW_Icon/BW_Icons_64/icon_112450_64.png">038</option>'+
'<option value="39" title="../ICONS/BW_Icon/BW_Icons_64/icon_113000_64.png">039</option>'+
'<option value="40" title="../ICONS/BW_Icon/BW_Icons_64/icon_113010_64.png">040</option>'+
'<option value="41" title="../ICONS/BW_Icon/BW_Icons_64/icon_114520_64.png">041</option>'+
'<option value="42" title="../ICONS/BW_Icon/BW_Icons_64/icon_114530_64.png">042</option>'+
'<option value="43" title="../ICONS/BW_Icon/BW_Icons_64/icon_114770_64.png">043</option>'+
'<option value="44" title="../ICONS/BW_Icon/BW_Icons_64/icon_114780_64.png">044</option>'+
'<option value="45" title="../ICONS/BW_Icon/BW_Icons_64/icon_128020_64.png">045</option>'+
'<option value="46" title="../ICONS/BW_Icon/BW_Icons_64/icon_124660_64.png">046</option>'+
'<option value="47" title="../ICONS/BW_Icon/BW_Icons_64/icon_127930_64.png">047</option>'+
'<option value="48" title="../ICONS/Flat_Icons/s64_f_business_72_0nbg.png">048</option>'+
'<option value="49" title="../ICONS/Flat_Icons/s64_f_business_76_0nbg.png">049</option>'+
'<option value="50" title="../ICONS/Flat_Icons/s64_f_object_6_2nbg.png">050</option>'+
'<option value="51" title="../ICONS/Flat_Icons/s64_f_object_7_2nbg.png">051</option>'+
'<option value="52" title="../ICONS/Flat_Icons/s64_f_object_24_1nbg.png">052</option>'+
'<option value="53" title="../ICONS/Flat_Icons/s64_f_object_25_0nbg.png">053</option>'+
'<option value="54" title="../ICONS/Flat_Icons/s64_f_object_27_2nbg.png">054</option>'+
'<option value="55" title="../ICONS/Flat_Icons/s64_f_object_155_1nbg.png">055</option>'+
'<option value="56" title="../ICONS/Flat_Icons/s64_f_object_164_2nbg.png">056</option>'+
'<option value="57" title="../ICONS/Flat_Icons/s64_f_object_167_0nbg.png">057</option>'+
'<option value="58" title="../ICONS/Flat_Icons/s64_f_object_173_0nbg.png">058</option>'+
'<option value="59" title="../ICONS/Flat_Icons/s64_f_object_115_0nbg.png">059</option>'+
'<option value="60" title="../ICONS/Flat_Icons/s64_f_object_116_1nbg.png">060</option>'+
'</select></div><BR>'+
'<div><tr><td><BR><div id="num_001"></div><div id="slider_001"></div>'+
'<BR><BR><div id="Selected_Icon">Selected Icon: <img src=""></div>'+
'</td></tr></div><BR>(注) ここで使用しているアイコン素材は、<A HREF = "http://flat-icon-design.com/" target="_blank"> FLAT ICON DESIGN </A>および' +
'<A HREF = "http://icooon-mono.com/" target="_blank"> ICOON MONO </A>から取得しており、<BR>' +
'これらアイコン素材データの著作権は TopeconHeroes が保持しています。</p><div>');
$('#Selected_Icon img').attr('src', Icon_Url);
$('#dialog_001').dialog({
autoOpen: false,
title: 'Please Set the Icon Style.',
height: 450,
width: 300,
closeOnEscape: true,
modal: true,
buttons: {
"設定": function(){
Set_Text = document.Form_001.txt_mk.value;
var Temp = Marker_Samples.options[Marker_Samples.selectedIndex].title;
Icon_Url = Temp;
Icon_AW = Math.round(Icon_W / 2);
Icon_AH = Math.round(Icon_H / 2);
Icon_PW = 0;
Icon_PH = Math.round(Icon_H / 2) * -1;
Change_Marker();
$(this).dialog('close');
}
}
});
$("body").append('<div id="dialog_002" style="z-index: 2000;"><p><form name="Form_002">'+
'Title: <input type="text" style="width: 230px;" name="txt_dat" value=""></form></p><HR>'+
'<p> File Select:'+
'<form name="subinput">'+
'<center>CSVファイルを指定してください。<BR><BR>'+
' <TD><input type="file" name="select" id="select_002" value=""></TD>'+
' <BR><BR>'+
'</center></p></div>');
$('#dialog_002').dialog({
autoOpen: false,
title: 'CSVファイル選択',
height: 400,
width: 300,
closeOnEscape: true,
modal: true,
show: "fade",
hide: "fade",
buttons: {
"Select the Marker": function(){
Dialog_001();
},
"Set Markers": function(){
CSV_Data();
CSV_Markers();
},
"Set Traced Point": function(){
CSV_Data();
CSV_Trace();
},
"Close": function(){
$(this).dialog('close');
}
}
});
$("body").append('<div id="dialog_AD_001" style="z-index: 2000;"><p><form name="Form_AD_001">'+
'Status: <input type="text" style="width: 230px;" name="txt_AD_001" value=""></form></p><HR>'+
'<div id="num_AD_001"></div><div id="slider_AD_001"></div>');
$('#dialog_AD_001').dialog({
autoOpen: false,
title: 'Position Trace',
height: 180,
width: 300,
closeOnEscape: true,
modal: false,
show: "fade",
hide: "fade",
buttons: {
"Start the Trace": function(){
document.Form_AD_001.txt_AD_001.value = " Trace in Progress ";
Start_Trace();
},
" Stop & Close ": function(){
document.Form_AD_001.txt_AD_001.value = " Stop ";
Interval_flag = 0;
Stop_Trace();
$(this).dialog('close');
}
}
});
$('#slider_001, #slider_AD_001').slider( {
orientation: 'horizontal',
range: 'min',
max: 255,
value: 127,
slide: refreshSwatch,
change: refreshSwatch
} );
$( '#slider_001' ).slider( 'value', 96 );
$( '#slider_AD_001' ).slider( 'value', 1 );
$( '#Marker_Samples' ).msDropDown({
visibleRows:4,
on:{change:function(data, ui) {
Icon_Url = Marker_Samples.options[Marker_Samples.selectedIndex].title;
$('#Selected_Icon img').attr('src', Icon_Url);
}}
});
});
function Dialog_001() {
document.Form_001.txt_mk.value = "";
$('#dialog_001').dialog('open');
}
function Dialog_002() {
CSV_Data();
document.Form_002.txt_dat.value = "";
$('#dialog_002').dialog('open');
}
function Dialog_AD_001() {
if(Interval_flag * 1.0 == 0) {
document.Form_AD_001.txt_AD_001.value = " Stop ";
} else {
document.Form_AD_001.txt_AD_001.value = " Trace in Progress ";
}
$('#dialog_AD_001').dialog('open');
}
function refreshSwatch() {
Icon_W = Math.round($('#slider_001').slider('value') / 255 * Max_M_Size);
if (Icon_W <= Min_M_Size) { Icon_W = Min_M_Size; }
Icon_H = Icon_W;
$( '#num_001' ).html( 'Marker Size: ' + Icon_W );
$( '#Selected_Icon img' ).css( { width: Icon_W, height: Icon_H } );
Interval = Math.round($('#slider_AD_001').slider('value') / 255 * Max_Interval);
if (Interval <= Min_Interval) { Interval = Min_Interval; }
$( '#num_AD_001' ).html( 'Interval Time (Minutes) : ' + Interval );
}
function CSV_Data() {
if(window.File) {
var select = document.getElementById('select_002');
select.addEventListener('change', function(e) {
var fileData = e.target.files[0];
Data_CSV = [];
var reader = new FileReader();
reader.onerror = function() {
alert('ファイル読み込みに失敗しました。');
}
reader.onload = function() {
var lineArr = reader.result.split("\r\n");
for (var i = 0; i < lineArr.length; i++) {
Data_CSV[i] = lineArr[i].split(",");
}
}
reader.readAsText(fileData);
}, false);
}
}
###Leafletで色々な地図を表示する記事内容
1、Leafletで色々な地図を表示する
2、Overlay表示
3、色々な表示
4、マーカーの表示
5、色々な図形の表示
6、おまけ
追加-1、デバイスの位置を地図上に表示する
追加ー2、写真の撮影地を地図上に表示する
ここに記載したHTML/JavaScriptの動作を確認したい方は、「https://github.com/To-Fujita/Leaflet.JS_Tutorial」 あるいは 「http://hal322.html.xdomain.jp/」を参照ください。