2019-06-08 17:20:51 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
import $ from 'jquery';
|
2019-09-07 03:42:29 +02:00
|
|
|
import Events from '../_events';
|
|
|
|
import mapBoxGL from 'mapbox-gl';
|
2019-06-08 17:20:51 +02:00
|
|
|
//import "./mapStorage";
|
|
|
|
|
2019-09-07 03:42:29 +02:00
|
|
|
import '../../scss/_components/_ui.map.scss';
|
2019-06-08 17:20:51 +02:00
|
|
|
|
|
|
|
const W = window;
|
|
|
|
|
|
|
|
const MapAPI = (($) => {
|
|
|
|
const STORAGE = W.localStorage;
|
|
|
|
|
|
|
|
// Constants
|
|
|
|
const NAME = 'jsMapAPI';
|
|
|
|
const DATA_KEY = NAME;
|
|
|
|
const $BODY = $('body');
|
|
|
|
let Map;
|
|
|
|
let currentStyle;
|
|
|
|
|
|
|
|
class MapAPI {
|
|
|
|
// Constructor
|
2019-09-07 03:42:29 +02:00
|
|
|
constructor(el) {
|
|
|
|
this._el = el;
|
|
|
|
const $el = $(this._el);
|
|
|
|
const config = $el.data();
|
2019-06-08 17:20:51 +02:00
|
|
|
|
|
|
|
const center = [
|
2019-09-07 03:42:29 +02:00
|
|
|
(config['lng'] ? config['lng'] : $BODY.data('default-lng')),
|
|
|
|
(config['lat'] ? config['lat'] : $BODY.data('default-lat')),
|
2019-06-08 17:20:51 +02:00
|
|
|
];
|
2019-09-07 03:42:29 +02:00
|
|
|
const popup = new mapBoxGL.Popup({
|
2019-06-08 17:20:51 +02:00
|
|
|
closeOnClick: false,
|
|
|
|
className: 'popup',
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2019-09-07 03:42:29 +02:00
|
|
|
currentStyle = this.getStyle();
|
|
|
|
mapBoxGL.accessToken = $el.data('key');
|
2019-06-08 17:20:51 +02:00
|
|
|
Map = new mapBoxGL.Map({
|
2019-10-20 01:40:40 +02:00
|
|
|
'container': $el.find('.mapAPI-map')[0],
|
|
|
|
center,
|
|
|
|
//hash: true,
|
|
|
|
'style': currentStyle,
|
|
|
|
'localIdeographFontFamily': $BODY.css('font-family'),
|
|
|
|
'zoom': (config['mapZoom'] ? config['mapZoom'] : 10),
|
|
|
|
'attributionControl': false,
|
|
|
|
'antialias': true,
|
|
|
|
/*'pitch': 45,
|
2019-09-07 03:42:29 +02:00
|
|
|
'bearing': -17.6*/
|
|
|
|
|
2019-10-20 01:40:40 +02:00
|
|
|
/*transformRequest: (url, resourceType)=> {
|
2019-09-07 03:42:29 +02:00
|
|
|
if(resourceType === 'Source' && url.startsWith('http://myHost')) {
|
|
|
|
return {
|
|
|
|
url: url.replace('http', 'https'),
|
|
|
|
headers: { 'my-custom-header': true},
|
|
|
|
credentials: 'include' // Include cookies for cross-origin requests
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
2019-10-20 01:40:40 +02:00
|
|
|
})
|
2019-06-08 17:20:51 +02:00
|
|
|
.addControl(new mapBoxGL.AttributionControl({
|
|
|
|
compact: true,
|
|
|
|
}))
|
|
|
|
.addControl(new mapBoxGL.NavigationControl(), 'top-right')
|
|
|
|
.addControl(new mapBoxGL.GeolocateControl({
|
|
|
|
positionOptions: {
|
|
|
|
enableHighAccuracy: true,
|
|
|
|
},
|
|
|
|
trackUserLocation: true,
|
|
|
|
}), 'bottom-right')
|
2019-09-07 03:42:29 +02:00
|
|
|
.addControl(new mapBoxGL.ScaleControl({
|
2019-06-08 17:20:51 +02:00
|
|
|
maxWidth: 80,
|
|
|
|
unit: 'metric',
|
2019-09-07 03:42:29 +02:00
|
|
|
}), 'top-left')
|
|
|
|
.addControl(new mapboxgl.FullscreenControl());
|
|
|
|
|
|
|
|
$el.data('Map', Map);
|
|
|
|
$el.data('Popup', popup);
|
2019-06-08 17:20:51 +02:00
|
|
|
|
|
|
|
// event.target
|
|
|
|
Map.on('load', (e) => {
|
2019-09-07 03:42:29 +02:00
|
|
|
// Insert the layer beneath any symbol layer.
|
|
|
|
if (config['3d']) {
|
|
|
|
const layers = Map.getStyle().layers;
|
|
|
|
let labelLayerId;
|
|
|
|
for (let i = 0; i < layers.length; i++) {
|
|
|
|
if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
|
|
|
|
labelLayerId = layers[i].id;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Map.addLayer({
|
|
|
|
'id': '3d-buildings',
|
|
|
|
'source': 'composite',
|
|
|
|
'source-layer': 'building',
|
|
|
|
'filter': ['==', 'extrude', 'true'],
|
|
|
|
'type': 'fill-extrusion',
|
|
|
|
'minzoom': 15,
|
|
|
|
'paint': {
|
|
|
|
'fill-extrusion-color': '#aaa',
|
|
|
|
|
|
|
|
// use an 'interpolate' expression to add a smooth transition effect to the
|
|
|
|
// buildings as the user zooms in
|
|
|
|
'fill-extrusion-height': [
|
|
|
|
"interpolate", ["linear"],
|
|
|
|
["zoom"],
|
|
|
|
15, 0,
|
2019-10-20 01:40:40 +02:00
|
|
|
15.05, ["get", "height"],
|
2019-09-07 03:42:29 +02:00
|
|
|
],
|
|
|
|
'fill-extrusion-base': [
|
|
|
|
"interpolate", ["linear"],
|
|
|
|
["zoom"],
|
|
|
|
15, 0,
|
2019-10-20 01:40:40 +02:00
|
|
|
15.05, ["get", "min_height"],
|
2019-09-07 03:42:29 +02:00
|
|
|
],
|
2019-10-20 01:40:40 +02:00
|
|
|
'fill-extrusion-opacity': .6,
|
|
|
|
},
|
2019-09-07 03:42:29 +02:00
|
|
|
}, labelLayerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
const firstMarker = config['geojson'].features[0].geometry.coordinates;
|
|
|
|
//Map.setCenter(firstMarker);
|
|
|
|
const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker);
|
|
|
|
|
2019-06-08 17:20:51 +02:00
|
|
|
// add markers to map
|
2019-09-07 03:42:29 +02:00
|
|
|
config['geojson'].features.forEach((marker) => {
|
|
|
|
const id = marker.id;
|
|
|
|
const crds = marker.geometry.coordinates;
|
|
|
|
const content = marker.properties.content;
|
|
|
|
|
|
|
|
// create a DOM el for the marker
|
|
|
|
const $el = $(`<div id="Marker${ id }" data-id="${ id }" class="marker">${ marker.icon }</div>`);
|
2019-06-08 17:20:51 +02:00
|
|
|
|
|
|
|
$el.on('click', () => {
|
2019-09-07 03:42:29 +02:00
|
|
|
popup.setLngLat(crds)
|
2019-06-08 17:20:51 +02:00
|
|
|
.setHTML(content)
|
|
|
|
.addTo(Map);
|
2019-09-07 03:42:29 +02:00
|
|
|
|
|
|
|
if (config['flyToMarker']) {
|
|
|
|
Map.flyTo({
|
|
|
|
center: crds,
|
|
|
|
zoom: 17,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
$el.trigger(Events.MAPMARKERCLICK);
|
2019-06-08 17:20:51 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
// add marker to map
|
2019-09-07 03:42:29 +02:00
|
|
|
new mapBoxGL.Marker($el[0])
|
|
|
|
.setLngLat(crds)
|
2019-06-08 17:20:51 +02:00
|
|
|
.addTo(Map);
|
2019-09-07 03:42:29 +02:00
|
|
|
bounds.extend(crds);
|
|
|
|
});
|
|
|
|
|
|
|
|
Map.fitBounds(bounds, {
|
|
|
|
padding: 30,
|
2019-06-08 17:20:51 +02:00
|
|
|
});
|
|
|
|
|
2019-09-07 03:42:29 +02:00
|
|
|
popup.on('close', (e) => {
|
|
|
|
if (config['flyToBounds']) {
|
|
|
|
Map.fitBounds(bounds, {
|
|
|
|
padding: 30,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
$el.trigger(Events.MAPPOPUPCLOSE);
|
|
|
|
});
|
|
|
|
|
|
|
|
$el.trigger(Events.MAPLOADED);
|
|
|
|
$(W).trigger(Events.MAPLOADED);
|
2019-06-08 17:20:51 +02:00
|
|
|
console.log('Map is loaded');
|
|
|
|
});
|
|
|
|
|
|
|
|
/*Map.on('render',function(event){
|
|
|
|
console.log('map moved');
|
|
|
|
console.log(event);
|
|
|
|
});
|
|
|
|
|
|
|
|
// event: MapDataEvent
|
|
|
|
Map.on('dataloading',() => {
|
|
|
|
console.log('Loading map data');
|
|
|
|
//console.log(event);
|
|
|
|
});
|
|
|
|
|
|
|
|
// event: MapDataEvent
|
|
|
|
Map.on('data',(event) => {
|
|
|
|
console.log('Map data updated');
|
|
|
|
//console.log(event);
|
|
|
|
});*/
|
|
|
|
|
|
|
|
// check time every 60 mins and change to night style
|
|
|
|
const api = this;
|
|
|
|
setInterval(() => {
|
|
|
|
const newStyle = api.getStyle();
|
|
|
|
if (newStyle !== currentStyle) {
|
|
|
|
Map.setStyle(api.getStyle());
|
|
|
|
}
|
|
|
|
}, 36000);
|
|
|
|
|
|
|
|
|
2019-09-07 03:42:29 +02:00
|
|
|
$el.addClass(`${NAME}-active`);
|
2019-06-08 17:20:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Public methods
|
|
|
|
getMap() {
|
|
|
|
return Map;
|
|
|
|
}
|
|
|
|
|
|
|
|
getStyle() {
|
2019-09-07 03:42:29 +02:00
|
|
|
const $el = $(this._el);
|
|
|
|
return $el.data('map-style');
|
2019-06-08 17:20:51 +02:00
|
|
|
return 'mapbox://styles/mapbox/streets-v9';
|
|
|
|
const hour = new Date().getHours();
|
|
|
|
if (hour < 6 || hour > 18) {
|
|
|
|
// night
|
|
|
|
//return 'mapbox://styles/mapbox/streets-v7';
|
|
|
|
return 'mapbox://styles/tony-air/cjeacwih92iu42rpd8tcmuyb2';
|
|
|
|
}
|
2019-09-07 03:42:29 +02:00
|
|
|
// day
|
|
|
|
return 'mapbox://styles/mapbox/streets-v9';
|
2019-06-08 17:20:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
dispose() {
|
2019-09-07 03:42:29 +02:00
|
|
|
const $el = $(this._el);
|
2019-06-08 17:20:51 +02:00
|
|
|
|
2019-09-07 03:42:29 +02:00
|
|
|
$el.removeClass(`${NAME}-active`);
|
|
|
|
$.removeData(this._el, DATA_KEY);
|
|
|
|
this._el = null;
|
2019-06-08 17:20:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static _jQueryInterface() {
|
|
|
|
if (typeof W.localStorage !== 'undefined') {
|
|
|
|
return this.each(function() {
|
2019-09-07 03:42:29 +02:00
|
|
|
// attach functionality to el
|
|
|
|
const $el = $(this);
|
|
|
|
let data = $el.data(DATA_KEY);
|
2019-06-08 17:20:51 +02:00
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
data = new MapAPI(this);
|
2019-09-07 03:42:29 +02:00
|
|
|
$el.data(DATA_KEY, data);
|
2019-06-08 17:20:51 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// jQuery interface
|
|
|
|
$.fn[NAME] = MapAPI._jQueryInterface;
|
|
|
|
$.fn[NAME].Constructor = MapAPI;
|
|
|
|
$.fn[NAME].noConflict = function() {
|
|
|
|
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
|
|
|
return MapAPI._jQueryInterface;
|
|
|
|
};
|
|
|
|
|
|
|
|
// auto-apply
|
|
|
|
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
|
|
|
$('.mapAPI-map-container').jsMapAPI();
|
|
|
|
});
|
|
|
|
|
|
|
|
return MapAPI;
|
|
|
|
})($);
|
|
|
|
|
|
|
|
export default MapAPI;
|