/* * L.Control.Scale is used for displaying metric/imperial scale on the map. */ L.Control.Scale = L.Control.extend({ options: { position: 'bottomleft', maxWidth: 100, metric: false, imperial: true, updateWhenIdle: false, offset:[10,10] }, initialize: function (options) { L.setOptions(this, options); }, onAdd: function (map) { this._map = map; var className = 'leaflet-control-scale', container = L.DomUtil.create('div', className), options = this.options; switch(this.options.position){ case 'topleft': container.style.marginLeft = this.options.offset[0]+'px'; container.style.marginTop = this.options.offset[1]+'px'; break; case 'topright': container.style.marginRight = this.options.offset[0]+'px'; container.style.marginTop = this.options.offset[1]+'px'; break; case 'bottomleft': container.style.marginLeft = this.options.offset[0]+'px'; container.style.marginBottom = this.options.offset[1]+'px'; break; case 'bottomright': container.style.marginRight = this.options.offset[0]+'px'; container.style.marginBottom = this.options.offset[1]+'px'; break; } this._addScales(options, className, container); map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this); map.whenReady(this._update, this); L.DomEvent.on(container,'contextmenu',L.DomEvent.stopPropagation); return container; }, onRemove: function (map) { map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this); }, getUnit:function(){ return this.options.metric?'metric':'imperial' }, setUnit:function(unit){ if(unit == 'metric'){ this.options.metric = true; this.options.imperial = false; this._mScale.style.display = 'block'; this._iScale.style.display = 'none'; } if(unit == 'imperial'){ this.options.metric = false; this.options.imperial = true; this._iScale.style.display = 'block'; this._mScale.style.display = 'none'; } this._update(); }, _addScales: function (options, className, container) { this._mScale = L.DomUtil.create('div', className + '-line', container); this._iScale = L.DomUtil.create('div', className + '-line', container); if (options.metric) { this._mScale.style.display = 'block'; this._iScale.style.display = 'none'; } if (options.imperial) { this._iScale.style.display = 'block'; this._mScale.style.display = 'none'; } }, _update: function () { var bounds = this._map.getBounds(), centerLat = bounds.getCenter().lat, halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180), dist = halfWorldMeters * (bounds.getNorthEast().lng - bounds.getSouthWest().lng) / 180, size = this._map.getSize(), options = this.options, maxMeters = 0; if (size.x > 0) { maxMeters = dist * (options.maxWidth / size.x); } this._updateScales(options, maxMeters); }, _updateScales: function (options, maxMeters) { if (options.metric && maxMeters) { this._updateMetric(maxMeters); } if (options.imperial && maxMeters) { this._updateImperial(maxMeters); } }, _updateMetric: function (maxMeters) { var meters = this._getRoundNum(maxMeters); this._mScale.style.width = this._getScaleWidth(meters / maxMeters) + 'px'; this._mScale.innerHTML = meters < 1000 ? ''+meters + ' 米' : ''+(meters / 1000) + ' 公里'; }, _updateImperial: function (maxMeters) { var maxFeet = maxMeters * 3.2808399, scale = this._iScale, maxMiles, miles, feet; feet = this._getRoundNum(maxFeet); scale.style.width = this._getScaleWidth(feet / maxFeet) + 'px'; scale.innerHTML = ''+feet + ' 英尺'; }, _getScaleWidth: function (ratio) { return Math.round(this.options.maxWidth * ratio) - 10; }, _getRoundNum: function (num) { var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1), d = num / pow10; d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1; return pow10 * d; } }); L.Map.addInitHook(function () { if (this.options.scaleControl) { this.scaleControl = new L.Control.Scale(); this.addControl(this.scaleControl); } }); L.control.scale = function (options) { return new L.Control.Scale(options); }; /** * 添加比例尺控件 * @param {[type]} options [description] * @return {[type]} [description] */ map2DViewer.setScaleControl = function(options) { var defaultData = { action: 'add', position: 'bottomleft', offset: [10, 10] } _.merge(defaultData, options); switch (defaultData.action) { case 'add': this.scaleControl = new L.Control.Scale({ position: defaultData.position, offset: defaultData.offset, metric: defaultData.metric, imperial: defaultData.imperial, }).addTo(this.map); return this.scaleControl; break; case 'remove': this.map.removeControl(this.scaleControl) break; } }