如何覆盖现有地图而不是在下面添加新地图(OpenLayers)?

How can I overwrite existing map instead of adding a new one below (OpenLayers)?

我正在尝试构建一个包含多个可以打开和关闭的图层的 web 地图。最初绘制地图时没有任何问题,但是当我尝试关闭任何图层时,新地图会添加到现有地图下方(而不是替换它)。

当我关闭图层时,会调用 javascript refresh() 函数。此函数需要重建要绘制的图层列表,然后再次调用构建地图的函数。我希望这只会取代现有的地图,但下面会添加一张新地图。

...
...
<script type="text/javascript" src="ol.js"></script>        

<script defer="defer" type="text/javascript">

    function onLOAD()
    {
        var my_layers = 'layer_1,     \
                         layer_2,     \
                         layer_3,     \
                         ...'
        init(my_layers);
    }


    function init(my_layers){

        //The bounding box of Lund:lund_address_point
        var extent = [13.1267,55.6770,13.2601,55.7597];

        //Initial view
        var view = new ol.View({
                   center: ol.proj.transform([13.192927, 55.708944], 'EPSG:4326', 'EPSG:3857'),
                   zoom: 13
                   });              

        //The source for the layers
        var wmsSource = new ol.source.ImageWMS({
                        url: 'http://localhost:8080/geoserver/Test/wms',
                        params: {
                                 'LAYERS': my_layers
                                },
                        serverType: 'geoserver'
                        });             
                        
        //OpenStreetMap background and my_layers
        var layers = [
                      new ol.layer.Tile({
                          source: new ol.source.OSM()
                          }),
                      new ol.layer.Image({
                         source: wmsSource
                          })
                      ];
        
        //Bind the map object to our "map" div and add some extra functionality
        var map = new ol.Map({
                  layers: layers,
                  controls: ol.control.defaults({
                            attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
                                 collapsible: false
                          })
                  }).extend([
                        //Extra functionality of the map
                        //Control for displaying coordinates
                        new ol.control.MousePosition({
                             coordinateFormat: ol.coordinate.createStringXY(4),
                             projection: 'EPSG:4326',
                             className: 'custom-mouse-position',
                             target: document.getElementById('location'),
                             undefinedHTML: '&nbsp;'
                        }),
                        //Control for displaying a scale line
                        new ol.control.ScaleLine({
                            target: document.getElementById('scale-line')
                        }),
                        //Control for zooming to a defined extent
                        new ol.control.ZoomToExtent({
                            extent: ol.proj.transform(extent, 'EPSG:4326', 'EPSG:3857')
                        })
                  ]),
                  target: 'map',
                  view: view
        });

    }

    
    function refresh(){
      my_layers='';
      if (layer_1.checked) my_layers = my_layers + "layer_1,";
      if (layer_2.checked) my_layers = my_layers + "layer_2,";
      if (layer_3.checked) my_layers = my_layers + "layer_3,";
      ...  
      if (my_layers.length > 1){
        my_layers = my_layers.substring(0,my_layers.length-1);
      }
      init(my_layers);
    }           
    
</script>
</head>     



<body onload="onLOAD()">

<div>
    <br><input type="checkbox" id="layer_1" value="layer_1" checked="checked" onClick="refresh()">Layer_1
    <br><input type="checkbox" id="layer_2" value="layer_2" checked="checked" onClick="refresh()">Layer_2
    <br><input type="checkbox" id="layer_3" value="layer_3" checked="checked" onClick="refresh()">Layer_3
    ...
    ...
</div>

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

<div id="wrapper">
    <div id="location"></div>
    <br>
    <div id="scale-line" class="scale-line"></div>
</div>

...
...

要彻底删除旧地图,您需要对之前的地图对象调用 map.setTarget(null)

但在您的情况下,最好只创建一个地图并更新图层的可见性。 这样,地图/视图状态(如加载的图块、中心和缩放)就会被记住。

<div>
    <br><input type="checkbox" id="input-osm" value="osm" checked="checked">OSM
    <br><input type="checkbox" id="input-image" value="image" checked="checked">Image
</div>

在 init 函数外声明 map 和 layers 变量,以便可以从刷新函数访问。

var map, layers;

将图层存储在一个对象中并分配给声明的图层变量,以便能够按名称引用它们并以正确的可见性初始化它们:

layers = {
    osm: ol.layer.Tile({
        source: new ol.source.OSM(),
        visible: document.getElementById('input-osm').checked,
    }),
    image: new ol.layer.Image({
        source: wmsSource
        visible: document.getElementById('input-image').checked,
    })
};

将所有图层的地图分配给先前声明的变量:

map = new ol.Map({
    layers: Object.values(layers),
    ...

用户输入层的可见性应根据复选框更改:

function refresh(checkbox) {
    layers[checkbox.value].setVisible(checkbox.checked);
}
document.getElementById('input-osm').addEventListener('change', refresh);
document.getElementById('input-image').addEventListener('change', refresh);

祝你好运。

首先!对 HTML 进行一些更改。 refresh(this)

...
<input type="checkbox" id="layer_1" value="layer_1" checked="checked" onClick="refresh(this)">Layer_1
...

javascript

var layersMap;
function onLOAD() {
  var my_layers = "layer_1,layer_2,layer_3";
  init(my_layers.split(","));
}

function init(layerNames) {
  //The bounding box of Lund:lund_address_point
  var extent = [13.1267, 55.677, 13.2601, 55.7597];
  //Initial view
  var view = new ol.View({
    center: ol.proj.transform([13.192927, 55.708944], "EPSG:4326", "EPSG:3857"),
    zoom: 13,
  });
  //Bind the map object to our "map" div and add some extra functionality
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM(),
      }),
    ],
    controls: ol.control
      .defaults({
        attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
          collapsible: false,
        }),
      })
      .extend([
        //Extra functionality of the map
        //Control for displaying coordinates
        new ol.control.MousePosition({
          coordinateFormat: ol.coordinate.createStringXY(4),
          projection: "EPSG:4326",
          className: "custom-mouse-position",
          target: document.getElementById("location"),
          undefinedHTML: "&nbsp;",
        }),
        //Control for displaying a scale line
        new ol.control.ScaleLine({
          target: document.getElementById("scale-line"),
        }),
        //Control for zooming to a defined extent
        new ol.control.ZoomToExtent({
          extent: ol.proj.transform(extent, "EPSG:4326", "EPSG:3857"),
        }),
      ]),
    target: "map",
    view: view,
  });

  layerNames.forEach((layerName) => {
    layersMap[layerName] = generateImageWms(layerName);
    map.addLayer(layersMap[layerName]);
  });
}

function generateImageWms(layerName) {
  return new ol.source.ImageWMS({
    url: "http://localhost:8080/geoserver/Test/wms",
    params: {
      LAYERS: layerName,
    },
    serverType: "geoserver",
  });
}

function refresh(target) {
  layersMap[target.id] && layersMap[target.id].setVisible(target.checked);
}