Перейти к содержанию

Widget:KidsMap

Материал из Город на ладошках
 <button id="refreshMapBtn" style="background: #1565c0; color: white; border: none; padding: 6px 16px; border-radius: 20px; font-size: 14px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;">
   🔄 Обновить карту
 </button>
 

<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />

<style> .emoji-marker {

   background: white;
   border-radius: 50%;
   border: 2px solid #2e7d32;
   text-align: center;
   font-size: 18px;
   line-height: 28px;
   width: 28px !important;
   height: 28px !important;
   box-shadow: 0 2px 4px rgba(0,0,0,0.2);

}

  1. refreshStatus {
   font-size: 12px;
   color: #888;

} </style>

<script> var map = L.map('map').setView([59.9343, 30.3351], 12); L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {

   maxZoom: 19,
   attribution: '© OpenStreetMap'

}).addTo(map);

function getIconByType(type) {

   const icons = {
       'Парк': '🌳', 'Памятник': '🗿', 'Музей': '🏛️', 'Церковь': '⛪',
       'Школа': '🏫', 'Кафе': '☕', 'Мост': '🌉', 'Фонтан': '⛲',
       'Театр': '🎭', 'Библиотека': '📚', 'Стадион': '⚽', 'Аквапарк': '💦',
       'Зоопарк': '🐘', 'Кинотеатр': '🎬', 'Торговый центр': '🛍️',
       'Вокзал': '🚂', 'Гостиница': '🏨', 'Ресторан': '🍽️', 'Набережная': '🌊',
       'Сад': '🌿', 'Сквер': '🌳', 'Дворец': '🏰', 'Собор': '⛪',
       'Часовня': '🕯️', 'Монастырь': '🏯', 'Улица': '🛤️', 'Переулок': '🏘️',
       'Река': '🌊', 'Канал': '🌊', 'Остров': '🏝️', 'Метро': '🚇',
       'Скульптура': '🗿', 'Галерея': '🖼️', 'Выставка': '🎨',
       'Концертный зал': '🎵', 'Спорткомплекс': '🏟️', 'Клуб': '🎶',
       'Рынок': '🏪', 'Аптека': '💊', 'Больница': '🏥', 'Университет': '🎓',
       'Архив': '📜', 'Детский центр': '🧸', 'Парк аттракционов': '🎡',
       'Океанариум': '🐠', 'Дельфинарий': '🐬', 'Планетарий': '🌌',
       'Причал': '⚓', 'Смотровая площадка': '🌅', 'Арка': '🚪',
       'Детская площадка': '🧒', 'Спортплощадка': '⚽', 'Беговая дорожка': '🏃',
       'Велодорожка': '🚴', 'Скейт-парк': '🛹', 'Пляж': '🏖️',
       'Пруд': '🦆', 'Озеро': '🏞️', 'Лес': '🌲', 'Карьер': '⛏️',
       'Крепость': '🏯', 'Форт': '🛡️', 'Подземелье': '🕳️', 'Тоннель': '🚇',
       'Бизнес-центр': '🏢', 'Хостел': '🏨', 'Дом': '🏠', 'Завод': '🏭',
       'Фабрика': '🏭', 'Маяк': '🗼', 'Башня': '🗼', 'Стенд': '📋',
       'Скамейка': '🪑', 'Другое': '📍'
   };
   return L.divIcon({
       html: icons[type] || '📍',
       iconSize: [28, 28],
       className: 'emoji-marker',
       popupAnchor: [0, -14]
   });

}

function drawMarkers() {

   document.getElementById('loading-message').style.display = 'block';
   document.getElementById('refreshStatus').textContent = 'Загрузка...';
   
   fetch('/data.php?_=' + Date.now())
       .then(response => {
           if (!response.ok) throw new Error('HTTP ' + response.status);
           return response.json();
       })
       .then(data => {
           console.log('Данные загружены, объектов:', data.length);
           map.eachLayer(layer => {
               if (layer instanceof L.Marker) map.removeLayer(layer);
           });
           
           data.forEach(obj => {
               var lat = parseFloat(obj.lat);
               var lon = parseFloat(obj.lon);
               if (isNaN(lat) || isNaN(lon)) return;
               
               var icon = getIconByType(obj.type);
               var popupHtml = '' + obj.name + '
' + 'Тип: ' + obj.type + '
' + obj.address + '
'; if (obj.quest) popupHtml += '🎯 Квест: ' + obj.quest + '
'; if (obj.image) popupHtml += '<img src="' + obj.image + '" style="max-width:150px; max-height:100px; margin-top:8px; border-radius:8px;">
'; if (obj.description) popupHtml += 'Описание: ' + obj.description + '
'; if (obj.page) popupHtml += '<a href="/index.php/' + encodeURIComponent(obj.page) + '" target="_blank">📖 Читать подробнее</a>'; L.marker([lat, lon], {icon: icon}).addTo(map).bindPopup(popupHtml); }); document.getElementById('loading-message').style.display = 'none'; document.getElementById('refreshStatus').textContent = '✅ Обновлено (' + data.length + ' мест)'; if (data.length === 0) { document.getElementById('loading-message').innerHTML = '😕 Нет мест. Добавь первое!'; document.getElementById('loading-message').style.display = 'block'; } }) .catch(error => { console.error('Ошибка загрузки данных:', error); document.getElementById('loading-message').innerHTML = '⚠️ Не удалось загрузить данные. Попробуйте позже.'; document.getElementById('loading-message').style.display = 'block'; document.getElementById('refreshStatus').textContent = '❌ Ошибка'; });

}

function recreateCargoTable() {

   return fetch('/index.php/Шаблон:Объект_en?action=recreatedata')
       .then(response => {
           if (!response.ok) throw new Error('HTTP ' + response.status);
           return response.text();
       })
       .then(() => {
           console.log('Таблица Cargo пересоздана');
           // Ждём 1 секунду, чтобы Cargo успел обновиться
           return new Promise(resolve => setTimeout(resolve, 1000));
       });

}

function refreshMap() {

   var status = document.getElementById('refreshStatus');
   status.textContent = '⏳ Пересоздание таблицы...';
   
   recreateCargoTable()
       .then(() => {
           status.textContent = '⏳ Загрузка данных...';
           return drawMarkers();
       })
       .catch(error => {
           console.error('Ошибка пересоздания таблицы:', error);
           status.textContent = '⚠️ Ошибка, попробуйте позже';
           // Даже если пересоздание не сработало, пробуем загрузить данные
           drawMarkers();
       });

}

// Инициализация drawMarkers();

// Обработчик кнопки document.getElementById('refreshMapBtn').addEventListener('click', function() {

   refreshMap();

});

var attributionControl = map.attributionControl; if (attributionControl) {

   attributionControl.setPrefix();
   var style = document.createElement('style');
   style.innerHTML = '.leaflet-attribution-flag { display: none !important; }';
   document.head.appendChild(style);

} </script>