наложения переменной ширины, которые невозможно удалить одним щелчком мыши в диалоговом окне управления слоем

#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 наконец, ее вызывают.

В любом случае, я не понимаю такого поведения.

Есть какие-нибудь идеи?

Я просто хочу сделать так, чтобы линия наложения переменной ширины исчезала, независимо от того, какой слой отображается, после того, как пункт наложения в меню был снят.

Вот отдельная демонстрационная версия:

https://terrafrost.com/leaflet/demo01.html

Ответ №1:

Л. Контроль.О слоях в вашем коде заботятся только lightLines

 var overlays = {
    'Demo': lightLines
};
L.control.layers(baseMaps, overlays).addTo(mymap);
 

Когда вы нажимаете на элемент управления satelliteLines , ни streetsLines один из них не обрабатывается элементом управления. Кроме того, вы никогда не ставите hasOverlay на false , когда наложение удалено.

Таким образом, в зависимости от набора действий пользователя, которые вы выполняете, будет происходить разное поведение. В качестве примера:

  1. Откройте карту, Подсветка по умолчанию, Демонстрация выключена
  2. Демо-версия нажата ( hasOverlay = true и lightLines добавлена
  3. Нажмите на Улицы. lightLines удаляется (все еще в контроле есть проверка), streetsLine добавляется, hasOverlay есть true .
  4. Нажмите на Демо-версию. Событие не вызывается, так как lightLines его нет на карте, и streetLine оно все еще находится на карте, потому что элемент управления не знает об этом
  5. Нажмите на Демо-версию. lightLines добавляется на карту
  6. Нажмите на Демо-версию. lightDemo удаляется с карты и overlayremove вызывается событие удаления, поэтому удаляются три слоя наложения.

Чтобы исправить это, я буду придерживаться другого подхода, чем ваш. Вместо трех разных слоев наложения используйте только один. Слушайте только baselayerchange события. Не обрабатывайте вручную в этом обратном вызове добавление или удаление наложения с карты. Просто измените его стиль с setStyle помощью .