/
melissaaaz
/
MemoryOffice
Обзор
Документация
Войти
/
melissaaaz
/
MemoryOffice
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
front/src/components/Map.jsx
106 строк
4 KB
melissaaaz
upload files Frontend
19 дек 2025, 21:55
19 дек 2025, 21:55
bb001d3
Код
Авторство
О чём код?
import React, { useEffect } from 'react' import L from 'leaflet' import 'leaflet/dist/leaflet.css' delete L.Icon.Default.prototype._getIconUrl L.Icon.Default.mergeOptions({ iconRetinaUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png', iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png', shadowUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png', }) const MapCity = ({ routePoints = [], className = '', city = 'kaliningrad' }) => { const mapRef = React.useRef(null) const mapInstanceRef = React.useRef(null) // Конфигурация для разных городов const cityConfig = { kaliningrad: { center: [54.7065, 20.511], // Калининград zoom: 13, defaultPoints: [ { lat: 54.7065, lng: 20.511, title: 'Кафедральный собор' }, { lat: 54.702, lng: 20.514, title: 'Рыбная деревня' }, { lat: 54.708, lng: 20.501, title: 'Музей янтаря' }, { lat: 54.710, lng: 20.509, title: 'Кирха Св. Семейства' }, { lat: 54.712, lng: 20.507, title: 'Площадь Победы' }, ], tileStyle: 'light_all', borderColor: 'border-amber-300/50', label: 'Калининграда', textColor: 'text-amber-700' }, moscow: { center: [55.7558, 37.6173], // Москва zoom: 11, defaultPoints: [ { lat: 55.7520, lng: 37.6175, title: 'Кремль' }, { lat: 55.7539, lng: 37.6208, title: 'Красная площадь' }, { lat: 55.757, lng: 37.615, title: 'Большой театр' }, { lat: 55.744, lng: 37.619, title: 'Арбат' }, { lat: 55.749, lng: 37.540, title: 'Москва-Сити' }, ], tileStyle: 'light_all', borderColor: 'border-red-300/50', label: 'Москвы', textColor: 'text-red-700' } } // Получаем конфигурацию для текущего города const config = cityConfig[city] || cityConfig.kaliningrad useEffect(() => { if (!mapRef.current || mapInstanceRef.current) return // Инициализация карты с настройками для текущего города const map = L.map(mapRef.current).setView(config.center, config.zoom) mapInstanceRef.current = map L.tileLayer(`https://{s}.basemaps.cartocdn.com/${config.tileStyle}/{z}/{x}/{y}{r}.png`, { attribution: '© OpenStreetMap contributors © CARTO', maxZoom: 19, }).addTo(map) // Используем переданные точки маршрута или точки по умолчанию для города const points = routePoints.length > 0 ? routePoints : config.defaultPoints points.forEach((point, index) => { // Создаем кастомные иконки для разных городов const icon = L.icon({ iconUrl: city === 'moscow' ? 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-red.png' : 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-orange.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png', shadowSize: [41, 41] }) const marker = L.marker([point.lat, point.lng], { icon }).addTo(map) marker.bindPopup(`<b>${point.title}</b><br>Точка маршрута ${index + 1}`) }) return () => { if (mapInstanceRef.current) { mapInstanceRef.current.remove() mapInstanceRef.current = null } } }, [routePoints, config, city]) return ( <div className={`relative rounded-xl overflow-hidden border-2 shadow-vintage-lg ${config.borderColor} ${className}`}> <div ref={mapRef} className="h-96 w-full z-0" /> <div className={`absolute top-4 left-4 bg-white/90 backdrop-blur-sm rounded-lg p-3 shadow-vintage z-[1000] ${config.textColor}`}> <p className="text-sm font-medium">Карта {config.label}</p> </div> </div> ) } export default MapCity