在CMS processwire中实现openlayers-不显示地图

时间:2018-08-23 15:13:08

标签: openlayers processwire

我在openlayers研讨会link中工作,使其适应了我的需要,现在想在网站中实现结果。 我有一个正在运行的CMS processwire本地实例,它是我要在其中安装地图的网站的副本。 我尝试使用此tutorial在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);

它应该是这样的: Wished result

这是processwire中的样子: Actual result

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

让它运行。问题是:

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

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