Плитки карты Openlayers изначально не загружаются в одностраничное приложение - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть одностраничное приложение, созданное с

  • Экспресс (4.16.3),
  • Открытые слои (5.3) и
  • Моторный движок Pug (2.0.3 - ранее известный как Jade).

Контейнер карты загружен и содержит дочерние элементы с классами ol-, а также элементы управления масштабированием в верхнем левом углу. Так что скрипт Openlayers успешно выполнен. Но он не показывает плитки карты под нагрузкой.

Когда я изменяю размер браузера, плитки карты появляются внезапно. Вот мне и интересно:

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

Мой 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

А в части 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,
      })
    });

1 Ответ

0 голосов
/ 16 ноября 2018

Нашел ответ сам. Мое «решение» - это скорее обходной путь, чем реальное решение. Я жду выполнения сценария карты (что имеет место, когда контейнер карты имеет дочерний элемент с именем класса ol-viewport), а затем вручную запускаю событие браузера resize. За исключением того, что я ожидал, методы map.render() или map.renderSync() не загружают плитки. Таким образом, обходной путь выглядит так:

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