/** * Initializes a map to display geolocation data for IP addresses * @param {string} elementId - The ID of the element to display the map in * @param {Object} geoData - The geolocation data (latitude, longitude, country, etc.) * @param {boolean} showPopup - Whether to show a popup on the map */ function initMap(elementId, geoData, showPopup = true) { // Default to a global view if no coordinates let lat = 0; let lng = 0; let zoom = 1; let hasCoordinates = false; // Check if we have valid coordinates if (geoData && geoData.latitude && geoData.longitude && !isNaN(parseFloat(geoData.latitude)) && !isNaN(parseFloat(geoData.longitude))) { lat = parseFloat(geoData.latitude); lng = parseFloat(geoData.longitude); zoom = 5; hasCoordinates = true; } else if (geoData && geoData.country) { // If we have a country but no coordinates, we can approximate const countryCoords = getCountryCoordinates(geoData.country); if (countryCoords) { lat = countryCoords.lat; lng = countryCoords.lng; zoom = 4; hasCoordinates = true; } } // Initialize the map const map = L.map(elementId, { center: [lat, lng], zoom: zoom, zoomControl: true, scrollWheelZoom: false, attributionControl: false }); // Add dark-themed map tiles L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { attribution: '© OpenStreetMap contributors © CARTO', subdomains: 'abcd', maxZoom: 20 }).addTo(map); // Get or create info for display const ip = geoData.ip_address || 'Unknown IP'; const country = geoData.country || 'Unknown Country'; const city = geoData.city && geoData.city !== 'Unknown' ? geoData.city : ''; const location = city ? `${city}, ${country}` : country; const org = geoData.organization || ''; // Use a custom marker for better visibility if (hasCoordinates) { // Create custom icon with IP address const customIcon = L.divIcon({ className: 'custom-ip-marker', html: `
${ip} ${location}
`, iconSize: [250, 80], iconAnchor: [125, 80] }); // Add marker with custom icon const marker = L.marker([lat, lng], { icon: customIcon }).addTo(map); // Add detailed popup if requested if (showPopup) { const popupContent = `
${org ? `` : ''}
`; marker.bindPopup(popupContent, { closeButton: true, className: 'custom-popup' }); } // Add ripple effect animation const rippleMarker = L.circleMarker([lat, lng], { radius: 15, color: '#3b82f6', fillColor: '#60a5fa', fillOpacity: 0.3, weight: 2 }).addTo(map); // Animate the ripple effect function animateRipple() { let radius = 15; let opacity = 0.5; const interval = setInterval(() => { radius += 1; opacity -= 0.01; rippleMarker.setStyle({ radius: radius, fillOpacity: opacity, opacity: opacity }); if (opacity <= 0) { clearInterval(interval); rippleMarker.setStyle({ radius: 15, fillOpacity: 0.3, opacity: 0.5 }); setTimeout(animateRipple, 1000); } }, 50); } animateRipple(); } else { // If we don't have coordinates, display an info message on the map const noLocationDiv = document.createElement('div'); noLocationDiv.className = 'no-location-info'; noLocationDiv.innerHTML = `
IP: ${ip}
Location data unavailable
`; document.getElementById(elementId).appendChild(noLocationDiv); } // Invalidate size to ensure map renders correctly setTimeout(() => { map.invalidateSize(); }, 100); } /** * Gets approximate coordinates for a country * @param {string} countryName - The name of the country * @returns {Object|null} - The approximate coordinates or null if not found */ function getCountryCoordinates(countryName) { // This is a simplified mapping of countries to approximate coordinates const countryCoords = { 'United States': { lat: 37.0902, lng: -95.7129 }, 'USA': { lat: 37.0902, lng: -95.7129 }, 'United Kingdom': { lat: 55.3781, lng: -3.4360 }, 'UK': { lat: 55.3781, lng: -3.4360 }, 'Canada': { lat: 56.1304, lng: -106.3468 }, 'Australia': { lat: -25.2744, lng: 133.7751 }, 'Germany': { lat: 51.1657, lng: 10.4515 }, 'France': { lat: 46.2276, lng: 2.2137 }, 'Japan': { lat: 36.2048, lng: 138.2529 }, 'China': { lat: 35.8617, lng: 104.1954 }, 'India': { lat: 20.5937, lng: 78.9629 }, 'Brazil': { lat: -14.2350, lng: -51.9253 }, 'Russia': { lat: 61.5240, lng: 105.3188 }, 'Netherlands': { lat: 52.1326, lng: 5.2913 }, 'Ireland': { lat: 53.1424, lng: -7.6921 }, 'Singapore': { lat: 1.3521, lng: 103.8198 }, 'Switzerland': { lat: 46.8182, lng: 8.2275 }, 'South Africa': { lat: -30.5595, lng: 22.9375 }, 'Mexico': { lat: 23.6345, lng: -102.5528 }, 'Spain': { lat: 40.4637, lng: -3.7492 }, 'Italy': { lat: 41.8719, lng: 12.5674 }, 'South Korea': { lat: 35.9078, lng: 127.7669 }, 'Indonesia': { lat: -0.7893, lng: 113.9213 }, 'Turkey': { lat: 38.9637, lng: 35.2433 }, 'Saudi Arabia': { lat: 23.8859, lng: 45.0792 }, 'Poland': { lat: 51.9194, lng: 19.1451 }, 'Ukraine': { lat: 48.3794, lng: 31.1656 }, 'Sweden': { lat: 60.1282, lng: 18.6435 }, 'Norway': { lat: 60.4720, lng: 8.4689 }, 'Finland': { lat: 61.9241, lng: 25.7482 }, 'Denmark': { lat: 56.2639, lng: 9.5018 } }; // Try to find the country in our mapping return countryCoords[countryName] || null; }