I'm building a tracking system, it receives location signal from a websocket
and display the location long with the icon on the map.
I need now to make clustering, I read this but did not get how to amend my code to work with it.
The 'openlayers' code is:
<script>
var content = document.getElementById('popup-content');
var center = ol.proj.transform([44.6753, 25.7136], 'EPSG:4326', 'EPSG:3857'); //initial position of map
// ol.proj.fromLonLat([44.6753, 25.7136])
var view = new ol.View({
center: center,
zoom: 6
}); // {"unique_id": "Riyadh", "lat": 24.7136, "lon": 46.6753, "speed": 1}
//raster layer on map
var OSMBaseLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
straitSource = new ol.source.Vector({ wrapX: true });
var straitsLayer = new ol.layer.Vector({
source: straitSource
});
map = new ol.Map({
layers: [OSMBaseLayer, straitsLayer],
target: 'map',
view: view,
controls: [new ol.control.FullScreen(), new ol.control.Zoom()]
});
var icon = new ol.style.Icon({
anchor: [0.5, 0.5], // Default value is the icon center.
scale: 0.3,
color: '#ffcd46',
crossOrigin: 'anonymous',
src: 'http://127.0.0.1:8081/static/img/truck128.png'
});
var iconStyle = new ol.style.Style({
image: icon
});
// Popup showing the position the user clicked
var container = document.getElementById('popup');
var popup = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(popup);
/* Add a pointermove handler to the map to render the popup.*/
map.on('pointermove', function (evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel, function (feat, layer) {
return feat;
});
if (feature && feature.get('type') == 'Point') {
var coordinate = evt.coordinate; //default projection is EPSG:3857 you may want to use ol.proj.transform
content.innerHTML = feature.get('desc');
popup.setPosition(coordinate);
} else {
popup.setPosition(undefined);
}
});
</script>
And the websocket
code is:
<script>
var socket = new WebSocket("ws://127.0.0.1:8080/ws");
console.log(window.location.host)
var devices = []; // new Array();
var markers = {}; // new Object();
socket.onopen = function (event) {}
socket.onoclose = function (event) {}
socket.onerror = function (error) {
console.log('Error ${error.message}')
}
socket.onmessage = function (event) {
var messages = document.getElementById("messages");
var obj = JSON.parse(event.data);
var device = obj.unique_id;
var data=[{"Lon":19.455128,"Lat":41.310575}];
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([obj.lon, obj.lat], 'EPSG:4326', 'EPSG:3857')),
type: 'Point',
desc: '<pre> <b> First Location </b> ' + '<br>' + 'Latitude : ' + obj.lon + '<br>Longitude: ' + obj.lat + '</pre>'
});
iconFeature.setStyle(iconStyle);
if(!devices.includes(device)) {
devices.push(device);
var coordinates = [obj.lon, obj.lat];
markers[device]= iconFeature;
straitSource.addFeature(iconFeature);
} else {
straitSource.removeFeature(markers[device]);
straitSource.addFeature(iconFeature);
markers[device]= iconFeature;
}
};
</script>
Your code would look something like this, although you would probably want to refine it to your requirements
<script>
var content = document.getElementById('popup-content');
var center = ol.proj.transform([44.6753, 25.7136], 'EPSG:4326', 'EPSG:3857'); //initial position of map
// ol.proj.fromLonLat([44.6753, 25.7136])
var view = new ol.View({
center: center,
zoom: 6
}); // {"unique_id": "Riyadh", "lat": 24.7136, "lon": 46.6753, "speed": 1}
//raster layer on map
var OSMBaseLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
straitSource = new ol.source.Vector({ wrapX: true });
var clusterLayer = new ol.layer.Vector({
source: new ol.source.Cluster({
source: straitSource
distance: 40
})
});
map = new ol.Map({
layers: [OSMBaseLayer, clusterLayer],
target: 'map',
view: view,
controls: [new ol.control.FullScreen(), new ol.control.Zoom()]
});
var icon = new ol.style.Icon({
anchor: [0.5, 0.5], // Default value is the icon center.
scale: 0.3,
color: '#ffcd46',
crossOrigin: 'anonymous',
src: 'http://127.0.0.1:8081/static/img/truck128.png'
});
var iconStyle = new ol.style.Style({
image: icon
});
var styleCache = {};
clusterLayer.setStyle(function(feature, resolution) {
var size = feature.get('features').length;
if (size == 1 && resolution < map.getView.getResolutionForZoom(6)) {
// if a cluster of one show the normal icon
return iconStyle
} else {
// otherwise show the number of features
var style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
});
styleCache[size] = style;
}
return style;
}
});
// Popup showing the position the user clicked
var container = document.getElementById('popup');
var popup = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(popup);
/* Add a pointermove handler to the map to render the popup.*/
map.on('pointermove', function (evt) {
var cluster = map.forEachFeatureAtPixel(evt.pixel, function (feat) {
return feat;
},{
// restrict to the cluster layer
layerFilter: function(layer) {
return (layer === clusterLayer);
}
});
if (cluster) {
var coordinate = evt.coordinate; //default projection is EPSG:3857 you may want to use ol.proj.transform
// list all the features in the cluster
content.innerHTML = '';
cluster.get('features').forEach(function(feature) {
content.innerHTML += (feature.get('desc') + '<br>');
});
popup.setPosition(coordinate);
} else {
popup.setPosition(undefined);
}
});
</script>