Переключение слоев в OpenLayers 3

У меня проблема, когда мне нужно изменить слой карты (отображаемые фрагменты карты) в моем веб-приложении.

У меня есть это в моем HTML

<div id="map"></div>

<select onchange="changeMap()">
                <option value="BingSat">Bing Sat</option>
                <option value="BingRoad">Bing Road</option>
                <option value="OSM">OSM</option>
                <option value="MapquestSat">Mapquest Sat</option>
                <option value="MapQuestRoad">MapQuest Road</option>
</select> 

и это то, что у меня есть в моем JavaScript до сих пор

$(document).ready(function() {    
  map = new ol.Map({
    logo:'false',
    target: 'map',
    layers: [
        new ol.layer.Group({
            'title': 'Base maps',
            layers: [
                new ol.layer.Tile({
                    title: 'Water color',
                    type: 'base',
                    visible: false,
                    source: new ol.source.Stamen({
                        layer: 'watercolor'
                    })
                }),
                new ol.layer.Tile({
                    title: 'OSM',
                    type: 'base',
                    visible: true,
                    source: new ol.source.OSM()
                }),
                new ol.layer.Tile({
                    title: 'MapQuest Satellite',
                    type: 'base',
                    visible: false,
                    source: new ol.source.MapQuest({layer: 'sat'})
                }),

                 new ol.layer.Tile({
                    title: 'MapQuest OSM',
                    type: 'base',
                    visible: false,
                    source: new ol.source.MapQuest({layer: 'osm'})
                 }),
                  new ol.layer.Tile({
                      title: 'Bing Maps aerial',
                      type: 'base',
                      visible: false,
                      source: new ol.source.BingMaps({
                          imagerySet: 'AerialWithLabels',
                          key: '123'
                      })
                  }),
                     new ol.layer.Tile({
                         title: 'Bing Maps road',
                         type: 'base',
                         visible: false,
                         source: new ol.source.BingMaps({
                             imagerySet: 'Road',
                             key: '123'
                         })
                     })
            ]
        }),
    ],

    view: new ol.View({
        center: ol.proj.transform([17.813988, 43.342019], 'EPSG:4326', 'EPSG:3857'),
        zoom: 3
    })
});

}

function changeMap() {
  //grab the selected ID
 //change the map according to the selected ID

}

Что мне нужно сделать, чтобы изменить отображаемую карту? Я просмотрел https://github.com/walkermatt/ol3-layerswitcherdescription]1, но я не могу полностью включить его в свой проект, потому что мне нужен раскрывающийся список внутри переключаемой боковой панели. Я попытался отредактировать его код, чтобы он добавил сгенерированный HTML-код в мою боковую панель, но это не сработало.

Есть ли более простой способ изменить отображаемую карту?


person jiggergargle    schedule 26.12.2014    source источник


Ответы (3)


Вам нужны разные группы слоев. Я делаю это так:

var layersOSM = new ol.layer.Group({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        })
    ]
});

var layersMQ = new ol.layer.Group({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.MapQuest({layer: 'osm'})
        })
    ]
});

function setMapType(newType) {
    if(newType == 'OSM') {
        map.setLayerGroup(layersOSM);
    } else if (newType == 'MAPQUEST_OSM') {
        map.setLayerGroup(layersMQ);
    }
}

где setMapType — это функция, которую я вызываю с необходимым строковым атрибутом, когда хочу изменить стиль. mapэто моя переменная ol.Map.

Вы можете упорядочить группы слоев в виде массива и обращаться к ним по имени, как вы уже делали со слоями, вместо конструкции if/else, которую я использовал. Но у меня есть только 2 разные группы слоев.

person P.J.Meisch    schedule 09.01.2015

не прямой ответ, но может быть полезен для вас или других:

чтобы изменить слой, используя имя видимого слоя, используйте:

var group = map.getLayerGroup();
var layers = group.getLayers();
var element = layers.item(0);
var name = element.get('name');

Вот JSfiddle, чтобы понять, что я имею в виду.

person Mattijn    schedule 21.01.2015

Я работаю над чем-то подобным, используя Bootstrap. Это не «проще», но это должно соответствовать тому, что вы ищете.

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

...

<div class="panel panel-default">
    <div class="panel-heading">
        <h4 class="panel-title">
        <a data-toggle="collapse" href="#basemap-choice">
            <i class="fa fa-list-alt"></i>
            Basemaps
        </a>

        </h4>
    </div>
    <div id="basemap-choice" class="panel-collapse collapse in">
        <div class="panel-body" id="basemaps">

        </div>
        <div id="baseopacity">
            <label>Opacity</label>
            <input id="baseopslider" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="100"/>

        </div>                
    </div>
</div>

Под div, где id=basemaps, я динамически добавляю свои переключатели базовой карты.

Я объявил свои базовые карты так же, как и ваши, с типом: «база». После того, как я завершил инициализацию карты и слоев, я вызываю функцию javascript, чтобы добавить слои на панель боковой панели, а также привязать событие изменения переключателя, чтобы базовая карта изменилась на то, что выбрано:

function initBaseLayersList() {
    // get all the map layers
    var layers = map.getLayers().getArray();
    // array to hold the basemap layers
    var baseLayers = new Array();

    // loop through the layers and save
    // the ones with type = 'base'
    for (var i=0; i<layers.length; i++) {
        var lyrprop = layers[i].getProperties();
        if(lyrprop.type =='base') {   
            baseLayers.push(layers[i]);
        }
    }
    /* now that the basemap layers are separated, create appropriate HTML
       for each layer's radio button which will be appended to the sidebar panel
       body div */
    $.each(baseLayers, function(index) {
        var basecontent = '';
        var lyrprop = this.getProperties();
        basecontent += '<div class="input-group" id="radio-basemap-'+index+'">';
        // first basemap in the list is selected, others are not
        if(index==0) {
            basecontent += '<span class="input-group-addon"><input type="radio" name="radio-basemap" checked="checked">'+lyrprop.title+'</span>';
        }
        else {
            basecontent += '<span class="input-group-addon"><input type="radio" name="radio-basemap">'+lyrprop.title+'</span>'; 
        }
        basecontent += '</div>';

        $('#basemaps').append($(basecontent));

    });
    /* lastly, bind the radio button group to the change event making the 
       selected basemap visible and hiding the one deselected
    */

    $('#basemaps').bind( "change", function(event) {
        var newbase = $('input[name=radio-basemap]:checked');
        var btntext = newbase[0].nextSibling.nodeValue;

        for (var i=0; i<baseLayers.length;i++) {
            var lyrprop = baseLayers[i].getProperties();
            if (lyrprop.title == btntext) {

                baseLayers[i].setVisible(true);

                var baseslider = $('#baseopslider').slider();
                var baseopacity =  baseslider.slider('getValue')/100; 
                baseLayers[i].setOpacity(baseopacity);
            }
            else {
                baseLayers[i].setVisible(false);
            }
        }

    });
}

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

Если вы можете использовать то, что я написал, вы сможете изменить его для раскрывающегося списка на боковой панели вместо использования переключателей. Поскольку ранее я разработал страницу, используя jQuery mobile с переключателями для выбора базовой карты, я просто адаптировал этот код для Bootstrap и OpenLayers 3. Просто для информации: версия OL3 — 3.14.1, Bootstrap — 3.3.6, jQuery — 1.11.3. .

person teknocreator    schedule 09.03.2016