Edit

Declutter Group

mapbox7 declutter2 decluttering2 labels3 vector82

Group decluttering of vector symbols and text.

Different truthy declutter values enable declutter groups. If declutter was set to true on the vector layer in this example, the symbol and texts of the vector layer would prevent overlapping symbols and texts from the Mapbox styled layers below. Because it is set to "separate", which is a different value than true, the vector layer is decluttered separate from the Mapbox styled layers below. Symbols and texts of the Mapbox styled layers below can overlap those of the vector layer.

main.js
import Feature from 'ol/Feature.js';
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import {getCenter} from 'ol/extent.js';
import Point from 'ol/geom/Point.js';
import {fromExtent} from 'ol/geom/Polygon.js';
import LayerGroup from 'ol/layer/Group.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import {apply} from 'ol-mapbox-style';

const square = [-12e6, 3.5e6, -10e6, 5.5e6];
const overlay = new VectorLayer({
  declutter: 'separate',
  source: new VectorSource({
    features: [
      new Feature({
        geometry: fromExtent(square),
        text: 'Polygon above Mapbox styled layers',
      }),
      new Feature({
        geometry: new Point([-11e6, 4.3e6]),
        text: 'Point above Mapbox styled layers',
      }),
    ],
  }),
  style: {
    'stroke-color': 'rgba(180, 180, 255, 1)',
    'stroke-width': 1,
    'fill-color': 'rgba(200, 200, 255, 0.85)',
    'text-value': ['get', 'text'],
    'text-font': 'bold 14px sans-serif',
    'text-offset-y': -12,
    'text-overflow': true,
    'circle-radius': 5,
    'circle-fill-color': 'rgba(180, 180, 255, 1)',
    'circle-stroke-color': 'rgba(255, 255, 255, 1)',
  },
});

const layer = new LayerGroup();
apply(
  layer,
  'https://api.maptiler.com/maps/streets-v2/style.json?key=Get your own API key at https://www.maptiler.com/cloud/',
);

const map = new Map({
  target: 'map',
  view: new View({
    center: getCenter(square),
    zoom: 3.9,
  }),
  layers: [layer, overlay],
});
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Declutter Group</title>
    <link rel="stylesheet" href="node_modules/ol/ol.css">
    <style>
      .map {
        width: 100%;
        height: 400px;
      }
      .map .ol-rotate {
        left: .5em;
        bottom: .5em;
        top: auto;
        right: auto;
      }
      .map:-webkit-full-screen {
        height: 100%;
        margin: 0;
      }
      .map:fullscreen {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>

    <script type="module" src="main.js"></script>
  </body>
</html>
package.json
{
  "name": "declutter-group",
  "dependencies": {
    "ol": "10.5.0",
    "ol-mapbox-style": "^12.4.0"
  },
  "devDependencies": {
    "vite": "^3.2.3"
  },
  "scripts": {
    "start": "vite",
    "build": "vite build"
  }
}