0

我通过 openlayers 研讨会链接工作,根据我的需要对其进行了调整,现在想在网站中实现结果。我有一个正在运行的本地 CMS processwire实例,它是我要在其中安装地图的网站的副本。我尝试使用本教程在 processwire 中安装 openlayers 。我在 processwire 中添加了来自车间的 HTML 和 JS 代码,但结果充其量是平庸的......我在地图应该是的地方得到了黑色背景,没有别的。HTML 代码:

<head>
...
<!-- openlayers-->
<script type="module" src="<?php echo $config->urls->templates ?>scripts/map.js"></script>
...
</head>

<body>
...
<div id="map-container">
    <div id="tooltip" class="tooltip"></div>
</div>

JS代码(即map.js)

import '/ol/ol.css';
import GeoJSON from '/ol/format/GeoJSON';
import Map from '/ol/Map';
import Feature from '/ol/Feature';
import VectorLayer from '/ol/layer/Vector';
import VectorSource from '/ol/source/Vector';
import View from '/ol/View';
import Overlay from '/ol/Overlay';
import sync from '/ol-hashed';
import TileLayer from '/ol/layer/Tile';
import OSM from '/ol/source/OSM';
import {fromLonLat} from '/ol/proj';
import {Fill, Stroke, Style} from '/ol/style';

/** Map of canton names with their short name, i.e. Bern - be */
const cantonsMap = new Map();
cantonsMap.set('Aargau', 'ag');
cantonsMap.set('Appenzell Ausserrhoden', 'ar');
cantonsMap.set('Appenzell Innerrhoden', 'ai');
cantonsMap.set('Basel Land', 'bl');
cantonsMap.set('Basel Stadt', 'bs');
cantonsMap.set('Bern', 'be');
cantonsMap.set('Freiburg', 'fr');
cantonsMap.set('Genf', 'ge');
cantonsMap.set('Glarus', 'gl');
cantonsMap.set('Graubünden', 'gr');
cantonsMap.set('Jura', 'ju');
cantonsMap.set('Luzern', 'lu');
cantonsMap.set('Neuenburg', 'ne');
cantonsMap.set('Nidwalden', 'nw');
cantonsMap.set('Obwalden', 'ow');
cantonsMap.set('St. Gallen', 'sg');
cantonsMap.set('Schaffhausen', 'sh');
cantonsMap.set('Schwyz', 'sz');
cantonsMap.set('Solothurn', 'so');
cantonsMap.set('Thurgau', 'tg');
cantonsMap.set('Tessin', 'ti');
cantonsMap.set('Uri', 'ur');
cantonsMap.set('Waadt', 'vd');
cantonsMap.set('Wallis', 'vs');
cantonsMap.set('Zug', 'zg');
cantonsMap.set('Zürich', 'zh');

const BernLonLat = [8.1822, 46.8743];
const BernWebMercator = fromLonLat(BernLonLat);
const view = new View({
    center: BernWebMercator,
    zoom: 8.5
});

/** Style definitions */
const logoStyle = new Style({
    fill: new Fill({
        // color: 'green'
        color: 'rgba(0, 255, 0, 0.2)'
    }),
    stroke: new Stroke({
        color: 'blue'
    })
});
const defaultStyle = new Style({
    fill: new Fill({
        color: 'rgba(255, 0, 0, 0.2)'
    }),
    stroke: new Stroke({
        color: 'blue'
    })
});
const logoStyleHover = new Style({
    fill: new Fill({
        // color: 'green'
        color: 'rgba(0, 255, 0, 0.4)'
    }),
    stroke: new Stroke({
        color: 'blue'
    })
});
const defaultStyleHover = new Style({
    fill: new Fill({
        color: 'rgba(255, 0, 0, 0.4)'
    }),
    stroke: new Stroke({
        color: 'blue'
    })
});
const logoStyleSelected = new Style({
    fill: new Fill({
        // color: 'green'
        color: 'rgba(0, 255, 0, 0.7)'
    }),
    stroke: new Stroke({
        color: 'blue'
    })
});
const defaultStyleSelected = new Style({
    fill: new Fill({
        color: 'rgba(255, 0, 0, 0.7)'
    }),
    stroke: new Stroke({
        color: 'blue'
    })
});

/** Layers: Kantone GEOJSON & OpenStreetMap Tile */
const vectorSource = new VectorSource({
    url: '../data/kantone.geojson',
    format: new GeoJSON()
});
const kantoneVectorLayer = new VectorLayer({
    source: vectorSource,
    style: function(feature, resolution) {
        const typeBez = feature.get('TYP_BEZ');
        return typeBez == 'LOGO' ? logoStyle : defaultStyle;
    }
});
const osmTileLayer = new TileLayer({
    source: new OSM()
});

