-
Notifications
You must be signed in to change notification settings - Fork 134
Support multiple sprites #1266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple sprites #1266
Conversation
ahocevar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this will not work if more than one sprite is specified, because you're overwriting the spriteImageUrl, and the style function still can handle only one spriteImageUrl.
To do this properly, you could add the respective spriteImageUrl to the spriteData of each icon, and pass undefined as spriteImageUrl to the stylefunction().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new example should be added to the index file, with an appropriate short description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in a27f39f
src/mapbox.js
Outdated
| if (!Array.isArray(sprite)) { | ||
| throw new Error(`unexpected sprites type: ${typeof sprite}`); | ||
| } | ||
|
|
||
| const hasRequiredAttrs = sprite.every(function (spriteObj) { | ||
| const attrs = Object.keys(spriteObj); | ||
| return attrs.includes('id') && attrs.includes('url'); | ||
| }); | ||
|
|
||
| if (!hasRequiredAttrs) { | ||
| throw new Error('Some sprite definitions lack url or id'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We assume validated style objects, so these checks are not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for pointing that out, done in f2aaa7b
src/mapbox.js
Outdated
| return sprite.map(function (spriteObj) { | ||
| return { | ||
| 'id': spriteObj.id, | ||
| 'url': normalizeSpriteUrl(spriteObj.url, token, styleUrl), | ||
| }; | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When normalizeSpriteUrl() is done in place, you can simply
| return sprite.map(function (spriteObj) { | |
| return { | |
| 'id': spriteObj.id, | |
| 'url': normalizeSpriteUrl(spriteObj.url, token, styleUrl), | |
| }; | |
| }); | |
| } | |
| return sprite; |
here without any new allocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, also done in f2aaa7b
src/apply.js
Outdated
| sizeFactor + | ||
| '.json' + | ||
| sprite.search; | ||
| for (const sprite of sprites) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sprites have to be fetched in parallel, with Promise.all, not separately in a loop. Otherwise we don't know when we're done.
38cbe56 to
a27f39f
Compare
- remove unnecessary checks - avoid allocation by updating url inplace
- uses a Promise.all to fetch the sprite definitions - passes the urls to stylefunction
|
Thanks a lot for your review and pointers!! I completely overlooked
I implemented your suggestion by "parametrizing" the image objects by the url. I adapted one of the examples to test and demo this multi-sprite feature. I was wondering though, how would you feel about instead making {
default: "https://example.com/default-sprites",
alt: "https://alt-example.com/some/more/sprites"
}on top of what it currently supports? |
|
Unfortunately this does not work yet. I'm adding a commit with 3 fixes:
|
ahocevar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @remogeissbuehler
|
awesome, thanks a lot for your help @ahocevar |
Overview
This PR adds support for multiple sprite sources. In the most recent spec used by MapLibre, the
spritefield in thestyle.jsoncan either be a simple string (as is assumed to be the case now) or an array of multiple sprites, like the following:This PR adds support for this kind of definition.
Motivation
Note that the multiple definitions kind is used by versatiles, which currently does not work with ol-mapbox-style:
source
With this change, the map is shown correctly, including the sprites:

and they still do for the existing maps, like the sdf-sprites example:

Implementation Details
To support this, I added a new function to utils which normalizes all sprite definitions to the array-kind, to make it easier to work with.
In
apply.js, I replaced the code that fetches thespriteData. It now loops over all the different sprite sources and assigns the different sprites tospriteData, prefixed by the sprite source id, as is specified by MapLibre.This should be fully backwards-compatible, as the "old" way of just having a url is still supported.