#leaflet
Вопрос:
Я пытаюсь сделать так, чтобы ширина линии наложения менялась в зависимости от того, какой слой используется. А именно, у меня есть этот код:
var params = {
color: 'blue',
opacity: 0.75,
smoothFactor: 1
};
var latlngs = [[30.267222, -97.743056],[31.267222, -96.743056]];
tempParams = Object.assign(params, {weight: 10});
satelliteLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {weight: 3});
lightLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {weight: 5});
streetsLines.addLayer(L.polyline(latlngs, tempParams));
var hasOverlay = false;
mymap.on('baselayerchange', function(e) {
switch (e.name) {
case 'Light':
if (hasOverlay) {
lightLines.addTo(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
}
break;
case 'Streets':
if (hasOverlay) {
lightLines.removeFrom(mymap);
streetsLines.addTo(mymap);
satelliteLines.removeFrom(mymap);
}
break;
case 'Satellite':
if (hasOverlay) {
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.addTo(mymap);
}
}
});
mymap.on('overlayadd', function(e) {
console.log('overlayadd called');
hasOverlay = true;
});
Это отлично работает, когда я включаю «Демонстрационное» наложение, но оно работает не так хорошо, когда я выключаю наложение и нахожусь в слое, отличном от «Легкого» слоя по умолчанию. Что происходит, когда я нахожусь в слое, отличном от «Светлого» слоя, так это то, что линия не удаляется. Он удаляется только в «Легком» слое.
Чтобы преодолеть эту проблему, я добавил следующее:
mymap.on('overlayremove', function(e) {
console.log('overlayremove called');
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
});
Вот тогда-то все и начинает становиться странным. Чтобы удалить всю эту «демонстрационную» линию наложения для любого слоя, кроме слоя «Light» по умолчанию, мне теперь нужно дважды щелкнуть ссылку наложения «Демонстрация» в диалоговом окне управления наложением, чтобы линия наложения «Демонстрация» исчезла. Я хочу, чтобы он исчез всего после одного щелчка (так бы это обычно работало в любом случае, если бы я не пытался динамически регулировать ширину).
В соответствии console.log
с этим я вижу, что при первом изменении слоев вызывается overlayremove, но не overlayadd. Это наводит меня на мысль, что lightLines.removeFrom(mymap);
запускает overlayremove
событие. Но если это так, то почему не overlayadd
вызывается событие? Независимо от этого, если я сниму флажок, а затем проверю ссылку наложения «Демо» в правом верхнем углу, ничего не произойдет. По крайней мере, не в первый раз, когда я нажимаю на него. Линия все еще там, и ни overlayadd
то, ни overlayremove
другое не вызывается. НО когда я нажимаю на ссылку «Демонстрация» overlayadd
, вызывается ссылка наложения. Когда я снимаю флажок после этого, строка исчезает, и, overlayremove
наконец, ее вызывают.
В любом случае, я не понимаю такого поведения.
Есть какие-нибудь идеи?
Я просто хочу сделать так, чтобы линия наложения переменной ширины исчезала, независимо от того, какой слой отображается, после того, как пункт наложения в меню был снят.
Вот отдельная демонстрационная версия:
Ответ №1:
Л. Контроль.О слоях в вашем коде заботятся только lightLines
var overlays = {
'Demo': lightLines
};
L.control.layers(baseMaps, overlays).addTo(mymap);
Когда вы нажимаете на элемент управления satelliteLines
, ни streetsLines
один из них не обрабатывается элементом управления. Кроме того, вы никогда не ставите hasOverlay
на false
, когда наложение удалено.
Таким образом, в зависимости от набора действий пользователя, которые вы выполняете, будет происходить разное поведение. В качестве примера:
- Откройте карту, Подсветка по умолчанию, Демонстрация выключена
- Демо-версия нажата (
hasOverlay = true
иlightLines
добавлена - Нажмите на Улицы.
lightLines
удаляется (все еще в контроле есть проверка),streetsLine
добавляется,hasOverlay
естьtrue
. - Нажмите на Демо-версию. Событие не вызывается, так как
lightLines
его нет на карте, иstreetLine
оно все еще находится на карте, потому что элемент управления не знает об этом - Нажмите на Демо-версию.
lightLines
добавляется на карту - Нажмите на Демо-версию.
lightDemo
удаляется с карты иoverlayremove
вызывается событие удаления, поэтому удаляются три слоя наложения.
Чтобы исправить это, я буду придерживаться другого подхода, чем ваш. Вместо трех разных слоев наложения используйте только один. Слушайте только baselayerchange
события. Не обрабатывайте вручную в этом обратном вызове добавление или удаление наложения с карты. Просто измените его стиль с setStyle
помощью .