Newer
Older
2025-shino / map2.html
<html>
<head>
<title>待ち合わせMAP</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
  <style>
    body { font-family: sans-serif; text-align: center; }
    #map { height: 500px; width: 90%; margin: 20px auto; border: 2px solid #aaa; }
    button { padding: 10px 20px; font-size: 16px; margin-top: 10px; }
    #nearest { font-size: 18px; margin-top: 15px; color: #333; font-weight: bold; }
  </style>
</head>
<body>
  <h1>現在地と近くの駅を表示</h1>
  <button onclick="getLocation()">現在地を取得して表示</button>
  <div id="map"></div>
  <p id="nearest"></p> <!-- ★ここに最寄り駅を表示 -->

  <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
  <script>
    let map = L.map('map').setView([35.6812, 139.7671], 13); // 初期位置:東京駅
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    function getLocation() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition, showError);
      } else {
        alert("このブラウザでは位置情報が使えません。");
      }
    }

    function showPosition(position) {
      const lat = position.coords.latitude;
      const lon = position.coords.longitude;

      map.setView([lat, lon], 15);

      // 現在地マーカー
      L.marker([lat, lon]).addTo(map)
        .bindPopup("📍 あなたの現在地").openPopup();

      searchStations(lat, lon, 2000); // 最初は2kmで検索
    }

    // ★ 駅検索関数
    function searchStations(lat, lon, radius) {
      const overpassUrl = `https://overpass-api.de/api/interpreter?data=[out:json];node["railway"="station"](around:${radius},${lat},${lon});out;`;

      fetch(overpassUrl)
        .then(response => response.json())
        .then(data => {
          if (data.elements.length === 0 && radius < 10000) {
            console.log(`駅が見つかりません。範囲を広げます: ${radius}m → ${radius * 2}m`);
            searchStations(lat, lon, radius * 2);
            return;
          }

          if (data.elements.length === 0) {
            document.getElementById("nearest").textContent = "10km以内に駅が見つかりませんでした。";
            return;
          }

          // 駅マーカーを追加
          data.elements.forEach(station => {
            const name = station.tags.name || "駅名不明";
            const sLat = station.lat;
            const sLon = station.lon;

            L.marker([sLat, sLon]).addTo(map)
              .bindPopup(`🚉 ${name}`);
          });

          // ★ 最寄り駅を特定
          const nearest = findNearestStation(lat, lon, data.elements);
          if (nearest) {
            const nearestName = nearest.tags.name || "駅名不明";
            document.getElementById("nearest").textContent =
              `現在地から近い駅は「${nearestName}駅」です!`;
          }
        })
        .catch(err => {
          console.error(err);
          alert("駅情報の取得に失敗しました。");
        });
    }

    // ★ 最寄り駅を探す関数(距離を計算)
    function findNearestStation(lat, lon, stations) {
      let nearest = null;
      let minDistance = Infinity;

      stations.forEach(station => {
        const sLat = station.lat;
        const sLon = station.lon;
        const distance = getDistance(lat, lon, sLat, sLon);
        if (distance < minDistance) {
          minDistance = distance;
          nearest = station;
        }
      });

      return nearest;
    }

    // ★ 2点間の距離をメートルで返す(Haversine formula)
    function getDistance(lat1, lon1, lat2, lon2) {
      const R = 6371000; // 地球の半径 (m)
      const dLat = (lat2 - lat1) * Math.PI / 180;
      const dLon = (lon2 - lon1) * Math.PI / 180;
      const a =
        Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(lat1 * Math.PI / 180) *
        Math.cos(lat2 * Math.PI / 180) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      return R * c;
    }

    function showError(error) {
      alert("位置情報を取得できませんでした: " + error.message);
    }
  </script>
</body>
</html>