Newer
Older
sunapara / building_zenkai.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>ビル内テナントマップ(角度ずらし重なり回避)</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js"></script>
  <style>
    #map { width: 100%; height: 600px; }
  </style>
</head>
<body>
  <h2>ビル内テナントマップ(1F・2F・3F 角度ずらし表示)</h2>
  <div id="map"></div>

  <script>
    const map = L.map('map').setView([38.917, 139.839], 16);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    const csvUrl = 'snackbuilding.csv';

    // 階ごとのオフセット(半径と角度でずらす)
    const floorOffsets = {
      '1F': { r: 0.00008, theta: 0 },      // 0度
      '2F': { r: 0.00008, theta: 120 },    // 120度
      '3F': { r: 0.00008, theta: 240 }     // 240度
    };

    // 階ごとのマーカー色
    const floorColors = {
      '1F': 'red',
      '2F': 'blue',
      '3F': 'green'
    };

    function createIcon(color) {
      return new L.Icon({
        iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-${color}.png`,
        shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
        iconSize: [25, 41],
        iconAnchor: [12, 41],
        popupAnchor: [1, -34],
        shadowSize: [41, 41]
      });
    }

    // 度→ラジアン変換
    function toRad(deg) {
      return deg * Math.PI / 180;
    }

    Papa.parse(csvUrl, {
      download: true,
      header: true,
      complete: function(results) {
        const data = results.data;

        data.forEach(row => {
          if (!row.building_name || !row.lat || !row.lon || !row.floor) return;

          const baseLat = parseFloat(row.lat);
          const baseLon = parseFloat(row.lon);
          const floor = row.floor;

          // オフセット計算
          const offset = floorOffsets[floor] || { r: 0, theta: 0 };
          const dLat = offset.r * Math.cos(toRad(offset.theta));
          const dLon = offset.r * Math.sin(toRad(offset.theta));
          const lat = baseLat + dLat;
          const lon = baseLon + dLon;

          const color = floorColors[floor] || 'gray';
          const icon = createIcon(color);

          const popupHtml = `
            <b>${row.building_name}</b><br>
            ${floor}: ${row.shop_name}(${row.category})
          `;

          L.marker([lat, lon], { icon })
            .addTo(map)
            .bindPopup(popupHtml);
        });
      }
    });
  </script>
</body>
</html>