Skip to content
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

Allow styles to use multiple sprites and individual images #358

Closed
mourner opened this issue Mar 28, 2014 · 30 comments
Closed

Allow styles to use multiple sprites and individual images #358

mourner opened this issue Mar 28, 2014 · 30 comments

Comments

@mourner
Copy link
Member

mourner commented Mar 28, 2014

Make it possible to use multiple sprites (not just one) and reference individual images too.

Multiple sprites can be useful because nature of images can be very different so compression might be much more efficient when breaking down one sprite into several (e.g. one is BW icons, another is fill patterns etc.). They could use different formats too (e.g. color/detail-heavy icons could use JPEG instead of PNG etc.)

Individual images referencing is important to make it easy for people to play with, add custom icons on the map quickly, etc.

@kkaefer
Copy link
Member

kkaefer commented Apr 3, 2014

Currently, we load the image and use the image as is as a texture. Instead, we could use the stylesheet to find the parts of the sprite that are actually used and assemble a sprite texture using the binpack code that we already have for the glyph atlas (and reuse much of the glyph atlas code). That way, we could also enable referencing single individual images, or automatically generated images (e.g. for highway shields).

@mourner mourner added this to the future milestone Jun 24, 2014
@mourner mourner added question and removed question labels Jun 24, 2014
@ansis
Copy link
Contributor

ansis commented Jul 10, 2014

If we want to do this, should this be in v4?

@mourner
Copy link
Member Author

mourner commented Jul 10, 2014

Not critical I think, could be moved to v5.

@kkaefer
Copy link
Member

kkaefer commented Dec 9, 2014

Sprite Atlas is happening in #851

This was referenced Feb 17, 2015
@lbud
Copy link
Contributor

lbud commented Mar 9, 2015

bump :) this could be helpful from an API/editor perspective as well. What do you guys think?

@jfirebaugh jfirebaugh removed this from the future milestone Jun 15, 2015
@msbarry
Copy link
Contributor

msbarry commented Nov 24, 2015

Hi, @mourner @kkaefer I'm trying to understand what it would take to get individual images for symbols working? It looks like the symbol rendering code is pretty tied in with in with having a single sprite atlas. Would individual images need to go through a completely separate code path?

I'm trying to hack a proof-of-concept together that requires individual images for symbols. Thanks!

@jfirebaugh
Copy link
Contributor

This would require:

  • Style spec addition to add URL support for "icon-image" and probably "{fill,line,background}-pattern" as well. To disambiguate from sprite icon names, we'd probably want to use a CSS-like url(...) syntax. This would be part of a new style spec version.
  • Implementation in mapbox-gl-js.
  • Implementation in mapbox-gl-native.
  • Tests in mapbox-gl-test-suite.
  • Backend work on the Mapbox style APIs to support the new spec version. Most likely we'd not allow styles uploaded to the API to use this feature, because we want to ensure that styles uploaded to the API can be rendered server-side without requiring loading resources from arbitrary third party domains.

@buchanae
Copy link
Contributor

Have you considered allowing some form of client-defined programmatic evaluation of style spec properties, i.e. allow "icon-image" to be a function that returns an HTML Image.

If that was the case, maybe people would have implemented third-party libraries to handle lots marker/custom-image cases already.

Want to render an SVG elements to canvas, dump that to an Image, and pass that off to Mapbox? No problem! Just return it all via "icon-image": SVGDumper(mySvgEl) (or maybe via sprite?)

@buchanae
Copy link
Contributor

Actually, evaluating a function isn't necessary I guess, since you can use map.setLayoutProperty() anyway. Maybe the core of the idea is considering more complex data types (such as HTML Image) for style spec values.

Or, maybe if you could set the sprite property to an object with some interface, say Spritesheet, people could provide their own implementations, which would allow all sorts of different loading/rendering mechanisms.

@jfirebaugh
Copy link
Contributor

We don't want to introduce language-specific dynamic evaluation to the style specification. See this comment for more.

@jfirebaugh
Copy link
Contributor

Another thing we'll need to think about is how to support high-DPI (retina/@2x and beyond) images.

@mourner
Copy link
Member Author

mourner commented Dec 14, 2015

Another thing we'll need to think about is how to support high-DPI (retina/@2x and beyond) images.

We should consider just using one @2x image for both retina and non-retina. The size difference is negligible and it shouldn't affect performance if we use 2x for 1x case.

@jfirebaugh
Copy link
Contributor

Even if we support only a single pixel ratio per image, we still need a way to indicate what that pixel ratio is, image-by-image. On one hand, not everyone has @2x assets available, and on the other we should build something that can support @3x and up.

@yuvadm
Copy link

yuvadm commented Jan 24, 2016

I'm curious about any workaround that are possible for this use case, until this issue is resolved. It seems that using popups as "enhanced" markers harms performance significantly.

@kkaefer
Copy link
Member

kkaefer commented Jan 25, 2016

We should consider just using one @2x image for both retina and non-retina. The size difference is negligible and it shouldn't affect performance if we use 2x for 1x case.

