import _ from 'underscore'; import d3 from 'd3'; import L from 'leaflet'; import 'leaflet.markercluster'; import 'leaflet/dist/leaflet.css'; import 'leaflet.markercluster/dist/MarkerCluster.css'; import 'leaflet.markercluster/dist/MarkerCluster.Default.css'; import markerIcon from 'leaflet/dist/images/marker-icon.png'; import markerIconRetina from 'leaflet/dist/images/marker-icon-2x.png'; import markerShadow from 'leaflet/dist/images/marker-shadow.png'; import 'leaflet-fullscreen'; import 'leaflet-fullscreen/dist/leaflet.fullscreen.css'; import template from './map.html'; import editorTemplate from './map-editor.html'; /* This is a workaround for an issue with giving Leaflet load the icon on its own. */ L.Icon.Default.mergeOptions({ iconUrl: markerIcon, iconRetinaUrl: markerIconRetina, shadowUrl: markerShadow, }); delete L.Icon.Default.prototype._getIconUrl; function mapRenderer() { return { restrict: 'E', template, link($scope, elm) { const colorScale = d3.scale.category10(); const map = L.map(elm[0].children[0].children[0], { scrollWheelZoom: false, fullscreenControl: true, }); const mapControls = L.control.layers().addTo(map); const layers = {}; const tileLayer = L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', }).addTo(map); function getBounds() { $scope.visualization.options.bounds = map.getBounds(); } function setBounds() { const b = $scope.visualization.options.bounds; if (b) { map.fitBounds([[b._southWest.lat, b._southWest.lng], [b._northEast.lat, b._northEast.lng]]); } else if (layers) { const allMarkers = _.flatten(_.map(_.values(layers), l => l.getLayers())); // eslint-disable-next-line new-cap const group = new L.featureGroup(allMarkers); map.fitBounds(group.getBounds()); } } map.on('focus', () => { map.on('moveend', getBounds); }); map.on('blur', () => { map.off('moveend', getBounds); }); function resize() { if (!map) return; map.invalidateSize(false); setBounds(); } const createMarker = (lat, lon) => L.marker([lat, lon]); const heatpoint = (lat, lon, color) => { const style = { fillColor: color, fillOpacity: 0.9, stroke: false, }; return L.circleMarker([lat, lon], style); }; function createDescription(latCol, lonCol, row) { const lat = row[latCol]; const lon = row[lonCol]; let description = '