class MapSelector { constructor(options = {}) { this.options = { onSelectionConfirmed: () => {}, initialCenter: [46.603354, 1.888334], initialZoom: 6, initialSelections: [], ...options }; this.isInitialized = false; this.map = null; this.drawnItems = null; this.drawControl = null; this.selectedAreas = options.initialSelections || []; this.searchResultsLayer = null; this.activeMode = 'search'; this.modalWrapper = null; this._eventsBound = false; this.isEditing = false; this.hasMultiPolygon = false; // Initialisation des managers this.drawingManager = new MapDrawingManager(this); this.searchManager = new MapSearchManager(this); this.geoJSONHandler = new GeoJSONHandler(this); this.uiManager = new UIManager(this); } setInitialSelections(selections) { if (this.isInitialized) { this.geoJSONHandler.clearAllPolygons(); } this.options.initialSelections = selections; this.selectedAreas = this.options.initialSelections; if (this.isInitialized) { this.initSelection(selections); } } open() { this._findModalWrapper(); this._showModal(); this._bindEventsIfNeeded(); this._initMapWithDelay(); this.modalWrapper.style.display = 'flex'; this.uiManager.updateSelectedAreasList(); } close() { if (this.modalWrapper) { this.modalWrapper.classList.add('hidden'); } } initMap() { this.isInitialized = true; if (this.map) { this.map.invalidateSize(); return; } this._setupLeafletPatches(); this._createMap(); this._setupLayers(); this.drawingManager.setupDrawControls(); this.drawingManager.setupMapEvents(); if (this.options.initialSelections.length > 0) { this.initSelection(this.options.initialSelections); const bounds = this.drawnItems.getBounds(); if (bounds.isValid()) { this.map.fitBounds(bounds, { padding: [50, 50] }); } } this.searchManager.initSearchControls(); setTimeout(() => { this.map.invalidateSize(); this.drawingManager.replaceDrawIcons(); }, 200); this.setMode(this.activeMode); } initSelection(selections) { selections?.forEach(selection => { this.drawingManager.disableEditingForMultiPolygon(selection); this.geoJSONHandler.renderGeoJSONOnMap(selection); }); } setMode(mode) { this.activeMode = mode; const drawControls = document.querySelector('.leaflet-draw'); const searchInputContainer = document.querySelector('.mapSearchInputContainer'); if (mode === 'draw') { drawControls?.classList.remove('hidden'); searchInputContainer?.classList.add('hidden'); } else if (mode === 'search') { drawControls?.classList.add('hidden'); searchInputContainer?.classList.remove('hidden'); } // Mise à jour des boutons const drawModeBtn = document.querySelector('#drawModeBtn'); const searchModeBtn = document.querySelector('#searchModeBtn'); if (drawModeBtn && searchModeBtn) { drawModeBtn.classList.toggle('active', mode === 'draw'); searchModeBtn.classList.toggle('active', mode === 'search'); } } _findModalWrapper() { this.modalWrapper = document.querySelector('.mapSelectorModalWrapper'); if (!this.modalWrapper) { console.error("Erreur: Impossible de trouver l'élément .mapSelectorModalWrapper"); return false; } return true; } _showModal() { this.modalWrapper.classList.remove('hidden'); this.modalWrapper.style.display = 'flex'; } _bindEventsIfNeeded() { if (!this._eventsBound) { this.uiManager.bindEvents(); this._eventsBound = true; } } _initMapWithDelay() { setTimeout(() => { this.initMap(); }, 50); } _setupLeafletPatches() { this._patchGeometryUtil(); this._patchDrawLocal(); } _createMap() { this.map = L.map('map', { zoomControl: false, attributionControl: false, }).setView(this.options.initialCenter, this.options.initialZoom); L.control .zoom({ position: "topright", }) .addTo(this.map); L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { maxZoom: 19 }).addTo(this.map); } _setupLayers() { this.drawnItems = new L.FeatureGroup(); this.map.addLayer(this.drawnItems); this.searchResultsLayer = new L.FeatureGroup(); this.map.addLayer(this.searchResultsLayer); } _patchGeometryUtil() { if (L.GeometryUtil && L.GeometryUtil.readableDistance) { const originalReadableDistance = L.GeometryUtil.readableDistance; L.GeometryUtil.readableDistance = function(distance, unit, precision, isNauticalMile) { if (distance === null || distance === undefined) { distance = 0; } else if (typeof distance === 'string') { distance = parseFloat(distance); if (isNaN(distance)) distance = 0; } else if (typeof distance !== 'number') { console.warn('Type de distance non pris en charge:', typeof distance, distance); try { distance = Number(distance); if (isNaN(distance)) distance = 0; } catch (e) { distance = 0; } } return originalReadableDistance.call(this, distance, unit, precision, isNauticalMile); }; } } _patchDrawLocal() { if (L.drawLocal && L.drawLocal.draw && L.drawLocal.draw.handlers) { const originalFormatArea = L.drawLocal.draw.handlers.circle && L.drawLocal.draw.handlers.circle.tooltip && L.drawLocal.draw.handlers.circle.tooltip.radius; if (originalFormatArea) { const originalFunction = L.Draw.Circle.prototype._getTooltipText; L.Draw.Circle.prototype._getTooltipText = function() { try { return originalFunction.call(this); } catch (error) { console.warn('Erreur lors de la génération du texte de tooltip:', error); return { text: 'Dessinez un cercle en cliquant et faisant glisser.' }; } }; } } } clearSelection() { this.selectedAreas = []; if (this.drawnItems) { this.drawnItems.clearLayers(); } if (this.searchResultsLayer) { this.searchResultsLayer.clearLayers(); } this.drawingManager.updateMultiPolygonState(); this.uiManager.updateSelectedAreasList(); } getSelectedAreas() { return [...this.selectedAreas]; } setupEditingEvents() { this.map.on('draw:editstart', () => { this.isEditing = true; const confirmBtn = document.querySelector('#confirmSelectionBtn'); const closeBtn = document.querySelector('.mapSelectorCloseBtn'); if (confirmBtn) confirmBtn.classList.add('disabled'); if (closeBtn) closeBtn.classList.add('disabled'); }); this.map.on('draw:editstop', () => { this.isEditing = false; const confirmBtn = document.querySelector('#confirmSelectionBtn'); const closeBtn = document.querySelector('.mapSelectorCloseBtn'); if (confirmBtn) confirmBtn.classList.remove('disabled'); if (closeBtn) closeBtn.classList.remove('disabled'); }); } } window.MapSelector = MapSelector;