diff --git a/app/static/app/js/components/Map.jsx b/app/static/app/js/components/Map.jsx index 6604a8299..ff17a591e 100644 --- a/app/static/app/js/components/Map.jsx +++ b/app/static/app/js/components/Map.jsx @@ -26,7 +26,8 @@ import LayersControl from './LayersControl'; import update from 'immutability-helper'; import Utils from '../classes/Utils'; import '../vendor/leaflet/Leaflet.Ajax'; -import '../vendor/leaflet/Leaflet.Awesome-markers'; +import 'rbush'; +import '../vendor/leaflet/leaflet-markers-canvas'; import { _ } from '../classes/gettext'; class Map extends React.Component { @@ -228,41 +229,45 @@ class Map extends React.Component { // Add camera shots layer if available if (meta.task && meta.task.camera_shots && !this.addedCameraShots){ - const shotsLayer = new L.GeoJSON.AJAX(meta.task.camera_shots, { - style: function (feature) { - return { - opacity: 1, - fillOpacity: 0.7, - color: "#000000" - } - }, - pointToLayer: function (feature, latlng) { - return new L.CircleMarker(latlng, { - color: '#3498db', - fillColor: '#3498db', - fillOpacity: 0.9, - radius: 10, - weight: 1 - }); - }, - onEachFeature: function (feature, layer) { - if (feature.properties && feature.properties.filename) { - let root = null; - const lazyrender = () => { - if (!root) root = document.createElement("div"); - ReactDOM.render(, root); - return root; - } - - layer.bindPopup(L.popup( - { - lazyrender, - maxHeight: 450, - minWidth: 320 - })); + var camIcon = L.icon({ + iconUrl: "/static/app/js/icons/marker-camera.png", + iconSize: [41, 46], + iconAnchor: [17, 46], + }); + + const shotsLayer = new L.MarkersCanvas(); + $.getJSON(meta.task.camera_shots) + .done((shots) => { + if (shots.type === 'FeatureCollection'){ + let markers = []; + + shots.features.forEach(s => { + let marker = L.marker( + [s.geometry.coordinates[1], s.geometry.coordinates[0]], + { icon: camIcon } + ); + markers.push(marker); + + if (s.properties && s.properties.filename){ + let root = null; + const lazyrender = () => { + if (!root) root = document.createElement("div"); + ReactDOM.render(, root); + return root; + } + + marker.bindPopup(L.popup( + { + lazyrender, + maxHeight: 450, + minWidth: 320 + })); } + }); + + shotsLayer.addMarkers(markers, this.map); } - }); + }); shotsLayer[Symbol.for("meta")] = {name: name + " " + _("(Cameras)"), icon: "fa fa-camera fa-fw"}; this.setState(update(this.state, { @@ -274,44 +279,45 @@ class Map extends React.Component { // Add ground control points layer if available if (meta.task && meta.task.ground_control_points && !this.addedGroundControlPoints){ - const gcpMarker = L.AwesomeMarkers.icon({ - icon: 'dot-circle', - markerColor: 'blue', - prefix: 'fa' + const gcpIcon = L.icon({ + iconUrl: "/static/app/js/icons/marker-gcp.png", + iconSize: [41, 46], + iconAnchor: [17, 46], }); - - const gcpLayer = new L.GeoJSON.AJAX(meta.task.ground_control_points, { - style: function (feature) { - return { - opacity: 1, - fillOpacity: 0.7, - color: "#000000" - } - }, - pointToLayer: function (feature, latlng) { - return new L.marker(latlng, { - icon: gcpMarker - }); - }, - onEachFeature: function (feature, layer) { - if (feature.properties && feature.properties.observations) { - // TODO! - let root = null; - const lazyrender = () => { + + const gcpLayer = new L.MarkersCanvas(); + $.getJSON(meta.task.ground_control_points) + .done((gcps) => { + if (gcps.type === 'FeatureCollection'){ + let markers = []; + + gcps.features.forEach(gcp => { + let marker = L.marker( + [gcp.geometry.coordinates[1], gcp.geometry.coordinates[0]], + { icon: gcpIcon } + ); + markers.push(marker); + + if (gcp.properties && gcp.properties.observations){ + let root = null; + const lazyrender = () => { if (!root) root = document.createElement("div"); - ReactDOM.render(, root); + ReactDOM.render(, root); return root; - } - - layer.bindPopup(L.popup( - { - lazyrender, - maxHeight: 450, - minWidth: 320 - })); + } + + marker.bindPopup(L.popup( + { + lazyrender, + maxHeight: 450, + minWidth: 320 + })); } + }); + + gcpLayer.addMarkers(markers, this.map); } - }); + }); gcpLayer[Symbol.for("meta")] = {name: name + " " + _("(GCPs)"), icon: "far fa-dot-circle fa-fw"}; this.setState(update(this.state, { diff --git a/app/static/app/js/icons/marker-camera.png b/app/static/app/js/icons/marker-camera.png new file mode 100644 index 000000000..50c90c79f Binary files /dev/null and b/app/static/app/js/icons/marker-camera.png differ diff --git a/app/static/app/js/icons/marker-gcp.png b/app/static/app/js/icons/marker-gcp.png new file mode 100644 index 000000000..90613e5bf Binary files /dev/null and b/app/static/app/js/icons/marker-gcp.png differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-matte.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-matte.png deleted file mode 100644 index 178258665..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-matte.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-matte@2x.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-matte@2x.png deleted file mode 100644 index c981244dd..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-matte@2x.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-plain.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-plain.png deleted file mode 100644 index 763f35893..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-plain.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-shadow.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-shadow.png deleted file mode 100644 index 33cf95504..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-shadow.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-shadow@2x.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-shadow@2x.png deleted file mode 100644 index 1116503f6..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-shadow@2x.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-soft.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-soft.png deleted file mode 100644 index 9ee4c348d..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-soft.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-soft@2x.png b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-soft@2x.png deleted file mode 100644 index 540ce6375..000000000 Binary files a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/images/markers-soft@2x.png and /dev/null differ diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/index.js b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/index.js deleted file mode 100644 index ce696ca11..000000000 --- a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/index.js +++ /dev/null @@ -1,127 +0,0 @@ -/* - Leaflet.AwesomeMarkers, a plugin that adds colorful iconic markers for Leaflet, based on the Font Awesome icons - (c) 2012-2013, Lennard Voogdt - - http://leafletjs.com - https://github.com/lvoogdt -*/ - -/*global L*/ - -import "./leaflet.awesome-markers.css"; - -(function (window, document, undefined) { - "use strict"; - /* - * Leaflet.AwesomeMarkers assumes that you have already included the Leaflet library. - */ - - L.AwesomeMarkers = {}; - - L.AwesomeMarkers.version = '2.0.1'; - - L.AwesomeMarkers.Icon = L.Icon.extend({ - options: { - iconSize: [35, 45], - iconAnchor: [17, 42], - popupAnchor: [1, -32], - shadowAnchor: [10, 12], - shadowSize: [36, 16], - className: 'awesome-marker', - prefix: 'glyphicon', - spinClass: 'fa-spin', - extraClasses: '', - icon: 'home', - markerColor: 'blue', - iconColor: 'white' - }, - - initialize: function (options) { - options = L.Util.setOptions(this, options); - }, - - createIcon: function () { - var div = document.createElement('div'), - options = this.options; - - if (options.icon) { - div.innerHTML = this._createInner(); - } - - if (options.bgPos) { - div.style.backgroundPosition = - (-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px'; - } - - this._setIconStyles(div, 'icon-' + options.markerColor); - return div; - }, - - _createInner: function() { - var iconClass, iconSpinClass = "", iconColorClass = "", iconColorStyle = "", options = this.options; - - if(options.icon.slice(0,options.prefix.length+1) === options.prefix + "-") { - iconClass = options.icon; - } else { - iconClass = options.prefix + "-" + options.icon; - } - - if(options.spin && typeof options.spinClass === "string") { - iconSpinClass = options.spinClass; - } - - if(options.iconColor) { - if(options.iconColor === 'white' || options.iconColor === 'black') { - iconColorClass = "icon-" + options.iconColor; - } else { - iconColorStyle = "style='color: " + options.iconColor + "' "; - } - } - - return ""; - }, - - _setIconStyles: function (img, name) { - var options = this.options, - size = L.point(options[name === 'shadow' ? 'shadowSize' : 'iconSize']), - anchor; - - if (name === 'shadow') { - anchor = L.point(options.shadowAnchor || options.iconAnchor); - } else { - anchor = L.point(options.iconAnchor); - } - - if (!anchor && size) { - anchor = size.divideBy(2, true); - } - - img.className = 'awesome-marker-' + name + ' ' + options.className; - - if (anchor) { - img.style.marginLeft = (-anchor.x) + 'px'; - img.style.marginTop = (-anchor.y) + 'px'; - } - - if (size) { - img.style.width = size.x + 'px'; - img.style.height = size.y + 'px'; - } - }, - - createShadow: function () { - var div = document.createElement('div'); - - this._setIconStyles(div, 'shadow'); - return div; - } - }); - - L.AwesomeMarkers.icon = function (options) { - return new L.AwesomeMarkers.Icon(options); - }; - -}(this, document)); - - - diff --git a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/leaflet.awesome-markers.css b/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/leaflet.awesome-markers.css deleted file mode 100644 index 588a99c85..000000000 --- a/app/static/app/js/vendor/leaflet/Leaflet.Awesome-markers/leaflet.awesome-markers.css +++ /dev/null @@ -1,124 +0,0 @@ -/* -Author: L. Voogdt -License: MIT -Version: 1.0 -*/ - -/* Marker setup */ -.awesome-marker { - background: url('images/markers-soft.png') no-repeat 0 0; - width: 35px; - height: 46px; - position:absolute; - left:0; - top:0; - display: block; - text-align: center; -} - -.awesome-marker-shadow { - background: url('images/markers-shadow.png') no-repeat 0 0; - width: 36px; - height: 16px; -} - -/* Retina displays */ -@media (min--moz-device-pixel-ratio: 1.5),(-o-min-device-pixel-ratio: 3/2), -(-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5),(min-resolution: 1.5dppx) { - .awesome-marker { - background-image: url('images/markers-soft@2x.png'); - background-size: 720px 46px; - } - .awesome-marker-shadow { - background-image: url('images/markers-shadow@2x.png'); - background-size: 35px 16px; - } -} - -.awesome-marker i { - color: #333; - margin-top: 10px; - display: inline-block; - font-size: 14px; -} - -.awesome-marker .icon-white { - color: #fff; -} - -/* Colors */ -.awesome-marker-icon-red { - background-position: 0 0; -} - -.awesome-marker-icon-darkred { - background-position: -180px 0; -} - -.awesome-marker-icon-lightred { - background-position: -360px 0; -} - -.awesome-marker-icon-orange { - background-position: -36px 0; -} - -.awesome-marker-icon-beige { - background-position: -396px 0; -} - -.awesome-marker-icon-green { - background-position: -72px 0; -} - -.awesome-marker-icon-darkgreen { - background-position: -252px 0; -} - -.awesome-marker-icon-lightgreen { - background-position: -432px 0; -} - -.awesome-marker-icon-blue { - background-position: -108px 0; -} - -.awesome-marker-icon-darkblue { - background-position: -216px 0; -} - -.awesome-marker-icon-lightblue { - background-position: -468px 0; -} - -.awesome-marker-icon-purple { - background-position: -144px 0; -} - -.awesome-marker-icon-darkpurple { - background-position: -288px 0; -} - -.awesome-marker-icon-pink { - background-position: -504px 0; -} - -.awesome-marker-icon-cadetblue { - background-position: -324px 0; -} - -.awesome-marker-icon-white { - background-position: -574px 0; -} - -.awesome-marker-icon-gray { - background-position: -648px 0; -} - -.awesome-marker-icon-lightgray { - background-position: -612px 0; -} - -.awesome-marker-icon-black { - background-position: -682px 0; -} diff --git a/app/static/app/js/vendor/leaflet/leaflet-markers-canvas.js b/app/static/app/js/vendor/leaflet/leaflet-markers-canvas.js new file mode 100644 index 000000000..578f4ce7c --- /dev/null +++ b/app/static/app/js/vendor/leaflet/leaflet-markers-canvas.js @@ -0,0 +1,493 @@ +/*https://github.com/francoisromain/leaflet-markers-canvas/blob/master/licence.md*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('leaflet'), require('rbush')) : + typeof define === 'function' && define.amd ? define(['leaflet', 'rbush'], factory) : + (global = global || self, factory(global.L, global.RBush)); + }(this, (function (L, RBush) { 'use strict'; + + L = L && Object.prototype.hasOwnProperty.call(L, 'default') ? L['default'] : L; + RBush = RBush && Object.prototype.hasOwnProperty.call(RBush, 'default') ? RBush['default'] : RBush; + + var markersCanvas = { + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // private: properties + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + _map: null, + _canvas: null, + _context: null, + + // leaflet markers (used to getBounds) + _markers: [], + + // visible markers + _markersTree: null, + + // every marker positions (even out of the canvas) + _positionsTree: null, + + // icon images index + _icons: {}, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // public: global + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + addTo: function addTo(map) { + map.addLayer(this); + + return this; + }, + + getBounds: function getBounds() { + var bounds = new L.LatLngBounds(); + + this._markers.forEach(function (marker) { + bounds.extend(marker.getLatLng()); + }); + + return bounds; + }, + + redraw: function redraw() { + this._redraw(true); + }, + + clear: function clear() { + this._positionsTree = new RBush(); + this._markersTree = new RBush(); + this._markers = []; + this._redraw(true); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // public: markers + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + addMarker: function addMarker(marker, map) { + var ref = this._addMarker(marker, map); + var markerBox = ref.markerBox; + var positionBox = ref.positionBox; + var isVisible = ref.isVisible; + + if (markerBox && isVisible) { + this._markersTree.insert(markerBox); + } + + if (positionBox) { + this._positionsTree.insert(positionBox); + } + }, + + // add multiple markers (better for rBush performance) + addMarkers: function addMarkers(markers, map) { + if (!this._markersTree) this._markersTree = new RBush(); + if (!this._positionsTree) this._positionsTree = new RBush(); + + var this$1 = this; + + var markerBoxes = []; + var positionBoxes = []; + + markers.forEach(function (marker) { + var ref = this$1._addMarker(marker, map); + var markerBox = ref.markerBox; + var positionBox = ref.positionBox; + var isVisible = ref.isVisible; + + if (markerBox && isVisible) { + markerBoxes.push(markerBox); + } + + if (positionBox) { + positionBoxes.push(positionBox); + } + }); + + this._markersTree.load(markerBoxes); + this._positionsTree.load(positionBoxes); + }, + + removeMarker: function removeMarker(marker) { + var latLng = marker.getLatLng(); + var isVisible = this._map.getBounds().contains(latLng); + + var positionBox = { + minX: latLng.lng, + minY: latLng.lat, + maxX: latLng.lng, + maxY: latLng.lat, + marker: marker, + }; + + this._positionsTree.remove(positionBox, function (a, b) { + return a.marker._leaflet_id === b.marker._leaflet_id; + }); + + if (isVisible) { + this._redraw(true); + } + }, + + // remove multiple markers (better for rBush performance) + removeMarkers: function removeMarkers(markers) { + var this$1 = this; + + var hasChanged = false; + + markers.forEach(function (marker) { + var latLng = marker.getLatLng(); + var isVisible = this$1._map.getBounds().contains(latLng); + + var positionBox = { + minX: latLng.lng, + minY: latLng.lat, + maxX: latLng.lng, + maxY: latLng.lat, + marker: marker, + }; + + this$1._positionsTree.remove(positionBox, function (a, b) { + return a.marker._leaflet_id === b.marker._leaflet_id; + }); + + if (isVisible) { + hasChanged = true; + } + }); + + if (hasChanged) { + this._redraw(true); + } + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // leaflet: default methods + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + initialize: function initialize(options) { + L.Util.setOptions(this, options); + }, + + // called by Leaflet on `map.addLayer` + onAdd: function onAdd(map) { + this._map = map; + if (!this._canvas) this._initCanvas(); + this.getPane().appendChild(this._canvas); + + map.on("moveend", this._reset, this); + map.on("resize", this._reset, this); + + map.on("click", this._fire, this); + map.on("mousemove", this._fire, this); + + if (map._zoomAnimated) { + map.on("zoomanim", this._animateZoom, this); + } + + this._reset(); + }, + + // called by Leaflet + onRemove: function onRemove(map) { + this.getPane().removeChild(this._canvas); + + map.off("click", this._fire, this); + map.off("mousemove", this._fire, this); + map.off("moveend", this._reset, this); + map.off("resize", this._reset, this); + + if (map._zoomAnimated) { + map.off("zoomanim", this._animateZoom, this); + } + }, + + setOptions: function setOptions(options) { + L.Util.setOptions(this, options); + + return this.redraw(); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // private: global methods + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + _initCanvas: function _initCanvas() { + var ref = this._map.getSize(); + var x = ref.x; + var y = ref.y; + var isAnimated = this._map.options.zoomAnimation && L.Browser.any3d; + + this._canvas = L.DomUtil.create( + "canvas", + "leaflet-markers-canvas-layer leaflet-layer" + ); + this._canvas.width = x; + this._canvas.height = y; + this._context = this._canvas.getContext("2d"); + + L.DomUtil.addClass( + this._canvas, + ("leaflet-zoom-" + (isAnimated ? "animated" : "hide")) + ); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // private: marker methods + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + _addMarker: function _addMarker(marker, map) { + if (marker.options.pane !== "markerPane" || !marker.options.icon) { + console.error("This is not a marker", marker); + + return { markerBox: null, positionBox: null, isVisible: null }; + } + + // required for pop-up and tooltip + marker._map = map; + + // add _leaflet_id property + L.Util.stamp(marker); + + var latLng = marker.getLatLng(); + var isVisible = map.getBounds().contains(latLng); + var ref = map.latLngToContainerPoint(latLng); + var x = ref.x; + var y = ref.y; + var ref$1 = marker.options.icon.options; + var iconSize = ref$1.iconSize; + var iconAnchor = ref$1.iconAnchor; + + var markerBox = { + minX: x - iconAnchor[0], + minY: y - iconAnchor[1], + maxX: x + iconSize[0] - iconAnchor[0], + maxY: y + iconSize[1] - iconAnchor[1], + marker: marker, + }; + + var positionBox = { + minX: latLng.lng, + minY: latLng.lat, + maxX: latLng.lng, + maxY: latLng.lat, + marker: marker, + }; + + if (isVisible) { + this._drawMarker(marker, { x: x, y: y }); + } + + this._markers.push(marker); + + return { markerBox: markerBox, positionBox: positionBox, isVisible: isVisible }; + }, + + _drawMarker: function _drawMarker(marker, ref) { + if (!this._map) return; + + var this$1 = this; + var x = ref.x; + var y = ref.y; + + var ref$1 = marker.options.icon.options; + var iconUrl = ref$1.iconUrl; + + if (marker.image) { + this._drawImage(marker, { x: x, y: y }); + } else if (this._icons[iconUrl]) { + marker.image = this._icons[iconUrl].image; + + if (this._icons[iconUrl].isLoaded) { + this._drawImage(marker, { x: x, y: y }); + } else { + this._icons[iconUrl].elements.push({ marker: marker, x: x, y: y }); + } + } else { + var image = new Image(); + image.src = iconUrl; + marker.image = image; + + this._icons[iconUrl] = { + image: image, + isLoaded: false, + elements: [{ marker: marker, x: x, y: y }], + }; + + image.onload = function () { + this$1._icons[iconUrl].isLoaded = true; + this$1._icons[iconUrl].elements.forEach(function (ref) { + var marker = ref.marker; + var x = ref.x; + var y = ref.y; + + this$1._drawImage(marker, { x: x, y: y }); + }); + }; + } + }, + + _drawImage: function _drawImage(marker, ref) { + var x = ref.x; + var y = ref.y; + + var ref$1 = marker.options.icon.options; + var rotationAngle = ref$1.rotationAngle; + var iconAnchor = ref$1.iconAnchor; + var iconSize = ref$1.iconSize; + var angle = rotationAngle || 0; + + this._context.save(); + this._context.translate(x, y); + this._context.rotate((angle * Math.PI) / 180); + this._context.drawImage( + marker.image, + -iconAnchor[0], + -iconAnchor[1], + iconSize[0], + iconSize[1] + ); + this._context.restore(); + }, + + _redraw: function _redraw(clear) { + var this$1 = this; + + if (clear) { + this._context.clearRect(0, 0, this._canvas.width, this._canvas.height); + } + + if (!this._map || !this._positionsTree) { return; } + + var mapBounds = this._map.getBounds(); + var mapBoundsBox = { + minX: mapBounds.getWest(), + minY: mapBounds.getSouth(), + maxX: mapBounds.getEast(), + maxY: mapBounds.getNorth(), + }; + + // draw only visible markers + var markers = []; + this._positionsTree.search(mapBoundsBox).forEach(function (ref) { + var marker = ref.marker; + + var latLng = marker.getLatLng(); + var ref$1 = this$1._map.latLngToContainerPoint(latLng); + var x = ref$1.x; + var y = ref$1.y; + var ref$2 = marker.options.icon.options; + var iconSize = ref$2.iconSize; + var iconAnchor = ref$2.iconAnchor; + + var markerBox = { + minX: x - iconAnchor[0], + minY: y - iconAnchor[1], + maxX: x + iconSize[0] - iconAnchor[0], + maxY: y + iconSize[1] - iconAnchor[1], + marker: marker, + }; + + markers.push(markerBox); + this$1._drawMarker(marker, { x: x, y: y }); + }); + + this._markersTree.clear(); + this._markersTree.load(markers); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // private: event methods + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + _reset: function _reset() { + var topLeft = this._map.containerPointToLayerPoint([0, 0]); + L.DomUtil.setPosition(this._canvas, topLeft); + + var ref = this._map.getSize(); + var x = ref.x; + var y = ref.y; + this._canvas.width = x; + this._canvas.height = y; + + this._redraw(); + }, + + _fire: function _fire(event) { + if (!this._markersTree) { return; } + + var ref = event.containerPoint; + var x = ref.x; + var y = ref.y; + var markers = this._markersTree.search({ + minX: x, + minY: y, + maxX: x, + maxY: y, + }); + + if (markers && markers.length) { + this._map._container.style.cursor = "pointer"; + var marker = markers[0].marker; + + if (event.type === "click") { + if (marker.listens("click")) { + marker.fire("click"); + } + } + + if (event.type === "mousemove") { + if (this._mouseOverMarker && this._mouseOverMarker !== marker) { + if (this._mouseOverMarker.listens("mouseout")) { + this._mouseOverMarker.fire("mouseout"); + } + } + + if (!this._mouseOverMarker || this._mouseOverMarker !== marker) { + this._mouseOverMarker = marker; + if (marker.listens("mouseover")) { + marker.fire("mouseover"); + } + } + } + } else { + this._map._container.style.cursor = ""; + if (event.type === "mousemove" && this._mouseOverMarker) { + if (this._mouseOverMarker.listens("mouseout")) { + this._mouseOverMarker.fire("mouseout"); + } + + delete this._mouseOverMarker; + } + } + }, + + _animateZoom: function _animateZoom(event) { + var scale = this._map.getZoomScale(event.zoom); + var offset = this._map._latLngBoundsToNewLayerBounds( + this._map.getBounds(), + event.zoom, + event.center + ).min; + + L.DomUtil.setTransform(this._canvas, offset, scale); + }, + }; + + L.MarkersCanvas = L.Layer.extend(markersCanvas); + + }))); \ No newline at end of file diff --git a/package.json b/package.json index 7ccd1218f..6d9f56448 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "proj4": "^2.4.3", "qrcode.react": "^0.7.2", "raw-loader": "^0.5.1", + "rbush": "^3.0.1", "react": "^16.4.0", "react-dom": "^16.4.0", "react-router": "^4.1.1",