mapbox / mapbox/mapbox-gl-js

Limit the number of features rendered per layer

Open
#7,955 8 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature :green_apple:
Dominant language
TypeScript
Stars
12.4k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Description

## Motivation

The use case is that I use a symbol layer linked to a source containing a bunch of features. Instead of rendering them all in the viewport, I would like to render up to X of them, counted after collision detection occurred. They are already sorted by rank of importance so I assume that using a counter at rendering level would be sufficient to stop rendering when the counter reach the maximum, still having somehow to deal with collisions that could make some features not appear.

## Current implementation

At the moment I am able to achieve more or less this goal. Whenever the map moves, I loop over the features of the source visible in the viewport, increment a counter and when I reach the limit I want, I apply a property to the remaining features, this property I use in my layer setup to define opacity. That works but is not ideal for two reasons:
1. this occurs as a second round of computation, so it frequently happens that some features appear (from mapbox layer rendering) and quickly disappear (after my own computation)
2. If I loop over all the features of the source, I am not able to detect which of them have been hidden because of a collision; is there a way to get this info at a feature level? Instead I need to loop over the list returned by `queryRenderedFeature`. But if do so, and I hide a feature responsible of a collision because it is out of the limit, then the collided features will show up again...
In order to prevent features from blinking I also tend to not hide a feature that is already visible (ie previous round did not count it out and it did not go out of the viewport during this round).

## Proper implementation

Do you know if there would be better approaches to achieve the desired behaviour, specifically at a lower level? I had a look at the way symbol layers are rendered in the code of mapbox-gl-js but I am not sure yet where collision applies. Also I am wondering if no one requested such a feature before, but I could not find any reference. Thank you in advance!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing symbol-layer rendering and collision detection in mapbox-gl-js, including how queryRenderedFeature exposes rendered features. The issue needs an agreed lower-level limit counted after collisions, defined behavior for collided features, and tests covering the limit without blinking.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.