简体   繁体   English

OpenLayers 3中的层切换

[英]Layer switching in OpenLayers 3

I have an issue in where I need to change the map layer ( the displayed map tiles) in my web application. 我有一个问题,我需要在我的Web应用程序中更改地图图层(显示的地图图块)。

I have this in my HTML 我的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> 

and this is what I have in my JavaScript so far 这就是我到目前为止在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

} }

What would I need to do in order to change the displayed map? 为了更改显示的地图,我需要做什么? I have looked into https://github.com/walkermatt/ol3-layerswitcherdescription] 1 but I cannot incorporate it entirely into my project because I need the dropdown list inside a toggable sidebar. 我已经查看了https://github.com/walkermatt/ol3-layerswitcherdescription] 1但我无法将其完全合并到我的项目中,因为我需要一个可切换边栏内的下拉列表。 I tried editing his code so it would add the generated HTML inside my sidebar but it did not work. 我尝试编辑他的代码,因此它会在我的侧边栏中添加生成的HTML,但它不起作用。

Is there a simpler way of changing the displayed map? 是否有更简单的方法来更改显示的地图?

You need different layer groups. 您需要不同的图层组。 I do it this way: 我是这样做的:

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);
    }
}

where setMapType is a function that I call with the necessary string attribute when I want to change the style. 其中setMapType是我想要更改样式时使用必要的字符串属性调用的函数。 map is my ol.Map variable. map是我的ol.Map变量。

You might arrange the layer groups in an array, and access them by name as you did already with the layers instead of the if/else construct I used. 您可以将图层组排列在一个数组中,并按名称访问它们,就像使用图层而不是我使用的if / else构造一样。 But I have only 2 different layer groups. 但我只有2个不同的图层组。

not directly an answer, but might be helpful for you or others: 不是直接答案,但可能对您或其他人有帮助:

to change the layer by using the name of the visible layer use: 通过使用可见图层的名称来更改图层:

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

Here a JSfiddle to see what I mean. 这里有一个JSfiddle ,看看我的意思。

I'm working on something similar using Bootstrap. 我正在使用Bootstrap开发类似的东西。 This isn't "simpler", but it should be along the lines of what you're looking for. 这不是“更简单”,但它应该与您正在寻找的一致。

So first in the HTML, I have this within my right sidebar for the basemaps: 首先在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>

Under the div where id=basemaps is where I dynamically add my basemap radio buttons. 在id = basemaps的div下,我动态添加我的底图单选按钮。

I declared my basemaps in a similar fashion yours with type: 'base'. 我用类似的方式声明了我的底图:'base'。 Once I've completed the initializing the map and layers, I call a javascript function to add the layers to the sidebar panel and also bind a radio button change event so the basemap changes to what's selected: 一旦我完成了初始化地图和图层,我调用一个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);
            }
        }

    });
}

As my code indicates, I also have a Bootstrap compatible slider which can adjust the basemap opacity. 正如我的代码所示,我还有一个Bootstrap兼容的滑块,可以调整底图的不透明度。

If you can use what I've written, you should be able to modify it for a dropdown list in the sidebar vs using radio buttons. 如果您可以使用我编写的内容,您应该能够修改侧边栏中的下拉列表与使用单选按钮。 As I had developed a page previously using jQuery mobile with radio buttons for basemap selection, I just adapted that code for Bootstrap and OpenLayers 3. Just for info, OL3 version is 3.14.1, Bootstrap is 3.3.6, jQuery is 1.11.3. 由于我之前使用带有用于底图选择的单选按钮的jQuery mobile开发了一个页面,我只是为Bootstrap和OpenLayers 3修改了代码。仅仅为了信息,OL3版本是3.14.1,Bootstrap是3.3.6,jQuery是1.11.3 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM