(function () { const config = window.HaritaConfig || {}; const mapElement = document.getElementById('sehirHafizaMap'); const emptyElement = document.getElementById('haritaEmpty'); const countElement = document.getElementById('haritaVisibleCount'); const searchElement = document.getElementById('haritaSearch'); const filterElements = Array.from(document.querySelectorAll('.harita-filters input[type="checkbox"]')); if (!mapElement || typeof L === 'undefined') { return; } const typeLabels = { mekan: 'Mekân', fotograf: 'Fotoğraf', hatira: 'Hatıra', etkinlik: 'Etkinlik' }; const iconClasses = { mekan: 'fas fa-landmark', fotograf: 'fas fa-camera', 'fotograf-360': 'fas fa-vr-cardboard', hatira: 'fas fa-comment-dots', etkinlik: 'fas fa-calendar-alt' }; const map = L.map(mapElement, { scrollWheelZoom: true, preferCanvas: true }).setView(config.center || [39.75, 37.0167], config.zoom || 12); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap contributors' }).addTo(map); const cluster = L.markerClusterGroup({ showCoverageOnHover: false, maxClusterRadius: 48 }); map.addLayer(cluster); let items = []; let markers = []; fetch(config.endpoint, { headers: { Accept: 'application/json' } }) .then((response) => response.ok ? response.json() : Promise.reject(response)) .then((data) => { items = Array.isArray(data) ? data : []; markers = items.map(createMarker).filter(Boolean); applyFilters(); }) .catch(() => { items = []; markers = []; applyFilters(); }); filterElements.forEach((input) => input.addEventListener('change', applyFilters)); if (searchElement) { searchElement.addEventListener('input', applyFilters); } function createMarker(item) { if (!Number.isFinite(Number(item.lat)) || !Number.isFinite(Number(item.lng))) { return null; } const marker = L.marker([Number(item.lat), Number(item.lng)], { icon: createIcon(item) }); marker.hafizaItem = item; marker.bindPopup(createPopup(item), { maxWidth: 280, className: 'harita-popup-container' }); return marker; } function createIcon(item) { const iconType = item.is_360 ? 'fotograf-360' : item.icon; const className = iconClasses[iconType] || 'fas fa-map-marker-alt'; return L.divIcon({ className: '', html: '
', iconSize: [34, 34], iconAnchor: [17, 17], popupAnchor: [0, -18] }); } function createPopup(item) { const title = escapeHtml(item.title || 'İsimsiz İçerik'); const description = escapeHtml(item.description || ''); const type = escapeHtml(typeLabels[item.type] || item.type || 'İçerik'); const badge = item.is_360 ? '360°' : ''; const url = escapeAttribute(item.url || '#'); const thumbnailUrl = item.thumbnail_url ? escapeAttribute(item.thumbnail_url) : ''; const thumbnail = thumbnailUrl ? '' + title + '' : ''; return [ '
', thumbnail, '

' + title + '

', '
' + type + '' + badge + '
', description ? '

' + description + '

' : '', 'Detaya Git', '
' ].join(''); } function applyFilters() { const selected = getSelectedFilters(); const query = normalize(searchElement ? searchElement.value : ''); const visibleMarkers = markers.filter((marker) => { const item = marker.hafizaItem; const matchesType = matchesSelectedType(item, selected); const matchesQuery = !query || normalize(item.title || '').includes(query); return matchesType && matchesQuery; }); cluster.clearLayers(); cluster.addLayers(visibleMarkers); if (countElement) { countElement.textContent = String(visibleMarkers.length); } if (emptyElement) { emptyElement.hidden = visibleMarkers.length > 0; } if (visibleMarkers.length > 0) { const bounds = L.featureGroup(visibleMarkers).getBounds(); if (bounds.isValid() && visibleMarkers.length > 1) { map.fitBounds(bounds.pad(0.15), { maxZoom: 15 }); } else { map.setView(visibleMarkers[0].getLatLng(), Math.max(map.getZoom(), config.zoom || 12)); } } } function getSelectedFilters() { return filterElements.reduce((selected, input) => { selected[input.value] = input.checked; return selected; }, {}); } function matchesSelectedType(item, selected) { if (item.type === 'fotograf') { return item.is_360 ? Boolean(selected.fotograf360) : Boolean(selected.fotograf); } return Boolean(selected[item.type]); } function normalize(value) { return String(value) .toLocaleLowerCase('tr-TR') .normalize('NFD') .replace(/[\u0300-\u036f]/g, '') .trim(); } function escapeHtml(value) { return String(value).replace(/[&<>"']/g, function (char) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[char]; }); } function escapeAttribute(value) { return escapeHtml(value).replace(/`/g, '`'); } })();