Evaluate an expression, outside of rendering
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
## Motivation
MapboxGL expressions allow computing things based on feature properties. For example, at my work, we use an expression to determine which color various point features should be rendered as.
However, sometimes it is useful to be able to reuse logic between Mapbox code and other code. In this case, we would like a marker tooltip attached to a point to have the same color as the point.
## Design Alternatives
Currently, if a value is needed both during rendering, and outside of rendering, it looks like you need to implement it once as an expression, and once in Javascript. This is possible (and is what we're doing now), but has some downsides:
* If the expression is somewhat complicated, it's possible that there will be differences between the expression version and the Javascript version.
* It's not possible to write unit tests for expressions at present, so it's also not possible to test that the implementations match.
## Design
The `Map` instance could include a method to evaluate expressions. It would take an expression and a feature, and return the result of evaluating that expression on that feature. Any global properties (such as `zoom`) would come from the map.
Alternatively, the evaluation could be a pure function, independent of a map. However, this would make it more difficult to handle properties like `zoom`, and doesn't really add much value in the case described under "Motivation".
### Mock-Up
Here's a simplified example:
```js
const map = new mapboxgl.Map();
const colorExpr = ['case', ['get', 'isRed'], 'red', 'green'];
const redFeature = {
type: "Feature",
geometry: { type: "Point", coordinates: [0, 0] },
properties: { isRed: true },
}
const notRedFeature = {
type: "Feature",
geometry: { type: "Point", coordinates: [0, 1] },
properties: { isRed: false },
}
map.evaluateExpression(colorExpr, redFeature); // 'red'
map.evaluateExpression(colorExpr, notRedFeature); // 'green'
```
### Concepts
Adding an entry under the list of methods [here](https://www.mapbox.com/mapbox-gl-js/api/) should be sufficient, I think.
### Implementation
I'm currently not very familiar with the internals of MapboxGL JS. However, a quick look inside the source, under `style-spec/expression/index.js`, shows code that compiles and executes expressions, so I would hope that it wouldn't require too much work to hook into this code. With a little direction, I'd be happy to take a stab at this.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with style-spec/expression/index.js, which the issue identifies as the expression compilation and execution entry point, then review the Map API method list. Define how an expression and feature are evaluated, including map-provided global properties such as zoom, and consider coverage for matching rendered and external results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- api, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100