The styling issue
Previously we used SVG and CSS to handle all the styling. With the new WebGL renderer, that wouldn't work, so we hard coded the styling rules in this file: https://github.com/facebook/Rapid/blob/main/modules/core/StyleSystem.js
Those many thousands of css rules spread out over a lot of files have been replaced by about 500 lines of hardcoded JSON, and the new render is visually very close to the old one.
But we sort of invented our own mini styling language.
This issue is:
- How are we going to style the scene going forward:
- Do we formalize this styling language? It's kind of like a very simplified MapCSS with styles and tag selectors.
- Or do we just use a simplified subset of MapCSS - I like feel MapCSS just contains too much stuff?
- Provide a way for people to paste their own custom style somewhere? It can be really simple.
- We still will want to use map styles in other parts of the UI - for example to adjust the colors in preset icons. ~~That's why I haven't thrown out all the CSS just yet. But we will need to change any other code that uses CSS to call
styleMatch(tags)somehow, so that means exposing it as a proper callable method, not just a thing internal to the renderer.~~ Update: This was done, it's a core system now and can be called from anywhere.
Changing this part of the codebase sounds like it will open up many new possibilities, so I am excited to hear it. A few unrelated thoughts…
Vector Style Specification – I wonder why styling the map with https://docs.mapbox.com/mapbox-gl-js/style-spec/ did not make the list. I am new to the whole vector style world, so this is a very general question. From what I saw until now, it looked like I would not want to write those styles by hand… – but the base could be created in one of the editors, right?
Custom styles – Would that open up a way for power users to create custom styles with Maputnik/Mapbox Studio which iD could allow as JSON or even external style URL? One would need a (fake) example dataset for this, right?
Thematic styles – It would be great if this opens up a way for custom styles to be added to iD. That would open up a lot of possibiliites, many of them only for power users or people that get directed to iD as part of a mapping campaign for a certain top. One think I have in mind is getting the parking:lane schema visible on the map. For a visual inspiration, see this map (mainly the lila bricks (cars)). iD could consider changing styles based on settings but also based on selected features or even tag-groups in the feature selection (eg. while I focus on the surface input, I see a style focusses on surface on the map).
"Readonly elements" – Whenever I think about thematic styles of iD, I also think about disabling editing for some feature. So if possible, something like user-select: none; (Mozilla, Tailwind CSS) would be great. With that, I could – for example – gray out all building and keep them as a reference but not have them selectable for a given Thematic style to help the user focus on something else. This is likely not just styling, however…
MapCSS? – I only know this from styling Overpass Turbo Queries which only supports a subset of MapCSS (I think here) and I need to look it up in the wiki every time … – However, I think I would still prefer learning more about MacCSS for iD since I can use this knowledge else where than learning something new…
Styling "engine" for the SDK? – Whatever route you take, would this be something that other apps could use as well? Or is it tightly coupled to the new pixi setup? I just really like the idea of the iD-SDK to some day speed up the creation of single purpose editors.
We still will want to use map styles in other parts of the UI - for example to adjust the colors in preset icons. … But we will need to change any other code that uses CSS to call styleMatch(tags) somehow, so that means exposing it as a proper callable method, not just a thing internal to the renderer.
That part made me think about Tailwind CSS's config file and ability to call TW styles from JS.
FYI I wondered what MapComplete uses for styling, and Pieter told me it's something custom. MC does have the ability to do some simple styling as part of their JSON based themes.
To weigh in:
In a MapComplete theme, a feature can have one or more 'rendering blocks'.
A rendering block consists of the location (e.g. centroid, start, end or missing if a way should be rendered).
For a point, an icon, a label, size and anchoring can be defined. For a way/area, a color, fillcolor, dasharray, ... can be defined.
Every mapRendering block will then be converted into a single SVG-element (in other words, one feature can have multiple renderings, e.g. a start, end, centroid and multiple lines, e.g. for stacking effects)
The properties themselves have a field render which often acts as default, but might have a {key} (which is substituted by the corresponding value of the feature;
it might also have mappings, of which the first match defines what is taken.
A (pseudo)-JSON example is
mapRenderings:[
{
location: ["centroid"],
icon: "some_icon.svg",
mappings: [
{
if: "vending~*"
then: "icons/{vending}.svg"
},
{
if: "amenity=vending_machine",
then: "icons/vending_machine.svg"
},
{
if: "shop~*",
then: "icons/{shop}.svg"
}
]
},
{
# if location is missing, this will be interpreted as a way
color: {
render: #ffffff,
mappings: [
{
if: "key=value",
then: #ff0000
}
]
}
]
This is relatively slow, but as MC never shows many features at once, it isn't a problem.