Newer
Older
instance / rescue / help.js
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)
                });
            };
        }
    });
}