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

Serve Mapbox-GL style files #64

Closed
jimbok8 opened this issue Feb 7, 2019 · 6 comments
Closed

Serve Mapbox-GL style files #64

jimbok8 opened this issue Feb 7, 2019 · 6 comments

Comments

@jimbok8
Copy link

jimbok8 commented Feb 7, 2019

is it possible to serve other files; i.e. like a standard http server?
In particular I am trying to use mapbox-gl.js which uses a .json file to store the style and also the mbtiles source location.
How can I serve the .json file from http://localhost?
Thanks.

@brendan-ward
Copy link
Collaborator

@jimbok8 right now, mbtileserver does not serve other files; it was not intended to be a generic http server. However, the idea of being able to serve styles directly alongside tiles is compelling.

I've been thinking toward providing a way to have a default mapbox style that you could publish for each tileset (e.g., to use in our map preview endpoint), but I wasn't thinking of that in terms of publishing styles more broadly - e.g., those that use > 1 tileset on mbtileserver. I could see exposing this as an endpoint /services/<tileset ID>/style for each service, if there is an associated <tileset ID>.style.json file that is a sibling of <tileset>.mbtiles in the tiles directory.

I think if we enabled publishing styles more broadly (e.g., consuming >=1 hosted service plus external services), we'd want it to do a few updates to the style file to make it match the endpoint URLs of the server - so that it is fully self contained.

e.g., using something like url: 'mbtileserver://<tileset ID>' in your style file would then get converted by the server to have same external facing domain as you assign to the mbtileserver. Could be tricky if proxies are involved though (but in that case you could always just write your url to use the externally known domain name).

To do this, we could create a new flag to pass in a styles directory, and in there you would have one or more json files of mapbox GL styles. These could be updated per above then published at /styles/<style ID>

For now, I'd recommend using a static fileserver to serve your styles (e.g., nginx, caddy, etc).

@brendan-ward brendan-ward changed the title Serve other files Serve Mapbox-GL style files Feb 7, 2019
@schwiet
Copy link

schwiet commented May 23, 2019

@brendan-ward, I have a semi-related question that I didn't think was quite appropriate to open an issue for:

I'm using your server on an embedded system alongside another webserver that serves my app along with a generic style.json. The styles (and tiles) come from OpenMapTiles and all of the vector-related layers use a specific name for their source (e.g. openmaptiles).

So, when the app is about to display a map (with mapbox-gl), it needs to fill in the missing tile source info in the style. The app queries your server for services then loops through the response to fetch the TileJson objects for each service and then takes the tiles value and copies that to the style.json object's sources.openmaptiles.tiles. Then, I create the Mapbox-gl Map with the modified style.

I'd like to be able to utilize multiple .mbtiles if they're present on the server, but can't figure out how to get this to mesh with the styles. My naive approach was to concatenate all of the .tiles arrays in each TileJson and make that concatenated list the source.openmaptiles.tiles list. This almost seems to work, but some tiles are blank in an area covered by one of the .mbtiles. I suspect my wishful approach is misguided.

Is there a way to use multiple .mbtiles served from your server with one style.source?

@brendan-ward
Copy link
Collaborator

@schwiet each source in your style is a distinct tile service (.mbtiles). That means that you can't combine multiple origin tile services into a single source by having multiple entries in the tiles that are logically different tilesets. The docs are a bit spare, but my interpretation is that the tiles array defines multiple domains hosting the same tileset with the same zoom / bounds / etc properties.

You can have one source per tile service, and then one or more layers per source - but that means authoring your own more specific style.

If you are hosting on OpenMapTiles, they may be combining multiple spatial datasets into one .mbtiles to be able to serve those as multiple layers in a single tile service. If it is for one of their basemaps, this is likely the case.

You should leverage multiple sources and layers to produce the functionality that it seems like you are trying to get at (by supplementingopenmaptiles with additional data?). In this case, you would setup a source for each tile service you want to bring in (in addition to openmaptiles source), and create one or more layers from it depending on how you want to style your data.

Depending on your use case, you could then remove one or more layers against the openmaptiles source, and use your own layer pointing at your own tiles in place of those, if you are substituting layers. Or you could create your layers and insert them into a particular position in the style.

You can also programmatically add sources and layers after your map has loaded the underlying style (i.e., you are using the style to define the basemap). This is most commonly what I do with tile services hosted in mbtileserver.

@schwiet
Copy link

schwiet commented May 24, 2019

@brendan-ward thank you for that quick reply (especially since this seems to be a more general style question). I think this answers my question.

For reference, the use case I am imagining is aimed at allowing users to have a couple different regions of map tiles on the server and the app handling displaying all of what is available. Like I said, it's an embedded platform with limited resource, so if a particular user will be using the device in Dallas and Houston, the easiest way I could imagine giving them what they needed, without including the state of Texas or larger, what to let them throw an .mbtiles for each city on the server. Sounds like I could still do that, but will need to have a source in the style for each and corresponding layers for each.

Thanks again for taking the time to clear that up for me.

@brendan-ward
Copy link
Collaborator

@schwiet are you generating localized tiles, or are your users generating them?

For something like what you are describing, it is possible to create a tileset for each locality to finer levels of detail, then merge them later. E.g., houston.mbtiles and dallas.mbtiles can be generated for each with bounds and zoom levels appropriate for each, and then you can use tile-join to merge them together as separate layers in the same tileset. This would let you use a single tile source with a layer for Houston and a layer for Dallas, and the resources should be minimal since you will only pull in the high level of detail for a specific locality. This makes sense if you have different attributes or data structures in each locality and need a layer specific to each.

Or - because vector tiles are intended to be lightweight and shard things spatially anyway - it seems like all your data could be merged into a single tileset, and the localized data will only be fetched for the tiles in the extent of the given user, and not the other locality. Just don't include the locality data at coarser zoom levels, and resource usage should be fine.

@brendan-ward
Copy link
Collaborator

Closing, because using a reverse proxy or a companion static file server should be sufficient to serve style files and assets.

We may revisit this in the future, but for now it is not part of the roadmap.

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

No branches or pull requests

3 participants