-
-
Notifications
You must be signed in to change notification settings - Fork 93
Description
Design Proposal: Add split operator
Motivation
Tag values in OSM sometimes include semicolon-delimited lists. A common example is cuisine, where values like cuisine=donut;coffee_shop have thousands of uses. Sometimes these values will show up in map tiles and we'd want to handle them with MapLibre. Commonly, I'd want to query if an attribute contains a given value in a list. I could do:
["in", "tea", ["get", "cuisine"]]
But this fails in cases where the text "tea" exists somewhere else in the list, such as in bubble_tea. So currently my query would look like this:
[
"any",
// check if exact match (one item in list)
["==", ["get", "cuisine"], "tea"],
// check if item is listed between others
["in", ";tea;", ["get", "cuisine"]],
// check if item is first in list
["==", ["slice", ["get", "cuisine"], 0, ["length", "tea;"]], "tea"],
// check if item is last in list
["==", ["slice", ["get", "cuisine"], ["-", ["length", ["get", "cuisine"]], ["length", ";tea"]]], ";tea"]
]
Which does work, but is highly verbose and probably not performant.
Proposed Change
The best way I can think of to query items in a semicolon-delimited list is to add a split operator that takes a delimiter and returns an array of strings separated by that delimiter:
["split", "tea;coffee_shop", ";"] -> ["tea", "coffee_shop"]
This would make it easy to check if an item appears in a list using in:
["in", "tea", ["split", ["get", "cuisine"], ";"]]
API Modifications
Add a split operator.
Migration Plan and Compatibility
The change is purely additive, and compliments the existing string operators like slice and index-of.
Rejected Alternatives
Continue to use a verbose expression (tedious, slow, and hard to maintain) or preprocess map tiles to avoid semicolons (not always desirable or possible).