import React from 'react';
import { Portal } from 'react-portal';
import { connect } from 'react-redux'
import * as selectors from '../selectors'
import hash from 'object-hash';
import 'leaflet';
import { isNotNullNorUndefined } from '../js/utilities';
import MapSites from './MapSites.jsx';
import MapEvents from './MapEvents.jsx';
import MapSelectedEvents from './MapSelectedEvents.jsx';
import MapNarratives from './MapNarratives.jsx';
import MapDefsMarkers from './MapDefsMarkers.jsx';
class Map extends React.Component {
constructor() {
super();
this.svgRef = React.createRef();
this.map = null;
this.state = {
mapTransformX: 0,
mapTransformY: 0
}
}
componentDidMount(){
if (this.map === null) {
this.initializeMap();
}
}
componentWillReceiveProps(nextProps) {
if (hash(nextProps.app.selected) !== hash(this.props.app.selected)) {
// Fly to first of events selected
const eventPoint = (nextProps.app.selected.length > 0) ? nextProps.app.selected[0] : null;
if (eventPoint !== null && eventPoint.latitude && eventPoint.longitude) {
this.map.setView([eventPoint.latitude, eventPoint.longitude]);
}
}
}
initializeMap() {
/**
* Creates a Leaflet map and a tilelayer for the map background
*/
const map =
L.map(this.props.mapId)
.setView(this.props.app.mapAnchor, 14)
.setMinZoom(10)
.setMaxZoom(18)
.setMaxBounds([[180, -180], [-180, 180]])
let s;
if (process.env.MAPBOX_TOKEN && process.env.MAPBOX_TOKEN !== 'your_token') {
s = L.tileLayer(
`http://a.tiles.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}@2x.png?access_token=${process.env.MAPBOX_TOKEN}`
);
} else {
// eslint-disable-next-line
alert(`No mapbox token specified in config.
Timemap does not currently support any other tiling layer,
so you will need to sign up for one at:
https://www.mapbox.com/
Stop and start the development process in terminal after you have added your token to config.js`
)
return
}
s = s.addTo(map);
map.keyboard.disable();
map.on('move zoomend viewreset moveend', () => this.alignLayers());
map.on('zoomstart', () => { if (this.svgRef.current !== null) this.svgRef.current.classList.add('hide') });
map.on('zoomend', () => { if (this.svgRef.current !== null) this.svgRef.current.classList.remove('hide'); });
window.addEventListener('resize', () => { this.alignLayers(); });
this.map = map;
}
alignLayers() {
const mapNode = document.querySelector('.leaflet-map-pane');
if (mapNode === null) return { transformX: 0, transformY: 0 };
// We'll get the transform of the leaflet container,
// which will let us offset the SVG by the same quantity
const transform = window
.getComputedStyle(mapNode)
.getPropertyValue('transform');
// Offset with leaflet map transform boundaries
this.setState({
mapTransformX: +transform.split(',')[4],
mapTransformY: +transform.split(',')[5].split(')')[0]
})
}
getClientDims() {
const boundingClient = document.querySelector(`#${this.props.mapId}`).getBoundingClientRect();
return {
width: boundingClient.width,
height: boundingClient.height
}
}
renderSVG() {
if (this.map === null) return '';
const pane = this.map.getPanes().overlayPane;
const { width, height } = this.getClientDims();
return (