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

Stacking multiple tilejson sources #288

Closed
alpha-beta-soup opened this issue Jun 27, 2017 · 6 comments
Closed

Stacking multiple tilejson sources #288

alpha-beta-soup opened this issue Jun 27, 2017 · 6 comments

Comments

@alpha-beta-soup
Copy link

alpha-beta-soup commented Jun 27, 2017

I have a base layer style being used like so:

<ReactMapboxGl
  style={"mapbox://styles/user/xxxxxxxxxxxxxxxxxxxxxx"}
  accessToken={"token"}
/>

I then add various sources and layers for both image tiles (<Layer type={"raster"}/>) and GeoJSON data, both from custom APIs. This all works great. However I would now like to show coastlines and other basemap-like labels on top of these non-Mapbox layers, separately from the most fundamental base style. From my understanding, it is not possible to declare this kind of stacking in the root style. So I thought that I would be able to define two more styles in Mapbox Studio, and use the URLs to them as references, and then place coastlines and labels on top. Then users could use a checkbox to turn coastlines and labels off/on as they wish.

I tried:

// A Mapbox Studio style using standard OSM data, but only showing text labels
const LabelSource = <Source
  id={"overlay-labels-source"}
  tileJsonSource={{
    type: "vector",
    url: "mapbox://styles/user/yyyyyyyyyyyyyyyyy"
  }}

const LabelLayer = <Layer
  key="overlay-labels"}
  id={"overlay-labels"}
  sourceId={"overlay-labels-source"}
/>

...

<ReactMapboxGl
  style={"mapbox://styles/user/xxxxxxxxxxxxxxxxxxxxxx"}
  accessToken={"token"}
>
{rasterTileSources}
{rasterTileLayers}
{geoJsonSources}
{geoJsonLayers}
{LabelSource}
{LabelLayer}
</ReactMapboxGl/>

This is fine, except for these additional Mapbox styles. I didn't expect this approach to work, and it doesn't, but I'm not sure if what I'm attempting to achieve is actually possible at all. It seems as if that root style in the ReacMapboxGl component is the only way to include remote Mapbox styles? If it isn't, is there an example of stacking multiple Mapbox sources in a particular order?

@alpha-beta-soup
Copy link
Author

Suspect I'm coming up against a generic Mapbox GL JS issue, unrelated to this project. e.g. mapbox/mapbox-gl-js#4000

@alex3165
Copy link
Owner

Hey @alpha-beta-soup that is quite specific and indeed I don't think there is a way to achieve that at the moment. I will keep this issue open and if you could follow up on the mapbox-gl-js issue and keep this issue updated, that would be nice 👍

@Wykks Wykks changed the title Stacking multiple vector tile sources Stacking multiple tilejson sources Sep 23, 2017
@cyrilchapon
Copy link
Contributor

Aww what a shame :(

So the only workaround I found is to define it in the style property

@cyrilchapon
Copy link
Contributor

In the same motion, it would be very valuable to be able to define a <Map /> without a style property, and let it initialize from children

@redbmk
Copy link
Contributor

redbmk commented Feb 9, 2018

@cyrilchapon I think maybe you're getting styles and sources mixed up. The style itself has links for the sources, and those sources are what you want to enter in as the tileJsonSource in Source. Instead of tileJsonSource="mapbox://styles/user/yyyyyy" it might look like tileJsonSource="mapbox://user.zzzzzzzz". If you download the style json, you'll see the source urls in the sources property.

You could also download the style and parse it dynamically, creating React components where you need. I didn't test this, so consider it pseudo code, but for example:

async componentWillMount() {
  const response = await fetch('https://api.mapbox.com/styles/v1/user/yyyyyyy?access_token=token');
  this.setState({ await response.json() });
}

render() {
  const { style } = this.state;
  if (!style) return null;

  return (
    <div>
      {Object.keys(style.sources).map(sourceId => (
        <Source key={sourceId} id={sourceId} tileJsonSource={style.sources[sourceId]} />
      ))}
      {style.layers.map(layer => (
        <Layer
          {...layer}
          key={layer.id}
          sourceId={layer.source}
          sourceLayer={layer['source-layer']}
          minZoom={layer.minzoom}
          maxZoom={layer.maxzoom}
        />
      ))}
    </div>
  );
}

If you're going the dynamic route, you would also need to make sure that the main style you're using has all the fonts and icons you need. Also, I think mapbox calls all the sources "composite" by default, so you might need to rename them to avoid duplicate source ids.

@alex3165
Copy link
Owner

alex3165 commented Feb 12, 2018

I will close this issue as it is not clear to me what the issue with react-mapbox-gl exactly is. There is no example with many sources added in particular order but I would expect this to be feasible by explicitly mounting many Source components. If you have a specific issue related to react-mapbox-gl with many Source components, feel free to reproduce it and open a new issue with an example of the problem reproduced with the webpackbin link mentioned in the readme.

@cyrilchapon I raised an issue for style to be optional as I think it is a valid point, I came across this use case where I wanted to create a map including only 1 geoJSON layer without any remote tile server involved. cf: #531

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

4 participants