openlayers 5 的聚类标记

Clustering markers at openlayers 5

我正在构建一个跟踪系统,它从 websocket 接收位置信号并在地图上用图标显示位置。

我现在需要进行聚类,我阅读了 this 但不知道如何修改我的代码以使用它。

'openlayers'代码是:

<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>

websocket 代码是:

<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>

您的代码看起来像这样,尽管您可能希望根据您的要求对其进行优化

<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>