kh03's picture
Upload 7 files
0a08a10 verified
/**
* 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: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
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: `<div class="ip-marker">
<div class="ip-marker-content">
<span class="ip-text">${ip}</span>
<span class="location-text">${location}</span>
</div>
</div>`,
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 = `
<div class="map-popup">
<div class="popup-header">Server Information</div>
<div class="popup-row"><strong>IP:</strong> ${ip}</div>
<div class="popup-row"><strong>Location:</strong> ${location}</div>
${org ? `<div class="popup-row"><strong>Organization:</strong> ${org}</div>` : ''}
</div>
`;
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 = `
<div class="no-location-content">
<i class="fas fa-map-marker-alt"></i>
<div>
<div>IP: ${ip}</div>
<div>Location data unavailable</div>
</div>
</div>
`;
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;
}