From 3143bb81198f5b610cec20f9ff2c9000d76a9fbb Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 13 Apr 2023 11:45:24 -0700 Subject: [PATCH] Upgrade all the dependencies, use external links for all 3rd party plugins --- mapmakr/static/3rdparty/L.Terminator.js | 143 --- .../static/3rdparty/MarkerCluster.Default.css | 60 -- mapmakr/static/3rdparty/MarkerCluster.css | 14 - .../static/3rdparty/leaflet-easybutton.css | 56 -- mapmakr/static/3rdparty/leaflet-easybutton.js | 366 ------- mapmakr/static/3rdparty/leaflet-label.css | 52 - mapmakr/static/3rdparty/leaflet-label.js | 9 - .../static/3rdparty/leaflet-search-icon.png | Bin 3838 -> 0 bytes .../static/3rdparty/leaflet-search-loader.gif | Bin 1849 -> 0 bytes mapmakr/static/3rdparty/leaflet-search.css | 113 --- mapmakr/static/3rdparty/leaflet-search.js | 934 ------------------ .../static/3rdparty/leaflet.markercluster.js | 6 - mapmakr/static/js/mapmakr.js | 42 +- mapmakr/templates/index.html | 73 +- 14 files changed, 71 insertions(+), 1797 deletions(-) delete mode 100644 mapmakr/static/3rdparty/L.Terminator.js delete mode 100644 mapmakr/static/3rdparty/MarkerCluster.Default.css delete mode 100644 mapmakr/static/3rdparty/MarkerCluster.css delete mode 100644 mapmakr/static/3rdparty/leaflet-easybutton.css delete mode 100644 mapmakr/static/3rdparty/leaflet-easybutton.js delete mode 100644 mapmakr/static/3rdparty/leaflet-label.css delete mode 100644 mapmakr/static/3rdparty/leaflet-label.js delete mode 100644 mapmakr/static/3rdparty/leaflet-search-icon.png delete mode 100644 mapmakr/static/3rdparty/leaflet-search-loader.gif delete mode 100644 mapmakr/static/3rdparty/leaflet-search.css delete mode 100644 mapmakr/static/3rdparty/leaflet-search.js delete mode 100644 mapmakr/static/3rdparty/leaflet.markercluster.js diff --git a/mapmakr/static/3rdparty/L.Terminator.js b/mapmakr/static/3rdparty/L.Terminator.js deleted file mode 100644 index 8e21458..0000000 --- a/mapmakr/static/3rdparty/L.Terminator.js +++ /dev/null @@ -1,143 +0,0 @@ -/* Terminator.js -- Overlay day/night region on a Leaflet map */ - -Date.prototype.getJulian = function() { - /* Calculate the present UTC Julian Date. Function is valid after - * the beginning of the UNIX epoch 1970-01-01 and ignores leap - * seconds. */ - return (this / 86400000) + 2440587.5; -} - -Date.prototype.getGMST = function() { - /* Calculate Greenwich Mean Sidereal Time according to - http://aa.usno.navy.mil/faq/docs/GAST.php */ - var julianDay = this.getJulian(); - var d = julianDay - 2451545.0; - // Low precision equation is good enough for our purposes. - return (18.697374558 + 24.06570982441908 * d) % 24; -} - -L.Terminator = L.Polygon.extend({ - options: { - color: '#00', - opacity: 0.5, - fillColor: '#00', - fillOpacity: 0.5, - resolution: 2 - }, - - initialize: function(options) { - this.version = '0.1.0'; - this._R2D = 180 / Math.PI; - this._D2R = Math.PI / 180; - L.Util.setOptions(this, options); - var latLng = this._compute(this.options.time || null) - this.setLatLngs(latLng); - }, - - setTime: function(date) { - this.options.time = date; - var latLng = this._compute(date || null) - this.setLatLngs(latLng); - }, - - _sunEclipticPosition: function(julianDay) { - /* Compute the position of the Sun in ecliptic coordinates at - julianDay. Following - http://en.wikipedia.org/wiki/Position_of_the_Sun */ - // Days since start of J2000.0 - var n = julianDay - 2451545.0; - // mean longitude of the Sun - var L = 280.460 + 0.9856474 * n; - L %= 360; - // mean anomaly of the Sun - var g = 357.528 + 0.9856003 * n; - g %= 360; - // ecliptic longitude of Sun - var lambda = L + 1.915 * Math.sin(g * this._D2R) + - 0.02 * Math.sin(2 * g * this._D2R); - // distance from Sun in AU - var R = 1.00014 - 0.01671 * Math.cos(g * this._D2R) - - 0.0014 * Math.cos(2 * g * this._D2R); - return {"lambda": lambda, "R": R}; - }, - - _eclipticObliquity: function(julianDay) { - // Following the short term expression in - // http://en.wikipedia.org/wiki/Axial_tilt#Obliquity_of_the_ecliptic_.28Earth.27s_axial_tilt.29 - var n = julianDay - 2451545.0; - // Julian centuries since J2000.0 - var T = n / 36525; - var epsilon = 23.43929111 - - T * (46.836769 / 3600 - - T * (0.0001831 / 3600 - + T * (0.00200340 / 3600 - - T * (0.576e-6 / 3600 - - T * 4.34e-8 / 3600)))); - return epsilon; - }, - - _sunEquatorialPosition: function(sunEclLng, eclObliq) { - /* Compute the Sun's equatorial position from its ecliptic - * position. Inputs are expected in degrees. Outputs are in - * degrees as well. */ - var alpha = Math.atan(Math.cos(eclObliq * this._D2R) - * Math.tan(sunEclLng * this._D2R)) * this._R2D; - var delta = Math.asin(Math.sin(eclObliq * this._D2R) - * Math.sin(sunEclLng * this._D2R)) * this._R2D; - - var lQuadrant = Math.floor(sunEclLng / 90) * 90; - var raQuadrant = Math.floor(alpha / 90) * 90; - alpha = alpha + (lQuadrant - raQuadrant); - - return {"alpha": alpha, "delta": delta}; - }, - - _hourAngle: function(lng, sunPos, gst) { - /* Compute the hour angle of the sun for a longitude on - * Earth. Return the hour angle in degrees. */ - var lst = gst + lng / 15; - return lst * 15 - sunPos.alpha; - }, - - _latitude: function(ha, sunPos) { - /* For a given hour angle and sun position, compute the - * latitude of the terminator in degrees. */ - var lat = Math.atan(-Math.cos(ha * this._D2R) / - Math.tan(sunPos.delta * this._D2R)) * this._R2D; - return lat; - }, - - _compute: function(time) { - if (time == null) - var today = new Date(); - else - var today = new Date(time); - var julianDay = today.getJulian(); - var gst = today.getGMST(); - var latLng = []; - var ha, lat; - - var sunEclPos = this._sunEclipticPosition(julianDay); - var eclObliq = this._eclipticObliquity(julianDay); - var sunEqPos = this._sunEquatorialPosition(sunEclPos.lambda, eclObliq); - for (var i = 0; i <= 720 * this.options.resolution; i++) { - lng = -360 + i / this.options.resolution; - ha = this._hourAngle(lng, sunEqPos, gst); - lat = this._latitude(ha, sunEqPos); - latLng[i+1] = [lat, lng]; - } - if (sunEqPos.delta < 0) { - latLng[0] = [90, -360]; - latLng[latLng.length] = [90, 360]; - } else { - latLng[0] = [-90, -360]; - latLng[latLng.length] = [-90, 360]; - } - return latLng; - } -}); - -L.terminator = function(options) { - return new L.Terminator(options); -}; - diff --git a/mapmakr/static/3rdparty/MarkerCluster.Default.css b/mapmakr/static/3rdparty/MarkerCluster.Default.css deleted file mode 100644 index bbc8c9f..0000000 --- a/mapmakr/static/3rdparty/MarkerCluster.Default.css +++ /dev/null @@ -1,60 +0,0 @@ -.marker-cluster-small { - background-color: rgba(181, 226, 140, 0.6); - } -.marker-cluster-small div { - background-color: rgba(110, 204, 57, 0.6); - } - -.marker-cluster-medium { - background-color: rgba(241, 211, 87, 0.6); - } -.marker-cluster-medium div { - background-color: rgba(240, 194, 12, 0.6); - } - -.marker-cluster-large { - background-color: rgba(253, 156, 115, 0.6); - } -.marker-cluster-large div { - background-color: rgba(241, 128, 23, 0.6); - } - - /* IE 6-8 fallback colors */ -.leaflet-oldie .marker-cluster-small { - background-color: rgb(181, 226, 140); - } -.leaflet-oldie .marker-cluster-small div { - background-color: rgb(110, 204, 57); - } - -.leaflet-oldie .marker-cluster-medium { - background-color: rgb(241, 211, 87); - } -.leaflet-oldie .marker-cluster-medium div { - background-color: rgb(240, 194, 12); - } - -.leaflet-oldie .marker-cluster-large { - background-color: rgb(253, 156, 115); - } -.leaflet-oldie .marker-cluster-large div { - background-color: rgb(241, 128, 23); -} - -.marker-cluster { - background-clip: padding-box; - border-radius: 20px; - } -.marker-cluster div { - width: 30px; - height: 30px; - margin-left: 5px; - margin-top: 5px; - - text-align: center; - border-radius: 15px; - font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; - } -.marker-cluster span { - line-height: 30px; - } \ No newline at end of file diff --git a/mapmakr/static/3rdparty/MarkerCluster.css b/mapmakr/static/3rdparty/MarkerCluster.css deleted file mode 100644 index c60d71b..0000000 --- a/mapmakr/static/3rdparty/MarkerCluster.css +++ /dev/null @@ -1,14 +0,0 @@ -.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow { - -webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in; - -moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in; - -o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in; - transition: transform 0.3s ease-out, opacity 0.3s ease-in; -} - -.leaflet-cluster-spider-leg { - /* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */ - -webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in; - -moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in; - -o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in; - transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in; -} diff --git a/mapmakr/static/3rdparty/leaflet-easybutton.css b/mapmakr/static/3rdparty/leaflet-easybutton.css deleted file mode 100644 index 670b220..0000000 --- a/mapmakr/static/3rdparty/leaflet-easybutton.css +++ /dev/null @@ -1,56 +0,0 @@ -.leaflet-bar button, -.leaflet-bar button:hover { - background-color: #fff; - border: none; - border-bottom: 1px solid #ccc; - width: 26px; - height: 26px; - line-height: 26px; - display: block; - text-align: center; - text-decoration: none; - color: black; -} - -.leaflet-bar button { - background-position: 50% 50%; - background-repeat: no-repeat; - overflow: hidden; - display: block; -} - -.leaflet-bar button:hover { - background-color: #f4f4f4; -} - -.leaflet-bar button:first-of-type { - border-top-left-radius: 4px; - border-top-right-radius: 4px; -} - -.leaflet-bar button:last-of-type { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-bottom: none; -} - -.leaflet-bar.disabled, -.leaflet-bar button.disabled { - cursor: default; - pointer-events: none; - opacity: .4; -} - -.easy-button-button .button-state{ - display: block; - width: 100%; - heigth: 100%; - position: relative; -} - - -.leaflet-touch .leaflet-bar button { - width: 30px; - height: 30px; - line-height: 30px; -} diff --git a/mapmakr/static/3rdparty/leaflet-easybutton.js b/mapmakr/static/3rdparty/leaflet-easybutton.js deleted file mode 100644 index 6401f54..0000000 --- a/mapmakr/static/3rdparty/leaflet-easybutton.js +++ /dev/null @@ -1,366 +0,0 @@ -(function(){ - -// This is for grouping buttons into a bar -// takes an array of `L.easyButton`s and -// then the usual `.addTo(map)` -L.Control.EasyBar = L.Control.extend({ - - options: { - position: 'topleft', // part of leaflet's defaults - id: null, // an id to tag the Bar with - leafletClasses: true // use leaflet classes? - }, - - - initialize: function(buttons, options){ - - if(options){ - L.Util.setOptions( this, options ); - } - - this._buildContainer(); - this._buttons = []; - - for(var i = 0; i < buttons.length; i++){ - buttons[i]._bar = this; - buttons[i]._container = buttons[i].button; - this._buttons.push(buttons[i]); - this.container.appendChild(buttons[i].button); - } - - }, - - - _buildContainer: function(){ - this._container = this.container = L.DomUtil.create('div', ''); - this.options.leafletClasses && L.DomUtil.addClass(this.container, 'leaflet-bar easy-button-container leaflet-control'); - this.options.id && (this.container.id = this.options.id); - }, - - - enable: function(){ - L.DomUtil.addClass(this.container, 'enabled'); - L.DomUtil.removeClass(this.container, 'disabled'); - this.container.setAttribute('aria-hidden', 'false'); - return this; - }, - - - disable: function(){ - L.DomUtil.addClass(this.container, 'disabled'); - L.DomUtil.removeClass(this.container, 'enabled'); - this.container.setAttribute('aria-hidden', 'true'); - return this; - }, - - - onAdd: function () { - return this.container; - }, - - addTo: function (map) { - this._map = map; - - for(var i = 0; i < this._buttons.length; i++){ - this._buttons[i]._map = map; - } - - var container = this._container = this.onAdd(map), - pos = this.getPosition(), - corner = map._controlCorners[pos]; - - L.DomUtil.addClass(container, 'leaflet-control'); - - if (pos.indexOf('bottom') !== -1) { - corner.insertBefore(container, corner.firstChild); - } else { - corner.appendChild(container); - } - - return this; - } - -}); - -L.easyBar = function(){ - var args = [L.Control.EasyBar]; - for(var i = 0; i < arguments.length; i++){ - args.push( arguments[i] ); - } - return new (Function.prototype.bind.apply(L.Control.EasyBar, args)); -}; - -// L.EasyButton is the actual buttons -// can be called without being grouped into a bar -L.Control.EasyButton = L.Control.extend({ - - options: { - position: 'topleft', // part of leaflet's defaults - - id: null, // an id to tag the button with - - type: 'replace', // [(replace|animate)] - // replace swaps out elements - // animate changes classes with all elements inserted - - states: [], // state names look like this - // { - // stateName: 'untracked', - // onClick: function(){ handle_nav_manually(); }; - // title: 'click to make inactive', - // icon: 'fa-circle', // wrapped with - // } - - leafletClasses: true // use leaflet styles for the button - }, - - - - initialize: function(icon, onClick, title){ - - // clear the states manually - this.options.states = []; - - // storage between state functions - this.storage = {}; - - // is the last item an object? - if( typeof arguments[arguments.length-1] === 'object' ){ - - // if so, it should be the options - L.Util.setOptions( this, arguments[arguments.length-1] ); - } - - // if there aren't any states in options - // use the early params - if( this.options.states.length === 0 && - typeof icon === 'string' && - typeof onClick === 'function'){ - - // turn the options object into a state - this.options.states.push({ - icon: icon, - onClick: onClick, - title: typeof title === 'string' ? title : '' - }); - } - - // curate and move user's states into - // the _states for internal use - this._states = []; - - for(var i = 0; i < this.options.states.length; i++){ - this._states.push( new State(this.options.states[i], this) ); - } - - this._buildButton(); - - this._activateState(this._states[0]); - - }, - - _buildButton: function(){ - - this.button = L.DomUtil.create('button', ''); - - if (this.options.id ){ - this.button.id = this.options.id; - } - - if (this.options.leafletClasses){ - L.DomUtil.addClass(this.button, 'easy-button-button leaflet-bar-part'); - } - - // don't let double clicks get to the map - L.DomEvent.addListener(this.button, 'dblclick', L.DomEvent.stop); - - // take care of normal clicks - L.DomEvent.addListener(this.button,'click', function(e){ - L.DomEvent.stop(e); - this._currentState.onClick(this, this._map ? this._map : null ); - this._map.getContainer().focus(); - }, this); - - // prep the contents of the control - if(this.options.type == 'replace'){ - this.button.appendChild(this._currentState.icon); - } else { - for(var i=0;i"']/) ){ - - // if so, the user should have put in html - // so move forward as such - tmpIcon = ambiguousIconString; - - // then it wasn't html, so - // it's a class list, figure out what kind - } else { - ambiguousIconString = ambiguousIconString.replace(/(^\s*|\s*$)/g,''); - tmpIcon = L.DomUtil.create('span', ''); - - if( ambiguousIconString.indexOf('fa-') === 0 ){ - L.DomUtil.addClass(tmpIcon, 'fa ' + ambiguousIconString) - } else if ( ambiguousIconString.indexOf('glyphicon-') === 0 ) { - L.DomUtil.addClass(tmpIcon, 'glyphicon ' + ambiguousIconString) - } else { - L.DomUtil.addClass(tmpIcon, /*rollwithit*/ ambiguousIconString) - } - - // make this a string so that it's easy to set innerHTML below - tmpIcon = tmpIcon.outerHTML; - } - - return tmpIcon; -} - -})(); diff --git a/mapmakr/static/3rdparty/leaflet-label.css b/mapmakr/static/3rdparty/leaflet-label.css deleted file mode 100644 index adedd3a..0000000 --- a/mapmakr/static/3rdparty/leaflet-label.css +++ /dev/null @@ -1,52 +0,0 @@ -.leaflet-label { - background: rgb(235, 235, 235); - background: rgba(235, 235, 235, 0.8); - background-clip: padding-box; - border-color: #777; - border-color: rgba(0,0,0,0.25); - border-radius: 8px; - border-style: solid; - border-width: 1px; - color: #111; - display: block; - font: 9px/12x "Helvetica Neue", Arial, Helvetica, sans-serif; - padding: 1px 6px; - position: absolute; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - pointer-events: none; - white-space: nowrap; - z-index: 6; -} - -.leaflet-label.leaflet-clickable { - cursor: pointer; -} - -.leaflet-label:before, -.leaflet-label:after { - border-top: 6px solid transparent; - border-bottom: 6px solid transparent; - content: none; - position: absolute; - top: 5px; -} - -.leaflet-label:before { - border-right: 6px solid black; - border-right-color: inherit; - left: -10px; -} - -.leaflet-label:after { - border-left: 6px solid black; - border-left-color: inherit; - right: -10px; -} - -.leaflet-label-right:before, -.leaflet-label-left:after { - content: ""; -} diff --git a/mapmakr/static/3rdparty/leaflet-label.js b/mapmakr/static/3rdparty/leaflet-label.js deleted file mode 100644 index b918ca5..0000000 --- a/mapmakr/static/3rdparty/leaflet-label.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps. - (c) 2012-2013, Jacob Toye, Smartrak - - https://github.com/Leaflet/Leaflet.label - http://leafletjs.com - https://github.com/jacobtoye -*/ -(function(){L.labelVersion="0.2.2-dev",L.Label=L.Class.extend({includes:L.Mixin.Events,options:{className:"",clickable:!1,direction:"right",noHide:!1,offset:[12,-15],opacity:1,zoomAnimation:!0},initialize:function(t,e){L.setOptions(this,t),this._source=e,this._animated=L.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},onAdd:function(t){this._map=t,this._pane=this._source instanceof L.Marker?t._panes.markerPane:t._panes.popupPane,this._container||this._initLayout(),this._pane.appendChild(this._container),this._initInteraction(),this._update(),this.setOpacity(this.options.opacity),t.on("moveend",this._onMoveEnd,this).on("viewreset",this._onViewReset,this),this._animated&&t.on("zoomanim",this._zoomAnimation,this),L.Browser.touch&&!this.options.noHide&&L.DomEvent.on(this._container,"click",this.close,this)},onRemove:function(t){this._pane.removeChild(this._container),t.off({zoomanim:this._zoomAnimation,moveend:this._onMoveEnd,viewreset:this._onViewReset},this),this._removeInteraction(),this._map=null},setLatLng:function(t){return this._latlng=L.latLng(t),this._map&&this._updatePosition(),this},setContent:function(t){return this._previousContent=this._content,this._content=t,this._updateContent(),this},close:function(){var t=this._map;t&&(L.Browser.touch&&!this.options.noHide&&L.DomEvent.off(this._container,"click",this.close),t.removeLayer(this))},updateZIndex:function(t){this._zIndex=t,this._container&&this._zIndex&&(this._container.style.zIndex=t)},setOpacity:function(t){this.options.opacity=t,this._container&&L.DomUtil.setOpacity(this._container,t)},_initLayout:function(){this._container=L.DomUtil.create("div","leaflet-label "+this.options.className+" leaflet-zoom-animated"),this.updateZIndex(this._zIndex)},_update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updatePosition(),this._container.style.visibility="")},_updateContent:function(){this._content&&this._map&&this._prevContent!==this._content&&"string"==typeof this._content&&(this._container.innerHTML=this._content,this._prevContent=this._content,this._labelWidth=this._container.offsetWidth)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},_setPosition:function(t){var e=this._map,i=this._container,n=e.latLngToContainerPoint(e.getCenter()),o=e.layerPointToContainerPoint(t),s=this.options.direction,a=this._labelWidth,l=L.point(this.options.offset);"right"===s||"auto"===s&&o.xi;i++)L.DomEvent.on(t,e[i],this._fireMouseEvent,this)}},_removeInteraction:function(){if(this.options.clickable){var t=this._container,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];L.DomUtil.removeClass(t,"leaflet-clickable"),L.DomEvent.off(t,"click",this._onMouseClick,this);for(var i=0;e.length>i;i++)L.DomEvent.off(t,e[i],this._fireMouseEvent,this)}},_onMouseClick:function(t){this.hasEventListeners(t.type)&&L.DomEvent.stopPropagation(t),this.fire(t.type,{originalEvent:t})},_fireMouseEvent:function(t){this.fire(t.type,{originalEvent:t}),"contextmenu"===t.type&&this.hasEventListeners(t.type)&&L.DomEvent.preventDefault(t),"mousedown"!==t.type?L.DomEvent.stopPropagation(t):L.DomEvent.preventDefault(t)}}),L.BaseMarkerMethods={showLabel:function(){return this.label&&this._map&&(this.label.setLatLng(this._latlng),this._map.showLabel(this.label)),this},hideLabel:function(){return this.label&&this.label.close(),this},setLabelNoHide:function(t){this._labelNoHide!==t&&(this._labelNoHide=t,t?(this._removeLabelRevealHandlers(),this.showLabel()):(this._addLabelRevealHandlers(),this.hideLabel()))},bindLabel:function(t,e){var i=this.options.icon?this.options.icon.options.labelAnchor:this.options.labelAnchor,n=L.point(i)||L.point(0,0);return n=n.add(L.Label.prototype.options.offset),e&&e.offset&&(n=n.add(e.offset)),e=L.Util.extend({offset:n},e),this._labelNoHide=e.noHide,this.label||(this._labelNoHide||this._addLabelRevealHandlers(),this.on("remove",this.hideLabel,this).on("move",this._moveLabel,this).on("add",this._onMarkerAdd,this),this._hasLabelHandlers=!0),this.label=new L.Label(e,this).setContent(t),this},unbindLabel:function(){return this.label&&(this.hideLabel(),this.label=null,this._hasLabelHandlers&&(this._labelNoHide||this._removeLabelRevealHandlers(),this.off("remove",this.hideLabel,this).off("move",this._moveLabel,this).off("add",this._onMarkerAdd,this)),this._hasLabelHandlers=!1),this},updateLabelContent:function(t){this.label&&this.label.setContent(t)},getLabel:function(){return this.label},_onMarkerAdd:function(){this._labelNoHide&&this.showLabel()},_addLabelRevealHandlers:function(){this.on("mouseover",this.showLabel,this).on("mouseout",this.hideLabel,this),L.Browser.touch&&this.on("click",this.showLabel,this)},_removeLabelRevealHandlers:function(){this.off("mouseover",this.showLabel,this).off("mouseout",this.hideLabel,this),L.Browser.touch&&this.off("click",this.showLabel,this)},_moveLabel:function(t){this.label.setLatLng(t.latlng)}},L.Icon.Default.mergeOptions({labelAnchor:new L.Point(9,-20)}),L.Marker.mergeOptions({icon:new L.Icon.Default}),L.Marker.include(L.BaseMarkerMethods),L.Marker.include({_originalUpdateZIndex:L.Marker.prototype._updateZIndex,_updateZIndex:function(t){var e=this._zIndex+t;this._originalUpdateZIndex(t),this.label&&this.label.updateZIndex(e)},_originalSetOpacity:L.Marker.prototype.setOpacity,setOpacity:function(t,e){this.options.labelHasSemiTransparency=e,this._originalSetOpacity(t)},_originalUpdateOpacity:L.Marker.prototype._updateOpacity,_updateOpacity:function(){var t=0===this.options.opacity?0:1;this._originalUpdateOpacity(),this.label&&this.label.setOpacity(this.options.labelHasSemiTransparency?this.options.opacity:t)},_originalSetLatLng:L.Marker.prototype.setLatLng,setLatLng:function(t){return this.label&&!this._labelNoHide&&this.hideLabel(),this._originalSetLatLng(t)}}),L.CircleMarker.mergeOptions({labelAnchor:new L.Point(0,0)}),L.CircleMarker.include(L.BaseMarkerMethods),L.Path.include({bindLabel:function(t,e){return this.label&&this.label.options===e||(this.label=new L.Label(e,this)),this.label.setContent(t),this._showLabelAdded||(this.on("mouseover",this._showLabel,this).on("mousemove",this._moveLabel,this).on("mouseout remove",this._hideLabel,this),L.Browser.touch&&this.on("click",this._showLabel,this),this._showLabelAdded=!0),this},unbindLabel:function(){return this.label&&(this._hideLabel(),this.label=null,this._showLabelAdded=!1,this.off("mouseover",this._showLabel,this).off("mousemove",this._moveLabel,this).off("mouseout remove",this._hideLabel,this)),this},updateLabelContent:function(t){this.label&&this.label.setContent(t)},_showLabel:function(t){this.label.setLatLng(t.latlng),this._map.showLabel(this.label)},_moveLabel:function(t){this.label.setLatLng(t.latlng)},_hideLabel:function(){this.label.close()}}),L.Map.include({showLabel:function(t){return this.addLayer(t)}}),L.FeatureGroup.include({clearLayers:function(){return this.unbindLabel(),this.eachLayer(this.removeLayer,this),this},bindLabel:function(t,e){return this.invoke("bindLabel",t,e)},unbindLabel:function(){return this.invoke("unbindLabel")},updateLabelContent:function(t){this.invoke("updateLabelContent",t)}})})(this,document); \ No newline at end of file diff --git a/mapmakr/static/3rdparty/leaflet-search-icon.png b/mapmakr/static/3rdparty/leaflet-search-icon.png deleted file mode 100644 index 231df745b290ab38816a19972be5d3cb0fe6bbca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3838 zcmVEX>4Tx0C?J+Q+HUC_ZB|i_hk=OLfG)Jmu!ImA|tE_$Pihg5Rw34gb)%y#f69p zRumNxoJdu~g4GI0orvO~D7a@qiilc^Ra`jkAKa(4eR}Wh?fcjJyyu+f{LXpL4}cL8 zCXwc%Y5+M>g*-agACFH+#L2yY0u@N$1RxOR%fe>`#Q*^C19^CUbg)1C0k3ZW0swH; zE+i7i;s1lWP$pLZAdvvzA`<5d0gzGv$SzdK6adH=0I*ZDWC{S3003-xd_p1ssto|_ z^hrJi0NAOM+!p}Yq8zCR0F40vnJ7mj0zkU}U{!%qECRs70HCZuA}$2Lt^t5qwlYTo zfV~9(c8*w(4?ti5fSE!p%m5%b0suoE6U_r4Oaq`W(!b!TUvP!ENC5!A%azTSOVTqG zxRuZvck=My;vwR~Y_URN7by^C3FIQ2mzyIKNaq7g&I|wm8u`(|{y0C7=jP<$=4R(? z@ASo@{%i1WB0eGU-~POe0t5gMPS5Y!U*+Z218~Oyuywy{sapWrRsd+<`CT*H37}dE z(0cicc{uz)9-g64$UGe!3JVMEC1RnyFyo6p|1;rl;ER6t{6HT5+j{T-ahgDxt-zy$ z{c&M#cCJ#6=gR~_F>d$gBmT#QfBlXr(c(0*Tr3re@mPttP$EsodAU-NL?OwQ;u7h9 zGVvdl{RxwI4FIf$Pry#L2er#=z<%xl0*ek<(slqqe)BDi8VivC5N9+pdG`PSlfU_o zKq~;2Moa!tiTSO!5zH77Xo1hL_iEAz&sE_ z2IPPo3ZWR5K^auQI@koYumc*P5t`u;w81er4d>tzT!HIw7Y1M$p28Tsh6w~g$Osc* zAv%Z=Vvg7%&IlKojszlMNHmgwq#)^t6j36@$a16tsX}UzT}UJHEpik&ja)$bklV;0 zGK&0)yhkyVfwEBp)B<%txu_o+ipHRG(R4HqU4WLNYtb6C9zB4zqNmYI=yh}eeTt4_ zfYC7yW{lZkT#ScBV2M~7CdU?I?5=ix(HVZgM=}{CnA%mPqZa^68Xe5gFH?u96Et<2 zCC!@_L(8Nsqt(!wX=iEoXfNq>x(VHb9z~bXm(pwK2kGbOgYq4YG!XMxcgB zqf}$J#u<$v7REAV@mNCEa#jQDENhreVq3EL>`ZnA`x|yIdrVV9bE;;nW|3x{=5fsd z4#u(I@HyF>O3oq94bFQl11&!-vDRv>X03j$H`;pIzS?5#a_tuF>)P*iaGgM%ES>c_ zZ94aL3A#4AQM!e?+jYlFJ5+DSzi0S9#6BJCZ5(XZOGfi zTj0IRdtf>~J!SgN=>tB-J_4V5pNGDtz9Qc}z9W9tewls;{GR(e`pf-~_`l(K@)q$< z1z-We0p$U`ff|9c18V~x1epY-2Q>wa1-k|>3_cY?3<(WcA99m#z!&lx`C~KOXDpi0 z70L*m6G6C?@k ziR8rC#65}Qa{}jVnlqf_npBo_W3J`gqPZ95>CVfZcRX1&S&)1jiOPpx423?lIEROmG(H@JAFg?XogQlb;dIZPf{y+kr|S? zBlAsGMAqJ{&)IR=Ejg5&l$@hd4QZCNE7vf$D7Q~$D=U)?Nn}(WA6du22pZOfRS_cv~1-c(_QtNLti0-)8>m`6CO07JR*suu!$(^sg%jf zZm#rNxnmV!m1I@#YM0epR(~oNm0zrItf;Q|utvD%;#W>z)qM4NZQ9!2O1H}G>qzUQ z>u#*~S--DJy=p<#(1!30tsC);y-IHSJr>wyfLop*ExT zdYyk=%U1oZtGB+{Cfe4&-FJKQ4uc&PJKpb5^_C@dOYIJXG+^@gCvI%WcHjN%gI&kHifN$EH?V5MBa9S!3!a?Q1 zC*P)gd*e{(q0YnH!_D8Bf4B7r>qvPk(mKC&tSzH$pgp0z@92!9ogH2sN4~fJe(y2k zV|B+hk5`_cohUu=`Q(C=R&z?UQbnZ;IU-!xL z-sg{9@Vs#JBKKn3CAUkhJ+3`ResKNaNUvLO>t*-L?N>ambo5Q@JJIjcfBI^`)pOVQ z*DhV3dA;w(>>IakCfyvkCA#(acJ}QTcM9%I++BK)c(44v+WqPW`VZ=VwEnSWz-{38 zV8CF{!&wjS4he^z{*?dIhvCvk%tzHDMk9@nogW_?4H~`jWX_Y}r?RIL&&qyQ|9R_k ztLNYS;`>X_Sp3-V3;B!Bzpi}bfv;Y7EJV``BR9M69mtAOEWf;eQ z%g5}Fo7w83gt9GNhzd>nf(l!!IK>HWf-)Ii`GP{-jjlH$=*1Aca96^ZS3-rsdm;D% z;!T+-q81b!V>?TSHfD+7JX_;ZPqioA+N9n*iHGzg{V<3Zc_8HEJ@5N}zW&eopTPg! zHnq8T8*mrUBfqP_bzpwIfKgx&I0B3SJ7wQIa31&+m;@?ojruv@Ti_;e3zz|}0e=BC zpa8r9YzsOZ_Fad71HfCrgTRl#IB*8|47dnv2JQm}02jC*P6BNw@V-Pf2|NWvnjGE_ zd;l!Uo=m$`9|MX&85otO1ld7}z5=}5+=r0wdN;5gxB`45H4L)vfFGp$yL~KJ0T>l; zF0jxhlX+mS=}aKtqI~aY)j_dsvd4cW5b$SU7Dxe4i1#4gjsW|lhF1WumFMl!<%&?` z8DOg~r5<2E@R3Z-Ibf(A4;Q4v8KK8MAPMve_l^LsNS8zMDXhlD5O5gy9QZ?ObkjFA z9#E3?8ZZsK0NfrFA;7ZK<(wQ`mabouXg-mYEnu$ow`J zF{ZMbi~^vPItsigv$;oR+5&cogGYdS(N$7Zk<+y zYuzJ2qav@DrJljWwrzVsDHW*8N~xB*tdzQ7+jcE*Qj}7^0uFFDkOqc`5kH z3IYxJ({vo?R2?iHkFNl#uPs%pIF56=SS<9l1e`6G$LeXu<8g+EM;I9R=ilqVK!)Mr zkp`&ed0S@7<>M=&uV1*X`(*vPR4S3r=Sihfjg6^PihMp#sZ_#u<`D3DAfV@Y_xNv2 zO=TNE0Qr2rvDWHLv!-;!B0f4yyK{3x{+iX(^hfHC(z2}SmVmKXY@!YrkH;Heet=Xe z#mvn0Mjd0Z*hEVn7K??xTrQXMciP{8<~7T*D(Q4O-8?mo8YYwdR}+cESR@>7bh_E< zYmso6L?SU3G=f2+H|jXf>5hzECms%6>)HnFZ%f9wVOe)X?f?J)07*qoM6N<$f@-Z) AqyPW_ diff --git a/mapmakr/static/3rdparty/leaflet-search-loader.gif b/mapmakr/static/3rdparty/leaflet-search-loader.gif deleted file mode 100644 index d3ef195d52dad8449e21eb58817dcb3ae8a9ba73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1849 zcmb8wZBSF$83*voz31lM+?V7Kkqwb`LI|3K#DupH#kDs91c9=^D(v!75;4@Uum)Cy z?jn*Ggdnd)g0;V`yk- zVPRo$adBW^;L)Q;{r&x;qoZE07x{lG;@^_w8mr~7^?q3T+XYxk^J92F*%Bp&flYN$6OLI zV*Jqk9kFuB5sU+ryg?lYgfzthXK5r#@(}g_Xi5OQxHB^P{REn}M*No-6lgi(x7axA z_RbU|IcJ3J6K%80GlF34NSN7vP%iFBwnTAKy#3BId-_F^JO{_>r*@+bZ|z&25a}s7r+mryC?JJQm62T&ZEn|0Y>j&4wSnrK*^m~r2?-HbOnS{r2FN465qUXC8uo{# zi_}up{8u`$<`Z_QYIlM7+r{luSviBLanUFR6;9M7V|jFW$A_&dQ$eZLa|~ss`FzyI4eOdN}O4PN9evsRx-ctLw! z^gln>h=}t~ui3AVcZbaLIf~PI()DEEoMdUA_IoLxq*ZF*Rsu{Btu2vNzS*ojt}?#c zbL>j(5}xqv`QAmbRcq$H@%Ua zbb)#Bo8Z0f)aMW2ROsl&Z>u*#$QKR${nsv z*J|s`KWO%pH%6ZHoYwcAid+NWfq+Io;MZy&z$qhL%aU0Ybv%i&=Ut6L-D8nD-eAA^ zf^$gGVlWiz&EUB3%{O1Wbxjl^(Z<}eVezolYo5x#BJlvs^wo4e5VEyL-Lf)* zz%AJ}Ekl$Lj8fU5AxI?4T6v65&{ejh2q4%hYfDy7hEuf!BoSBvA}l}?hZ z{;pQFA(SBUwv_Q8pD+_brBcBV81eqG(u{7lQN5 zvYL$Y?Bei8Ta9NkFP{AL@gF+WA7B5M0G#rq7Aq=UXD@C^N|1Iuh6$n+&umze?&;>M zaZbx+oknzGWA`;pxM2SE3p3(g(0SWsPmd3Qcs?ISu{MmrghI+*lqYN8qwOdu=!vBI zP`*%)+Y0N->QrlU;{R`rI^9sI*xH~oWx)jhPFN)fQ5iE(*3>B*agb-~* zc|x0t=4)|$2keWMW7v^(4Hc-V^}m|cY$}T`$)8XY8L+zO7v5?nuFsrXv?55@;8@ua zCTRQV64>*0gl?wBm|_q!$wx-I=R)v5rRS8}f~Oa4NNz9aav5_t`zDyoW1~_KHirj+ zFgIS$;64m%E3=`H%&ySYv2Nx1O3{Im^(k#*s;7r3bs9>KWvJg??6EvLU56sw=_!cfRdqF6&- l_D(g8HN%}Tdxfxshf+T)13hQ9veoa(DbBA+@_$6D^&f%1ACmw8 diff --git a/mapmakr/static/3rdparty/leaflet-search.css b/mapmakr/static/3rdparty/leaflet-search.css deleted file mode 100644 index 7c62845..0000000 --- a/mapmakr/static/3rdparty/leaflet-search.css +++ /dev/null @@ -1,113 +0,0 @@ - -.leaflet-container .leaflet-control-search { - position:relative; - float:left; - background:#fff; - color:#1978cf; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - border-radius: 4px; - background-color: rgba(255, 255, 255, 0.8); - z-index:1000; - box-shadow: 0 1px 7px rgba(0,0,0,0.65); - margin-left: 10px; - margin-top: 10px; -} -.leaflet-control-search.search-exp {/*expanded*/ - box-shadow: 0 1px 7px #999; - background: #fff; -} -.leaflet-control-search .search-input { - display:block; - float:left; - background: #fff; - border:1px solid #666; - border-radius:2px; - height:18px; - padding:0 18px 0 2px; - margin:3px 0 3px 3px; -} -.leaflet-control-search.search-load .search-input { - background: url('leaflet-search-loader.gif') no-repeat center right #fff; -} -.leaflet-control-search.search-load .search-cancel { - visibility:hidden; -} -.leaflet-control-search .search-cancel { - display:block; - width:22px; - height:18px; - position:absolute; - right:22px; - margin:3px 0; - background: url('leaflet-search-icon.png') no-repeat 0 -46px; - text-decoration:none; - filter: alpha(opacity=80); - opacity: 0.8; -} -.leaflet-control-search .search-cancel:hover { - filter: alpha(opacity=100); - opacity: 1; -} -.leaflet-control-search .search-cancel span { - display:none;/* comment for cancel button imageless */ - font-size:18px; - line-height:20px; - color:#ccc; - font-weight:bold; -} -.leaflet-control-search .search-cancel:hover span { - color:#aaa; -} -.leaflet-control-search .search-button { - display:block; - float:left; - width:26px; - height:26px; - background: url('leaflet-search-icon.png') no-repeat 2px 2px; - border-radius:4px; -} -.leaflet-control-search .search-button:hover { - background: url('leaflet-search-icon.png') no-repeat 2px -22px; -} -.leaflet-control-search .search-tooltip { - position:absolute; - top:100%; - left:0; - float:left; - min-width:120px; - max-height:122px; - box-shadow: 1px 1px 6px rgba(0,0,0,0.4); - background-color: rgba(0, 0, 0, 0.25); - z-index:1010; - overflow-y:auto; - overflow-x:hidden; -} -.leaflet-control-search .search-tip { - margin:2px; - padding:2px 4px; - display:block; - color:black; - background: #eee; - border-radius:.25em; - text-decoration:none; - white-space:nowrap; - vertical-align:center; -} -.leaflet-control-search .search-tip-select, -.leaflet-control-search .search-tip:hover, -.leaflet-control-search .search-button:hover { - background-color: #fff; -} -.leaflet-control-search .search-alert { - cursor:pointer; - clear:both; - font-size:.75em; - margin-bottom:5px; - padding:0 .25em; - color:#e00; - font-weight:bold; - border-radius:.25em; -} - - diff --git a/mapmakr/static/3rdparty/leaflet-search.js b/mapmakr/static/3rdparty/leaflet-search.js deleted file mode 100644 index af81777..0000000 --- a/mapmakr/static/3rdparty/leaflet-search.js +++ /dev/null @@ -1,934 +0,0 @@ -(function() { - -L.Control.Search = L.Control.extend({ - includes: L.Mixin.Events, - // - // Name Data passed Description - // - //Managed Events: - // search_locationfound {latlng, title, layer} fired after moved and show markerLocation - // search_expanded {} fired after control was expanded - // search_collapsed {} fired after control was collapsed - // - //Public methods: - // setLayer() L.LayerGroup() set layer search at runtime - // showAlert() 'Text message' show alert message - // searchText() 'Text searched' search text by external code - // - options: { - url: '', //url for search by ajax request, ex: "search.php?q={s}". Can be function that returns string for dynamic parameter setting - layer: null, //layer where search markers(is a L.LayerGroup) - sourceData: null, //function that fill _recordsCache, passed searching text by first param and callback in second - jsonpParam: null, //jsonp param name for search by jsonp service, ex: "callback" - propertyLoc: 'loc', //field for remapping location, using array: ['latname','lonname'] for select double fields(ex. ['lat','lon'] ) support dotted format: 'prop.subprop.title' - propertyName: 'title', //property in marker.options(or feature.properties for vector layer) trough filter elements in layer, - formatData: null, //callback for reformat all data from source to indexed data object - filterData: null, //callback for filtering data from text searched, params: textSearch, allRecords - buildTip: null, //function that return row tip html node(or html string), receive text tooltip in first param - container: '', //container id to insert Search Control - minLength: 1, //minimal text length for autocomplete - initial: true, //search elements only by initial text - casesesitive: false, //search elements in case sensitive text - autoType: true, //complete input with first suggested result and select this filled-in text. - delayType: 400, //delay while typing for show tooltip - tooltipLimit: -1, //limit max results to show in tooltip. -1 for no limit. - tipAutoSubmit: true, //auto map panTo when click on tooltip - autoResize: true, //autoresize on input change - collapsed: true, //collapse search control at startup - autoCollapse: false, //collapse search control after submit(on button or on tips if enabled tipAutoSubmit) - autoCollapseTime: 1200, //delay for autoclosing alert and collapse after blur - zoom: null, //zoom after pan to location found, default: map.getZoom() - position: 'topleft', - textErr: 'Location not found', //error message - textCancel: 'Cancel', //title in cancel button - textPlaceholder: 'Search...',//placeholder value - animateLocation: true, //animate a circle over location found - circleLocation: true, //draw a circle in location found - markerLocation: false, //draw a marker in location found - markerIcon: new L.Icon.Default()//custom icon for maker location - //TODO add option for persist markerLoc after collapse! - //TODO implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer - //TODO implement can do research on multiple sources layers and remote - //TODO history: false, //show latest searches in tooltip - }, -//FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location -//FIXME option condition problem {autoCollapse: false } -// -//TODO important optimization!!! always append data in this._recordsCache -// now _recordsCache content is emptied and replaced with new data founded -// always appending data on _recordsCache give the possibility of caching ajax, jsonp and layersearch! -// -//TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results.. -// run one of callbacks search(sourceData,jsonpUrl or options.layer) and run this.showTooltip -// -//TODO change structure of _recordsCache -// like this: _recordsCache = {"text-key1": {loc:[lat,lng], ..other attributes.. }, {"text-key2": {loc:[lat,lng]}...}, ...} -// in this mode every record can have a free structure of attributes, only 'loc' is required - - initialize: function(options) { - L.Util.setOptions(this, options || {}); - this._inputMinSize = this.options.textPlaceholder ? this.options.textPlaceholder.length : 10; - this._layer = this.options.layer || new L.LayerGroup(); - this._filterData = this.options.filterData || this._defaultFilterData; - this._formatData = this.options.formatData || this._defaultFormatData; - this._autoTypeTmp = this.options.autoType; //useful for disable autoType temporarily in delete/backspace keydown - this._countertips = 0; //number of tips items - this._recordsCache = {}; //key,value table! that store locations! format: key,latlng - this._curReq = null; - }, - - onAdd: function (map) { - this._map = map; - this._container = L.DomUtil.create('div', 'leaflet-control-search'); - this._input = this._createInput(this.options.textPlaceholder, 'search-input'); - this._tooltip = this._createTooltip('search-tooltip'); - this._cancel = this._createCancel(this.options.textCancel, 'search-cancel'); - this._button = this._createButton(this.options.textPlaceholder, 'search-button'); - this._alert = this._createAlert('search-alert'); - - if(this.options.collapsed===false) - this.expand(this.options.collapsed); - - if(this.options.circleLocation || this.options.markerLocation || this.options.markerIcon) - this._markerLoc = new L.Control.Search.Marker([0,0], { - showCircle: this.options.circleLocation, - showMarker: this.options.markerLocation, - icon: this.options.markerIcon - });//see below - - this.setLayer( this._layer ); - map.on({ - // 'layeradd': this._onLayerAddRemove, - // 'layerremove': this._onLayerAddRemove - 'resize': this._handleAutoresize - }, this); - return this._container; - }, - addTo: function (map) { - - if(this.options.container) { - this._container = this.onAdd(map); - this._wrapper = L.DomUtil.get(this.options.container); - this._wrapper.style.position = 'relative'; - this._wrapper.appendChild(this._container); - } - else - L.Control.prototype.addTo.call(this, map); - - return this; - }, - - onRemove: function(map) { - this._recordsCache = {}; - // map.off({ - // 'layeradd': this._onLayerAddRemove, - // 'layerremove': this._onLayerAddRemove - // }, this); - }, - - // _onLayerAddRemove: function(e) { - // //console.info('_onLayerAddRemove'); - // //without this, run setLayer also for each Markers!! to optimize! - // if(e.layer instanceof L.LayerGroup) - // if( L.stamp(e.layer) != L.stamp(this._layer) ) - // this.setLayer(e.layer); - // }, - - _getPath: function(obj, prop) { - var parts = prop.split('.'), - last = parts.pop(), - len = parts.length, - cur = parts[0], - i = 1; - - if(len > 0) - while((obj = obj[cur]) && i < len) - cur = parts[i++]; - - if(obj) - return obj[last]; - }, - - setLayer: function(layer) { //set search layer at runtime - //this.options.layer = layer; //setting this, run only this._recordsFromLayer() - this._layer = layer; - this._layer.addTo(this._map); - if(this._markerLoc) - this._layer.addLayer(this._markerLoc); - return this; - }, - - showAlert: function(text) { - text = text || this.options.textErr; - this._alert.style.display = 'block'; - this._alert.innerHTML = text; - clearTimeout(this.timerAlert); - var that = this; - this.timerAlert = setTimeout(function() { - that.hideAlert(); - },this.options.autoCollapseTime); - return this; - }, - - hideAlert: function() { - this._alert.style.display = 'none'; - return this; - }, - - cancel: function() { - this._input.value = ''; - this._handleKeypress({keyCode:8});//simulate backspace keypress - this._input.size = this._inputMinSize; - this._input.focus(); - this._cancel.style.display = 'none'; - this._hideTooltip(); - return this; - }, - - expand: function(toggle) { - toggle = typeof toggle === 'boolean' ? toggle : true; - this._input.style.display = 'block'; - L.DomUtil.addClass(this._container, 'search-exp'); - if ( toggle !== false ) { - this._input.focus(); - this._map.on('dragstart click', this.collapse, this); - } - this.fire('search_expanded'); - return this; - }, - - collapse: function() { - this._hideTooltip(); - this.cancel(); - this._alert.style.display = 'none'; - this._input.blur(); - if(this.options.collapsed) - { - this._input.style.display = 'none'; - this._cancel.style.display = 'none'; - L.DomUtil.removeClass(this._container, 'search-exp'); - //this._markerLoc.hide();//maybe unuseful - this._map.off('dragstart click', this.collapse, this); - } - this.fire('search_collapsed'); - return this; - }, - - collapseDelayed: function() { //collapse after delay, used on_input blur - if (!this.options.autoCollapse) return this; - var that = this; - clearTimeout(this.timerCollapse); - this.timerCollapse = setTimeout(function() { - that.collapse(); - }, this.options.autoCollapseTime); - return this; - }, - - collapseDelayedStop: function() { - clearTimeout(this.timerCollapse); - return this; - }, - -////start DOM creations - _createAlert: function(className) { - var alert = L.DomUtil.create('div', className, this._container); - alert.style.display = 'none'; - - L.DomEvent - .on(alert, 'click', L.DomEvent.stop, this) - .on(alert, 'click', this.hideAlert, this); - - return alert; - }, - - _createInput: function (text, className) { - var label = L.DomUtil.create('label', className, this._container); - var input = L.DomUtil.create('input', className, this._container); - input.type = 'text'; - input.size = this._inputMinSize; - input.value = ''; - input.autocomplete = 'off'; - input.autocorrect = 'off'; - input.autocapitalize = 'off'; - input.placeholder = text; - input.style.display = 'none'; - input.role = 'search'; - input.id = input.role + input.type + input.size; - - label.htmlFor = input.id; - label.style.display = 'none'; - label.value = text; - - L.DomEvent - .disableClickPropagation(input) - .on(input, 'keyup', this._handleKeypress, this) - .on(input, 'keydown', this._handleAutoresize, this) - .on(input, 'blur', this.collapseDelayed, this) - .on(input, 'focus', this.collapseDelayedStop, this); - - return input; - }, - - _createCancel: function (title, className) { - var cancel = L.DomUtil.create('a', className, this._container); - cancel.href = '#'; - cancel.title = title; - cancel.style.display = 'none'; - cancel.innerHTML = "";//imageless(see css) - - L.DomEvent - .on(cancel, 'click', L.DomEvent.stop, this) - .on(cancel, 'click', this.cancel, this); - - return cancel; - }, - - _createButton: function (title, className) { - var button = L.DomUtil.create('a', className, this._container); - button.href = '#'; - button.title = title; - - L.DomEvent - .on(button, 'click', L.DomEvent.stop, this) - .on(button, 'click', this._handleSubmit, this) - .on(button, 'focus', this.collapseDelayedStop, this) - .on(button, 'blur', this.collapseDelayed, this); - - return button; - }, - - _createTooltip: function(className) { - var tool = L.DomUtil.create('ul', className, this._container); - tool.style.display = 'none'; - - var that = this; - L.DomEvent - .disableClickPropagation(tool) - .on(tool, 'blur', this.collapseDelayed, this) - .on(tool, 'mousewheel', function(e) { - that.collapseDelayedStop(); - L.DomEvent.stopPropagation(e);//disable zoom map - }, this) - .on(tool, 'mouseover', function(e) { - that.collapseDelayedStop(); - }, this); - return tool; - }, - - _createTip: function(text, val) {//val is object in recordCache, usually is Latlng - var tip; - - if(this.options.buildTip) - { - tip = this.options.buildTip.call(this, text, val); //custom tip node or html string - if(typeof tip === 'string') - { - var tmpNode = L.DomUtil.create('div'); - tmpNode.innerHTML = tip; - tip = tmpNode.firstChild; - } - } - else - { - tip = L.DomUtil.create('li', ''); - tip.innerHTML = text; - } - - L.DomUtil.addClass(tip, 'search-tip'); - tip._text = text; //value replaced in this._input and used by _autoType - - if(this.options.tipAutoSubmit) - L.DomEvent - .disableClickPropagation(tip) - .on(tip, 'click', L.DomEvent.stop, this) - .on(tip, 'click', function(e) { - this._input.value = text; - this._handleAutoresize(); - this._input.focus(); - this._hideTooltip(); - this._handleSubmit(); - }, this); - - return tip; - }, - -//////end DOM creations - - _getUrl: function(text) { - return (typeof this.options.url === 'function') ? this.options.url(text) : this.options.url; - }, - - _defaultFilterData: function(text, records) { - - var regFilter = new RegExp("^[.]$|[\[\]|()*]",'g'), //remove . * | ( ) ] [ - I, regSearch, - frecords = {}; - - text = text.replace(regFilter,''); //sanitize text - I = this.options.initial ? '^' : ''; //search only initial text - - regSearch = new RegExp(I + text, !this.options.casesesitive ? 'i' : undefined); - - //TODO use .filter or .map - for(var key in records) - if( regSearch.test(key) ) - frecords[key]= records[key]; - - return frecords; - }, - - showTooltip: function(records) { - var tip; - - this._countertips = 0; - - this._tooltip.innerHTML = ''; - this._tooltip.currentSelection = -1; //inizialized for _handleArrowSelect() - - for(var key in records)//fill tooltip - { - if(++this._countertips == this.options.tooltipLimit) break; - - tip = this._createTip(key, records[key] ); - - this._tooltip.appendChild(tip); - } - - if(this._countertips > 0) - { - this._tooltip.style.display = 'block'; - if(this._autoTypeTmp) - this._autoType(); - this._autoTypeTmp = this.options.autoType;//reset default value - } - else - this._hideTooltip(); - - this._tooltip.scrollTop = 0; - return this._countertips; - }, - - _hideTooltip: function() { - this._tooltip.style.display = 'none'; - this._tooltip.innerHTML = ''; - return 0; - }, - - _defaultFormatData: function(json) { //default callback for format data to indexed data - var propName = this.options.propertyName, - propLoc = this.options.propertyLoc, - i, jsonret = {}; - - if( L.Util.isArray(propLoc) ) - for(i in json) - jsonret[ this._getPath(json[i],propName) ]= L.latLng( json[i][ propLoc[0] ], json[i][ propLoc[1] ] ); - else - for(i in json) - jsonret[ this._getPath(json[i],propName) ]= L.latLng( this._getPath(json[i],propLoc) ); - //TODO throw new Error("propertyName '"+propName+"' not found in JSON data"); - return jsonret; - }, - - _recordsFromJsonp: function(text, callAfter) { //extract searched records from remote jsonp service - L.Control.Search.callJsonp = callAfter; - var script = L.DomUtil.create('script','leaflet-search-jsonp', document.getElementsByTagName('body')[0] ), - url = L.Util.template(this._getUrl(text)+'&'+this.options.jsonpParam+'=L.Control.Search.callJsonp', {s: text}); //parsing url - //rnd = '&_='+Math.floor(Math.random()*10000); - //TODO add rnd param or randomize callback name! in recordsFromJsonp - script.type = 'text/javascript'; - script.src = url; - return { abort: function() { script.parentNode.removeChild(script); } }; - }, - - _recordsFromAjax: function(text, callAfter) { //Ajax request - if (window.XMLHttpRequest === undefined) { - window.XMLHttpRequest = function() { - try { return new ActiveXObject("Microsoft.XMLHTTP.6.0"); } - catch (e1) { - try { return new ActiveXObject("Microsoft.XMLHTTP.3.0"); } - catch (e2) { throw new Error("XMLHttpRequest is not supported"); } - } - }; - } - var IE8or9 = ( L.Browser.ie && !window.atob && document.querySelector ), - request = IE8or9 ? new XDomainRequest() : new XMLHttpRequest(), - url = L.Util.template(this._getUrl(text), {s: text}); - - //rnd = '&_='+Math.floor(Math.random()*10000); - //TODO add rnd param or randomize callback name! in recordsFromAjax - - request.open("GET", url); - var that = this; - - request.onload = function() { - callAfter( JSON.parse(request.responseText) ); - }; - request.onreadystatechange = function() { - if(request.readyState === 4 && request.status === 200) { - this.onload(); - } - }; - - request.send(); - return request; - }, - - _recordsFromLayer: function() { //return table: key,value from layer - var that = this, - retRecords = {}, - propName = this.options.propertyName, - loc; - - this._layer.eachLayer(function(layer) { - - if(layer instanceof L.Control.Search.Marker) return; - - if(layer instanceof L.Marker || layer instanceof L.CircleMarker) - { - if(that._getPath(layer.options,propName)) - { - loc = layer.getLatLng(); - loc.layer = layer; - retRecords[ that._getPath(layer.options,propName) ] = loc; - - } - else if(that._getPath(layer.feature.properties,propName)){ - - loc = layer.getLatLng(); - loc.layer = layer; - retRecords[ that._getPath(layer.feature.properties,propName) ] = loc; - - } - else - throw new Error("propertyName '"+propName+"' not found in marker"); - } - else if(layer.hasOwnProperty('feature'))//GeoJSON - { - if(layer.feature.properties.hasOwnProperty(propName)) - { - loc = layer.getBounds().getCenter(); - loc.layer = layer; - retRecords[ layer.feature.properties[propName] ] = loc; - } - else - throw new Error("propertyName '"+propName+"' not found in feature"); - } - else if(layer instanceof L.LayerGroup) - { - //TODO: Optimize - layer.eachLayer(function(m) { - loc = m.getLatLng(); - loc.layer = m; - retRecords[ m.feature.properties[propName] ] = loc; - }); - } - - },this); - - return retRecords; - }, - - _autoType: function() { - - //TODO implements autype without selection(useful for mobile device) - - var start = this._input.value.length, - firstRecord = this._tooltip.firstChild._text, - end = firstRecord.length; - - if (firstRecord.indexOf(this._input.value) === 0) { // If prefix match - this._input.value = firstRecord; - this._handleAutoresize(); - - if (this._input.createTextRange) { - var selRange = this._input.createTextRange(); - selRange.collapse(true); - selRange.moveStart('character', start); - selRange.moveEnd('character', end); - selRange.select(); - } - else if(this._input.setSelectionRange) { - this._input.setSelectionRange(start, end); - } - else if(this._input.selectionStart) { - this._input.selectionStart = start; - this._input.selectionEnd = end; - } - } - }, - - _hideAutoType: function() { // deselect text: - - var sel; - if ((sel = this._input.selection) && sel.empty) { - sel.empty(); - } - else if (this._input.createTextRange) { - sel = this._input.createTextRange(); - sel.collapse(true); - var end = this._input.value.length; - sel.moveStart('character', end); - sel.moveEnd('character', end); - sel.select(); - } - else { - if (this._input.getSelection) { - this._input.getSelection().removeAllRanges(); - } - this._input.selectionStart = this._input.selectionEnd; - } - }, - - _handleKeypress: function (e) { //run _input keyup event - - switch(e.keyCode) - { - case 27: //Esc - this.collapse(); - break; - case 13: //Enter - if(this._countertips == 1) - this._handleArrowSelect(1); - this._handleSubmit(); //do search - break; - case 38://Up - this._handleArrowSelect(-1); - break; - case 40://Down - this._handleArrowSelect(1); - break; - case 37://Left - case 39://Right - case 16://Shift - case 17://Ctrl - //case 32://Space - break; - case 8://backspace - case 46://delete - this._autoTypeTmp = false;//disable temporarily autoType - break; - default://All keys - - if(this._input.value.length) - this._cancel.style.display = 'block'; - else - this._cancel.style.display = 'none'; - - if(this._input.value.length >= this.options.minLength) - { - var that = this; - - clearTimeout(this.timerKeypress); //cancel last search request while type in - this.timerKeypress = setTimeout(function() { //delay before request, for limit jsonp/ajax request - - that._fillRecordsCache(); - - }, this.options.delayType); - } - else - this._hideTooltip(); - } - }, - - searchText: function(text) { - var code = text.charCodeAt(text.length); - - this._input.value = text; - - this._input.style.display = 'block'; - L.DomUtil.addClass(this._container, 'search-exp'); - - this._autoTypeTmp = false; - - this._handleKeypress({keyCode: code}); - }, - - _fillRecordsCache: function() { -//TODO important optimization!!! always append data in this._recordsCache -// now _recordsCache content is emptied and replaced with new data founded -// always appending data on _recordsCache give the possibility of caching ajax, jsonp and layersearch! -// -//TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results.. -// run one of callbacks search(sourceData,jsonpUrl or options.layer) and run this.showTooltip -// -//TODO change structure of _recordsCache -// like this: _recordsCache = {"text-key1": {loc:[lat,lng], ..other attributes.. }, {"text-key2": {loc:[lat,lng]}...}, ...} -// in this way every record can have a free structure of attributes, only 'loc' is required - - var inputText = this._input.value, - that = this, records; - - if(this._curReq && this._curReq.abort) - this._curReq.abort(); - //abort previous requests - - L.DomUtil.addClass(this._container, 'search-load'); - - if(this.options.layer) - { - //TODO _recordsFromLayer must return array of objects, formatted from _formatData - this._recordsCache = this._recordsFromLayer(); - - records = this._filterData( this._input.value, this._recordsCache ); - - this.showTooltip( records ); - - L.DomUtil.removeClass(this._container, 'search-load'); - } - else - { - if(this.options.sourceData) - this._retrieveData = this.options.sourceData; - - else if(this.options.url) //jsonp or ajax - this._retrieveData = this.options.jsonpParam ? this._recordsFromJsonp : this._recordsFromAjax; - - this._curReq = this._retrieveData.call(this, inputText, function(data) { - - that._recordsCache = that._formatData(data); - - //TODO refact! - if(that.options.sourceData) - records = that._filterData( that._input.value, that._recordsCache ); - else - records = that._recordsCache; - - that.showTooltip( records ); - - L.DomUtil.removeClass(that._container, 'search-load'); - }); - } - }, - - _handleAutoresize: function() { //autoresize this._input - //TODO refact _handleAutoresize now is not accurate - if (this._input.style.maxWidth != this._map._container.offsetWidth) //If maxWidth isn't the same as when first set, reset to current Map width - this._input.style.maxWidth = L.DomUtil.getStyle(this._map._container, 'width'); - - if(this.options.autoResize && (this._container.offsetWidth + 45 < this._map._container.offsetWidth)) - this._input.size = this._input.value.length= (searchTips.length - 1))) {// If at end of list. - L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select'); - } - else if ((velocity == -1 ) && (this._tooltip.currentSelection <= 0)) { // Going back up to the search box. - this._tooltip.currentSelection = -1; - } - else if (this._tooltip.style.display != 'none') { - this._tooltip.currentSelection += velocity; - - L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select'); - - this._input.value = searchTips[this._tooltip.currentSelection]._text; - - // scroll: - var tipOffsetTop = searchTips[this._tooltip.currentSelection].offsetTop; - - if (tipOffsetTop + searchTips[this._tooltip.currentSelection].clientHeight >= this._tooltip.scrollTop + this._tooltip.clientHeight) { - this._tooltip.scrollTop = tipOffsetTop - this._tooltip.clientHeight + searchTips[this._tooltip.currentSelection].clientHeight; - } - else if (tipOffsetTop <= this._tooltip.scrollTop) { - this._tooltip.scrollTop = tipOffsetTop; - } - } - }, - - _handleSubmit: function() { //button and tooltip click and enter submit - - this._hideAutoType(); - - this.hideAlert(); - this._hideTooltip(); - - if(this._input.style.display == 'none') //on first click show _input only - this.expand(); - else - { - if(this._input.value === '') //hide _input only - this.collapse(); - else - { - var loc = this._getLocation(this._input.value); - - if(loc===false) - this.showAlert(); - else - { - this.showLocation(loc, this._input.value); - this.fire('search_locationfound', { - latlng: loc, - text: this._input.value, - layer: loc.layer ? loc.layer : null - }); - } - //this.collapse(); - //FIXME if collapse in _handleSubmit hide _markerLoc! - } - } - }, - - _getLocation: function(key) { //extract latlng from _recordsCache - - if( this._recordsCache.hasOwnProperty(key) ) - return this._recordsCache[key];//then after use .loc attribute - else - return false; - }, - - showLocation: function(latlng, title) { //set location on map from _recordsCache - - if(this.options.zoom) - this._map.setView(latlng, this.options.zoom); - else - this._map.panTo(latlng); - - if(this._markerLoc) - { - this._markerLoc.setLatLng(latlng); //show circle/marker in location found - this._markerLoc.setTitle(title); - this._markerLoc.show(); - if(this.options.animateLocation) - this._markerLoc.animate(); - //TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')... - } - - //FIXME autoCollapse option hide this._markerLoc before that visualized!! - if(this.options.autoCollapse) - this.collapse(); - return this; - } -}); - -L.Control.Search.Marker = L.Marker.extend({ - - includes: L.Mixin.Events, - - options: { - radius: 10, - weight: 3, - color: '#e03', - stroke: true, - fill: false, - title: '', - icon: new L.Icon.Default(), - showCircle: true, - showMarker: false //show icon optional, show only circleLoc - }, - - initialize: function (latlng, options) { - L.setOptions(this, options); - L.Marker.prototype.initialize.call(this, latlng, options); - if(this.options.showCircle) - this._circleLoc = new L.CircleMarker(latlng, this.options); - }, - - onAdd: function (map) { - L.Marker.prototype.onAdd.call(this, map); - if(this._circleLoc) - map.addLayer(this._circleLoc); - this.hide(); - }, - - onRemove: function (map) { - L.Marker.prototype.onRemove.call(this, map); - if(this._circleLoc) - map.removeLayer(this._circleLoc); - }, - - setLatLng: function (latlng) { - L.Marker.prototype.setLatLng.call(this, latlng); - if(this._circleLoc) - this._circleLoc.setLatLng(latlng); - return this; - }, - - setTitle: function(title) { - title = title || ''; - this.options.title = title; - if(this._icon) - this._icon.title = title; - return this; - }, - - show: function() { - if(this.options.showMarker) - { - if(this._icon) - this._icon.style.display = 'block'; - if(this._shadow) - this._shadow.style.display = 'block'; - //this._bringToFront(); - } - if(this._circleLoc) - { - this._circleLoc.setStyle({fill: this.options.fill, stroke: this.options.stroke}); - //this._circleLoc.bringToFront(); - } - return this; - }, - - hide: function() { - if(this._icon) - this._icon.style.display = 'none'; - if(this._shadow) - this._shadow.style.display = 'none'; - if(this._circleLoc) - this._circleLoc.setStyle({fill: false, stroke: false}); - return this; - }, - - animate: function() { - //TODO refact animate() more smooth! like this: http://goo.gl/DDlRs - if(this._circleLoc) - { - var circle = this._circleLoc, - tInt = 200, //time interval - ss = 10, //frames - mr = parseInt(circle._radius/ss), - oldrad = this.options.radius, - newrad = circle._radius * 2.5, - acc = 0; - - circle._timerAnimLoc = setInterval(function() { - acc += 0.5; - mr += acc; //adding acceleration - newrad -= mr; - - circle.setRadius(newrad); - - if(newrad=s;)n=n.__parent;return this._currentShownBounds.contains(n.getLatLng())&&(this.options.animateAddingMarkers?this._animationAddLayer(t,n):this._animationAddLayerNonAnimated(t,n)),this},removeLayer:function(t){if(t instanceof L.LayerGroup){var e=[];for(var i in t._layers)e.push(t._layers[i]);return this.removeLayers(e)}return t.getLatLng?this._map?t.__parent?(this._unspiderfy&&(this._unspiderfy(),this._unspiderfyLayer(t)),this._removeLayer(t,!0),this._topClusterLevel._recalculateBounds(),this._featureGroup.hasLayer(t)&&(this._featureGroup.removeLayer(t),t.clusterShow&&t.clusterShow()),this):this:(!this._arraySplice(this._needsClustering,t)&&this.hasLayer(t)&&this._needsRemoving.push(t),this):(this._nonPointGroup.removeLayer(t),this)},addLayers:function(t){var e,i,n,s,r=this._featureGroup,o=this._nonPointGroup,a=this.options.chunkedLoading,h=this.options.chunkInterval,u=this.options.chunkProgress;if(this._map){var _=0,l=(new Date).getTime(),d=L.bind(function(){for(var e=(new Date).getTime();_h)break}if(s=t[_],s.getLatLng){if(!this.hasLayer(s)&&(this._addLayer(s,this._maxZoom),s.__parent&&2===s.__parent.getChildCount())){var n=s.__parent.getAllChildMarkers(),c=n[0]===s?n[1]:n[0];r.removeLayer(c)}}else o.addLayer(s)}u&&u(_,t.length,(new Date).getTime()-l),_===t.length?(this._topClusterLevel._recalculateBounds(),this._featureGroup.eachLayer(function(t){t instanceof L.MarkerCluster&&t._iconNeedsUpdate&&t._updateIcon()}),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds)):setTimeout(d,this.options.chunkDelay)},this);d()}else{for(e=[],i=0,n=t.length;n>i;i++)s=t[i],s.getLatLng?this.hasLayer(s)||e.push(s):o.addLayer(s);this._needsClustering=this._needsClustering.concat(e)}return this},removeLayers:function(t){var e,i,n,s=this._featureGroup,r=this._nonPointGroup;if(!this._map){for(e=0,i=t.length;i>e;e++)n=t[e],this._arraySplice(this._needsClustering,n),r.removeLayer(n),this.hasLayer(n)&&this._needsRemoving.push(n);return this}if(this._unspiderfy)for(this._unspiderfy(),e=0,i=t.length;i>e;e++)n=t[e],this._unspiderfyLayer(n);for(e=0,i=t.length;i>e;e++)n=t[e],n.__parent?(this._removeLayer(n,!0,!0),s.hasLayer(n)&&(s.removeLayer(n),n.clusterShow&&n.clusterShow())):r.removeLayer(n);return this._topClusterLevel._recalculateBounds(),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds),s.eachLayer(function(t){t instanceof L.MarkerCluster&&t._updateIcon()}),this},clearLayers:function(){return this._map||(this._needsClustering=[],delete this._gridClusters,delete this._gridUnclustered),this._noanimationUnspiderfy&&this._noanimationUnspiderfy(),this._featureGroup.clearLayers(),this._nonPointGroup.clearLayers(),this.eachLayer(function(t){delete t.__parent}),this._map&&this._generateInitialClusters(),this},getBounds:function(){var t=new L.LatLngBounds;this._topClusterLevel&&t.extend(this._topClusterLevel._bounds);for(var e=this._needsClustering.length-1;e>=0;e--)t.extend(this._needsClustering[e].getLatLng());return t.extend(this._nonPointGroup.getBounds()),t},eachLayer:function(t,e){var i,n=this._needsClustering.slice();for(this._topClusterLevel&&this._topClusterLevel.getAllChildMarkers(n),i=n.length-1;i>=0;i--)t.call(e,n[i]);this._nonPointGroup.eachLayer(t,e)},getLayers:function(){var t=[];return this.eachLayer(function(e){t.push(e)}),t},getLayer:function(t){var e=null;return t=parseInt(t,10),this.eachLayer(function(i){L.stamp(i)===t&&(e=i)}),e},hasLayer:function(t){if(!t)return!1;var e,i=this._needsClustering;for(e=i.length-1;e>=0;e--)if(i[e]===t)return!0;for(i=this._needsRemoving,e=i.length-1;e>=0;e--)if(i[e]===t)return!1;return!(!t.__parent||t.__parent._group!==this)||this._nonPointGroup.hasLayer(t)},zoomToShowLayer:function(t,e){"function"!=typeof e&&(e=function(){});var i=function(){!t._icon&&!t.__parent._icon||this._inZoomAnimation||(this._map.off("moveend",i,this),this.off("animationend",i,this),t._icon?e():t.__parent._icon&&(this.once("spiderfied",e,this),t.__parent.spiderfy()))};if(t._icon&&this._map.getBounds().contains(t.getLatLng()))e();else if(t.__parent._zoome;e++)n=this._needsRemoving[e],this._removeLayer(n,!0);this._needsRemoving=[],this._zoom=this._map.getZoom(),this._currentShownBounds=this._getExpandedVisibleBounds(),this._map.on("zoomend",this._zoomEnd,this),this._map.on("moveend",this._moveEnd,this),this._spiderfierOnAdd&&this._spiderfierOnAdd(),this._bindEvents(),i=this._needsClustering,this._needsClustering=[],this.addLayers(i)},onRemove:function(t){t.off("zoomend",this._zoomEnd,this),t.off("moveend",this._moveEnd,this),this._unbindEvents(),this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim",""),this._spiderfierOnRemove&&this._spiderfierOnRemove(),delete this._maxLat,this._hideCoverage(),this._featureGroup.onRemove(t),this._nonPointGroup.onRemove(t),this._featureGroup.clearLayers(),this._map=null},getVisibleParent:function(t){for(var e=t;e&&!e._icon;)e=e.__parent;return e||null},_arraySplice:function(t,e){for(var i=t.length-1;i>=0;i--)if(t[i]===e)return t.splice(i,1),!0},_removeFromGridUnclustered:function(t,e){for(var i=this._map,n=this._gridUnclustered;e>=0&&n[e].removeObject(t,i.project(t.getLatLng(),e));e--);},_removeLayer:function(t,e,i){var n=this._gridClusters,s=this._gridUnclustered,r=this._featureGroup,o=this._map;e&&this._removeFromGridUnclustered(t,this._maxZoom);var a,h=t.__parent,u=h._markers;for(this._arraySplice(u,t);h&&(h._childCount--,h._boundsNeedUpdate=!0,!(h._zoom<0));)e&&h._childCount<=1?(a=h._markers[0]===t?h._markers[1]:h._markers[0],n[h._zoom].removeObject(h,o.project(h._cLatLng,h._zoom)),s[h._zoom].addObject(a,o.project(a.getLatLng(),h._zoom)),this._arraySplice(h.__parent._childClusters,h),h.__parent._markers.push(a),a.__parent=h.__parent,h._icon&&(r.removeLayer(h),i||r.addLayer(a))):i&&h._icon||h._updateIcon(),h=h.__parent;delete t.__parent},_isOrIsParent:function(t,e){for(;e;){if(t===e)return!0;e=e.parentNode}return!1},_propagateEvent:function(t){if(t.layer instanceof L.MarkerCluster){if(t.originalEvent&&this._isOrIsParent(t.layer._icon,t.originalEvent.relatedTarget))return;t.type="cluster"+t.type}this.fire(t.type,t)},_defaultIconCreateFunction:function(t){var e=t.getChildCount(),i=" marker-cluster-";return i+=10>e?"small":100>e?"medium":"large",new L.DivIcon({html:"
"+e+"
",className:"marker-cluster"+i,iconSize:new L.Point(40,40)})},_bindEvents:function(){var t=this._map,e=this.options.spiderfyOnMaxZoom,i=this.options.showCoverageOnHover,n=this.options.zoomToBoundsOnClick;(e||n)&&this.on("clusterclick",this._zoomOrSpiderfy,this),i&&(this.on("clustermouseover",this._showCoverage,this),this.on("clustermouseout",this._hideCoverage,this),t.on("zoomend",this._hideCoverage,this))},_zoomOrSpiderfy:function(t){for(var e=t.layer,i=e;1===i._childClusters.length;)i=i._childClusters[0];i._zoom===this._maxZoom&&i._childCount===e._childCount?this.options.spiderfyOnMaxZoom&&e.spiderfy():this.options.zoomToBoundsOnClick&&e.zoomToBounds(),t.originalEvent&&13===t.originalEvent.keyCode&&this._map._container.focus()},_showCoverage:function(t){var e=this._map;this._inZoomAnimation||(this._shownPolygon&&e.removeLayer(this._shownPolygon),t.layer.getChildCount()>2&&t.layer!==this._spiderfied&&(this._shownPolygon=new L.Polygon(t.layer.getConvexHull(),this.options.polygonOptions),e.addLayer(this._shownPolygon)))},_hideCoverage:function(){this._shownPolygon&&(this._map.removeLayer(this._shownPolygon),this._shownPolygon=null)},_unbindEvents:function(){var t=this.options.spiderfyOnMaxZoom,e=this.options.showCoverageOnHover,i=this.options.zoomToBoundsOnClick,n=this._map;(t||i)&&this.off("clusterclick",this._zoomOrSpiderfy,this),e&&(this.off("clustermouseover",this._showCoverage,this),this.off("clustermouseout",this._hideCoverage,this),n.off("zoomend",this._hideCoverage,this))},_zoomEnd:function(){this._map&&(this._mergeSplitClusters(),this._zoom=this._map._zoom,this._currentShownBounds=this._getExpandedVisibleBounds())},_moveEnd:function(){if(!this._inZoomAnimation){var t=this._getExpandedVisibleBounds();this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,this._zoom,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._map._zoom,t),this._currentShownBounds=t}},_generateInitialClusters:function(){var t=this._map.getMaxZoom(),e=this.options.maxClusterRadius,i=e;"function"!=typeof e&&(i=function(){return e}),this.options.disableClusteringAtZoom&&(t=this.options.disableClusteringAtZoom-1),this._maxZoom=t,this._gridClusters={},this._gridUnclustered={};for(var n=t;n>=0;n--)this._gridClusters[n]=new L.DistanceGrid(i(n)),this._gridUnclustered[n]=new L.DistanceGrid(i(n));this._topClusterLevel=new this._markerCluster(this,-1)},_addLayer:function(t,e){var i,n,s=this._gridClusters,r=this._gridUnclustered;for(this.options.singleMarkerMode&&this._overrideMarkerIcon(t);e>=0;e--){i=this._map.project(t.getLatLng(),e);var o=s[e].getNearObject(i);if(o)return o._addChild(t),t.__parent=o,void 0;if(o=r[e].getNearObject(i)){var a=o.__parent;a&&this._removeLayer(o,!1);var h=new this._markerCluster(this,e,o,t);s[e].addObject(h,this._map.project(h._cLatLng,e)),o.__parent=h,t.__parent=h;var u=h;for(n=e-1;n>a._zoom;n--)u=new this._markerCluster(this,n,u),s[n].addObject(u,this._map.project(o.getLatLng(),n));return a._addChild(u),this._removeFromGridUnclustered(o,e),void 0}r[e].addObject(t,i)}this._topClusterLevel._addChild(t),t.__parent=this._topClusterLevel},_enqueue:function(t){this._queue.push(t),this._queueTimeout||(this._queueTimeout=setTimeout(L.bind(this._processQueue,this),300))},_processQueue:function(){for(var t=0;tthis._map._zoom?(this._animationStart(),this._animationZoomOut(this._zoom,this._map._zoom)):this._moveEnd()},_getExpandedVisibleBounds:function(){return this.options.removeOutsideVisibleBounds?L.Browser.mobile?this._checkBoundsMaxLat(this._map.getBounds()):this._checkBoundsMaxLat(this._map.getBounds().pad(1)):this._mapBoundsInfinite},_checkBoundsMaxLat:function(t){var e=this._maxLat;return e!==i&&(t.getNorth()>=e&&(t._northEast.lat=1/0),t.getSouth()<=-e&&(t._southWest.lat=-1/0)),t},_animationAddLayerNonAnimated:function(t,e){if(e===t)this._featureGroup.addLayer(t);else if(2===e._childCount){e._addToMap();var i=e.getAllChildMarkers();this._featureGroup.removeLayer(i[0]),this._featureGroup.removeLayer(i[1])}else e._updateIcon()},_overrideMarkerIcon:function(t){var e=t.options.icon=this.options.iconCreateFunction({getChildCount:function(){return 1},getAllChildMarkers:function(){return[t]}});return e}}),L.MarkerClusterGroup.include({_mapBoundsInfinite:new L.LatLngBounds(new L.LatLng(-1/0,-1/0),new L.LatLng(1/0,1/0))}),L.MarkerClusterGroup.include({_noAnimation:{_animationStart:function(){},_animationZoomIn:function(t,e){this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this.fire("animationend")},_animationZoomOut:function(t,e){this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this.fire("animationend")},_animationAddLayer:function(t,e){this._animationAddLayerNonAnimated(t,e)}},_withAnimation:{_animationStart:function(){this._map._mapPane.className+=" leaflet-cluster-anim",this._inZoomAnimation++},_animationZoomIn:function(t,e){var i,n=this._getExpandedVisibleBounds(),s=this._featureGroup;this._topClusterLevel._recursively(n,t,0,function(r){var o,a=r._latlng,h=r._markers;for(n.contains(a)||(a=null),r._isSingleParent()&&t+1===e?(s.removeLayer(r),r._recursivelyAddChildrenToMap(null,e,n)):(r.clusterHide(),r._recursivelyAddChildrenToMap(a,e,n)),i=h.length-1;i>=0;i--)o=h[i],n.contains(o._latlng)||s.removeLayer(o)}),this._forceLayout(),this._topClusterLevel._recursivelyBecomeVisible(n,e),s.eachLayer(function(t){t instanceof L.MarkerCluster||!t._icon||t.clusterShow()}),this._topClusterLevel._recursively(n,t,e,function(t){t._recursivelyRestoreChildPositions(e)}),this._enqueue(function(){this._topClusterLevel._recursively(n,t,0,function(t){s.removeLayer(t),t.clusterShow()}),this._animationEnd()})},_animationZoomOut:function(t,e){this._animationZoomOutSingle(this._topClusterLevel,t-1,e),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,t,this._getExpandedVisibleBounds())},_animationAddLayer:function(t,e){var i=this,n=this._featureGroup;n.addLayer(t),e!==t&&(e._childCount>2?(e._updateIcon(),this._forceLayout(),this._animationStart(),t._setPos(this._map.latLngToLayerPoint(e.getLatLng())),t.clusterHide(),this._enqueue(function(){n.removeLayer(t),t.clusterShow(),i._animationEnd()})):(this._forceLayout(),i._animationStart(),i._animationZoomOutSingle(e,this._map.getMaxZoom(),this._map.getZoom())))}},_animationZoomOutSingle:function(t,e,i){var n=this._getExpandedVisibleBounds();t._recursivelyAnimateChildrenInAndAddSelfToMap(n,e+1,i);var s=this;this._forceLayout(),t._recursivelyBecomeVisible(n,i),this._enqueue(function(){if(1===t._childCount){var r=t._markers[0];r.setLatLng(r.getLatLng()),r.clusterShow&&r.clusterShow()}else t._recursively(n,i,0,function(t){t._recursivelyRemoveChildrenFromMap(n,e+1)});s._animationEnd()})},_animationEnd:function(){this._map&&(this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim","")),this._inZoomAnimation--,this.fire("animationend")},_forceLayout:function(){L.Util.falseFn(e.body.offsetWidth)}}),L.markerClusterGroup=function(t){return new L.MarkerClusterGroup(t)},L.MarkerCluster=L.Marker.extend({initialize:function(t,e,i,n){L.Marker.prototype.initialize.call(this,i?i._cLatLng||i.getLatLng():new L.LatLng(0,0),{icon:this}),this._group=t,this._zoom=e,this._markers=[],this._childClusters=[],this._childCount=0,this._iconNeedsUpdate=!0,this._boundsNeedUpdate=!0,this._bounds=new L.LatLngBounds,i&&this._addChild(i),n&&this._addChild(n)},getAllChildMarkers:function(t){t=t||[];for(var e=this._childClusters.length-1;e>=0;e--)this._childClusters[e].getAllChildMarkers(t);for(var i=this._markers.length-1;i>=0;i--)t.push(this._markers[i]);return t},getChildCount:function(){return this._childCount},zoomToBounds:function(){for(var t,e=this._childClusters.slice(),i=this._group._map,n=i.getBoundsZoom(this._bounds),s=this._zoom+1,r=i.getZoom();e.length>0&&n>s;){s++;var o=[];for(t=0;ts?this._group._map.setView(this._latlng,s):r>=n?this._group._map.setView(this._latlng,r+1):this._group._map.fitBounds(this._bounds)},getBounds:function(){var t=new L.LatLngBounds;return t.extend(this._bounds),t},_updateIcon:function(){this._iconNeedsUpdate=!0,this._icon&&this.setIcon(this)},createIcon:function(){return this._iconNeedsUpdate&&(this._iconObj=this._group.options.iconCreateFunction(this),this._iconNeedsUpdate=!1),this._iconObj.createIcon()},createShadow:function(){return this._iconObj.createShadow()},_addChild:function(t,e){this._iconNeedsUpdate=!0,this._boundsNeedUpdate=!0,this._setClusterCenter(t),t instanceof L.MarkerCluster?(e||(this._childClusters.push(t),t.__parent=this),this._childCount+=t._childCount):(e||this._markers.push(t),this._childCount++),this.__parent&&this.__parent._addChild(t,!0)},_setClusterCenter:function(t){this._cLatLng||(this._cLatLng=t._cLatLng||t._latlng)},_resetBounds:function(){var t=this._bounds;t._southWest&&(t._southWest.lat=1/0,t._southWest.lng=1/0),t._northEast&&(t._northEast.lat=-1/0,t._northEast.lng=-1/0)},_recalculateBounds:function(){var t,e,i,n,s=this._markers,r=this._childClusters,o=0,a=0,h=this._childCount;if(0!==h){for(this._resetBounds(),t=0;t=0;i--)n=s[i],n._icon&&(n._setPos(e),n.clusterHide())},function(t){var i,n,s=t._childClusters;for(i=s.length-1;i>=0;i--)n=s[i],n._icon&&(n._setPos(e),n.clusterHide())})},_recursivelyAnimateChildrenInAndAddSelfToMap:function(t,e,i){this._recursively(t,i,0,function(n){n._recursivelyAnimateChildrenIn(t,n._group._map.latLngToLayerPoint(n.getLatLng()).round(),e),n._isSingleParent()&&e-1===i?(n.clusterShow(),n._recursivelyRemoveChildrenFromMap(t,e)):n.clusterHide(),n._addToMap()})},_recursivelyBecomeVisible:function(t,e){this._recursively(t,0,e,null,function(t){t.clusterShow()})},_recursivelyAddChildrenToMap:function(t,e,i){this._recursively(i,-1,e,function(n){if(e!==n._zoom)for(var s=n._markers.length-1;s>=0;s--){var r=n._markers[s];i.contains(r._latlng)&&(t&&(r._backupLatlng=r.getLatLng(),r.setLatLng(t),r.clusterHide&&r.clusterHide()),n._group._featureGroup.addLayer(r))}},function(e){e._addToMap(t)})},_recursivelyRestoreChildPositions:function(t){for(var e=this._markers.length-1;e>=0;e--){var i=this._markers[e];i._backupLatlng&&(i.setLatLng(i._backupLatlng),delete i._backupLatlng)}if(t-1===this._zoom)for(var n=this._childClusters.length-1;n>=0;n--)this._childClusters[n]._restorePosition();else for(var s=this._childClusters.length-1;s>=0;s--)this._childClusters[s]._recursivelyRestoreChildPositions(t)},_restorePosition:function(){this._backupLatlng&&(this.setLatLng(this._backupLatlng),delete this._backupLatlng)},_recursivelyRemoveChildrenFromMap:function(t,e,i){var n,s;this._recursively(t,-1,e-1,function(t){for(s=t._markers.length-1;s>=0;s--)n=t._markers[s],i&&i.contains(n._latlng)||(t._group._featureGroup.removeLayer(n),n.clusterShow&&n.clusterShow())},function(t){for(s=t._childClusters.length-1;s>=0;s--)n=t._childClusters[s],i&&i.contains(n._latlng)||(t._group._featureGroup.removeLayer(n),n.clusterShow&&n.clusterShow())})},_recursively:function(t,e,i,n,s){var r,o,a=this._childClusters,h=this._zoom;if(e>h)for(r=a.length-1;r>=0;r--)o=a[r],t.intersects(o._bounds)&&o._recursively(t,e,i,n,s);else if(n&&n(this),s&&this._zoom===i&&s(this),i>h)for(r=a.length-1;r>=0;r--)o=a[r],t.intersects(o._bounds)&&o._recursively(t,e,i,n,s)},_isSingleParent:function(){return this._childClusters.length>0&&this._childClusters[0]._childCount===this._childCount}}),L.Marker.include({clusterHide:function(){return this.options.opacityWhenUnclustered=this.options.opacity||1,this.setOpacity(0)},clusterShow:function(){var t=this.setOpacity(this.options.opacity||this.options.opacityWhenUnclustered);return delete this.options.opacityWhenUnclustered,t}}),L.DistanceGrid=function(t){this._cellSize=t,this._sqCellSize=t*t,this._grid={},this._objectPoint={}},L.DistanceGrid.prototype={addObject:function(t,e){var i=this._getCoord(e.x),n=this._getCoord(e.y),s=this._grid,r=s[n]=s[n]||{},o=r[i]=r[i]||[],a=L.Util.stamp(t);this._objectPoint[a]=e,o.push(t)},updateObject:function(t,e){this.removeObject(t),this.addObject(t,e)},removeObject:function(t,e){var i,n,s=this._getCoord(e.x),r=this._getCoord(e.y),o=this._grid,a=o[r]=o[r]||{},h=a[s]=a[s]||[];for(delete this._objectPoint[L.Util.stamp(t)],i=0,n=h.length;n>i;i++)if(h[i]===t)return h.splice(i,1),1===n&&delete a[s],!0},eachObject:function(t,e){var i,n,s,r,o,a,h,u=this._grid;for(i in u){o=u[i];for(n in o)for(a=o[n],s=0,r=a.length;r>s;s++)h=t.call(e,a[s]),h&&(s--,r--)}},getNearObject:function(t){var e,i,n,s,r,o,a,h,u=this._getCoord(t.x),_=this._getCoord(t.y),l=this._objectPoint,d=this._sqCellSize,c=null;for(e=_-1;_+1>=e;e++)if(s=this._grid[e])for(i=u-1;u+1>=i;i++)if(r=s[i])for(n=0,o=r.length;o>n;n++)a=r[n],h=this._sqDist(l[L.Util.stamp(a)],t),d>h&&(d=h,c=a);return c},_getCoord:function(t){return Math.floor(t/this._cellSize)},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n}},function(){L.QuickHull={getDistant:function(t,e){var i=e[1].lat-e[0].lat,n=e[0].lng-e[1].lng;return n*(t.lat-e[0].lat)+i*(t.lng-e[0].lng)},findMostDistantPointFromBaseLine:function(t,e){var i,n,s,r=0,o=null,a=[];for(i=e.length-1;i>=0;i--)n=e[i],s=this.getDistant(n,t),s>0&&(a.push(n),s>r&&(r=s,o=n));return{maxPoint:o,newPoints:a}},buildConvexHull:function(t,e){var i=[],n=this.findMostDistantPointFromBaseLine(t,e);return n.maxPoint?(i=i.concat(this.buildConvexHull([t[0],n.maxPoint],n.newPoints)),i=i.concat(this.buildConvexHull([n.maxPoint,t[1]],n.newPoints))):[t[0]]},getConvexHull:function(t){var e,i=!1,n=!1,s=!1,r=!1,o=null,a=null,h=null,u=null,_=null,l=null;for(e=t.length-1;e>=0;e--){var d=t[e];(i===!1||d.lat>i)&&(o=d,i=d.lat),(n===!1||d.lats)&&(h=d,s=d.lng),(r===!1||d.lng=0;e--)t=i[e].getLatLng(),n.push(t);return L.QuickHull.getConvexHull(n)}}),L.MarkerCluster.include({_2PI:2*Math.PI,_circleFootSeparation:25,_circleStartAngle:Math.PI/6,_spiralFootSeparation:28,_spiralLengthStart:11,_spiralLengthFactor:5,_circleSpiralSwitchover:9,spiderfy:function(){if(this._group._spiderfied!==this&&!this._group._inZoomAnimation){var t,e=this.getAllChildMarkers(),i=this._group,n=i._map,s=n.latLngToLayerPoint(this._latlng);this._group._unspiderfy(),this._group._spiderfied=this,e.length>=this._circleSpiralSwitchover?t=this._generatePointsSpiral(e.length,s):(s.y+=10,t=this._generatePointsCircle(e.length,s)),this._animationSpiderfy(e,t)}},unspiderfy:function(t){this._group._inZoomAnimation||(this._animationUnspiderfy(t),this._group._spiderfied=null)},_generatePointsCircle:function(t,e){var i,n,s=this._group.options.spiderfyDistanceMultiplier*this._circleFootSeparation*(2+t),r=s/this._2PI,o=this._2PI/t,a=[];for(a.length=t,i=t-1;i>=0;i--)n=this._circleStartAngle+i*o,a[i]=new L.Point(e.x+r*Math.cos(n),e.y+r*Math.sin(n))._round();return a},_generatePointsSpiral:function(t,e){var i,n=this._group.options.spiderfyDistanceMultiplier,s=n*this._spiralLengthStart,r=n*this._spiralFootSeparation,o=n*this._spiralLengthFactor*this._2PI,a=0,h=[];for(h.length=t,i=t-1;i>=0;i--)a+=r/s+5e-4*i,h[i]=new L.Point(e.x+s*Math.cos(a),e.y+s*Math.sin(a))._round(),s+=o/a;return h},_noanimationUnspiderfy:function(){var t,e,i=this._group,n=i._map,s=i._featureGroup,r=this.getAllChildMarkers();for(this.setOpacity(1),e=r.length-1;e>=0;e--)t=r[e],s.removeLayer(t),t._preSpiderfyLatlng&&(t.setLatLng(t._preSpiderfyLatlng),delete t._preSpiderfyLatlng),t.setZIndexOffset&&t.setZIndexOffset(0),t._spiderLeg&&(n.removeLayer(t._spiderLeg),delete t._spiderLeg);i.fire("unspiderfied",{cluster:this,markers:r}),i._spiderfied=null}}),L.MarkerClusterNonAnimated=L.MarkerCluster.extend({_animationSpiderfy:function(t,e){var i,n,s,r,o=this._group,a=o._map,h=o._featureGroup,u=this._group.options.spiderLegPolylineOptions;for(i=0;i=0;n--)h=l.layerPointToLatLng(e[n]),s=t[n],s._preSpiderfyLatlng=s._latlng,s.setLatLng(h),s.clusterShow&&s.clusterShow(),f&&(r=s._spiderLeg,o=r._path,o.style.strokeDashoffset=0,r.setStyle({opacity:g}));this.setOpacity(.3),setTimeout(function(){_._animationEnd(),_.fire("spiderfied",{cluster:u,markers:t})},200)},_animationUnspiderfy:function(t){var e,i,n,s,r,o,a=this,h=this._group,u=h._map,_=h._featureGroup,l=t?u._latLngToNewLayerPoint(this._latlng,t.zoom,t.center):u.latLngToLayerPoint(this._latlng),d=this.getAllChildMarkers(),c=L.Path.SVG;for(h._animationStart(),this.setOpacity(1),i=d.length-1;i>=0;i--)e=d[i],e._preSpiderfyLatlng&&(e.setLatLng(e._preSpiderfyLatlng),delete e._preSpiderfyLatlng,o=!0,e._setPos&&(e._setPos(l),o=!1),e.clusterHide&&(e.clusterHide(),o=!1),o&&_.removeLayer(e),c&&(n=e._spiderLeg,s=n._path,r=s.getTotalLength()+.1,s.style.strokeDashoffset=r,n.setStyle({opacity:0})));setTimeout(function(){var t=0;for(i=d.length-1;i>=0;i--)e=d[i],e._spiderLeg&&t++;for(i=d.length-1;i>=0;i--)e=d[i],e._spiderLeg&&(e.clusterShow&&e.clusterShow(),e.setZIndexOffset&&e.setZIndexOffset(0),t>1&&_.removeLayer(e),u.removeLayer(e._spiderLeg),delete e._spiderLeg);h._animationEnd(),h.fire("unspiderfied",{cluster:a,markers:d})},200)}}),L.MarkerClusterGroup.include({_spiderfied:null,_spiderfierOnAdd:function(){this._map.on("click",this._unspiderfyWrapper,this),this._map.options.zoomAnimation&&this._map.on("zoomstart",this._unspiderfyZoomStart,this),this._map.on("zoomend",this._noanimationUnspiderfy,this)},_spiderfierOnRemove:function(){this._map.off("click",this._unspiderfyWrapper,this),this._map.off("zoomstart",this._unspiderfyZoomStart,this),this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._map.off("zoomend",this._noanimationUnspiderfy,this),this._noanimationUnspiderfy()},_unspiderfyZoomStart:function(){this._map&&this._map.on("zoomanim",this._unspiderfyZoomAnim,this)},_unspiderfyZoomAnim:function(t){L.DomUtil.hasClass(this._map._mapPane,"leaflet-touching")||(this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._unspiderfy(t))},_unspiderfyWrapper:function(){this._unspiderfy()},_unspiderfy:function(t){this._spiderfied&&this._spiderfied.unspiderfy(t)},_noanimationUnspiderfy:function(){this._spiderfied&&this._spiderfied._noanimationUnspiderfy()},_unspiderfyLayer:function(t){t._spiderLeg&&(this._featureGroup.removeLayer(t),t.clusterShow&&t.clusterShow(),t.setZIndexOffset&&t.setZIndexOffset(0),this._map.removeLayer(t._spiderLeg),delete t._spiderLeg)}}),L.MarkerClusterGroup.include({refreshClusters:function(t){return t?t instanceof L.MarkerClusterGroup?t=t._topClusterLevel.getAllChildMarkers():t instanceof L.LayerGroup?t=t._layers:t instanceof L.MarkerCluster?t=t.getAllChildMarkers():t instanceof L.Marker&&(t=[t]):t=this._topClusterLevel.getAllChildMarkers(),this._flagParentsIconsNeedUpdate(t),this._refreshClustersIcons(),this.options.singleMarkerMode&&this._refreshSingleMarkerModeMarkers(t),this},_flagParentsIconsNeedUpdate:function(t){var e,i;for(e in t)for(i=t[e].__parent;i;)i._iconNeedsUpdate=!0,i=i.__parent},_refreshClustersIcons:function(){this._featureGroup.eachLayer(function(t){t instanceof L.MarkerCluster&&t._iconNeedsUpdate&&t._updateIcon()})},_refreshSingleMarkerModeMarkers:function(t){var e,i;for(e in t)i=t[e],this.hasLayer(i)&&i.setIcon(this._overrideMarkerIcon(i))}}),L.Marker.include({refreshIconOptions:function(t,e){var i=this.options.icon;return L.setOptions(i,t),this.setIcon(i),e&&this.__parent&&this.__parent._group.refreshClusters(this),this}})}(window,document); \ No newline at end of file diff --git a/mapmakr/static/js/mapmakr.js b/mapmakr/static/js/mapmakr.js index 3be8f7b..c18b298 100644 --- a/mapmakr/static/js/mapmakr.js +++ b/mapmakr/static/js/mapmakr.js @@ -1,9 +1,9 @@ -let map, drawnItems, drawControl, currentLayer; +let map, drawnItems, drawControl, currentLayer, editModal, editForm; -function reload_map() { +function reloadMap() { fetch("/marker").then(response => response.json()).then(markers => { - // const map = window.map; + let markerBounds = new L.LatLngBounds(); drawnItems.clearLayers(); markers.forEach(marker => { let mapMarker = L.marker({"lat": marker.latitude, "lng": marker.longitude}); @@ -12,9 +12,10 @@ function reload_map() { for (const opt in marker.options) { mapMarker.options[opt] = marker.options[opt]; } - mapMarker.bindLabel(marker.name, {noHide: true}); + // mapMarker.bindTooltip(marker.name, {noHide: true}); mapMarker.bindPopup(marker.name); drawnItems.addLayer(mapMarker); + markerBounds.extend(mapMarker.getLatLng()); }); if (!drawControl) { // add drawControl only after some drawnItems exist, so @@ -31,25 +32,31 @@ function reload_map() { featureGroup: drawnItems } }); - console.log(map); - console.log(drawControl); map.addControl(drawControl); } + map.fitBounds(markerBounds); }); } -function setup_map() { +function setupMap() { + L.AwesomeMarkers.Icon.prototype.options.prefix = 'bs'; + + editForm = document.getElementById('edit-form'); + let editModalDiv = document.getElementById('edit-modal'); + editModal = new bootstrap.Modal(editModalDiv); + editModalDiv.addEventListener('hidden.bs.modal', () => editForm.reset()); + let osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', osmAttrib = '©
OpenStreetMap contributors', osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib}); - map = new L.Map('mapmakr', {layers: [osm], attributionControl: false, center: new L.LatLng(0, 0), zoom: 2 }); + map = new L.Map('mapmakr', {layers: [osm], attributionControl: false, center: new L.LatLng(0, 0), zoom: 5}); drawnItems = new L.MarkerClusterGroup({maxClusterRadius: 45}); map.addLayer(drawnItems); - reload_map(); + reloadMap(); - const refreshButton = new L.easyButton('icon ion-refresh', function() {reload_map();}); + const refreshButton = new L.easyButton('bi bi-arrow-clockwise', function() {reload_map();}); refreshButton.button.style.fontSize = '18px'; map.addControl(refreshButton); @@ -86,7 +93,7 @@ function setup_map() { } currentLayer = layer; - $("#edit-form").modal(); + editModal.show(); }); map.on('draw:edited', function (e) { @@ -100,13 +107,13 @@ function setup_map() { map.on('draw:deleted', function (e) { e.layers.eachLayer(layer => { let type = layer.layerType, id = layer.options.id; - fetch("/marker/" + id, {method: "DELETE"}).then(() => reload_map()); + fetch("/marker/" + id, {method: "DELETE"}).then(() => reloadMap()); }); }); - $("#marker-save").on("click", (event) => { + document.getElementById("marker-save").addEventListener("click", (event) => { event.preventDefault(); - let name = $("#marker-name").val(); + let name = document.getElementById("marker-name").value; const markerAttributes = { "name": name, "latitude": currentLayer.getLatLng()["lat"], @@ -124,17 +131,16 @@ function setup_map() { }, body: JSON.stringify(markerAttributes) }; - console.log(currentLayer); if (currentLayer.options.id) { requestOptions["method"] = "PATCH"; - fetch("/marker/" + currentLayer.options.id, requestOptions).then(() => reload_map()); + fetch("/marker/" + currentLayer.options.id, requestOptions).then(() => reloadMap()); } else { requestOptions["method"] = "POST"; - fetch("/marker", requestOptions).then(() => reload_map()); + fetch("/marker", requestOptions).then(() => reloadMap()); } } - $.modal.close(); + editModal.hide(); return false; }); } diff --git a/mapmakr/templates/index.html b/mapmakr/templates/index.html index 637e9ba..45b8753 100644 --- a/mapmakr/templates/index.html +++ b/mapmakr/templates/index.html @@ -2,38 +2,59 @@ {{site_title}} - - - - + + + + - - - - - - + + + +
-