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

map.getstyle() can't get custom layer #9001

Closed
aji-geo opened this issue Nov 20, 2019 · 8 comments
Closed

map.getstyle() can't get custom layer #9001

aji-geo opened this issue Nov 20, 2019 · 8 comments

Comments

@aji-geo
Copy link

aji-geo commented Nov 20, 2019

map.getstyle() method can get many layer in style but no custom layers, like deck.gl layer. how can I get all the layers include deck.gl layer?

@kkaefer
Copy link
Contributor

kkaefer commented Dec 4, 2019

Custom layers are explicitly excluded from getStyle in

_serializeLayers(ids: Array<string>): Array<Object> {
const serializedLayers = [];
for (const id of ids) {
const layer = this._layers[id];
if (layer.type !== 'custom') {
serializedLayers.push(layer.serialize());
}
}
return serializedLayers;
}
. getStyle is used for serializing a style to a JSON data structure, and custom layers contain functions that are cannot be represented in JSON.

To obtain an individual custom layer, use getLayer().

@kkaefer kkaefer closed this as completed Dec 4, 2019
@kkaefer kkaefer removed the bug 🐞 label Dec 4, 2019
@mayteio
Copy link

mayteio commented Jan 22, 2020

Can we make this a feature request then? We have a scenario where we're adding n custom layers, and need to track what has been added without knowing their ids ahead of time. I thought prefixing and filtering map.getStyle().layers for this prefix would work, then I found this issue.

@mayteio
Copy link

mayteio commented Jan 22, 2020

Seems it just searches the _layers object?

/**
* Return the style layer object with the given `id`.
*
* @param {string} id - id of the desired layer
* @returns {?Object} a layer, if one with the given `id` exists
*/
getLayer(id: string): Object {
return this._layers[id];
}

Something like this could work:

/**
 * Return the style layer object with the given `id`.
 *
 * @param {string} id - id of the desired layer
 * @returns {?Object} a layer, if one with the given `id` exists
 */
getLayer(id: string): Object {
  return this._layers[id];
}

/**
 * Return style layers whose `id` matches a search string
 *
 * @param {string} search - search string to filter layer ids
 * @returns {?Object[]} an array of layers, if any that include the given `search` in their `id` exists
 */
getLayers(search: string): Object[] {
  return Object.entries(this._layers)
    .filter(([id]) => id.includes(search))
    .map(([,layer]) => layer)
}

// or if you want to keep it OOP for referential equality
getLayers(search: string): Object[] {
  const results = [];
  const ids = Object.entries(this._layers)
    .filter(([id]) => id.includes(search))
    .foreach(([id]) => results.push(this._layers[id]))
  return results;
}

Would be happy to make a PR if you'll accept it!

@mayteio
Copy link

mayteio commented Jan 22, 2020

map.getstyle() method can get many layer in style but no custom layers, like deck.gl layer. how can I get all the layers include deck.gl layer?

@AJIKO You can access it currently with map.style._layers[customLayerId] - though I'm sure there's a reason _layers is private. Are you able to elaborate @kkaefer?

@kkaefer
Copy link
Contributor

kkaefer commented Jan 22, 2020

@mayteio same explanation as above: the idea of getStyle is to return a valid Style JSON file that conforms to the style specification. Custom layers inherently can't be part of a style document because they contain functions and always require the use of runtime styling. Therefore, you'll have to use individual getLayer calls. I recommend against using map.style._layers[customLayerId] in production code because this API is private and might change in future versions of Mapbox GL.

@mayteio
Copy link

mayteio commented Jan 22, 2020

OK great, thanks for the explanation.

Unfortunately we have a situation with deck.gl where we have an array of layers that we add to Mapbox via @deck.gl/mapbox. If an item is removed from that array, we have no way of knowing what it’s ID was. Thus we prefix all layers with “custom-“, find them in mapbox, find the difference (I.e those who are in mapbox and not in the deck.gl array) and then remove them. The only way for us is to use map._layers as these custom layers are (rightly) not in the style JSON.

@marcofugaro
Copy link

So how do I get a list of all the layers I added?

getLayers even exists in mapbox-gl-native

@mayteio
Copy link

mayteio commented Jun 9, 2020

When you call map.addLayer, prefix your layer id with custom-. Then you can get a list of all added layers with map._layers.filter(l => l.id.includes('custom-')). You can then loop through these and remove them one by one.

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

5 participants