var map;
var marker = null;
var locationLocked = false;
var markersOnMap = {}; // lat,lngをキーにしてマーカーを管理
window.onload = function() {
map = L.map('map', {
center: [38.8939762, 139.8189794],
zoom: 16,
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
map.on('click', onMapClick);
var lockBtn = document.getElementById("toggleLock");
if (lockBtn) lockBtn.onclick = () => locationLocked = !locationLocked;
loadAllMarkers(); // 初回ロード
setInterval(loadAllMarkers, 5000); // 0.5秒ごとに更新
// ------------------------------
// ここから 自動現在地取得
// ------------------------------
map.locate({
setView: true, // 初回は自動で地図中央へ
maxZoom: 16,
watch: true, // 自動追跡する
enableHighAccuracy: true
});
map.on('locationfound', gpsSuccess);
map.on('locationerror', gpsError);
};
// 現在地が取得できなかった場合の処理
function gpsError(e) {
alert("現在地を取得できませんでした。" + e.message);
}
// 現在地取得成功時の処理
let currentLocationMarker = null;
function gpsSuccess(e) {
const latlng = e.latlng;
if (currentLocationMarker) {
// 追跡モード → 座標だけ更新
currentLocationMarker.setLatLng(latlng);
} else {
// 初回 → マーカー生成
currentLocationMarker = L.circleMarker(latlng, {
radius: 8,
color: "blue",
fillColor: "blue",
fillOpacity: 0.8
}).addTo(map);
currentLocationMarker.bindPopup("📍現在地").openPopup();
}
}
async function onMapClick(e) {
if (locationLocked) return;
if (marker) map.removeLayer(marker);
marker = L.marker(e.latlng).addTo(map);
var lat = e.latlng.lat;
var lng = e.latlng.lng;
const popupHtml = `
<p>被害情報
<select name="00" id="00">
<option value="0-1">埋れている(建物、倒壊物等,,)</option>
<option value="0-2">流されている</option>
<option value="0-3">その他</option>
</select></p>
<p>症状 1 :
<select name="01" id="01">
<option value="1-1">1.意識が朦朧</option>
<option value="1-2">2.右腕が自分の意志で動かせない</option>
<option value="1-3">3.左腕が自分の意志で動かせない</option>
<option value="1-4">4.右手が自分の意志で動かせない</option>
<option value="1-5">5.左手が自分の意志で動かせない</option>
<option value="1-6">6.右脚が自分の意志で動かせない</option>
<option value="1-7">7.左脚が自分の意志で動かせない</option>
<option value="1-8">8.右足が自分の意志で動かせない</option>
<option value="1-9">9.左が自分の意志で動かせない</option>
<option value="1-10">10.腰が自分の意志で動かせない</option>
<option value="1-11">11.上半身が自分の意志で動かせない</option>
<option value="1-12">12.下半身が自分の意志で動かせない</option>
<option value="1-13">13.腰が自分の意志で動かせない</option>
<option value="1-14">14.頭が自分の意志で動かせない</option>
<option value="1-15">15.首が自分の意志で動かせない</option>
<option value="1-16">16.動けない</option>
<option value="1-16">17.意識不明</option>
<option value="1-17">18.当てはまらない</option>
</select></p>
<p>症状 2 :
<select name="02" id="02">
<option value="2-1">1.全身から多量の出血</option>
<option value="2-2">2.右腕から多量の出血</option>
<option value="2-3">3.左腕から多量の出血</option>
<option value="2-4">4.右手から多量の出血</option>
<option value="2-5">5.左手から多量の出血</option>
<option value="2-6">6.右脚から多量の出血</option>
<option value="2-7">7.左脚から多量の出血</option>
<option value="2-8">8.右足から多量の出血</option>
<option value="2-9">9.左足から多量の出血</option>
<option value="2-10">10.腰から多量の出血</option>
<option value="2-11">11.上半身から多量の出血</option>
<option value="2-12">12.下半身から多量の出血</option>
<option value="2-13">13.腰から多量の出血</option>
<option value="1-14">14.頭から多量の出血</option>
<option value="1-15">15.首から多量の出血</option>
<option value="2-16">16.当てはまらない</option>
</select></p>
<p>症状 3 :
<select name="03" id="03">
<option value="2-1">1.全身から出血</option>
<option value="2-2">2.右腕から出血</option>
<option value="2-3">3.左腕から出血</option>
<option value="2-4">4.右手から出血</option>
<option value="2-5">5.左手から出血</option>
<option value="2-6">6.右脚から出血</option>
<option value="2-7">7.左脚から出血</option>
<option value="2-8">8.右足から出血</option>
<option value="2-9">9.左足から出血</option>
<option value="2-10">10.腰から出血</option>
<option value="2-11">11.上半身から出血</option>
<option value="2-12">12.下半身から出血</option>
<option value="2-13">13.腰から出血</option>
<option value="1-14">14.頭から出血</option>
<option value="1-15">15.首から出血</option>
<option value="2-16">16.当てはまらない</option>
</select></p>
<button id="help" onclick="showMsg(${lat}, ${lng})">HELP!!</button>
`;
marker.bindPopup(popupHtml).openPopup();
}
window.showMsg = function(lat, lng) {
const info0 = document.getElementById("00").selectedOptions[0].text;
const info1 = document.getElementById("01").selectedOptions[0].text;
const info2 = document.getElementById("02").selectedOptions[0].text;
const info3 = document.getElementById("03").selectedOptions[0].text;
if(!confirm(`位置: ${lat}, ${lng}\n被害: ${info0}\n症状1: ${info1}\n症状2: ${info2}\n症状3: ${info3}\n送信しますか?`)) return;
const data = { lat, lng, text0: info0, text1: info1, text2: info2, text3: info3 };
fetch("http://localhost:3000/markers", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
}).then(() => {
const m = L.marker([lat, lng]).addTo(map);
m.bindPopup(`【送信済み】<br>被害情報: ${info0}<br>症状1: ${info1}<br>症状2: ${info2}<br>症状3: ${info3}`);
});
};
window.loadAllMarkers = async function() {
const res = await fetch("http://localhost:3000/markers");
const markers = await res.json();
markers.forEach(addMapMarker);
};
function addMapMarker(data) {
const key = `${data.lat},${data.lng}`;
if(markersOnMap[key]) return; // すでにある場合は追加しない
const m = L.marker([data.lat, data.lng]).addTo(map);
const circleId = `circle-${key}`;
const btnId = `resolve-btn-${key}`;
// 初期 popup HTML
m.bindPopup(`
【送信済み】<br>
被害情報: ${data.text0}<br>
症状1: ${data.text1}<br>
症状2: ${data.text2}<br>
症状3: ${data.text3}<br>
<div id="${circleId}" style="
width: 20px;
height: 20px;
background-color: ${data.resolved ? "green" : "red"};
border-radius: 50%;
display: inline-block;
margin-top: 5px;
"></div>
<button id="${btnId}">${data.resolved ? "解決済み" : "未解決"}</button>
`);
m.on("popupopen", async function() {
const btn = document.getElementById(btnId);
const circle = document.getElementById(circleId);
if(btn && circle && !data.resolved) {
btn.onclick = async () => {
circle.style.backgroundColor = "green";
btn.disabled = true;
btn.innerText = "解決済み";
// サーバーに解決状態を送信
data.resolved = true;
await fetch("http://localhost:3000/markers", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
});
};
}
});
}