I don't think this is a good idea, as it degrades the image quality quite a bit. Icons in particular benefit a lot from pixel grid fitting and we've invested a lot to make sure that is the case.

@bhousel
Copy link
Contributor

bhousel commented Jan 25, 2016

We should consider just using one @2x image for both retina and non-retina. The size difference is negligible and it shouldn't affect performance if we use 2x for 1x case.

Another point in favor of just using hidpi assets everywhere: we currently don't handle very well the situation of dragging a window from a retina to non-retina screen, and v.v. It seems kind of silly to refetch assets when this happens.

I don't think this is a good idea, as it degrades the image quality quite a bit. Icons in particular benefit a lot from pixel grid fitting and we've invested a lot to make sure that is the case.

Could we just generate a single base+1 mipmap level for each texture, then pass an appropriate level argument to texImage2D depending on whether the viewport is currently hidpi?

@kkaefer
Copy link
Member

kkaefer commented Jan 25, 2016

we currently don't handle very well the situation of dragging a window from a retina to non-retina screen

We used to do this, but dropped support for it, because it was such a rare occurrence.

Could we just generate a single base+1 mipmap level for each texture, then pass an appropriate level argument to texImage2D depending on whether the viewport is currently hidpi?

Yeah, we could do that, but that means we'd have to load both 1x and 2x assets as well, since scaling won't look good, no matter whether it's done by the CPU or GPU.

@lukerollans
Copy link

As an end user, I really want to see images from external URL's supported as marker icons in GL. It's core to our application, and without it we need to use mapbox js which just isn't as nice.

Is this planned?

@peterqliu
Copy link
Contributor

@lukerollans ah now I see your use case. We don't have a dedicated solution for that yet, but if you're clever, you can adapt GL popups (which are DOM elements overlaid onto the map) into markers with some CSS tweaking.

@lukerollans
Copy link

@peterqliu thanks for the tip, will look in to it!

@gmaclennan
Copy link
Contributor

+1 to the original request here (multiple sprites). I am building an app that overlays markers on a map. We want to allow the user to choose the background - one of the default mapbox styles or their custom vector tiles and/or style. Our markers (in the overlay) need to be sprites, but since there can only be one sprite associated with a map, we can't add those sprites to a map with a layer/style chosen by the user.

@spatialillusions
Copy link

It would really be great to create individual images in some way, in some cases the icons are based on so many properties that it is impossible to create an atlas of them. If it would be possible to point to an url, canvas, or base 64 encoding of the image would be nice. My use case is to use military symbology, where the possibilities of the symbols are several millions, and they have to be created according to standard documents. I have built a library for this, https://github.com/spatialillusions/milsymbol, and so far I have been abel to use it in several different mapping libraries, but not in mapbox-gl-js, and it would be very nice if I could.

@lukerollans
Copy link

It's honestly surprising to me that you can't just specify an external image as an icon if you wish.. but then again, I'm only just getting in to MapBox and am by far an expert

@xeob
Copy link

xeob commented Jul 27, 2016

Hey folks, at @mapillary we're using spritezero-cli to bundle traffic signs from all our traffic sign detection packages and use these sprites in mapbox-gl-js and in our libs . We'll be approaching the limit of 500 signs per sprite soon. Is there an ETA for multiple sprite support? We're updating sprite refs and updating the map-style, but that makes it impossible to display traffic sign detections from multiple sprites on one map.

Using Popup API is not an option, due to performance reasons.

@lucaswoj lucaswoj changed the title Multiple sprites and individual images in style Allow styles to use multiple sprites and individual images Jul 28, 2016
@jfirebaugh
Copy link
Contributor

the limit of 500 signs per sprite

Which limit are you referring to here, specifically?

@xeob
Copy link

xeob commented Aug 27, 2016

@jfirebaugh: At that time I was referring to editing style through Mapbox studio limit and assumed it's not supported to have more than 500 images in the sprite. Then I found d6d8ac4, the 500 limit still holds in Mapbox studio (at least it did last week), but we're tweaking style JSON now and use spritezero-cli for the sprites.

@mtoon
Copy link

mtoon commented Sep 14, 2016

Quick question around this.. We are looking at dynamically adding layers to the scene and ideally, each layer could have it's own discreet texture atlas. That way the shared "base" layer has it's texture atlas and the "feature" layers can bring their own atlas with them. Is there any effort underway for something like this?

@lucaswoj
Copy link
Contributor

@mtoon There is no effort underway yet. We recognize this is an important feature request. This issue tracks the feature and will be updated when there's something to report.

@jfirebaugh
Copy link
Contributor

Tracking an API that enables many of the use cases here -- Map#addImage -- in #2059.

bensleveritt pushed a commit to bensleveritt/mapbox-gl-js that referenced this issue Oct 24, 2016
@lucaswoj
Copy link
Contributor

Closing in favor of #2059 & mapbox/mapbox-gl-style-spec#220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests