В демо здесь я работаю над картой Maptiler, используя два типа карт по умолчанию и два пользовательских типа карт в переключателе стилей и один слой. Предполагается, что код будет переключаться между стилями при перезагрузке слоя geojson при каждом изменении стиля. Он отлично работает со стилями карт по умолчанию, но не с пользовательскими типами. Пользовательские типы вообще не загружаются. Опечатки проверены, пользовательские стили опубликованы и работают на различных примерах.
<select class = "mapstyles-select">
<option value = "e8a7d286-0cf1-4165-bac7-7b1854bb30a0" selected>Natural</option>
<option value = "75422893-dc2f-40fe-af5b-fd89c0ea92d3">Light</option>
<option value = "SATELLITE">Satellite</option>
<option value = "TOPO">Topo</option>
</select>
maptilersdk.config.apiKey = 'MY API KEY';
const map = new maptilersdk.Map({
container: 'map', // container id
style: "e8a7d286-0cf1-4165-bac7-7b1854bb30a0",
center: [100.507, 13.7231], // starting position [lng, lat]
zoom: 10, // starting zoom
});
document.querySelector('.mapstyles-select').addEventListener('change', (e) => {
const style_code = e.target.value.split(".");
console.info(style_code)
map.setStyle(maptilersdk.MapStyle[style_code[0]][style_code[0]], {
transformStyle: (previousStyle, nextStyle) => {
var custom_layers = previousStyle.layers.filter((layer) => {
console.info(layer.source)
if (layer.source) {
return (
layer.source.startsWith('my-polygon')
);
}
});
var layers = nextStyle.layers.concat(custom_layers);
var sources = nextStyle.sources;
for (const [key, value] of Object.entries(previousStyle.sources)) {
if (key.startsWith('my-polygon')) {
sources[key] = value;
}
}
return {
...nextStyle,
sources: sources,
layers: layers,
};
}
});
});
map.on('load', () => {
map.addSource('my-polygon', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'coordinates': [
[
[
100.53964892087583,
13.660619302818347
]
]
]
'type': 'Polygon'
}
}
});
map.addLayer({
'id': 'my-polygon',
'type': 'fill',
'source': 'my-polygon',
'layout': {},
'paint': {
'fill-color': '#FF0000',
'fill-opacity': 0.5
}
});
});
Я пробовал использовать имя своего пользовательского идентификатора карты, например «myTopo», и пробовал использовать одинарные кавычки вместо двойных, но не знаю, почему это не работает. Мои пользовательские карты работают здесь, но слой не сохраняется в других стилях. Вот соответствующий код этой версии:
<select class = "mapstyles-select">
<option value = "e8a7d286-0cf1-4165-bac7-7b1854bb30a0" selected>Natural</option>
<option value = "75422893-dc2f-40fe-af5b-fd89c0ea92d3">Light</option>
<option value = "SATELLITE">Satellite</option>
<option value = "TOPO">Topo</option>
</select>
maptilersdk.config.apiKey = 'MY API KEY';
const map = new maptilersdk.Map({
container: 'map', // container id
style: "e8a7d286-0cf1-4165-bac7-7b1854bb30a0",
center: [100.507, 13.7231], // starting position [lng, lat]
zoom: 10, // starting zoom
});
document.querySelector('.mapstyles-select').addEventListener('change', (e) => {
const style_code = e.target.value.split(".");
map.setStyle(maptilersdk.MapStyle[style_code[0]] || style_code[0]);
});
map.on('load', () => {
map.addSource('my-polygon', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'coordinates': [
[
[
100.53964892087583,
13.660619302818347
]`
]
],
'type': 'Polygon'
}
}
});
map.addLayer({
'id': 'my-polygon',
'type': 'fill',
'source': 'my-polygon',
'layout': {},
'paint': {
'fill-color': '#FF0000',
'fill-opacity': 0.5
}
});
});
Ideally, I would be able to use custom map styles and default map styles with whatever layers and have those layers persist across styles. In both code examples I abbreviated the geojson.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8" />
<title>Display a map</title>
<meta name = "viewport" content = "initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src = "https://cdn.maptiler.com/maptiler-sdk-js/v2.0.3/maptiler-sdk.umd.js"></script>
<link href = "https://cdn.maptiler.com/maptiler-sdk-js/v2.0.3/maptiler-sdk.css" rel = "stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.mapstyles-select {
position: absolute;
top: 10px;
left: 10px;
z-index: 1000;
background: white;
padding: 5px;
border-radius: 3px;
}
</style>
</head>
<body>
<div id = "map"></div>
<select class = "mapstyles-select">
<option value = "e8a7d286-0cf1-4165-bac7-7b1854bb30a0" selected>Natural</option>
<option value = "75422893-dc2f-40fe-af5b-fd89c0ea92d3">Light</option>
<option value = "satellite">SATELLITE</option>
<option value = "topo-v2">Topo</option>
</select>
<script>
maptilersdk.config.apiKey = 'your key';
const map = new maptilersdk.Map({
container: 'map', // container id
style: "https://api.maptiler.com/maps/e8a7d286-0cf1-4165-bac7-7b1854bb30a0/style.json?key=your key",
center: [100.507, 13.7231], // starting position [lng, lat]
zoom: 10, // starting zoom
});
const addCustomLayer = () => {
if (!map.getSource('my-polygon')) {
map.addSource('my-polygon', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[100.507, 13.7231],
[100.517, 13.7331],
[100.497, 13.7331],
[100.507, 13.7231]
]
]
}
}
});
}
if (!map.getLayer('my-polygon')) {
map.addLayer({
'id': 'my-polygon',
'type': 'fill',
'source': 'my-polygon',
'layout': {},
'paint': {
'fill-color': '#FF0000',
'fill-opacity': 0.5
}
});
}
};
document.querySelector('.mapstyles-select').addEventListener('change', (e) => {
const styleCode = e.target.value;
map.setStyle(`https://api.maptiler.com/maps/${styleCode}/style.json?key=${maptilersdk.config.apiKey}`, {
transformStyle: (previousStyle, nextStyle) => {
const customLayers = previousStyle.layers.filter((layer) => {
return layer.source && layer.source.startsWith('my-polygon');
});
const layers = nextStyle.layers.concat(customLayers);
const sources = { ...nextStyle.sources };
for (const [key, value] of Object.entries(previousStyle.sources)) {
if (key.startsWith('my-polygon')) {
sources[key] = value;
}
}
return {
...nextStyle,
sources,
layers,
};
}
});
map.once('styledata', addCustomLayer);
});
map.on('load', addCustomLayer);
</script>
</body>
</html>Теперь это должно работать так, как задумано. :) просто добавьте свой ключ