/** Define the map*/
const map = new Map({
    target: 'map-container',
    layers: [osmTileLayer, kantoneVectorLayer],
    view: view
});

const tooltip = document.getElementById('tooltip');
const overlay = new Overlay({
    element: tooltip,
    offset: [10, 0],
    positioning: 'bottom-left'
});
map.addOverlay(overlay);

/** Set a global 'active canton' to prevent styling when hovering.*/
let activeCantonFeature = new Feature();

/** Called when user clicks on a canton
 * @param {pixel} pixel : coordinates used to display the modules of the clicked canton */
function displayModules(pixel) {
    // hide all canton's module lists
    const container = document.getElementById('modules-container');
    const cantonItems = container.children;
    for (let i = 0; i < cantonItems.length; i++) {
        const childItem = cantonItems[i];
        childItem.style.display = 'none';
    }
    // set all other features to default style
    const cantonsVectorSource = kantoneVectorLayer.getSource();
    cantonsVectorSource.forEachFeature(function(feature, kantoneVectorLayer) {
        feature.setStyle(function(feature, resolution) {
            const typeBez = feature.get('TYP_BEZ');
            return typeBez == 'LOGO' ? logoStyle : defaultStyle;
        });
    });
    // set the feature style for the selected feature
    map.forEachFeatureAtPixel(pixel, function(feature, layer) {
        feature.setStyle(function(feature, resolution) {
            const typeBez = feature.get('TYP_BEZ');
            return typeBez == 'LOGO' ? logoStyleSelected : defaultStyleSelected;
        });
    });
    // get the list of features to display the module list information
    const features = [];
    map.forEachFeatureAtPixel(pixel, function(feature, layer) {
        activeCantonFeature = feature;
        features.push(feature);
    });
    if (features.length > 0) {
        let cantonID = '';
        for (let i = 0, ii = features.length; i < ii; ++i) {
            cantonID = cantonsMap.get(features[i].get('NAME'));
        }
        const activeCanton = document.getElementById(cantonID);
        if (activeCanton !== null) {
            activeCanton.style.display = 'block';
        }
    }
}

/** Called when user hovers over a canton
 * @param {pixel} pixel : coordinates used to highlight the canton hovered */
function highlightFeature(pixel) {
    const cantoneVectorSource = kantoneVectorLayer.getSource();
    cantoneVectorSource.forEachFeature(function(feature, kantoneVectorLayer) {
        if (feature != activeCantonFeature) {
            feature.setStyle(function(feature, resolution) {
                const typeBez = feature.get('TYP_BEZ');
                return typeBez == 'LOGO' ? logoStyle : defaultStyle;
            });
        }
    });
    map.forEachFeatureAtPixel(pixel, function(feature, kantoneVectorLayer) {
        if (feature != activeCantonFeature) {
            feature.setStyle(function(feature, resolution) {
                const typeBez = feature.get('TYP_BEZ');
                return typeBez == 'LOGO' ? logoStyleHover : defaultStyleHover;
            });
        }
    });
}

/** Displays the canton name as a tooltip
 * @param {event} evt : the event to pass */
function displayTooltip(evt) {
    const pixel = evt.pixel;
    const feature = map.forEachFeatureAtPixel(pixel, function(feature) {
        return feature;
    });
    tooltip.style.display = feature ? '' : 'none';
    if (feature) {
        overlay.setPosition(evt.coordinate);
        tooltip.innerHTML = feature.get('NAME');
    }
}

map.on('click', function(evt) {
    const pixel = evt.pixel;
    displayModules(pixel);
});

map.on('pointermove', function(evt) {
    const pixel = evt.pixel;
    highlightFeature(pixel);
    displayTooltip(evt);
});

sync(map);

这就是它的样子: 希望的结果

这就是 processwire 中的样子: 实际结果

问题:我没有收到任何错误。我究竟做错了什么?使用 index.HTML 的研讨会教程和仅使用 index.PHP 的 processwire 之间有区别吗?是否有一些特定的 PHP 设置需要配置?

4

2 回答 2

0

跑起来了 问题是:

  • 浏览器无权访问 /node_modules/... 文件夹。
  • 因此,在 map.js 中导入时,浏览器控制台中没有错误(或者至少并非总是如此!)。

我不得不从 openlayers 导入原始的 ol.js 文件。

于 2018-08-28T07:35:19.787 回答
0

这似乎与 ProcessWire 无关,而是与您的前端构建过程有关。您添加一个用 ES6 编写的 map.js 脚本,其中包含所有这些 import 语句。但是您应该首先构建您的 js 代码并添加一个已编译的 js 文件,其中包含 dist 文件夹中已包含的所有依赖项。只需按照您链接到的教程中概述的步骤操作即可。

于 2018-08-27T06:28:46.960 回答