<!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>