简体   繁体   English

Openlayers 地图图块最初未在单页应用程序中加载

[英]Openlayers map tiles are not initially loaded in single page app

I have a single page application built with我有一个使用构建的单页应用程序

  • Express (4.16.3),快递(4.16.3),
  • Openlayers (5.3) and Openlayers (5.3) 和
  • Pug (2.0.3 – formerly known as Jade) templating engine. Pug (2.0.3 – 以前称为 Jade) 模板引擎。

The map container is loaded and has child elements with ol- classes as well as the zoom controls in the upper left corner.地图容器已加载,并具有带有ol-的子元素以及左上角的缩放控件。 So the Openlayers script is successfully executed.这样 Openlayers 脚本就成功执行了。 But it doesn't show the map tiles on load.但它不会在加载时显示地图图块。

When I resize the browser the map tiles show up all of a sudden.当我调整浏览器的大小时,地图图块突然出现。 So I'm wondering:所以我想知道:

What is the event that triggers the sudden rendering of the tiles on browser resize, and how can I trigger it myself so the map is getting displayed correctly on load?在浏览器调整大小时触发瓷砖突然渲染的事件是什么,我如何自己触发它以便地图在加载时正确显示?

My index.pug looks like this:我的index.pug看起来像这样:

doctype html
html(lang='de')
  head
    meta(charset='UTF-8')
    meta(http-equiv='X-UA-Compatible', content='ie=edge')
    meta(
      name='viewport'
      content='width=device-width, initial-scale=1')
    title=`myTitle`

    // Stylesheets
    link(
      rel='stylesheet',
      href='https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css')
    link(
      rel='stylesheet',
      href='/assets/style.css')

    // Scripts
    script(src='https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js')
    script(src='https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList')
    script(src='https://code.jquery.com/jquery-3.3.1.min.js')
    script(data-main='/js/main', src='/js/require.js')

  body
    include header
    include tabs

    main
      #loader Loading...
      include map

    include footer

And in the main part you see the map pug template included that looks like this:main部分中,您会看到包含的map哈巴狗模板,如下所示:

section.component#component-map
  #map.map
  script.
    /**
    * Leaflet Map
    */
    // Create markers and geodata
    const mapCenter = [13.429, 52.494];
    const siteData = !{JSON.stringify(sites)};
    const features = siteData.map(site => {
      return {
        "type": "Feature",
        "geometry": {
          "type": "Point",
          "coordinates": [ Number(site.longitude), Number(site.latitude) ]
        }
      }
    });

    const image = new ol.style.Circle({
      radius: 5,
      fill: null,
      stroke: new ol.style.Stroke({color: "red", width: 1})
    });

    const styles = {
      "Point": new ol.style.Style({
        "image": image
      })
    }
    const styleFunction = function(feature) {
      return styles[feature.getGeometry().getType()];
    };

    const geojsonObject = {
      "type": "FeatureCollection",
      "features": features
    };

    const vectorSource = new ol.source.Vector({
      features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
    });

    const vectorLayer = new ol.layer.Vector({
      source: vectorSource,
      style: styleFunction
    });

    const map = new ol.Map({
      target: "map",
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        }),
        vectorLayer
      ],
      view: new ol.View({
        center: ol.proj.fromLonLat(mapCenter),
        zoom: 17,
      })
    });

Found the answer myself. 自己找到答案。 My "solution" is more of a workaround than an actual solution. 我的“解决方案”比实际解决方案更多是一种解决方法。 I wait for the map script to be executed (which is the case when the map container has a child element with class name ol-viewport ) and then I trigger the browser resize event manually. 我等待地图脚本执行(当地图容器具有子类名为ol-viewport的子元素时就是这种情况),然后手动触发浏览器resize事件。 Other than I expected, the map.render() or map.renderSync() methods do not load the tiles. 除了我的预期之外, map.render()map.renderSync()方法不会加载图块。 So the workaround looks like this: 因此,解决方法如下所示:

const waitForMap = setInterval(function() {
  if ($('.ol-viewport').length) {
      console.log("Exists!");
      window.dispatchEvent(new Event('resize'));
      clearInterval(waitForMap);
  }
}, 100);

A bit ugly but this solution saved me.有点难看,但这个解决方案救了我。 I'm not using jQuery so replaced .length() with:我没有使用 jQuery,所以将 .length() 替换为:

            const waitForMap = setInterval(function() {
                const e = document.querySelector(".ol-viewport");
                const cr = e.getClientRects();
                if ((cr.length != 0) && (cr[0].width != 0) && (cr[0].height != 0)) {
                    console.log("Render OpenLayer map");
                    window.dispatchEvent(new Event('resize'));
                    clearInterval(waitForMap);
                }
            }, 500);

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

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