document.addEventListener('DOMContentLoaded', function() { var map, layer, data = []; var urlParams = new URLSearchParams(window.location.search); var areaKey = urlParams.get('area') || 'chugoku'; var areaSettings = { 'hokkaido': { title: '北海道', center: [43.3, 142.8], zoom: 7, bounds: { minLat: 41.0, maxLat: 45.6, minLng: 139.0, maxLng: 146.0 } }, 'tohoku': { title: '東北地方', center: [39.0, 140.5], zoom: 7, bounds: { minLat: 37.0, maxLat: 41.6, minLng: 138.5, maxLng: 142.5 } }, 'kanto': { title: '関東地方', center: [36.0, 139.5], zoom: 8, bounds: { minLat: 34.5, maxLat: 37.5, minLng: 138.0, maxLng: 141.0 } }, 'koshinetsu': { title: '甲信越地方', center: [36.5, 138.0], zoom: 8, bounds: { minLat: 35.0, maxLat: 38.5, minLng: 137.0, maxLng: 139.5 } }, 'chubu': { title: '中部地方', center: [35.5, 137.0], zoom: 8, bounds: { minLat: 34.0, maxLat: 37.5, minLng: 135.5, maxLng: 138.5 } }, 'kinki': { title: '近畿地方', center: [34.5, 135.5], zoom: 8, bounds: { minLat: 33.0, maxLat: 36.0, minLng: 134.0, maxLng: 136.5 } }, 'chugoku': { title: '中国地方', center: [35.375, 133.535], zoom: 9, bounds: { minLat: 33.0, maxLat: 36.5, minLng: 130.5, maxLng: 134.5 } }, 'shikoku': { title: '四国地方', center: [33.766, 133.116], zoom: 9, bounds: { minLat: 32.5, maxLat: 34.5, minLng: 132.0, maxLng: 135.0 } }, 'kyushu': { title: '九州地方', center: [32.5, 130.5], zoom: 8, bounds: { minLat: 30.0, maxLat: 34.0, minLng: 128.0, maxLng: 132.0 } } }; var currentArea = areaSettings[areaKey] || areaSettings['chugoku']; var titleEl = document.getElementById('map-title'); if (titleEl) { titleEl.innerHTML = '⛰️ ' + currentArea.title + ' 遭難・歴史・グルメ・温泉マップ'; } window.activeMountainFilter = 'all'; window.showHuts = false; window.showParking = false; // ★追加: 駐車場表示フラグ window.showGourmet = false; // グルメ表示フラグ window.showOnsen = false; // 温泉表示フラグ // ===== 登頂チェックリスト ===== window.MountainChecklist = { KEY: 'hokkaido_climbed_v1', getAll: function() { try { return JSON.parse(localStorage.getItem(this.KEY)) || {}; } catch(e) { return {}; } }, isClimbed: function(title) { return !!this.getAll()[title]; }, toggle: function(title) { var all = this.getAll(); if (all[title]) { delete all[title]; } else { all[title] = new Date().toISOString().split('T')[0]; } localStorage.setItem(this.KEY, JSON.stringify(all)); MountainChecklist.updateBar(data); }, updateBar: function(mountainData) { var b = currentArea.bounds; var mountains = mountainData.filter(function(d) { return (d.cat === '百名山' || d.cat === '二百名山' || d.cat === '三百名山') && d.lat >= b.minLat && d.lat <= b.maxLat && d.lng >= b.minLng && d.lng <= b.maxLng; }); var all = MountainChecklist.getAll(); var done = mountains.filter(function(d) { return !!all[d.title]; }).length; var total = mountains.length; var text = document.getElementById('checklist-progress-text'); var fill = document.getElementById('checklist-bar-fill'); if (text) text.textContent = done + ' / ' + total + '座 登頂済み'; if (fill) fill.style.width = total ? (done / total * 100) + '%' : '0%'; }, share: function() { var done = Object.keys(this.getAll()).length; var text = currentArea.title + 'の山を ' + done + '座 登頂しました! #日本百名山 #登山'; window.open( 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(text) + '&url=' + encodeURIComponent(location.href), '_blank' ); } }; window.handleClimbToggle = function(btn, title) { MountainChecklist.toggle(title); var isC = MountainChecklist.isClimbed(title); btn.className = 'btn-climbed ' + (isC ? 'done' : 'not-done'); btn.textContent = isC ? '✓ 登頂済み(タップで解除)' : '🏔 登頂済みにする'; }; // 山小屋トグル window.toggleHuts = function() { window.showHuts = !window.showHuts; var btn = document.getElementById('hut-toggle-btn'); if (btn) { btn.className = 'toggle-btn toggle-btn-hut ' + (window.showHuts ? 'on' : 'off'); } update(); }; // ★追加: 駐車場トグル window.toggleParking = function() { window.showParking = !window.showParking; var btn = document.getElementById('parking-toggle-btn'); if (btn) { btn.className = 'toggle-btn toggle-btn-parking ' + (window.showParking ? 'on' : 'off'); } update(); }; // グルメトグル window.toggleGourmet = function() { window.showGourmet = !window.showGourmet; var btn = document.getElementById('gourmet-toggle-btn'); if (btn) { btn.className = 'toggle-btn toggle-btn-gourmet ' + (window.showGourmet ? 'on' : 'off'); } update(); }; // 温泉トグル window.toggleOnsen = function() { window.showOnsen = !window.showOnsen; var btn = document.getElementById('onsen-toggle-btn'); if (btn) { btn.className = 'toggle-btn toggle-btn-onsen ' + (window.showOnsen ? 'on' : 'off'); } update(); }; function loadData() { Promise.all([ fetch('/wp-content/uploads/alldata.json?_t=' + Date.now()).then(function(r){ return r.json(); }), fetch('/wp-content/uploads/hut_data.json?_t=' + Date.now()).then(function(r){ return r.json(); }), fetch('/wp-content/uploads/parking_data.json?_t=' + Date.now()).then(function(r){ return r.json(); }) // ★追加 ]) .then(function(results) { var alldata = results[0]; var hutRaw = results[1]; var parkingRaw = results[2]; // ★追加 // hut_data.jsonを alldata.json と同じ形式に変換 var hutdata = []; Object.keys(hutRaw).forEach(function(mountainName) { hutRaw[mountainName].forEach(function(hut) { hutdata.push({ title: hut.name, cat: '山小屋', lat: hut.lat, lng: hut.lng, desc: mountainName + 'の山小屋', stat: '', year: '', age: '', sex: '' }); }); }); // ★追加: parking_data.jsonを alldata.json と同じ形式に変換 var parkingdata = []; Object.keys(parkingRaw).forEach(function(mountainName) { parkingRaw[mountainName].forEach(function(p) { parkingdata.push({ title: p.name, cat: '駐車場', lat: p.lat, lng: p.lng, desc: mountainName + 'の駐車場' + (p.vicinity ? '(' + p.vicinity + ')' : ''), stat: '', year: '', age: '', sex: '' }); }); }); data = alldata.concat(hutdata).concat(parkingdata).map(function(d) { // ★parkingdata追加 d.lat += (Math.random() - 0.5) * 0.0001; d.lng += (Math.random() - 0.5) * 0.0001; return d; }); initMap(); }) .catch(function(err){ console.error('Data loading error:', err); if(titleEl) titleEl.innerText = "データの読み込みに失敗しました"; }); } function initMap() { if (map) return; map = L.map('map-canvas').setView(currentArea.center, currentArea.zoom); L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png').addTo(map); layer = L.markerClusterGroup({ maxClusterRadius: 40, spiderfyOnMaxZoom: true }).addTo(map); var mountainLayer = L.layerGroup().addTo(map); var hutLayer = L.layerGroup().addTo(map); var parkingLayer = L.layerGroup().addTo(map); // ★追加 var gourmetLayer = L.layerGroup().addTo(map); var onsenLayer = L.layerGroup().addTo(map); window.filterMountain = function(cat) { window.activeMountainFilter = cat; var leg100 = document.getElementById('leg-100'); var leg200 = document.getElementById('leg-200'); var leg300 = document.getElementById('leg-300'); if(leg100) leg100.style.opacity = (cat === 'all' || cat === '百名山') ? '1' : '0.4'; if(leg200) leg200.style.opacity = (cat === 'all' || cat === '二百名山') ? '1' : '0.4'; if(leg300) leg300.style.opacity = (cat === 'all' || cat === '三百名山') ? '1' : '0.4'; update(); }; window.update = function() { layer.clearLayers(); mountainLayer.clearLayers(); hutLayer.clearLayers(); parkingLayer.clearLayers(); // ★追加 gourmetLayer.clearLayers(); onsenLayer.clearLayers(); var yV = document.getElementById('yearF').value, aV = document.getElementById('ageF').value, sV = document.getElementById('sexF').value, cV = document.getElementById('catF').value, stV = document.getElementById('statF').value; data.forEach(function(d) { var inArea = (d.lat >= currentArea.bounds.minLat && d.lat <= currentArea.bounds.maxLat && d.lng >= currentArea.bounds.minLng && d.lng <= currentArea.bounds.maxLng); var isMountain = (d.cat === '百名山' || d.cat === '二百名山' || d.cat === '三百名山'); var isHut = (d.cat === '山小屋'); var isParking = (d.cat === '駐車場'); // ★追加 var isGourmet = (d.cat === 'グルメ'); var isOnsen = (d.cat === '温泉'); // 山小屋は専用レイヤーで制御 if (inArea && isHut) { if (window.showHuts) { var hutIcon = L.divIcon({ html: '