a2g_openlayers/main.js
2023-12-04 16:44:09 +01:00

1021 lines
47 KiB
JavaScript
Executable File

import './style.css';
import{
Overlay,
Map,
View,
Geolocation,
Feature,
} from 'ol';
import {
GPX,
GeoJSON,
}from 'ol/format';
import {
Circle as CircleStyle,
Fill,
Icon,
Stroke,
Style,
Text,
} from 'ol/style';
import {
DragPan,
MouseWheelZoom,
defaults
} from 'ol/interaction';
import {
Cluster,
OSM,
Stamen,
XYZ,
Vector as VectorSource,
} from 'ol/source';
import {toContext,
getRenderPixel
} from 'ol/render';
import {
Point,
} from 'ol/geom';
import {
Tile as TileLayer,
Vector as VectorLayer,
} from 'ol/layer';
import {getBottomLeft, getHeight, getWidth,
createEmpty,
extend,
} from 'ol/extent';
import {
ZoomSlider,
FullScreen,
defaults as defaultControls
} from 'ol/control';
import {
platformModifierKeyOnly
} from 'ol/events/condition';
import {fromLonLat} from 'ol/proj';
import {bbox} from 'ol/loadingstrategy';
if (typeof (a2gMapConfig) !== 'object') {
var a2gMapConfig = {};
}
const a2gMaps = {
mapWrapClass: 'a2g-map-wrap',
mapClass: 'a2g-map',
convexHullFill: null,
convexHullStroke: null,
textFill: null,
textStroke: null,
innerCircle: null,
outerCircle: null,
initMapConfig: function (config) {
if (this.layers.maptiler.a === null) {
if (config.api && config.api.maptiler && config.api.maptiler.key) {
this.layers.maptiler.a = config.api.maptiler.key;
}
}
if (this.layers.thunderforest.a === null) {
if (config.api && config.api.thunderforest && config.api.thunderforest.key) {
this.layers.thunderforest.a = config.api.thunderforest.key;
}
}
if (this.convexHullFill === null) {
if (config.style && typeof (config.style.convexHullFill) === 'object') {
this.convexHullFill = new Fill(config.style.convexHullFill);
} else {
this.convexHullFill = new Fill({
color: 'rgba(255, 153, 0, 0.4)'
});
}
}
if (this.convexHullStroke === null) {
if (config.style && typeof (config.style.convexHullStroke) === 'object') {
this.convexHullStroke = new Stroke(config.style.convexHullStroke);
} else {
this.convexHullStroke = new Stroke({
color: 'rgba(255, 153, 0, 0.4)'
});
}
}
if (this.textFill === null) {
if (config.style && typeof (config.style.textFill) === 'object') {
this.textFill = new Fill(config.style.textFill);
} else {
this.textFill = new Fill({
color: 'rgba(0, 0, 0, 0.9)'
});
}
}
if (this.textStroke === null) {
if (config.style && typeof (config.style.textStroke) === 'object') {
this.textStroke = new Stroke(config.style.textStroke);
} else {
this.textStroke = new Stroke({
color: 'rgba(255, 153, 0, 0.4)'
});
}
}
if (this.innerCircle === null) {
if (config.style && typeof (config.style.innerCircle) === 'object') {
this.innerCircle = new CircleStyle({
radius: config.style.innerCircle.radius,
fill: new Fill(config.style.innerCircle.fill)
});
} else {
this.innerCircle = new CircleStyle({
radius: 14,
fill: new Fill({
color: 'rgba(255, 165, 0, 0.7)'
})
});
}
}
if (this.outerCircle === null) {
if (config.style && typeof (config.style.outerCircle) === 'object') {
this.outerCircle = new CircleStyle({
radius: config.style.outerCircle.radius,
fill: new Fill(config.style.outerCircle.fill)
});
} else {
this.outerCircle = new CircleStyle({
radius: 14,
fill: new Fill({
color: 'rgba(255, 165, 0, 0.7)'
})
});
}
}
if (config.style && config.style.gpx) {
this.gpx.initConfig(config.style.gpx);
} else {
this.gpx.initConfig({});
}
},
styles: [],
mapWraps: [],
maps: [],
mapConfigs: [],
mapObjects: [],
gpx: {
mapSources: [],
mapLayers: [],
style: {
'Point': null,
'LineString': null,
'MultiLineString': null
},
initConfig: function (config) {
if (this.style['Point'] === null) {
if (typeof (config.Point) === 'object') {
this.style['Point'] = new Style({
image: new CircleStyle({
fill: new Fill(config.Point.image.fill),
radius: config.Point.image.radius,
stroke: new Stroke(config.Point.image.stroke)
})
});
} else {
this.style['Point'] = new Style({
image: new CircleStyle({
fill: new Fill({
color: 'rgba(255,255,0,0.4)'
}),
radius: 5,
stroke: new Stroke({
color: '#ff0',
width: 1
})
})
});
}
}
if (this.style['LineString'] === null) {
if (typeof (config.LineString) === 'object') {
this.style['LineString'] = new Style({
stroke: new Stroke(config.LineString.stroke)
});
} else {
this.style['LineString'] = new Style({
stroke: new Stroke({
color: '#f00',
width: 3
})
});
}
}
if (this.style['MultiLineString'] === null) {
if (typeof (config.MultiLineString) === 'object') {
this.style['MultiLineString'] = new Style({
stroke: new Stroke(config.MultiLineString.stroke)
});
} else {
this.style['MultiLineString'] = new Style({
stroke: new Stroke({
color: '#f00',
width: 3
})
});
}
}
},
init: function (mapId) {
var _this = this;
if (typeof (a2gMaps.mapConfigs[mapId].gpxSource) !== 'undefined') {
_this.mapSources[mapId] = new VectorSource({
url: a2gMaps.mapConfigs[mapId].gpxSource,
format: new GPX()
});
_this.mapLayers[mapId] = new VectorLayer({
source: _this.mapSources[mapId],
style: function (feature) {
return _this.style[feature.getGeometry().getType()];
}
});
a2gMaps.layers.mapLayers[mapId].push(_this.mapLayers[mapId]);
}
}
},
geolocate: {
locateMeDoms: [],
checkboxClass: 'a2g-map-geolocate-me',
geolocations: [],
positionFeature: new Feature(),
accuracyFeature: new Feature(),
mapSources: [],
mapLayers: [],
setPositionFeatureStyle: function () {
this.positionFeature.setStyle(
new Style({
image: new CircleStyle({
radius: 6,
fill: new Fill({
color: '#fff'
}),
stroke: new Stroke({
color: '#fff',
width: 2
})
})
})
);
},
setMapGeolocations: function (mapId) {
var _this = this;
_this.geolocations[mapId] = new Geolocation({
// enableHighAccuracy must be set to true to have the heading value.
trackingOptions: {
enableHighAccuracy: true
},
projection: a2gMaps.views[mapId].getProjection()
});
_this.geolocations[mapId].on('change:position', function () {
const coordinates = _this.geolocations[mapId].getPosition();
_this.positionFeature.setGeometry(coordinates ? new Point(coordinates) : null);
});
_this.geolocations[mapId].on('change:accuracyGeometry', function () {
_this.accuracyFeature.setGeometry(_this.geolocations[mapId].getAccuracyGeometry());
});
},
setGeolocateMeAction: function (mapId) {
var _this = this;
_this.locateMeDoms[mapId] = a2gMaps.mapWraps[mapId].getElementsByClassName(_this.checkboxClass);
if (_this.locateMeDoms[mapId].length > 0) {
_this.setMapGeolocations(mapId);
_this.mapSources[mapId] = new VectorSource({
features: [_this.accuracyFeature, _this.positionFeature]
});
_this.mapLayers[mapId] = new VectorLayer({
map: a2gMaps.mapObjects[mapId],
source: _this.mapSources[mapId]
});
}
for (var i = 0; i < _this.locateMeDoms[mapId].length; i++) {
_this.locateMeDoms[mapId][i].addEventListener('change', function () {
_this.geolocations[mapId].setTracking(this.checked);
for (var j = 0; j < _this.locateMeDoms[mapId].length; j++) {
_this.locateMeDoms[mapId][j].checked = this.checked;
}
if (this.checked) {
_this.mapLayers[mapId].setSource(_this.mapSources[mapId]);
} else {
_this.mapLayers[mapId].setSource(null);
}
});
}
},
init: function (mapId) {
this.setPositionFeatureStyle();
this.setGeolocateMeAction(mapId);
}
},
popup: {
class: 'a2g-map-popup',
contentClass: 'a2g-map-popup-content',
closerClass: 'a2g-map-popup-closer',
content: [],
closer: [],
overlay: [],
init: function (mapId) {
if (a2gMaps.mapWraps[mapId].querySelector('.' + a2gMaps.popup.class)) {
var popup = a2gMaps.mapWraps[mapId].querySelector('.' + a2gMaps.popup.class);
if (popup.classList.contains('d-none')) {
popup.classList.remove('d-none');
}
if (popup.querySelector('.' + a2gMaps.popup.contentClass) && typeof (this.content[mapId]) === 'undefined') {
this.content[mapId] = popup.querySelector('.' + a2gMaps.popup.contentClass);
}
if (popup.querySelector('.' + a2gMaps.popup.closerClass) && typeof (this.closer[mapId]) === 'undefined') {
this.closer[mapId] = popup.querySelector('.' + a2gMaps.popup.closerClass);
}
if (typeof (this.overlay[mapId]) === 'undefined') {
this.overlay[mapId] = new Overlay({
element: popup,
autoPan: {
animation: {
duration: 250
}
}
});
if (typeof (this.closer[mapId]) !== 'undefined') {
this.closer[mapId].onclick = function () {
a2gMaps.popup.overlay[mapId].setPosition(undefined);
a2gMaps.popup.closer[mapId].blur();
return false;
};
}
}
}
}
},
layers: {
mapLayerSources: [],
mapLayerSourcess: [],
mapLayers: [],
mapLayerSelects: [],
mapLayerSwitchers: [],
mapCountryOverlay: [],
mapLayerSwitcherClass: 'a2g-map-layer-swipe',
mapLayerSelectClass: 'a2g-map-layer-select',
coutriesGeojsonSource: '/data/countries.geojson',
attributions: '&copy; <a href="https://www.altogether.at" target="_blank"> altogether</a>',
attributionOpenStreetMap: '&copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>',
thunderforest: {
a: null,
baseUrl: 'https://tile.thunderforest.com/',
baseUrlSufix: '/{z}/{x}/{y}.png?apikey=',
getUrl: function (layer) {
return this.baseUrl + layer + this.baseUrlSufix + this.a;
}
},
maptiler: {
a: null,
baseUrl: 'https://api.maptiler.com/maps/',
baseUrlSufix: '/{z}/{x}/{y}.png?key=',
jpgUrlSufix: '/{z}/{x}/{y}.jpg?key=',
getUrl: function (layer) {
if (layer === 'hybrid' || layer === 'openstreetmap') {
return this.baseUrl + layer + this.jpgUrlSufix + this.a;
}
return this.baseUrl + layer + this.baseUrlSufix + this.a;
}
},
countryLayerStyle: new Style({
fill: new Fill({
color: '#aaa',
}),
stroke: new Stroke({
color: '#333'
})
}),
setCountryLayer: function (mapId, layerId, config) {
var _this = this;
_this.mapCountryOverlay[mapId] = layerId;
_this.mapLayerSources[mapId][layerId] = new VectorSource({
url: typeof (config.countryGeoSource) === 'undefined' ? _this.coutriesGeojsonSource : config.countryGeoSource,
format: new GeoJSON()
});
_this.mapLayers[mapId][layerId] = new VectorLayer({
source: _this.mapLayerSources[mapId][layerId],
style: function (feature) {
_this.countryLayerStyle.getFill().setColor('#aaa');
return _this.countryLayerStyle;
}
});
},
setMapXyzLayer: function (mapId, layerId, config) {
this.mapLayerSources[mapId][layerId] = new XYZ(config);
this.mapLayers[mapId][layerId] = new TileLayer({
source: this.mapLayerSources[mapId][layerId]
});
},
setMapOsmLayer: function (mapId, layerId, config) {
this.mapLayerSources[mapId][layerId] = new OSM(config);
this.mapLayers[mapId][layerId] = new TileLayer({
source: this.mapLayerSources[mapId][layerId]
});
},
setMapStamenLayer: function (mapId, layerId, config) {
this.mapLayerSources[mapId][layerId] = new Stamen(config);
this.mapLayers[mapId][layerId] = new TileLayer({
source: this.mapLayerSources[mapId][layerId]
});
},
appendToMapLayerSwitcher: function (mapId, layerConfig, key) {
for (var i = 0; i < this.mapLayerSelects[mapId].length; i++) {
if (typeof (layerConfig.label) !== 'undefined') {
var layerOption = document.createElement("option");
layerOption.text = layerConfig.label;
layerOption.value = key;
if (typeof (layerConfig.active) !== 'undefined' && layerConfig.active) {
layerOption.selected = true;
}
this.mapLayerSelects[mapId][i].add(layerOption);
} else {
var layerOption = document.createElement("option");
layerOption.text = key;
layerOption.value = key;
if (typeof (layerConfig.active) !== 'undefined' && layerConfig.active) {
layerOption.selected = true;
}
this.mapLayerSelects[mapId][i].add(layerOption);
}
}
},
setLayerSwitcherAction: function (mapId) {
var _this = this;
for (var i = 0; i < _this.mapLayerSelects[mapId].length; i++) {
_this.mapLayerSelects[mapId][i].dataset.map = mapId;
_this.mapLayerSelects[mapId][i].addEventListener('change', function (event) {
for (var j = 0; j < _this.mapLayerSources[this.dataset.map].length; j++) {
if (typeof (_this.layerSwitchLayerIds[this.dataset.map]) === 'undefined' || _this.layerSwitchLayerIds[this.dataset.map] !== j) {
_this.mapLayers[this.dataset.map][j].setSource(null);
}
}
_this.mapLayers[this.dataset.map][this.value].setSource(_this.mapLayerSources[this.dataset.map][this.value]);
for (var j = 0; j < _this.mapLayerSelects[mapId].length; j++) {
_this.mapLayerSelects[mapId][j].selectedIndex = this.selectedIndex;
}
});
}
},
layerSwitchLayerIds: [],
init: function (mapId) {
var _this = this;
if (typeof (_this.mapLayers[mapId]) === 'undefined') {
_this.mapLayers[mapId] = [];
_this.mapLayerSources[mapId] = [];
}
_this.mapLayerSelects[mapId] = a2gMaps.mapWraps[mapId].getElementsByClassName(_this.mapLayerSelectClass);
_this.mapLayerSwitchers[mapId] = a2gMaps.mapWraps[mapId].getElementsByClassName(_this.mapLayerSwitcherClass);
if (typeof (a2gMaps.mapConfigs[mapId].mapLayers) !== 'undefined') {
var layerConfig = a2gMaps.mapConfigs[mapId].mapLayers;
var initWithoutActiveLayer = true, activeLayerCount = 0;
var justOsm = true;
for (var i = 0; i < layerConfig.length; i++) {
if (typeof (layerConfig[i].layer) !== '' && typeof (layerConfig[i].config) === 'object') {
switch (layerConfig[i].layer) {
case 'osm':
break;
case 'country':
break;
default:
justOsm = false;
break;
}
}
}
for (var i = 0; i < layerConfig.length; i++) {
if (typeof (layerConfig[i].layer) !== '' && typeof (layerConfig[i].config) === 'object') {
layerConfig[i].config.attributions = _this.attributions;
switch (layerConfig[i].layer) {
case 'osm':
if (justOsm) {
layerConfig[i].config.attributions = layerConfig[i].config.attributions + ', ' + _this.attributionOpenStreetMap;
}
this.setMapOsmLayer(mapId, i, layerConfig[i].config);
break;
case 'stamen':
this.setMapStamenLayer(mapId, i, layerConfig[i].config);
break;
case 'thunderforest':
layerConfig[i].config.url = _this.thunderforest.getUrl(layerConfig[i].config.layer);
this.setMapXyzLayer(mapId, i, layerConfig[i].config);
break;
case 'maptiler':
layerConfig[i].config.url = _this.maptiler.getUrl(layerConfig[i].config.layer);
this.setMapXyzLayer(mapId, i, layerConfig[i].config);
break;
case 'country':
this.setCountryLayer(mapId, i, layerConfig[i].config);
break;
}
}
if (typeof (layerConfig[i].active) === 'undefined' || !layerConfig[i].active) {
_this.mapLayers[mapId][i].setSource(null);
} else {
initWithoutActiveLayer = false;
activeLayerCount++;
if (typeof (_this.mapLayerSwitchers[mapId][0]) !== 'undefined') {
if (activeLayerCount === 2) {
for (var j = 0; j < _this.mapLayerSwitchers[mapId].length; j++) {
_this.mapLayers[mapId][i].on('prerender', function (e) {
const ctx = e.context;
const mapSize = a2gMaps.mapObjects[mapId].getSize();
const width = mapSize[0] * (_this.mapLayerSwitchers[mapId][0].value / 100);
const tl = getRenderPixel(e, [width, 0]);
const tr = getRenderPixel(e, [mapSize[0], 0]);
const bl = getRenderPixel(e, [width, mapSize[1]]);
const br = getRenderPixel(e, mapSize);
ctx.save();
ctx.beginPath();
ctx.moveTo(tl[0], tl[1]);
ctx.lineTo(bl[0], bl[1]);
ctx.lineTo(br[0], br[1]);
ctx.lineTo(tr[0], tr[1]);
ctx.closePath();
ctx.clip();
});
_this.mapLayerSwitchers[mapId][j].addEventListener('input', function () {
a2gMaps.mapObjects[mapId].render();
});
_this.mapLayerSwitchers[mapId][j].addEventListener('change', function () {
a2gMaps.mapObjects[mapId].render();
});
}
_this.mapLayers[mapId][i].on('postrender', function (event) {
const ctx = event.context;
ctx.restore();
});
_this.layerSwitchLayerIds[mapId] = i;
} else if (activeLayerCount > 2) {
this.mapLayers[mapId][i].setSource(null);
}
} else if (activeLayerCount > 2) {
this.mapLayers[mapId][i].setSource(null);
}
}
this.appendToMapLayerSwitcher(mapId, layerConfig[i], i);
}
this.setLayerSwitcherAction(mapId);
if (initWithoutActiveLayer) {
this.mapLayers[mapId][a2gMaps.layers.mapLayers[mapId].length - 1].setSource(a2gMaps.layers.mapLayerSources[mapId][a2gMaps.layers.mapLayerSources[mapId].length - 1]);
for (var i = 0; i < this.mapLayerSelects[mapId].length; i++) {
this.mapLayerSelects[mapId][i].selectedIndex = a2gMaps.layers.mapLayers[mapId].length - 1;
}
}
}
}
},
views: [],
controls: [],
setMapFeatureLayer: function(mapId){
var _this = this;
_this.setFeatureOverlayStyle(mapId, _this.mapConfigs[mapId]);
_this.featureOverlay[mapId] = new VectorLayer({
source: new VectorSource(),
style: _this.featureOverlayStyle[mapId]
});
_this.layers.mapLayers[mapId].push(_this.featureOverlay[mapId]);
},
setMapObject: function (mapId) {
var _this = this;
var center = [
typeof (_this.mapConfigs[mapId].centerLon) === 'number' ? _this.mapConfigs[mapId].centerLon : 0,
typeof (_this.mapConfigs[mapId].centerLat) === 'number' ? _this.mapConfigs[mapId].centerLat : 0
];
_this.views[mapId] = new View({
center: fromLonLat(center),
padding: [170, 50, 30, 150],
zoom: typeof (_this.mapConfigs[mapId].zoom) === 'number' ? _this.mapConfigs[mapId].zoom : 1,
maxZoom: typeof (_this.mapConfigs[mapId].maxZoom) === 'number' ? _this.mapConfigs[mapId].maxZoom : 18,
showFullExtent: true
});
_this.controls[mapId] = [];
if (_this.mapConfigs[mapId].fullScreen && (_this.mapConfigs[mapId].fullScreen === true || _this.mapConfigs[mapId].fullScreen === 'true')) {
_this.controls[mapId].push(new FullScreen());
}
if (_this.mapConfigs[mapId].zoomSlider && (_this.mapConfigs[mapId].zoomSlider === true || _this.mapConfigs[mapId].zoomSlider === 'true')) {
_this.controls[mapId].push(new ZoomSlider());
}
_this.mapObjects[mapId] = new Map({
layers: _this.layers.mapLayers[mapId],
interactions: defaults({dragPan: false, mouseWheelZoom: false}).extend([
new DragPan({
condition: function (event) {
return this.getPointerCount() === 2 || platformModifierKeyOnly(event);
}
}),
new MouseWheelZoom({
condition: platformModifierKeyOnly
})
]),
controls: defaultControls().extend(_this.controls[mapId]),
target: _this.maps[mapId],
overlays: [_this.popup.overlay[mapId]],
view: _this.views[mapId]
});
// _this.setFeatureOverlayStyle(mapId, _this.mapConfigs[mapId]);
// _this.featureOverlay[mapId] = new VectorLayer({
// source: new VectorSource(),
// map: _this.mapObjects[mapId],
// style: _this.featureOverlayStyle[mapId]
// });
if (typeof (_this.mapConfigs[mapId].centerCountry) !== 'undefined' && _this.mapConfigs[mapId].centerCountry === true) {
document.addEventListener('DOMContentLoaded', () => {
if (typeof (_this.layers.mapCountryOverlay[mapId]) !== 'undefined') {
document.addEventListener('pointermove', function () {
if (typeof (_this.executedInitActions[mapId]) === 'undefined') {
_this.views[mapId].fit(_this.layers.mapLayerSources[mapId][_this.layers.mapCountryOverlay[mapId]].getFeatures()[0].getGeometry(),{duration: 500, padding: [170, 50, 30, 150]});
_this.executedInitActions[mapId] = true;
}
});
document.addEventListener('click', function () {
if (typeof (_this.executedInitActions[mapId]) === 'undefined') {
_this.views[mapId].fit(_this.layers.mapLayerSources[mapId][_this.layers.mapCountryOverlay[mapId]].getFeatures()[0].getGeometry(),{duration: 500, padding: [170, 50, 30, 150]});
_this.executedInitActions[mapId] = true;
}
});
document.addEventListener('focus', function () {
if (typeof (_this.executedInitActions[mapId]) === 'undefined') {
_this.views[mapId].fit(_this.layers.mapLayerSources[mapId][_this.layers.mapCountryOverlay[mapId]].getFeatures()[0].getGeometry(),{duration: 500, padding: [170, 50, 30, 150]});
_this.executedInitActions[mapId] = true;
}
});
document.addEventListener('scroll', function () {
if (typeof (_this.executedInitActions[mapId]) === 'undefined') {
_this.views[mapId].fit(_this.layers.mapLayerSources[mapId][_this.layers.mapCountryOverlay[mapId]].getFeatures()[0].getGeometry(),{duration: 500, padding: [170, 50, 30, 150]});
_this.executedInitActions[mapId] = true;
}
});
}
});
}
},
executedInitActions: [],
featureOverlaySource: [],
featureOverlayStyle: [],
setFeatureOverlayStyle: function (mapId, config) {
if (typeof (this.featureOverlayStyle[mapId]) === 'undefined') {
if (config.style && typeof (config.style.featureOverlay) === 'object') {
if (typeof (config.style.featureOverlay.fill) === 'object' && typeof (config.style.featureOverlay.stroke) === 'object') {
this.featureOverlayStyle[mapId] = new Style({fill: new Fill(config.style.featureOverlay.fill), stroke: new Stroke(config.style.featureOverlay.stroke)});
} else if (typeof (config.style.featureOverlay.fill) === 'object') {
this.featureOverlayStyle[mapId] = new Style({fill: new Fill(config.style.featureOverlay.fill)});
} else if (typeof (config.style.featureOverlay.stroke) === 'object') {
this.featureOverlayStyle[mapId] = new Style({stroke: new Stroke(config.style.featureOverlay.stroke)});
}
} else {
this.featureOverlayStyle[mapId] = new Style({
stroke: new Stroke({
color: 'rgba(255,255,255, 0.6)',
width: 4
})
});
}
}
},
featureOverlay: [],
featureHighlight: [],
setMapClickAction: function (mapId) {
if (a2gMaps.layers.mapCountryOverlay[mapId] !== null) {
a2gMaps.mapObjects[mapId].on('pointermove', function (event) {
if (typeof (a2gMaps.layers.mapLayers[mapId][a2gMaps.layers.mapCountryOverlay[mapId]]) !== 'undefined') {
a2gMaps.layers.mapLayers[mapId][a2gMaps.layers.mapCountryOverlay[mapId]].getFeatures(event.pixel).then(function (features) {
const feature = features.length ? features[0] : undefined;
if (feature !== a2gMaps.featureHighlight[mapId]) {
if (a2gMaps.featureHighlight[mapId]) {
a2gMaps.featureOverlay[mapId].getSource().removeFeature(a2gMaps.featureHighlight[mapId]);
}
if (feature) {
a2gMaps.featureOverlay[mapId].getSource().addFeature(feature);
}
a2gMaps.featureHighlight[mapId] = feature;
}
});
}
});
}
a2gMaps.mapObjects[mapId].on('click', function (event) {
var doNot = true;
if (typeof (a2gMaps.marker.layers.mapClusters[mapId]) !== 'undefined') {
a2gMaps.marker.layers.mapClusters[mapId].getFeatures(event.pixel).then(function (features) {
if (features.length > 0) {
doNot = false;
const clusterMembers = features[0].get('features');
if (clusterMembers.length > 1) {
// Calculate the extent of the cluster members.
const extent = createEmpty();
clusterMembers.forEach((feature) =>
extend(extent, feature.getGeometry().getExtent())
);
const view = a2gMaps.mapObjects[mapId].getView();
const resolution = a2gMaps.mapObjects[mapId].getView().getResolution();
if (view.getZoom() === view.getMaxZoom()) {
// Show an expanded view of the cluster members.
clickFeature = features[0];
clickResolution = resolution;
a2gMaps.marker.layers.mapClusterCircles[mapId].setStyle(a2gMaps.marker.layers.clusterCircleStyle);
} else {
// Zoom to the extent of the cluster members.
view.fit(extent, {duration: 500, padding: [170, 50, 30, 150]});
}
} else {
// fill single click
if (typeof (clusterMembers[0]['values_']['popup']) !== 'undefined') {
a2gMaps.popup.content[mapId].innerHTML = clusterMembers[0]['values_']['popup'];
a2gMaps.popup.overlay[mapId].setPosition(clusterMembers[0].getGeometry().getCoordinates());
}
}
}
});
}
if (a2gMaps.layers.mapCountryOverlay[mapId] !== null && typeof (a2gMaps.layers.mapLayers[mapId][a2gMaps.layers.mapCountryOverlay[mapId]]) !== 'undefined') {
a2gMaps.layers.mapLayers[mapId][a2gMaps.layers.mapCountryOverlay[mapId]].getFeatures(event.pixel).then(function (features) {
if (doNot) {
const feature = features.length ? features[0] : undefined;
if (feature !== undefined && feature.get('popup') !== undefined) {
a2gMaps.popup.content[mapId].innerHTML = feature.get('popup');
var lon = 0.0, lat = 0.0, x = 0;
for (var i = 0; i < feature.getGeometry().getCoordinates().length; i++) {
for (var j = 0; j < feature.getGeometry().getCoordinates()[i].length; j++) {
lon += feature.getGeometry().getCoordinates()[i][j][0];
lat += feature.getGeometry().getCoordinates()[i][j][1];
x++;
}
}
lon = lon / x;
lat = lat / x;
a2gMaps.popup.overlay[mapId].setPosition([lon, lat]);
a2gMaps.views[mapId].fit(feature.getGeometry(),{duration: 500, padding: [170, 50, 30, 150]});
}
}
});
}
});
},
marker: {
markerSwitcherClass: 'a2g-map-marker-visible-switcher',
markerSwitchers: [],
setMarkerSwitcherAction: function (mapId) {
var _this = this;
_this.markerSwitchers[mapId] = a2gMaps.mapWraps[mapId].getElementsByClassName(this.markerSwitcherClass);
for (var i = 0; i < _this.markerSwitchers[mapId].length; i++) {
_this.markerSwitchers[mapId][i].addEventListener('change', function (e) {
if (this.checked) {
_this.layers.mapClusters[mapId].setSource(null);
_this.layers.mapClusterCircles[mapId].setSource(null);
} else {
_this.layers.mapClusters[mapId].setSource(_this.layers.mapClusterSources[mapId]);
_this.layers.mapClusterCircles[mapId].setSource(_this.layers.mapClusterSources[mapId]);
}
for (var j = 0; j < _this.markerSwitchers[mapId].length; j++) {
_this.markerSwitchers[mapId][j].checked = this.checked;
}
});
}
},
icons: {
costumIconsDataTag: 'icons',
costumIconsUrlTag: 'iconsUrl',
costumIconsId: 'a2g-costum-icons',
defaulMarkerIcon: 'https://travel.altogether.at/typo3conf/ext/a2g_maps/Resources/Public/Icons/Marker/markerSolid.svg',
defaultMarkerIconDataAttribute: 'defaultMarkerIcon',
costumIcons: [],
mapIcons: [],
defaultIcons: [],
fillCostumIconsHelper: function (costumIcons, mapId) {
if (a2gMaps.mapConfigs[mapId].defaultMarkerIcon) {
this.defaultIcons[mapId] = new Icon({
src: a2gMaps.mapConfigs[mapId].defaultMarkerIcon
});
} else {
this.defaultIcons[mapId] = new Icon({
src: this.defaulMarkerIcon
});
}
for (let i = 0; i < costumIcons.length; i++) {
if (typeof (costumIcons[i].uid) !== 'undefined') {
if (typeof (this.costumIcons[costumIcons[i].uid]) === 'undefined') {
if (typeof (costumIcons[i].icon) === 'undefined') {
this.costumIcons[costumIcons[i].uid] = null;
} else {
this.costumIcons[costumIcons[i].uid] = new Icon({
src: costumIcons[i].icon
});
}
}
}
}
},
fillCostumIcons: function (mapId) {
if (document.getElementById(this.costumIconsId)) {
this.fillCostumIconsHelper(JSON.parse(document.getElementById(this.costumIconsId).dataset.content), mapId);
}
},
clusterMemberStyle: function (clusterMember) {
if (typeof (clusterMember.get('icon')) === 'undefined' || typeof (this.costumIcons[clusterMember.get('icon')]) === 'undefined') {
return new Style({
geometry: clusterMember.getGeometry(),
image: this.defaultIcons[0] // to do get map id
});
} else {
return new Style({
geometry: clusterMember.getGeometry(),
image: this.costumIcons[clusterMember.get('icon')]
});
}
}
},
layers: {
clusterDistance: 35,
circleDistanceMultiplier: 1,
circleFootSeparation: 28,
circleStartAngle: Math.PI / 2,
mapClusterSources: [],
mapVectorSources: [],
mapClusters: [],
mapClusterCircles: [],
generatePointsCircle: function (count, clusterCenter, resolution) {
const circumference =
this.circleDistanceMultiplier * this.circleFootSeparation * (2 + count);
let legLength = circumference / (Math.PI * 2); //radius from circumference
const angleStep = (Math.PI * 2) / count;
const res = [];
let angle;
legLength = Math.max(legLength, 45) * resolution; // Minimum distance to get outside the cluster icon.
for (let i = 0; i < count; ++i) {
// Clockwise, like spiral.
angle = this.circleStartAngle + i * angleStep;
res.push([
clusterCenter[0] + legLength * Math.cos(angle),
clusterCenter[1] + legLength * Math.sin(angle)
]);
}
return res;
},
clusterStyle: function (feature) {
const size = feature.get('features').length;
if (size > 1) {
return [
new Style({
image: a2gMaps.outerCircle
}),
new Style({
image: a2gMaps.innerCircle,
text: new Text({
text: size.toString(),
fill: a2gMaps.textFill,
stroke: a2gMaps.textStroke
})
})
];
} else {
return a2gMaps.marker.icons.clusterMemberStyle(feature.get('features')[0]);
}
},
clusterCircleStyle: function (cluster, resolution) {
if (cluster !== a2gMaps.clickFeature || resolution !== a2gMaps.clickResolution) {
return;
}
const clusterMembers = cluster.get('features');
const centerCoordinates = cluster.getGeometry().getCoordinates();
return a2gMaps.marker.layers.generatePointsCircle(
clusterMembers.length,
cluster.getGeometry().getCoordinates(),
resolution
).reduce((styles, coordinates, i) => {
const point = new Point(coordinates);
styles.push(
a2gMaps.marker.icons.clusterMemberStyle(
new Feature({
...clusterMembers[i].getProperties(),
geometry: point
})
)
);
return styles;
}, []);
},
setMapMarkerLayer: function (mapId) {
if (typeof (this.mapVectorSources[mapId]) === 'undefined') {
if (a2gMaps.mapConfigs[mapId].markerSource) {
this.mapVectorSources[mapId] = new VectorSource({
format: new GeoJSON(),
url: a2gMaps.mapConfigs[mapId].markerSource
});
} else {
this.mapVectorSources[mapId] = null;
}
}
if (typeof (this.mapClusterSources[mapId]) === 'undefined' && this.mapVectorSources[mapId] !== null) {
this.mapClusterSources[mapId] = new Cluster({
distance: this.clusterDistance,
source: this.mapVectorSources[mapId]
});
}
if (typeof (this.mapClusters[mapId]) === 'undefined' && typeof (this.mapClusterSources[mapId]) === 'object') {
this.mapClusters[mapId] = new VectorLayer({
source: this.mapClusterSources[mapId],
style: this.clusterStyle
});
}
if (typeof (this.mapClusterCircles[mapId]) === 'undefined' && typeof (this.mapClusterSources[mapId]) === 'object') {
this.mapClusterCircles[mapId] = new VectorLayer({
source: this.mapClusterSources[mapId],
style: this.clusterCircleStyle
});
}
if (this.mapVectorSources[mapId] !== null) {
a2gMaps.layers.mapLayers[mapId].push(this.mapClusters[mapId]);
a2gMaps.layers.mapLayers[mapId].push(this.mapClusterCircles[mapId]);
}
// a2gMaps.mapObjects[mapId].getView().fit(a2gMaps.layers.mapVectorSources[mapId].getExtent());
}
}
},
clickFeature: null,
clickResolution: null,
fillMapConfigs: function (mapId) {
if (this.maps[mapId].dataset.mapConfig) {
this.mapConfigs[mapId] = JSON.parse(this.maps[mapId].dataset.mapConfig);
}
if (typeof (this.mapConfigs[mapId]) === 'undefined') {
this.mapConfigs[mapId] = {};
}
if (this.maps[mapId].dataset.markers) {
this.mapConfigs[mapId].markers = this.maps[mapId].dataset.markers;
}
if (this.maps[mapId].dataset.markerSource) {
this.mapConfigs[mapId].markerSource = this.maps[mapId].dataset.markerSource;
}
if (this.maps[mapId].dataset.mapLayers) {
this.mapConfigs[mapId].mapLayers = JSON.parse(this.maps[mapId].dataset.mapLayers);
}
if (this.maps[mapId].dataset.gpxSource) {
this.mapConfigs[mapId].gpxSource = this.maps[mapId].dataset.gpxSource;
}
if (this.maps[mapId].dataset.defaultMarkerIcon) {
this.mapConfigs[mapId].defaultMarkerIcon = this.maps[mapId].dataset.defaultMarkerIcon;
}
if (this.maps[mapId].dataset.centerLon) {
this.mapConfigs[mapId].centerLon = this.maps[mapId].dataset.centerLon;
}
if (this.maps[mapId].dataset.centerLat) {
this.mapConfigs[mapId].centerLat = this.maps[mapId].dataset.centerLat;
}
if (this.maps[mapId].dataset.zoom) {
this.mapConfigs[mapId].zoom = this.maps[mapId].dataset.zoom;
}
if (this.maps[mapId].dataset.maxZoom) {
this.mapConfigs[mapId].maxZoom = this.maps[mapId].dataset.maxZoom;
}
if (this.maps[mapId].dataset.zoomSlider) {
this.mapConfigs[mapId].zoomSlider = this.maps[mapId].dataset.zoomSlider;
}
if (this.maps[mapId].dataset.fullScreen) {
this.mapConfigs[mapId].fullScreen = this.maps[mapId].dataset.fullScreen;
}
},
init: function (config) {
this.initMapConfig(config);
var tmpMapWraps = document.getElementsByClassName(this.mapWrapClass);
for (let i = 0; i < tmpMapWraps.length; i++) {
this.mapWraps[i] = tmpMapWraps[i];
this.maps[i] = this.mapWraps[i].querySelector('.' + this.mapClass);
this.fillMapConfigs(i);
this.layers.init(i);
this.marker.icons.fillCostumIcons(i);
this.setMapFeatureLayer(i);
this.marker.layers.setMapMarkerLayer(i);
this.popup.init(i);
this.gpx.init(i);
this.setMapObject(i);
this.setMapClickAction(i);
this.geolocate.init(i);
this.marker.setMarkerSwitcherAction(i);
}
}
};
a2gMaps.init(a2gMapConfig);