let map_all, free_entrance, free_homesteads; const Territory_Map = { async init() { let html = await fetch('/lib/pages/territory/map/index.html').then((response) => response.text()); app.innerHTML = html; Territory_Map.map.init(); Territory_Map.info.setHTML(); }, info: { async loadAPI(url) { const uuid = localStorage.getItem("uuid"); const response = await fetch(url, { method: 'GET', headers: { "Content-Type": "application/json", "Authorization": uuid } }); return await response.json(); }, async setHTML() { const houses = await Territory_Map.info.loadAPI(`${CONFIG.api}houses/list`); const homestead = await Territory_Map.info.loadAPI(`${CONFIG.api}homestead/list`); Territory_Map.map.added({ type: "house", data: houses }); Territory_Map.map.added({ type: "homestead", data: homestead }); } }, map: { polygons: [], init() { if (map_all && map_all.remove) map_all.remove(); const mapElement = document.getElementById('map'); if (!mapElement) return; let firstLocate = true; let googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', { maxZoom: 20, minZoom: 15, subdomains: ['mt0', 'mt1', 'mt2', 'mt3'] }); let osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { }); let mytile = L.tileLayer('https://sheep-service.com/map/{z}/{x}/{y}.webp', { maxZoom: 20, minZoom: 15, tms: true }); free_entrance = new L.FeatureGroup(); free_homesteads = new L.FeatureGroup(); map_all = L.map(mapElement, { renderer: L.canvas(), center: [49.5629016, 25.6145625], zoom: 17, zoomControl: false, layers: [ googleHybrid, osm, mytile, free_entrance, free_homesteads ] }); map_all.locate({ setView: true, // 🔥 сразу центрирует карту maxZoom: 16 }); let baseMaps = { "Google Hybrid": googleHybrid, "OpenStreetMap": osm, "Sheep Service Map": mytile, }; let baseLayer = { "Вільні під'їзди": free_entrance, "Вільні райони": free_homesteads }; L.control.layers(baseMaps, baseLayer, { position: 'bottomright' }).addTo(map_all); map_all.pm.setLang("ua"); map_all.on('zoomend', () => { const z = map_all.getZoom(); if (z <= 15) { map_all.removeLayer(free_homesteads); } else { map_all.addLayer(free_homesteads); } if (z <= 16) { map_all.removeLayer(free_entrance); } else { map_all.addLayer(free_entrance); } }); // слежение в реальном времени map_all.locate({ setView: false, watch: true, enableHighAccuracy: true }); map_all.on('locationfound', (e) => { if (firstLocate) map_all.setView(e.latlng, 16); if (!map_all._userMarker) { map_all._userMarker = L.marker(e.latlng).addTo(map_all).bindPopup(""); map_all._userMarker.on("popupopen", () => { const div = document.createElement("div"); div.className = 'marker_popup' div.innerHTML = `
Ви тут!
`; map_all._userMarker.setPopupContent(div); }); } else { map_all._userMarker.setLatLng(e.latlng); } firstLocate = false; }); }, added({ type, data }) { for (let index = 0; index < data.length; index++) { const element = data[index]; let posPersonal, posGroup; let polygonOptions = type === "homestead" ? { color: "#f2bd53", radius: 500, fillOpacity: 0.3, dashArray: '20,15', dashOffset: '20', } : { color: "#585858", fillColor: "#f2bd53", fillOpacity: 0.8 }; if (type === "homestead") { posPersonal = Home.personal.homestead.list.map(e => e.id).indexOf(element.id); posGroup = Home.group.homestead.list.map(e => e.id).indexOf(element.id); if (posPersonal != -1 || posGroup != -1) { polygonOptions = { color: "#9a77c9", fradius: 500, fillOpacity: 0.3, dashArray: '20,15', dashOffset: '20', } } this.marker({ id: element.id, type: 'homestead', free: element.working ? 0 : 1, geo: element.geo }) } else { posPersonal = Home.personal.house.list.map(e => e.id).indexOf(element.id); posGroup = Home.group.house.list.map(e => e.id).indexOf(element.id); if (posPersonal != -1 || posGroup != -1) { polygonOptions = { color: "#585858", fillColor: "#9a77c9", fillOpacity: 0.8 } } this.marker({ id: element.id, type: 'house', free: element.entrance.quantity - element.entrance.working, geo: element.geo }) } const polygon = L.polygon(element.points, polygonOptions).addTo(map_all); polygon.bindPopup(""); // при открытии popup генерим div заново polygon.on("popupopen", () => { const div = document.createElement("div"); let text = () => { if (posPersonal != -1) return `Моя територія${element.title} ${element.number}
Перейти до території` else if (posGroup != -1) return `Групова територія${element.title} ${element.number}
Перейти до території` return `${element.title} ${element.number}
` } div.className = 'marker_popup' div.innerHTML = `${text()}`; if (USER.possibilities.can_manager_territory || USER.mode == 2) div.innerHTML += `Керування`; polygon.setPopupContent(div); }); // Territory_Map.map.polygons[type][element.id] = polygon; // сохраним ссылку на маркер } }, marker({ id, type, free, geo }) { if (!USER.possibilities.can_manager_territory || USER.mode != 2) return; if (free <= 0) return; const redDot = L.divIcon({ className: "marker", html: `${free}`, iconSize: [30, 30], iconAnchor: [15, 15] }); // создаём маркер const marker = L.marker([geo.lat, geo.lng], { icon: redDot }).addTo(type == 'homestead' ? free_homesteads : free_entrance); marker.bindPopup(""); // при открытии popup генерим div заново marker.on("popupopen", () => { const div = document.createElement("div"); div.className = 'marker_popup' div.innerHTML = `Перейти до території`; marker.setPopupContent(div); }); } } }