This is the 21st day of my participation in the August Text Challenge.More challenges in August

Introduction to the

This article describes how to draw aggregate annotations. In development, we often need to draw a large number of annotation points, and when the map scale to the maximum, we need to load all the points. It’s kind of dense and you can’t tell directly how much data there is at the approximate location. To solve this problem, OpenLayers provides ol.source.cluster

ol.source.Cluster

  • It is a layer source for clustering vector data. That’s right, it’s not a layer, it’s just a source of vector layers.

Use it by instantiating the Cluster as a vector element.

ol.source.Cluster({ 
    distance: 10.// Marks the spacing between elements, in pixels.
    source: source,/ / the data source
});
Copy the code

Begin to use

Initialize the map

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, /> <title>Document</title> </head> <style type="text/ CSS ">. width: 100%; } </style> <link rel="stylesheet" Href = "https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/css/ol.css" / > < script SRC = "https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/build/ol.js" > < / script > < body > < div id="map" class="map"></div> </body> <script> var map = new ol.Map({ target: 'map'}) var layerTile = new ol.layer.Tile({source: new ol.source.XYZ({url: new ol.source.xyz) 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x= {x} & y = {} y & z = {} z'})})/var/view view = new ol.View({ center: ol.proj.fromLonLat([0, 0]), zoom: 4 }) map.setView(view) map.addLayer(layerTile) </script> </html>Copy the code

Join the collection data source

    const e = 4500000
    const count = 2000
    const features = new Array(count)
    for (let i = 0; i < count; ++i) {
      const coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e]
      features[i] = new ol.Feature(new ol.geom.Point(coordinates))
    }
    // Vector data source
    let source = new ol.source.Vector({
      features: features
    })
    // Instantiate the aggregate data source and set the aggregate distance
    let clusterSource = new ol.source.Cluster({
      distance: 40.source: source
    })
    // Create a layer
    let layer = new ol.layer.Vector({
      source: clusterSource,
      style: clusterStyle.call(this)
    })
    map.addLayer(layer)

    function clusterStyle() {
      return (feature, solution) = > {
        const size = feature.get('features').length
        let style = new ol.style.Style({
          image: new ol.style.Circle({
            radius: 15.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'})})})return style
      }
    }
Copy the code

  1. Create a point element array and add it to the vector data source.
  2. Put the vector data source into the aggregate data source. Set the aggregation distance and parameters by parameters.
  • distanceThe distance (in pixels) at which the elements will be clustered.
  • minDistanceThe minimum distance in pixels between clusters. The value cannot be greater than the configured distance.
  • sourceVector data source
  1. To create vector layers, note that styles are returned using the form method, where we can retrieve the current aggregate element data in real time to generate different styles.

Modify the collection color based on the quantity

.let style = new ol.style.Style({
      image: new ol.style.Circle({
        radius: 15.stroke: new ol.style.Stroke({
          color: '#fff'
        }),
        fill: new ol.style.Fill({
          color: getColor(size)
        })
      }),
      text: new ol.style.Text({
        text: size.toString(),
        fill: new ol.style.Fill({
          color: '#fff'})})})...function getColor(val) {
      if (val < 100) {
        return '# 444693'
      } else if (val >= 100 && val < 500) {
        return '#f47920'
      } else if (val >= 500) {
        return '#ef5b9c'}}Copy the code

  • Very simple, let’s define a function to determine the color. inStyleUse this function in. Since the map is redrawn with every change, the color changes according to the number of changes.
  • In addition to point aggregation, you can also achieve polygon aggregation if you are interested in it.