PageSourceSearch

https://domicnoosa.com/wp-content/themes/domic/src/js/modules/maps.js?ver=1755825485

js domicnoosa.com collected 2026-09-26 17:25:47 UTC 6,332 bytes, 181 lines download raw bytes

1/**
2 * Map functionality using Leaflet and OpenStreetMap
3 * No API key required - completely free!
4 */
5
6class DomicMaps {
7    constructor() {
8        this.maps = new Map();
9        this.init();
10    }
11
12    init() {
13        // Wait for DOM to be ready
14        if (document.readyState === 'loading') {
15            document.addEventListener('DOMContentLoaded', () => this.initializeMaps());
16        } else {
17            this.initializeMaps();
18        }
19    }
20
21    initializeMaps() {
22        // Find all map containers
23        const mapContainers = document.querySelectorAll('.form-map');
24        
25        mapContainers.forEach(container => {
26            this.initializeMap(container);
27        });
28    }
29
30    async initializeMap(container) {
31        const address = container.getAttribute('data-address');
32        const zoom = parseInt(container.getAttribute('data-zoom')) || 13;
33        const mapId = container.id;
34
35        if (!address) {
36            console.warn('No address provided for map:', mapId);
37            return;
38        }
39
40        try {
41            // Try to geocode the address
42            const coordinates = await this.geocodeAddress(address);
43            
44            if (coordinates) {
45                this.createMap(container, coordinates, zoom);
46            } else {
47                this.showError(container, 'Could not find location for: ' + address);
48            }
49        } catch (error) {
50            console.error('Error initializing map:', error);
51            this.showError(container, 'Error loading map');
52        }
53    }
54
55    async geocodeAddress(address) {
56        // Check if address is already coordinates (lat,lng format)
57        const coordMatch = address.match(/^(-?\d+\.?\d*),\s*(-?\d+\.?\d*)$/);
58        if (coordMatch) {
59            return {
60                lat: parseFloat(coordMatch[1]),
61                lng: parseFloat(coordMatch[2])
62            };
63        }
64
65        // Use Nominatim geocoding service (free, no API key required)
66        const encodedAddress = encodeURIComponent(address);
67        const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodedAddress}&limit=1`;
68
69        try {
70            const response = await fetch(url, {
71                headers: {
72                    'User-Agent': 'Domic WordPress Theme ([email protected])' // Be polite to Nominatim
73                }
74            });
75
76            if (!response.ok) {
77                throw new Error(`HTTP error! status: ${response.status}`);
78            }
79
80            const data = await response.json();
81            
82            if (data && data.length > 0) {
83                return {
84                    lat: parseFloat(data[0].lat),
85                    lng: parseFloat(data[0].lon)
86                };
87            }
88            
89            return null;
90        } catch (error) {
91            console.error('Geocoding error:', error);
92            return null;
93        }
94    }
95
96    createMap(container, coordinates, zoom) {
97        // Create the map
98        const map = L.map(container).setView([coordinates.lat, coordinates.lng], zoom);
99
100        // Add OpenStreetMap tile layer
101        // You can easily switch to different tile providers here for different styles:
102        
103        // Option 1: Standard OpenStreetMap (current)
104        // L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
105        //     attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
106        //     maxZoom: 19
107        // }).addTo(map);
108        
109        // Option 2: CartoDB Positron (minimal, light)
110        L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
111            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
112            maxZoom: 19
113        }).addTo(map);
114        
115        // Option 3: CartoDB Voyager (minimal, balanced)
116        // L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
117        //     attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
118        //     maxZoom: 19
119        // }).addTo(map);
120
121        // Add a marker at the location
122        const marker = L.marker([coordinates.lat, coordinates.lng]).addTo(map);
123
124        // Store the map instance
125        this.maps.set(container.id, {
126            map: map,
127            marker: marker,
128            coordinates: coordinates
129        });
130
131        // Add resize observer to handle container size changes
132        if (window.ResizeObserver) {
133            const resizeObserver = new ResizeObserver(() => {
134                map.invalidateSize();
135            });
136            resizeObserver.observe(container);
137        }
138    }
139
140    showError(container, message) {
141        container.innerHTML = `
142            <div class="map-error">
143                <p><strong>Map Error:</strong> ${message}</p>
144                <p>Please check the address and try again.</p>
145            </div>
146        `;
147    }
148
149    // Public method to get map instance
150    getMap(containerId) {
151        return this.maps.get(containerId);
152    }
153
154    // Public method to update map location
155    async updateMapLocation(containerId, newAddress) {
156        const mapData = this.maps.get(containerId);
157        if (!mapData) return false;
158
159        try {
160            const coordinates = await this.geocodeAddress(newAddress);
161            if (coordinates) {
162                mapData.map.setView([coordinates.lat, coordinates.lng]);
163                mapData.marker.setLatLng([coordinates.lat, coordinates.lng]);
164                mapData.coordinates = coordinates;
165                return true;
166            }
167        } catch (error) {
168            console.error('Error updating map location:', error);
169        }
170        
171        return false;
172    }
173}
174
175// Initialize when script loads
176document.addEventListener('DOMContentLoaded', () => {
177    window.domicMaps = new DomicMaps();
178});
179
180// Also make it available globally for potential external use
181window.DomicMaps = DomicMaps;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.