mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.2k stars 2.22k forks source link

Feature request: expression for string.split(<separator>) #8526

Open bergkvist opened 5 years ago

bergkvist commented 5 years ago

Motivation

Underlying problem: The MVT format does not support array properties

I want to send 48 numbers (between 0 and 1) along with every feature. These values represent congestion in electrical grid lines over 48 hours. I want to have a time slider to pick the hour, and style every feature according to their individual congestion at that hour.

*A workaround for this that I've used in OpenLayers is to use a string property, which contains all the values separated by semicolon. They are then split up in the style function, and the "current congestion" (according to the slider) is used to style each line individually.*

It seems like this is not easily doable in Mapbox GL, which is why I'm making this feature request.

Design Alternatives

It might be the case that there is some good alternative to this approach that I'm not seeing (that does not severely affect performance or scalability).

Design

Proposition: implement the following expression:

["split", separator_string, string]: array

Example:

["split", ";", "1;0.5;0.33;0.101;0.2"]
-> ["1", "0.5", "0.33", "0.101", "0.2"]

The behavior should essentially be the same as the following (javascript):

// ";" is the separator_string:
"1;0.5;0.33;0.101;0.2".split(";")
// ["1", "0.5", "0.33", "0.101", "0.2"]
andrewharvey commented 5 years ago

related to join which I experimented with at https://github.com/mapbox/mapbox-gl-js/compare/join-expression

mourner commented 5 years ago

It seems like this is not easily doable in Mapbox GL, which is why I'm making this feature request.

I believe the current workaround for such use case is to use numbered properties — e.g. "properties": {"value1": 10, "value2": 20, ...}. As an example, this is how it's done in https://electricitytransition.com/

bergkvist commented 5 years ago

I believe the current workaround for such use case is to use numbered properties — e.g. "properties": {"value1": 10, "value2": 20, ...}. As an example, this is how it's done in https://electricitytransition.com/

This is what I ended up doing (and it worked), but a downside of this is that the length/count of the numbered properties is less flexible

(at least in my setup with PostGIS and GeoServer, since "value1", "value2" etc. have to be individual columns in PostGIS)

MeijiRestored commented 3 years ago

Is this being worked on ? i created a tileset with data of European roads for showing a extra e-road shield on these roads in plus of the regular ref=* shield, but sometimes roads have multiple e-road refs (like "int_ref=E 17;E 42", shows litteraly "E17; E 42" on the shield) so a slice() formula could've helped out returning only the first ref when there is multiple...