class MapApp { constructor() { this.map = null; this.layerManager = new LayerManager(); this.sidebarManager = null; this.coordinatesBalloon = null; this.rasterLayer = null; } init() { ymaps.ready(() => { this.createMap(); this.sidebarManager = new SidebarManager(this); this.loadCollectionInfo(); this.loadAllObjects(); this.initCoordinatesTool(); this.initMapClickHandler(); }); } createMap() { this.map = new ymaps.Map("map", { center: [55.89724, 37.81824], zoom: 15, type: 'yandex#satellite' }); } // Инициализация инструмента координат initCoordinatesTool() { this.map.events.add('click', (e) => { const coords = e.get('coords'); const lat = coords[0].toFixed(5); const lon = coords[1].toFixed(5); this.showCoordinatesBalloon(coords, `${lat}, ${lon}`); }); } // Обработчик кликов по карте (не по объектам) initMapClickHandler() { this.map.events.add('click', (e) => { // Если кликнули не по объекту (по карте) if (!e.get('target').properties) { // Закрываем балун координат this.closeCoordinatesBalloon(); // Закрываем панель объекта if (this.sidebarManager && this.sidebarManager.isDetailsPanelOpen()) { this.sidebarManager.hideObjectDetails(); } } }); } // Показать балун с координатами showCoordinatesBalloon(coords, coordString) { if (this.coordinatesBalloon) { this.coordinatesBalloon.close(); } this.coordinatesBalloon = new ymaps.Balloon(this.map, { content: this.createCoordinatesContent(coordString), layout: 'default#imageWithContent', position: coords }); this.coordinatesBalloon.open(coords); } // Создание содержимого балуна createCoordinatesContent(coordString) { return `
${coordString}
`; } // Закрытие балуна координат closeCoordinatesBalloon() { if (this.coordinatesBalloon) { this.coordinatesBalloon.close(); this.coordinatesBalloon = null; } } // Добавление растрового слоя async addRasterLayer(config) { try { const style = this.getRasterStyle(config.layers); const rasterLayer = new ymaps.GeoObject({ geometry: { type: 'Rectangle', coordinates: config.bounds } }, { fillMethod: 'stretch', fillImageHref: config.url, fillOpacity: style.fillOpacity || config.opacity || 0.7, stroke: false, zIndex: style.zIndex || 100 }); if (this.sidebarManager) { this.sidebarManager.addRasterLayer(config, rasterLayer); } return rasterLayer; } catch (error) { console.error('Ошибка загрузки растрового слоя:', config.name, error); } } // Получение стилей для растровых слоев getRasterStyle(layers) { if (layers && layers.length > 0) { for (let layer of layers) { const layerKey = `layer:${layer}`; if (StyleRules[layerKey]) { return StyleRules[layerKey]; } } } return {}; } async loadCollectionInfo() { try { const response = await fetch('data/collection.json'); const collection = await response.json(); console.log('Коллекция загружена:', collection.name); document.title = collection.name; } catch (error) { console.error('Ошибка загрузки коллекции:', error); } } async loadRasterLayers() { try { const response = await fetch('data/raster-configs.json'); const config = await response.json(); console.log('Загружено растровых слоев:', config.rasters.length); for (const rasterConfig of config.rasters) { await this.addRasterLayer(rasterConfig); } } catch (error) { console.error('Ошибка загрузки конфига растров:', error); } } async loadAllObjects() { try { const objectsList = await this.getObjectsList(); console.log(`Найдено объектов: ${objectsList.length}`); const loadPromises = objectsList.map(file => this.loadObject(`data/objects/${file}`) ); await Promise.all(loadPromises); console.log('Все объекты загружены и отображены'); await this.loadRasterLayers(); this.sidebarManager.applyInitialVisibility(); } catch (error) { console.error('Ошибка загрузки объектов:', error); } } async getObjectsList() { try { const response = await fetch('data/objects-index.json'); const index = await response.json(); console.log(`Загружен индекс: ${index.files.length} файлов`); return index.files; } catch (error) { console.error('Ошибка загрузки objects-index.json:', error); return []; } } async loadObject(filePath) { try { const response = await fetch(filePath); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const feature = await response.json(); console.log(`Загружен: ${feature.properties.name}`); const mapObjects = this.layerManager.addObject(feature, this.map); const fileName = filePath.split('/').pop().replace('.json', ''); this.sidebarManager.addObject(feature, mapObjects.main, mapObjects.vertices, fileName); } catch (error) { console.error(`Ошибка загрузки ${filePath}:`, error); } } } // Глобальные функции для кнопок в балуне function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { console.log('Координаты скопированы: ' + text); }).catch(err => { console.error('Ошибка копирования: ', err); }); } function closeCoordinatesBalloon() { if (window.app && window.app.closeCoordinatesBalloon) { window.app.closeCoordinatesBalloon(); } } const app = new MapApp(); window.app = app; app.init();