Our goal is to display website visitors on the map, similar to the screenshot below.
We will convert their IP address to lat/lng coordinates and display those markers on OpenStreetMap map. To perform the conversion of IP addresses to lat/lng pairs we are going to use the geolocation data from ip2location.com.
We will display users that were active in the last ten minutes. If the user had some activity in the last 60 seconds, their dot will be pulsing.
There is also a YouTube video that provides more details of this project.
1. Database structure.
We are going to need two tables, ‘users’ and ‘ip2location’. The following is the script for MySQL database.
Please note that this SQL script only creates ‘ip2location’ but doesn’t come with the data. The data set itself is about 300Mb and you can download it for free at https://lite.ip2location.com/database/ip-country.
2. Insert a code snippet into a page where you want to display the map. In our case it would be the menu page. The code itself is very simple, it merely outputs the div with ‘map’ ID.
PHP code:
3. AfterApplicationInitialized event
PHP code:
4. custom_function.js
The following Javascript code goes to Event Editor -> custom_function.js section.
$(document).ready(function() { $("#map").width($(".r-fluid").width()); var height = $(window).height() - $("#map").offset().top - 30; $("#map").height(height); window.mapObj = new OpenLayers.Map("map", { controls: [ new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.Navigation() ], }); var layer = new OpenLayers.Layer.OSM(); mapObj.addLayer(layer); window.markersList = new OpenLayers.Layer.Markers("Markers"); mapObj.addLayer(markersList); mapObj.zoomToMaxExtent(); updateMarkers(); setInterval(updateMarkers, 5000); function updateMarkers() { $.post("", { getActiveUsers: true }, function(response) { var coordsArr = JSON.parse(response), activeIds = coordsArr.map(function(coords) { return coords.id; }), allIds = markersList.markers.map(function(marker) { return marker.id; }); $.each(coordsArr, function(i, latLon) { if (!allIds.includes(latLon.id)) { addMarker(latLon.id, latLon.lat, latLon.lng, latLon.active); } else { var curMarker = markersList.markers.find(function(marker) { return marker.id == latLon.id }); if (curMarker.active != latLon.active) { $(curMarker.icon.imageDiv).toggleClass("active", latLon.active); } } }); allIds = markersList.markers.map(function(marker) { return marker.id; }); for (var i = 0; i < allIds.length; i++) { if (allIds[i] != undefined && !activeIds.includes(allIds[i])) { var markerToRemove = markersList.markers.find(function(marker) { return marker.id == allIds[i] }); markersList.removeMarker(markerToRemove); } } function addMarker(id, lat, lng, active) { var lonLat = new OpenLayers.LonLat(lng, lat) .transform( new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984 mapObj.getProjectionObject() // to Spherical Mercator Projection ); var icon = new OpenLayers.Icon("", new OpenLayers.Size(15, 15)); var marker = new OpenLayers.Marker(lonLat, icon); if (active) { $(marker.icon.imageDiv).addClass("active"); } marker.id = id; marker.active = active; markersList.addMarker(marker); return marker; } }); } updateMarkers(); });
5. CSS code ( Style Editor -> Modify CSS )
We use this CSS code to customize and prettify the default look of OSM map.