javascript OpenLayers 3 中的层交换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27658280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Layer switching in OpenLayers 3
提问by jiggergargle
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]1but I cannot incorporate it entirely into my project because I need the dropdown list inside a toggable sidebar. I tried editing his code so it would add the generated HTML inside my sidebar but it did not work.
我需要做什么才能更改显示的地图?我已经查看了https://github.com/walkermatt/ol3-layerswitcherdescription] 1但我无法将其完全合并到我的项目中,因为我需要可切换侧边栏中的下拉列表。我尝试编辑他的代码,以便将生成的 HTML 添加到我的侧边栏中,但它不起作用。
Is there a simpler way of changing the displayed map?
有没有更简单的方法来更改显示的地图?
回答by P.J.Meisch
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. map
is my ol.Map variable.
setMapType
当我想更改样式时,我使用必要的字符串属性调用的函数在哪里。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. But I have only 2 different layer groups.
您可以将图层组排列在一个数组中,并按名称访问它们,就像您对图层所做的那样,而不是我使用的 if/else 构造。但我只有 2 个不同的图层组。
回答by Mattijn
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 JSfiddleto see what I mean.
这里有一个JSfiddle来看看我的意思。
回答by teknocreator
I'm working on something similar using Bootstrap. This isn't "simpler", but it should be along the lines of what you're looking for.
我正在使用 Bootstrap 做类似的事情。这不是“更简单”,但它应该符合您正在寻找的内容。
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'. 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:
我以类似的方式声明了我的底图,类型为:'base'。完成地图和图层的初始化后,我调用一个 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 .