1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 2"use strict"; 3 4Object.defineProperty(exports, "__esModule", { 5 value: true 6}); 7exports["default"] = undefined; 8 9var _util = require("./util"); 10 11function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12 13function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 14 15function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 16 17var ClusterLayerStore = /*#__PURE__*/function () { 18 function ClusterLayerStore(group) { 19 _classCallCheck(this, ClusterLayerStore); 20 21 this._layers = {}; 22 this._group = group; 23 } 24 25 _createClass(ClusterLayerStore, [{ 26 key: "add", 27 value: function add(layer, id) { 28 if (typeof id !== "undefined" && id !== null) { 29 if (this._layers[id]) { 30 this._group.removeLayer(this._layers[id]); 31 } 32 33 this._layers[id] = layer; 34 } 35 36 this._group.addLayer(layer); 37 } 38 }, { 39 key: "remove", 40 value: function remove(id) { 41 if (typeof id === "undefined" || id === null) { 42 return; 43 } 44 45 id = (0, _util.asArray)(id); 46 47 for (var i = 0; i < id.length; i++) { 48 if (this._layers[id[i]]) { 49 this._group.removeLayer(this._layers[id[i]]); 50 51 delete this._layers[id[i]]; 52 } 53 } 54 } 55 }, { 56 key: "clear", 57 value: function clear() { 58 this._layers = {}; 59 60 this._group.clearLayers(); 61 } 62 }]); 63 64 return ClusterLayerStore; 65}(); 66 67exports["default"] = ClusterLayerStore; 68 69 70},{"./util":17}],2:[function(require,module,exports){ 71"use strict"; 72 73Object.defineProperty(exports, "__esModule", { 74 value: true 75}); 76 77function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 78 79function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 80 81function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 82 83var ControlStore = /*#__PURE__*/function () { 84 function ControlStore(map) { 85 _classCallCheck(this, ControlStore); 86 87 this._controlsNoId = []; 88 this._controlsById = {}; 89 this._map = map; 90 } 91 92 _createClass(ControlStore, [{ 93 key: "add", 94 value: function add(control, id, html) { 95 if (typeof id !== "undefined" && id !== null) { 96 if (this._controlsById[id]) { 97 this._map.removeControl(this._controlsById[id]); 98 } 99 100 this._controlsById[id] = control; 101 } else { 102 this._controlsNoId.push(control); 103 } 104 105 this._map.addControl(control); 106 } 107 }, { 108 key: "get", 109 value: function get(id) { 110 var control = null; 111 112 if (this._controlsById[id]) { 113 control = this._controlsById[id]; 114 } 115 116 return control; 117 } 118 }, { 119 key: "remove", 120 value: function remove(id) { 121 if (this._controlsById[id]) { 122 var control = this._controlsById[id]; 123 124 this._map.removeControl(control); 125 126 delete this._controlsById[id]; 127 } 128 } 129 }, { 130 key: "clear", 131 value: function clear() { 132 for (var i = 0; i < this._controlsNoId.length; i++) { 133 var control = this._controlsNoId[i]; 134 135 this._map.removeControl(control); 136 } 137 138 this._controlsNoId = []; 139 140 for (var key in this._controlsById) { 141 var _control = this._controlsById[key]; 142 143 this._map.removeControl(_control); 144 } 145 146 this._controlsById = {}; 147 } 148 }]); 149 150 return ControlStore; 151}(); 152 153exports["default"] = ControlStore; 154 155 156},{}],3:[function(require,module,exports){ 157"use strict"; 158 159Object.defineProperty(exports, "__esModule", { 160 value: true 161}); 162exports.getCRS = getCRS; 163 164var _leaflet = require("./global/leaflet"); 165 166var _leaflet2 = _interopRequireDefault(_leaflet); 167 168var _proj4leaflet = require("./global/proj4leaflet"); 169 170var _proj4leaflet2 = _interopRequireDefault(_proj4leaflet); 171 172function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 173 174// Helper function to instanciate a ICRS instance. 175function getCRS(crsOptions) { 176 var crs = _leaflet2["default"].CRS.EPSG3857; // Default Spherical Mercator 177 178 switch (crsOptions.crsClass) { 179 case "L.CRS.EPSG3857": 180 crs = _leaflet2["default"].CRS.EPSG3857; 181 break; 182 183 case "L.CRS.EPSG4326": 184 crs = _leaflet2["default"].CRS.EPSG4326; 185 break; 186 187 case "L.CRS.EPSG3395": 188 crs = _leaflet2["default"].CRS.EPSG3395; 189 break; 190 191 case "L.CRS.Simple": 192 crs = _leaflet2["default"].CRS.Simple; 193 break; 194 195 case "L.Proj.CRS": 196 if (crsOptions.options && crsOptions.options.bounds) { 197 crsOptions.options.bounds = _leaflet2["default"].bounds(crsOptions.options.bounds); 198 } 199 200 if (crsOptions.options && crsOptions.options.transformation) { 201 crsOptions.options.transformation = new _leaflet2["default"].Transformation(crsOptions.options.transformation[0], crsOptions.options.transformation[1], crsOptions.options.transformation[2], crsOptions.options.transformation[3]); 202 } 203 204 crs = new _proj4leaflet2["default"].CRS(crsOptions.code, crsOptions.proj4def, crsOptions.options); 205 break; 206 207 case "L.Proj.CRS.TMS": 208 if (crsOptions.options && crsOptions.options.bounds) { 209 crsOptions.options.bounds = _leaflet2["default"].bounds(crsOptions.options.bounds); 210 } 211 212 if (crsOptions.options && crsOptions.options.transformation) { 213 crsOptions.options.transformation = _leaflet2["default"].Transformation(crsOptions.options.transformation[0], crsOptions.options.transformation[1], crsOptions.options.transformation[2], crsOptions.options.transformation[3]); 214 } // L.Proj.CRS.TMS is deprecated as of Leaflet 1.x, fall back to L.Proj.CRS 215 //crs = new Proj4Leaflet.CRS.TMS(crsOptions.code, crsOptions.proj4def, crsOptions.projectedBounds, crsOptions.options); 216 217 218 crs = new _proj4leaflet2["default"].CRS(crsOptions.code, crsOptions.proj4def, crsOptions.options); 219 break; 220 } 221 222 return crs; 223} 224 225 226},{"./global/leaflet":10,"./global/proj4leaflet":11}],4:[function(require,module,exports){ 227"use strict"; 228 229Object.defineProperty(exports, "__esModule", { 230 value: true 231}); 232exports["default"] = undefined; 233 234var _util = require("./util"); 235 236function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 237 238function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 239 240function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 241 242var DataFrame = /*#__PURE__*/function () { 243 function DataFrame() { 244 _classCallCheck(this, DataFrame); 245 246 this.columns = []; 247 this.colnames = []; 248 this.colstrict = []; 249 this.effectiveLength = 0; 250 this.colindices = {}; 251 } 252 253 _createClass(DataFrame, [{ 254 key: "_updateCachedProperties", 255 value: function _updateCachedProperties() { 256 var _this = this; 257 258 this.effectiveLength = 0; 259 this.colindices = {}; 260 this.columns.forEach(function (column, i) { 261 _this.effectiveLength = Math.max(_this.effectiveLength, column.length); 262 _this.colindices[_this.colnames[i]] = i; 263 }); 264 } 265 }, { 266 key: "_colIndex", 267 value: function _colIndex(colname) { 268 var index = this.colindices[colname]; 269 if (typeof index === "undefined") return -1; 270 return index; 271 } 272 }, { 273 key: "col", 274 value: function col(name, values, strict) { 275 if (typeof name !== "string") throw new Error("Invalid column name \"" + name + "\""); 276 277 var index = this._colIndex(name); 278 279 if (arguments.length === 1) { 280 if (index < 0) return null;else return (0, _util.recycle)(this.columns[index], this.effectiveLength); 281 } 282 283 if (index < 0) { 284 index = this.colnames.length; 285 this.colnames.push(name); 286 } 287 288 this.columns[index] = (0, _util.asArray)(values); 289 this.colstrict[index] = !!strict; // TODO: Validate strictness (ensure lengths match up with other stricts) 290 291 this._updateCachedProperties(); 292 293 return this; 294 } 295 }, { 296 key: "cbind",
297 value: function cbind(obj, strict) { 298 var _this2 = this; 299 300 Object.keys(obj).forEach(function (name) { 301 var coldata = obj[name]; 302 303 _this2.col(name, coldata); 304 }); 305 return this; 306 } 307 }, { 308 key: "get", 309 value: function get(row, col, missingOK) { 310 var _this3 = this; 311 312 if (row > this.effectiveLength) throw new Error("Row argument was out of bounds: " + row + " > " + this.effectiveLength); 313 var colIndex = -1; 314 315 if (typeof col === "undefined") { 316 var rowData = {}; 317 this.colnames.forEach(function (name, i) { 318 rowData[name] = _this3.columns[i][row % _this3.columns[i].length]; 319 }); 320 return rowData; 321 } else if (typeof col === "string") { 322 colIndex = this._colIndex(col); 323 } else if (typeof col === "number") { 324 colIndex = col; 325 } 326 327 if (colIndex < 0 || colIndex > this.columns.length) { 328 if (missingOK) return void 0;else throw new Error("Unknown column index: " + col); 329 } 330 331 return this.columns[colIndex][row % this.columns[colIndex].length]; 332 } 333 }, { 334 key: "nrow", 335 value: function nrow() { 336 return this.effectiveLength; 337 } 338 }]); 339 340 return DataFrame; 341}(); 342 343exports["default"] = DataFrame; 344 345 346},{"./util":17}],5:[function(require,module,exports){ 347"use strict"; 348 349var _leaflet = require("./global/leaflet"); 350 351var _leaflet2 = _interopRequireDefault(_leaflet); 352 353function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 354 355// In RMarkdown's self-contained mode, we don't have a way to carry around the 356// images that Leaflet needs but doesn't load into the page. Instead, we'll use 357// the unpkg CDN. 358if (typeof _leaflet2["default"].Icon.Default.imagePath === "undefined") { 359 _leaflet2["default"].Icon.Default.imagePath = "https://unpkg.com/[email protected]/dist/images/"; 360} 361 362 363},{"./global/leaflet":10}],6:[function(require,module,exports){ 364"use strict"; 365 366var _leaflet = require("./global/leaflet"); 367 368var _leaflet2 = _interopRequireDefault(_leaflet); 369 370function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 371 372// add texxtsize, textOnly, and style 373_leaflet2["default"].Tooltip.prototype.options.textsize = "10px"; 374_leaflet2["default"].Tooltip.prototype.options.textOnly = false; 375_leaflet2["default"].Tooltip.prototype.options.style = null; // copy original layout to not completely stomp it. 376 377var initLayoutOriginal = _leaflet2["default"].Tooltip.prototype._initLayout; 378 379_leaflet2["default"].Tooltip.prototype._initLayout = function () { 380 initLayoutOriginal.call(this); 381 this._container.style.fontSize = this.options.textsize; 382 383 if (this.options.textOnly) { 384 _leaflet2["default"].DomUtil.addClass(this._container, "leaflet-tooltip-text-only"); 385 } 386 387 if (this.options.style) { 388 for (var property in this.options.style) { 389 this._container.style[property] = this.options.style[property]; 390 } 391 } 392}; 393 394 395},{"./global/leaflet":10}],7:[function(require,module,exports){ 396"use strict"; 397 398var _leaflet = require("./global/leaflet"); 399 400var _leaflet2 = _interopRequireDefault(_leaflet); 401 402function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 403 404var protocolRegex = /^\/\//; 405 406var upgrade_protocol = function upgrade_protocol(urlTemplate) { 407 if (protocolRegex.test(urlTemplate)) { 408 if (window.location.protocol === "file:") { 409 // if in a local file, support http 410 // http should auto upgrade if necessary 411 urlTemplate = "http:" + urlTemplate; 412 } 413 } 414 415 return urlTemplate; 416}; 417 418var originalLTileLayerInitialize = _leaflet2["default"].TileLayer.prototype.initialize; 419 420_leaflet2["default"].TileLayer.prototype.initialize = function (urlTemplate, options) { 421 urlTemplate = upgrade_protocol(urlTemplate); 422 originalLTileLayerInitialize.call(this, urlTemplate, options); 423}; 424 425var originalLTileLayerWMSInitialize = _leaflet2["default"].TileLayer.WMS.prototype.initialize; 426 427_leaflet2["default"].TileLayer.WMS.prototype.initialize = function (urlTemplate, options) { 428 urlTemplate = upgrade_protocol(urlTemplate); 429 originalLTileLayerWMSInitialize.call(this, urlTemplate, options); 430}; 431 432 433},{"./global/leaflet":10}],8:[function(require,module,exports){ 434(function (global){(function (){ 435"use strict"; 436 437Object.defineProperty(exports, "__esModule", { 438 value: true 439}); 440exports["default"] = global.HTMLWidgets; 441 442 443}
443).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 444},{}],9:[function(require,module,exports){ 445(function (global){(function (){ 446"use strict"; 447 448Object.defineProperty(exports, "__esModule", { 449 value: true 450}); 451exports["default"] = global.jQuery; 452 453 454}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 455},{}],10:[function(require,module,exports){ 456(function (global){(function (){ 457"use strict"; 458 459Object.defineProperty(exports, "__esModule", { 460 value: true 461}); 462exports["default"] = global.L; 463 464 465}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 466},{}],11:[function(require,module,exports){ 467(function (global){(function (){ 468"use strict"; 469 470Object.defineProperty(exports, "__esModule", { 471 value: true 472}); 473exports["default"] = global.L.Proj; 474 475 476}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 477},{}],12:[function(require,module,exports){ 478(function (global){(function (){ 479"use strict"; 480 481Object.defineProperty(exports, "__esModule", { 482 value: true 483}); 484exports["default"] = global.Shiny; 485 486 487}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 488},{}],13:[function(require,module,exports){ 489"use strict"; 490 491var _jquery = require("./global/jquery"); 492 493var _jquery2 = _interopRequireDefault(_jquery); 494 495var _leaflet = require("./global/leaflet"); 496 497var _leaflet2 = _interopRequireDefault(_leaflet); 498 499var _shiny = require("./global/shiny"); 500 501var _shiny2 = _interopRequireDefault(_shiny); 502 503var _htmlwidgets = require("./global/htmlwidgets"); 504 505var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets); 506 507var _util = require("./util"); 508 509var _crs_utils = require("./crs_utils"); 510 511var _controlStore = require("./control-store"); 512 513var _controlStore2 = _interopRequireDefault(_controlStore); 514 515var _layerManager = require("./layer-manager"); 516 517var _layerManager2 = _interopRequireDefault(_layerManager); 518 519var _methods = require("./methods"); 520 521var _methods2 = _interopRequireDefault(_methods); 522 523require("./fixup-default-icon"); 524 525require("./fixup-default-tooltip"); 526 527require("./fixup-url-protocol"); 528 529var _dataframe = require("./dataframe"); 530 531var _dataframe2 = _interopRequireDefault(_dataframe); 532 533var _clusterLayerStore = require("./cluster-layer-store"); 534 535var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore); 536 537function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 538 539window.LeafletWidget = {}; 540window.LeafletWidget.utils = {}; 541 542var methods = window.LeafletWidget.methods = _jquery2["default"].extend({}, _methods2["default"]); 543 544window.LeafletWidget.DataFrame = _dataframe2["default"]; 545window.LeafletWidget.ClusterLayerStore = _clusterLayerStore2["default"]; 546window.LeafletWidget.utils.getCRS = _crs_utils.getCRS; // Send updated bounds back to app. Takes a leaflet event object as input. 547 548function updateBounds(map) { 549 var id = map.getContainer().id; 550 var bounds = map.getBounds(); 551 552 _shiny2["default"].onInputChange(id + "_bounds", { 553 north: bounds.getNorthEast().lat, 554 east: bounds.getNorthEast().lng,
555 south: bounds.getSouthWest().lat, 556 west: bounds.getSouthWest().lng 557 }); 558 559 _shiny2["default"].onInputChange(id + "_center", { 560 lng: map.getCenter().lng, 561 lat: map.getCenter().lat 562 }); 563 564 _shiny2["default"].onInputChange(id + "_zoom", map.getZoom()); 565} 566 567function preventUnintendedZoomOnScroll(map) { 568 // Prevent unwanted scroll capturing. Similar in purpose to 569 // https://github.com/CliffCloud/Leaflet.Sleep but with a 570 // different set of heuristics. 571 // The basic idea is that when a mousewheel/DOMMouseScroll 572 // event is seen, we disable scroll wheel zooming until the 573 // user moves their mouse cursor or clicks on the map. This 574 // is slightly trickier than just listening for mousemove, 575 // because mousemove is fired when the page is scrolled, 576 // even if the user did not physically move the mouse. We 577 // handle this by examining the mousemove event's screenX 578 // and screenY properties; if they change, we know it's a 579 // "true" move. 580 // lastScreen can never be null, but its x and y can. 581 var lastScreen = { 582 x: null, 583 y: null 584 }; 585 (0, _jquery2["default"])(document).on("mousewheel DOMMouseScroll", "*", function (e) { 586 // Disable zooming (until the mouse moves or click) 587 map.scrollWheelZoom.disable(); // Any mousemove events at this screen position will be ignored. 588 589 lastScreen = { 590 x: e.originalEvent.screenX, 591 y: e.originalEvent.screenY 592 }; 593 }); 594 (0, _jquery2["default"])(document).on("mousemove", "*", function (e) { 595 // Did the mouse really move? 596 if (lastScreen.x !== null && e.screenX !== lastScreen.x || e.screenY !== lastScreen.y) { 597 // It really moved. Enable zooming. 598 map.scrollWheelZoom.enable(); 599 lastScreen = { 600 x: null, 601 y: null 602 }; 603 } 604 }); 605 (0, _jquery2["default"])(document).on("mousedown", ".leaflet", function (e) { 606 // Clicking always enables zooming. 607 map.scrollWheelZoom.enable(); 608 lastScreen = { 609 x: null, 610 y: null 611 }; 612 }); 613} 614 615_htmlwidgets2["default"].widget({ 616 name: "leaflet", 617 type: "output", 618 factory: function factory(el, width, height) { 619 var map = null; 620 return { 621 // we need to store our map in our returned object. 622 getMap: function getMap() { 623 return map; 624 }, 625 renderValue: function renderValue(data) { 626 // Create an appropriate CRS Object if specified 627 if (data && data.options && data.options.crs) { 628 data.options.crs = (0, _crs_utils.getCRS)(data.options.crs); 629 } // As per https://github.com/rstudio/leaflet/pull/294#discussion_r79584810 630 631 632 if (map) { 633 map.remove(); 634 635 map = function () { 636 return; 637 }(); // undefine map 638 639 } 640 641 if (data.options.mapFactory && typeof data.options.mapFactory === "function") { 642 map = data.options.mapFactory(el, data.options); 643 } else { 644 map = _leaflet2["default"].map(el, data.options); 645 } 646 647 preventUnintendedZoomOnScroll(map); // Store some state in the map object 648 649 map.leafletr = { 650 // Has the map ever rendered successfully? 651 hasRendered: false, 652 // Data to be rendered when resize is called with area != 0 653 pendingRenderData: null 654 }; // Check if the map is rendered statically (no output binding) 655 656 if (_htmlwidgets2["default"].shinyMode && /\bshiny-bound-output\b/.test(el.className)) { 657 map.id = el.id; // Store the map on the element so we can find it later by ID 658 659 (0, _jquery2["default"])(el).data("leaflet-map", map); // When the map is clicked, send the coordinates back to the app 660 661 map.on("click", function (e) { 662 _shiny2["default"].onInputChange(map.id + "_click", { 663 lat: e.latlng.lat, 664 lng: e.latlng.lng, 665 ".nonce": Math.random() // Force reactivity if lat/lng hasn't changed 666 667 }); 668 }); 669 var groupTimerId = null; 670 map.on("moveend", function (e) { 671 updateBounds(e.target); 672 }).on("layeradd layerremove", function (e) { 673 // If the layer that's coming or going is a group we created, tell 674 // the server. 675 if (map.layerManager.getGroupNameFromLayerGroup(e.layer)) { 676 // But to avoid chattiness, coalesce events 677 if (groupTimerId) { 678 clearTimeout(groupTimerId); 679 groupTimerId = null; 680 } 681 682 groupTimerId = setTimeout(function () { 683 groupTimerId = null; 684 685 _shiny2["default"].onInputChange(map.id + "_groups", map.layerManager.getVisibleGroups()); 686 }, 100); 687 } 688 }); 689 } 690 691 this.doRenderValue(data, map); 692 }, 693 doRenderValue: function doRenderValue(data, map) { 694 // Leaflet does not behave well when you set up a bunch of layers when 695 // the map is not visible (width/height == 0). Popups get misaligned 696 // relative to their owning markers, and the fitBounds calculations 697 // are off. Therefore we wait until the map is actually showing to 698 // render the value (we rely on the resize() callback being invoked 699 // at the appropriate time). 700 if (el.offsetWidth === 0 || el.offsetHeight === 0) { 701 map.leafletr.pendingRenderData = data; 702 return; 703 } 704 705 map.leafletr.pendingRenderData = null; // Merge data options into defaults 706 707 var options = _jquery2["default"].extend({ 708 zoomToLimits: "always" 709 }, data.options); 710 711 if (!map.layerManager) { 712 map.controls = new _controlStore2["default"](map); 713 map.layerManager = new _layerManager2["default"](map); 714 } else { 715 map.controls.clear(); 716 map.layerManager.clear(); 717 } 718 719 var explicitView = false;
720 721 if (data.setView) { 722 explicitView = true; 723 map.setView.apply(map, data.setView); 724 } 725 726 if (data.fitBounds) { 727 explicitView = true; 728 methods.fitBounds.apply(map, data.fitBounds); 729 } 730 731 if (data.flyTo) { 732 if (!explicitView && !map.leafletr.hasRendered) { 733 // must be done to give a initial starting point 734 map.fitWorld(); 735 } 736 737 explicitView = true; 738 map.flyTo.apply(map, data.flyTo); 739 } 740 741 if (data.flyToBounds) { 742 if (!explicitView && !map.leafletr.hasRendered) { 743 // must be done to give a initial starting point 744 map.fitWorld(); 745 } 746 747 explicitView = true; 748 methods.flyToBounds.apply(map, data.flyToBounds); 749 } 750 751 if (data.options.center) { 752 explicitView = true; 753 } // Returns true if the zoomToLimits option says that the map should be 754 // zoomed to map elements. 755 756 757 function needsZoom() { 758 return options.zoomToLimits === "always" || options.zoomToLimits === "first" && !map.leafletr.hasRendered; 759 } 760 761 if (!explicitView && needsZoom() && !map.getZoom()) { 762 if (data.limits && !_jquery2["default"].isEmptyObject(data.limits)) { 763 // Use the natural limits of what's being drawn on the map 764 // If the size of the bounding box is 0, leaflet gets all weird 765 var pad = 0.006; 766 767 if (data.limits.lat[0] === data.limits.lat[1]) { 768 data.limits.lat[0] = data.limits.lat[0] - pad; 769 data.limits.lat[1] = data.limits.lat[1] + pad; 770 } 771 772 if (data.limits.lng[0] === data.limits.lng[1]) { 773 data.limits.lng[0] = data.limits.lng[0] - pad; 774 data.limits.lng[1] = data.limits.lng[1] + pad; 775 } 776 777 map.fitBounds([[data.limits.lat[0], data.limits.lng[0]], [data.limits.lat[1], data.limits.lng[1]]]); 778 } else { 779 map.fitWorld(); 780 } 781 } 782 783 for (var i = 0; data.calls && i < data.calls.length; i++) { 784 var call = data.calls[i]; 785 if (methods[call.method]) methods[call.method].apply(map, call.args);else (0, _util.log)("Unknown method " + call.method); 786 } 787 788 map.leafletr.hasRendered = true; 789 790 if (_htmlwidgets2["default"].shinyMode) { 791 setTimeout(function () { 792 updateBounds(map); 793 }, 1); 794 } 795 }, 796 resize: function resize(width, height) { 797 if (map) { 798 map.invalidateSize(); 799 800 if (map.leafletr.pendingRenderData) { 801 this.doRenderValue(map.leafletr.pendingRenderData, map); 802 } 803 } 804 } 805 }; 806 } 807}); 808 809if (_htmlwidgets2["default"].shinyMode) { 810 _shiny2["default"].addCustomMessageHandler("leaflet-calls", function (data) { 811 var id = data.id; 812 var el = document.getElementById(id); 813 var map = el ? (0, _jquery2["default"])(el).data("leaflet-map") : null; 814 815 if (!map) { 816 (0, _util.log)("Couldn't find map with id " + id); 817 return; 818 } // If the map has not rendered, stash the proposed `leafletProxy()` calls 819 // in `pendingRenderData.calls` to be run on display via `doRenderValue()`. 820 // This is necessary if the map has not been rendered. 821 // If new pendingRenderData is set via a new `leaflet()`, the previous calls will be discarded. 822 823 824 if (!map.leafletr.hasRendered) { 825 map.leafletr.pendingRenderData.calls = map.leafletr.pendingRenderData.calls.concat(data.calls); 826 return; 827 } 828 829 for (var i = 0; i < data.calls.length; i++) { 830 var call = data.calls[i]; 831 var args = call.args; 832 833 for (var _i = 0; _i < call.evals.length; _i++) { 834 window.HTMLWidgets.evaluateStringMember(args, call.evals[_i]); 835 } 836 837 if (call.dependencies) { 838 _shiny2["default"].renderDependencies(call.dependencies); 839 } 840 841 if (methods[call.method]) methods[call.method].apply(map, args);else (0, _util.log)("Unknown method " + call.method); 842 } 843 }); 844} 845 846 847},{"./cluster-layer-store":1,"./control-store":2,"./crs_utils":3,"./dataframe":4,"./fixup-default-icon":5,"./fixup-default-tooltip":6,"./fixup-url-protocol":7,"./global/htmlwidgets":8,"./global/jquery":9,"./global/leaflet":10,"./global/shiny":12,"./layer-manager"
847:14,"./methods":15,"./util":17}],14:[function(require,module,exports){ 848(function (global){(function (){ 849"use strict"; 850 851Object.defineProperty(exports, "__esModule", { 852 value: true 853}); 854exports["default"] = undefined; 855 856var _jquery = require("./global/jquery"); 857 858var _jquery2 = _interopRequireDefault(_jquery); 859 860var _leaflet = require("./global/leaflet"); 861 862var _leaflet2 = _interopRequireDefault(_leaflet); 863 864var _util = require("./util"); 865 866function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 867 868function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 869 870function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 871 872function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 873 874var LayerManager = /*#__PURE__*/function () { 875 function LayerManager(map) { 876 _classCallCheck(this, LayerManager); 877 878 this._map = map; // BEGIN layer indices 879 // {<groupname>: {<stamp>: layer}} 880 881 this._byGroup = {}; // {<categoryName>: {<stamp>: layer}} 882 883 this._byCategory = {}; // {<categoryName_layerId>: layer} 884 885 this._byLayerId = {}; // {<stamp>: { 886 // "group": <groupname>, 887 // "layerId": <layerId>, 888 // "category": <category>, 889 // "container": <container> 890 // } 891 // } 892 893 this._byStamp = {}; // {<crosstalkGroupName>: {<key>: [<stamp>, <stamp>, ...], ...}} 894 895 this._byCrosstalkGroup = {}; // END layer indices 896 // {<categoryName>: L.layerGroup} 897 898 this._categoryContainers = {}; // {<groupName>: L.layerGroup} 899 900 this._groupContainers = {}; 901 } 902 903 _createClass(LayerManager, [{ 904 key: "addLayer", 905 value: function addLayer(layer, category, layerId, group, ctGroup, ctKey) { 906 var _this = this; 907 908 // Was a group provided? 909 var hasId = typeof layerId === "string"; 910 var grouped = typeof group === "string"; 911 var stamp = _leaflet2["default"].Util.stamp(layer) + ""; // This will be the default layer group to add the layer to. 912 // We may overwrite this let before using it (i.e. if a group is assigned). 913 // This one liner creates the _categoryContainers[category] entry if it 914 // doesn't already exist. 915 916 var container = this._categoryContainers[category] = this._categoryContainers[category] || _leaflet2["default"].layerGroup().addTo(this._map); 917 918 var oldLayer = null; 919 920 if (hasId) { 921 // First, remove any layer with the same category and layerId 922 var prefixedLayerId = this._layerIdKey(category, layerId); 923 924 oldLayer = this._byLayerId[prefixedLayerId]; 925 926 if (oldLayer) { 927 this._removeLayer(oldLayer); 928 } // Update layerId index 929 930 931 this._byLayerId[prefixedLayerId] = layer; 932 } // Update group index 933 934 935 if (grouped) { 936 this._byGroup[group] = this._byGroup[group] || {}; 937 this._byGroup[group][stamp] = layer; // Since a group is assigned, don't add the layer to the category's layer 938 // group; instead, use the group's layer group. 939 // This one liner creates the _groupContainers[group] entry if it doesn't 940 // already exist. 941 942 container = this.getLayerGroup(group, true); 943 } // Update category index 944 945 946 this._byCategory[category] = this._byCategory[category] || {}; 947 this._byCategory[category][stamp] = layer; // Update stamp index 948 949 var layerInfo = this._byStamp[stamp] = { 950 layer: layer, 951 group: group, 952 ctGroup: ctGroup, 953 ctKey: ctKey, 954 layerId: layerId, 955 category: category, 956 container: container, 957 hidden: false 958 }; // Update crosstalk group index 959 960 if (ctGroup) { 961 if (layer.setStyle) {
962 // Need to save this info so we know what to set opacity to later 963 layer.options.origOpacity = typeof layer.options.opacity !== "undefined" ? layer.options.opacity : 0.5; 964 layer.options.origFillOpacity = typeof layer.options.fillOpacity !== "undefined" ? layer.options.fillOpacity : 0.2; 965 } 966 967 var ctg = this._byCrosstalkGroup[ctGroup]; 968 969 if (!ctg) { 970 ctg = this._byCrosstalkGroup[ctGroup] = {}; 971 var crosstalk = global.crosstalk; 972 973 var handleFilter = function handleFilter(e) { 974 if (!e.value) { 975 var groupKeys = Object.keys(ctg); 976 977 for (var i = 0; i < groupKeys.length; i++) { 978 var key = groupKeys[i]; 979 var _layerInfo = _this._byStamp[ctg[key]]; 980 981 _this._setVisibility(_layerInfo, true); 982 } 983 } else { 984 var selectedKeys = {}; 985 986 for (var _i = 0; _i < e.value.length; _i++) { 987 selectedKeys[e.value[_i]] = true; 988 } 989 990 var _groupKeys = Object.keys(ctg); 991 992 for (var _i2 = 0; _i2 < _groupKeys.length; _i2++) { 993 var _key = _groupKeys[_i2]; 994 var _layerInfo2 = _this._byStamp[ctg[_key]]; 995 996 _this._setVisibility(_layerInfo2, selectedKeys[_groupKeys[_i2]]); 997 } 998 } 999 }; 1000 1001 var filterHandle = new crosstalk.FilterHandle(ctGroup); 1002 filterHandle.on("change", handleFilter); 1003 1004 var handleSelection = function handleSelection(e) { 1005 if (!e.value || !e.value.length) { 1006 var groupKeys = Object.keys(ctg); 1007 1008 for (var i = 0; i < groupKeys.length; i++) { 1009 var key = groupKeys[i]; 1010 var _layerInfo3 = _this._byStamp[ctg[key]]; 1011 1012 _this._setOpacity(_layerInfo3, 1.0); 1013 } 1014 } else { 1015 var selectedKeys = {}; 1016 1017 for (var _i3 = 0; _i3 < e.value.length; _i3++) { 1018 selectedKeys[e.value[_i3]] = true; 1019 } 1020 1021 var _groupKeys2 = Object.keys(ctg); 1022 1023 for (var _i4 = 0; _i4 < _groupKeys2.length; _i4++) { 1024 var _key2 = _groupKeys2[_i4]; 1025 var _layerInfo4 = _this._byStamp[ctg[_key2]]; 1026 1027 _this._setOpacity(_layerInfo4, selectedKeys[_groupKeys2[_i4]] ? 1.0 : 0.2); 1028 } 1029 } 1030 }; 1031 1032 var selHandle = new crosstalk.SelectionHandle(ctGroup); 1033 selHandle.on("change", handleSelection); 1034 setTimeout(function () { 1035 handleFilter({ 1036 value: filterHandle.filteredKeys 1037 }); 1038 handleSelection({ 1039 value: selHandle.value 1040 }); 1041 }, 100); 1042 } 1043 1044 if (!ctg[ctKey]) ctg[ctKey] = []; 1045 ctg[ctKey].push(stamp); 1046 } // Add to container 1047 1048 1049 if (!layerInfo.hidden) container.addLayer(layer); 1050 return oldLayer; 1051 } 1052 }, { 1053 key: "brush", 1054 value: function brush(bounds, extraInfo) { 1055 var _this2 = this; 1056 1057 /* eslint-disable no-console */ 1058 // For each Crosstalk group... 1059 Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) { 1060 var ctg = _this2._byCrosstalkGroup[ctGroupName]; 1061 var selection = []; // ...iterate over each Crosstalk key (each of which may have multiple 1062 // layers)... 1063 1064 Object.keys(ctg).forEach(function (ctKey) { 1065 // ...and for each layer... 1066 ctg[ctKey].forEach(function (stamp) { 1067 var layerInfo = _this2._byStamp[stamp]; // ...if it's something with a point... 1068 1069 if (layerInfo.layer.getLatLng) { 1070 // ... and it's inside the selection bounds... 1071 // TODO: Use pixel containment, not lat/lng containment 1072 if (bounds.contains(layerInfo.layer.getLatLng())) { 1073 // ...add the key to the selection. 1074 selection.push(ctKey); 1075 } 1076 } 1077 }); 1078 }); 1079 new global.crosstalk.SelectionHandle(ctGroupName).set(selection, extraInfo); 1080 }); 1081 } 1082 }, { 1083 key: "unbrush", 1084 value: function unbrush(extraInfo) {
1085 Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) { 1086 new global.crosstalk.SelectionHandle(ctGroupName).clear(extraInfo); 1087 }); 1088 } 1089 }, { 1090 key: "_setVisibility", 1091 value: function _setVisibility(layerInfo, visible) { 1092 if (layerInfo.hidden ^ visible) { 1093 return; 1094 } else if (visible) { 1095 layerInfo.container.addLayer(layerInfo.layer); 1096 layerInfo.hidden = false; 1097 } else { 1098 layerInfo.container.removeLayer(layerInfo.layer); 1099 layerInfo.hidden = true; 1100 } 1101 } 1102 }, { 1103 key: "_setOpacity", 1104 value: function _setOpacity(layerInfo, opacity) { 1105 if (layerInfo.layer.setOpacity) { 1106 layerInfo.layer.setOpacity(opacity); 1107 } else if (layerInfo.layer.setStyle) { 1108 layerInfo.layer.setStyle({ 1109 opacity: opacity * layerInfo.layer.options.origOpacity, 1110 fillOpacity: opacity * layerInfo.layer.options.origFillOpacity 1111 }); 1112 } 1113 } 1114 }, { 1115 key: "getLayer", 1116 value: function getLayer(category, layerId) { 1117 return this._byLayerId[this._layerIdKey(category, layerId)]; 1118 } 1119 }, { 1120 key: "removeLayer", 1121 value: function removeLayer(category, layerIds) { 1122 var _this3 = this; 1123 1124 // Find layer info 1125 _jquery2["default"].each((0, _util.asArray)(layerIds), function (i, layerId) { 1126 var layer = _this3._byLayerId[_this3._layerIdKey(category, layerId)]; 1127 1128 if (layer) { 1129 _this3._removeLayer(layer); 1130 } 1131 }); 1132 } 1133 }, { 1134 key: "clearLayers", 1135 value: function clearLayers(category) { 1136 var _this4 = this; 1137 1138 // Find all layers in _byCategory[category] 1139 var catTable = this._byCategory[category]; 1140 1141 if (!catTable) { 1142 return false; 1143 } // Remove all layers. Make copy of keys to avoid mutating the collection 1144 // behind the iterator you're accessing. 1145 1146 1147 var stamps = []; 1148 1149 _jquery2["default"].each(catTable, function (k, v) { 1150 stamps.push(k); 1151 }); 1152 1153 _jquery2["default"].each(stamps, function (i, stamp) { 1154 _this4._removeLayer(stamp); 1155 }); 1156 } 1157 }, { 1158 key: "getLayerGroup", 1159 value: function getLayerGroup(group, ensureExists) { 1160 var g = this._groupContainers[group]; 1161 1162 if (ensureExists && !g) { 1163 this._byGroup[group] = this._byGroup[group] || {}; 1164 g = this._groupContainers[group] = _leaflet2["default"].featureGroup(); 1165 g.groupname = group; 1166 g.addTo(this._map); 1167 } 1168 1169 return g; 1170 } 1171 }, { 1172 key: "getGroupNameFromLayerGroup", 1173 value: function getGroupNameFromLayerGroup(layerGroup) { 1174 return layerGroup.groupname; 1175 } 1176 }, { 1177 key: "getVisibleGroups", 1178 value: function getVisibleGroups() { 1179 var _this5 = this; 1180 1181 var result = []; 1182 1183 _jquery2["default"].each(this._groupContainers, function (k, v) { 1184 if (_this5._map.hasLayer(v)) { 1185 result.push(k); 1186 } 1187 }); 1188 1189 return result; 1190 } 1191 }, { 1192 key: "getAllGroupNames", 1193 value: function getAllGroupNames() { 1194 var result = []; 1195 1196 _jquery2["default"].each(this._groupContainers, function (k, v) { 1197 result.push(k); 1198 }); 1199 1200 return result; 1201 } 1202 }, { 1203 key: "clearGroup", 1204 value: function clearGroup(group) { 1205 var _this6 = this; 1206 1207 // Find all layers in _byGroup[group] 1208 var groupTable = this._byGroup[group]; 1209 1210 if (!groupTable) { 1211 return false; 1212 } // Remove all layers. Make copy of keys to avoid mutating the collection 1213 // behind the iterator you're accessing. 1214 1215 1216 var stamps = []; 1217 1218 _jquery2["default"].each(groupTable, function (k, v) { 1219 stamps.push(k); 1220 }); 1221 1222 _jquery2["default"].each(stamps, function (i, stamp) { 1223 _this6._removeLayer(stamp); 1224 }); 1225 } 1226 }, { 1227 key: "clear", 1228 value: function clear() { 1229 function clearLayerGroup(key, layerGroup) { 1230 layerGroup.clearLayers(); 1231 } // Clear all indices and layerGroups 1232 1233 1234 this._byGroup = {}; 1235 this._byCategory = {}; 1236 this._byLayerId = {}; 1237 this._byStamp = {}; 1238 this._byCrosstalkGroup = {}; 1239 1240 _jquery2["default"].each(this._categoryContainers, clearLayerGroup); 1241 1242 this._categoryContainers = {}; 1243 1244 _jquery2["default"].each(this._groupContainers, clearLayerGroup); 1245 1246 this._groupContainers = {}; 1247 } 1248 }, { 1249 key: "_removeLayer", 1250 value: function _removeLayer(layer) { 1251 var stamp; 1252 1253 if (typeof layer === "string") { 1254 stamp = layer; 1255 } else { 1256 stamp = _leaflet2["default"].Util.stamp(layer); 1257 } 1258 1259 var layerInfo = this._byStamp[stamp]; 1260 1261 if (!layerInfo) { 1262 return false;
1263 } 1264 1265 layerInfo.container.removeLayer(stamp); 1266 1267 if (typeof layerInfo.group === "string") { 1268 delete this._byGroup[layerInfo.group][stamp]; 1269 } 1270 1271 if (typeof layerInfo.layerId === "string") { 1272 delete this._byLayerId[this._layerIdKey(layerInfo.category, layerInfo.layerId)]; 1273 } 1274 1275 delete this._byCategory[layerInfo.category][stamp]; 1276 delete this._byStamp[stamp]; 1277 1278 if (layerInfo.ctGroup) { 1279 var ctGroup = this._byCrosstalkGroup[layerInfo.ctGroup]; 1280 var layersForKey = ctGroup[layerInfo.ctKey]; 1281 var idx = layersForKey ? layersForKey.indexOf(stamp) : -1; 1282 1283 if (idx >= 0) { 1284 if (layersForKey.length === 1) { 1285 delete ctGroup[layerInfo.ctKey]; 1286 } else { 1287 layersForKey.splice(idx, 1); 1288 } 1289 } 1290 } 1291 } 1292 }, { 1293 key: "_layerIdKey", 1294 value: function _layerIdKey(category, layerId) { 1295 return category + "\n" + layerId; 1296 } 1297 }]); 1298 1299 return LayerManager; 1300}(); 1301 1302exports["default"] = LayerManager; 1303 1304 1305}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 1306},{"./global/jquery":9,"./global/leaflet":10,"./util":17}],15:[function(require,module,exports){ 1307(function (global){(function (){ 1308"use strict"; 1309 1310Object.defineProperty(exports, "__esModule", { 1311 value: true 1312}); 1313 1314var _jquery = require("./global/jquery"); 1315 1316var _jquery2 = _interopRequireDefault(_jquery); 1317 1318var _leaflet = require("./global/leaflet"); 1319 1320var _leaflet2 = _interopRequireDefault(_leaflet); 1321 1322var _shiny = require("./global/shiny"); 1323 1324var _shiny2 = _interopRequireDefault(_shiny); 1325 1326var _htmlwidgets = require("./global/htmlwidgets"); 1327 1328var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets); 1329 1330var _util = require("./util"); 1331 1332var _crs_utils = require("./crs_utils"); 1333 1334var _dataframe = require("./dataframe"); 1335 1336var _dataframe2 = _interopRequireDefault(_dataframe); 1337 1338var _clusterLayerStore = require("./cluster-layer-store"); 1339 1340var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore); 1341 1342var _mipmapper = require("./mipmapper"); 1343 1344var _mipmapper2 = _interopRequireDefault(_mipmapper); 1345 1346function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 1347 1348var methods = {}; 1349exports["default"] = methods; 1350 1351function mouseHandler(mapId, layerId, group, eventName, extraInfo) { 1352 return function (e) { 1353 if (!_htmlwidgets2["default"].shinyMode) return; 1354 var latLng = e.target.getLatLng ? e.target.getLatLng() : e.latlng; 1355 1356 if (latLng) { 1357 // retrieve only lat, lon values to remove prototype 1358 // and extra parameters added by 3rd party modules 1359 // these objects are for json serialization, not javascript 1360 var latLngVal = _leaflet2["default"].latLng(latLng); // make sure it has consistent shape 1361 1362 1363 latLng = { 1364 lat: latLngVal.lat, 1365 lng: latLngVal.lng 1366 }; 1367 } 1368 1369 var eventInfo = _jquery2["default"].extend({ 1370 id: layerId, 1371 ".nonce": Math.random() // force reactivity 1372 1373 }, group !== null ? { 1374 group: group 1375 } : null, latLng, extraInfo); 1376 1377 _shiny2["default"].onInputChange(mapId + "_" + eventName, eventInfo); 1378 }; 1379} 1380 1381methods.mouseHandler = mouseHandler; 1382 1383methods.clearGroup = function (group) { 1384 var _this = this; 1385 1386 _jquery2["default"].each((0, _util.asArray)(group), function (i, v) { 1387 _this.layerManager.clearGroup(v); 1388 }); 1389}; 1390 1391methods.setView = function (center, zoom, options) { 1392 this.setView(center, zoom, options); 1393}; 1394 1395methods.fitBounds = function (lat1, lng1, lat2, lng2, options) { 1396 this.fitBounds([[lat1, lng1], [lat2, lng2]], options); 1397}; 1398 1399methods.flyTo = function (center, zoom, options) { 1400 this.flyTo(center, zoom, options); 1401}; 1402 1403methods.flyToBounds = function (lat1, lng1, lat2, lng2, options) { 1404 this.flyToBounds([[lat1, lng1], [lat2, lng2]], options); 1405}; 1406 1407methods.setMaxBounds = function (lat1, lng1, lat2, lng2) { 1408 this.setMaxBounds([[lat1, lng1], [lat2, lng2]]); 1409}; 1410 1411methods.addPopups = function (lat, lng, popup, layerId, group, options) { 1412 var _this2 = this; 1413 1414 var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("popup", popup).col("layerId", layerId).col("group", group).cbind(options); 1415 1416 var _loop = function _loop(i) { 1417 if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) { 1418 (function () {
1419 var popup = _leaflet2["default"].popup(df.get(i)).setLatLng([df.get(i, "lat"), df.get(i, "lng")]).setContent(df.get(i, "popup")); 1420 1421 var thisId = df.get(i, "layerId"); 1422 var thisGroup = df.get(i, "group"); 1423 this.layerManager.addLayer(popup, "popup", thisId, thisGroup); 1424 }).call(_this2); 1425 } 1426 }; 1427 1428 for (var i = 0; i < df.nrow(); i++) { 1429 _loop(i); 1430 } 1431}; 1432 1433methods.removePopup = function (layerId) { 1434 this.layerManager.removeLayer("popup", layerId); 1435}; 1436 1437methods.clearPopups = function () { 1438 this.layerManager.clearLayers("popup"); 1439}; 1440 1441methods.addTiles = function (urlTemplate, layerId, group, options) { 1442 this.layerManager.addLayer(_leaflet2["default"].tileLayer(urlTemplate, options), "tile", layerId, group); 1443}; 1444 1445methods.removeTiles = function (layerId) { 1446 this.layerManager.removeLayer("tile", layerId); 1447}; 1448 1449methods.clearTiles = function () { 1450 this.layerManager.clearLayers("tile"); 1451}; 1452 1453methods.addWMSTiles = function (baseUrl, layerId, group, options) { 1454 if (options && options.crs) { 1455 options.crs = (0, _crs_utils.getCRS)(options.crs); 1456 } 1457 1458 this.layerManager.addLayer(_leaflet2["default"].tileLayer.wms(baseUrl, options), "tile", layerId, group); 1459}; // Given: 1460// {data: ["a", "b", "c"], index: [0, 1, 0, 2]} 1461// returns: 1462// ["a", "b", "a", "c"] 1463 1464 1465function unpackStrings(iconset) { 1466 if (!iconset) { 1467 return iconset; 1468 } 1469 1470 if (typeof iconset.index === "undefined") { 1471 return iconset; 1472 } 1473 1474 iconset.data = (0, _util.asArray)(iconset.data); 1475 iconset.index = (0, _util.asArray)(iconset.index); 1476 return _jquery2["default"].map(iconset.index, function (e, i) { 1477 return iconset.data[e]; 1478 }); 1479} 1480 1481function addMarkers(map, df, group, clusterOptions, clusterId, markerFunc) { 1482 (function () { 1483 var _this3 = this; 1484 1485 var clusterGroup = this.layerManager.getLayer("cluster", clusterId), 1486 cluster = clusterOptions !== null; 1487 1488 if (cluster && !clusterGroup) { 1489 clusterGroup = _leaflet2["default"].markerClusterGroup.layerSupport(clusterOptions); 1490 1491 if (clusterOptions.freezeAtZoom) { 1492 var freezeAtZoom = clusterOptions.freezeAtZoom; 1493 delete clusterOptions.freezeAtZoom; 1494 clusterGroup.freezeAtZoom(freezeAtZoom); 1495 } 1496 1497 clusterGroup.clusterLayerStore = new _clusterLayerStore2["default"](clusterGroup); 1498 } 1499 1500 var extraInfo = cluster ? { 1501 clusterId: clusterId 1502 } : {}; 1503 1504 var _loop2 = function _loop2(i) { 1505 if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) { 1506 (function () { 1507 var marker = markerFunc(df, i); 1508 var thisId = df.get(i, "layerId"); 1509 var thisGroup = cluster ? null : df.get(i, "group"); 1510 1511 if (cluster) { 1512 clusterGroup.clusterLayerStore.add(marker, thisId); 1513 } else { 1514 this.layerManager.addLayer(marker, "marker", thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true)); 1515 } 1516 1517 var popup = df.get(i, "popup"); 1518 var popupOptions = df.get(i, "popupOptions"); 1519 1520 if (popup !== null) { 1521 if (popupOptions !== null) { 1522 marker.bindPopup(popup, popupOptions); 1523 } else { 1524 marker.bindPopup(popup); 1525 } 1526 } 1527 1528 var label = df.get(i, "label"); 1529 var labelOptions = df.get(i, "labelOptions"); 1530 1531 if (label !== null) { 1532 if (labelOptions !== null) { 1533 if (labelOptions.permanent) { 1534 marker.bindTooltip(label, labelOptions).openTooltip(); 1535 } else { 1536 marker.bindTooltip(label, labelOptions); 1537 } 1538 } else { 1539 marker.bindTooltip(label); 1540 } 1541 } 1542 1543 marker.on("click", mouseHandler(this.id, thisId, thisGroup, "marker_click", extraInfo), this); 1544 marker.on("mouseover", mouseHandler(this.id, thisId, thisGroup, "marker_mouseover", extraInfo), this); 1545 marker.on("mouseout", mouseHandler(this.id, thisId, thisGroup, "marker_mouseout", extraInfo), this); 1546 marker.on("dragend", mouseHandler(this.id, thisId, thisGroup, "marker_dragend", extraInfo), this); 1547 }).call(_this3); 1548 } 1549 }; 1550 1551 for (var i = 0; i < df.nrow(); i++) { 1552 _loop2(i); 1553 } 1554 1555 if (cluster) { 1556 this.layerManager.addLayer(clusterGroup, "cluster", clusterId, group); 1557 } 1558 }).call(map); 1559} 1560 1561methods.addGenericMarkers = addMarkers; 1562 1563methods.addMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) { 1564 var icondf; 1565 var getIcon; 1566 1567 if (icon) { 1568 // Unpack icons 1569 icon.iconUrl = unpackStrings(icon.iconUrl); 1570 icon.iconRetinaUrl = unpackStrings(icon.iconRetinaUrl); 1571 icon.shadowUrl = unpackStrings(icon.shadowUrl); 1572 icon.shadowRetinaUrl = unpackStrings(icon.shadowRetinaUrl); // This cbinds the icon URLs and any other icon options; they're all 1573 // present on the icon object. 1574 1575 icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe. 1576 1577 getIcon = function getIcon(i) { 1578 var opts = icondf.get(i); 1579 1580 if (!opts.iconUrl) { 1581 return new _leaflet2["default"].Icon.Default(); 1582 } // Composite options (like points or sizes) are passed from R with each 1583 // individual component as its own option. We need to combine them now 1584 // into their composite form. 1585 1586 1587 if (opts.iconWidth) { 1588 opts.iconSize = [opts.iconWidth, opts.iconHeight]; 1589 } 1590 1591 if (opts.shadowWidth) { 1592 opts.shadowSize = [opts.shadowWidth, opts.shadowHeight]; 1593 } 1594 1595 if (opts.iconAnchorX) { 1596 opts.iconAnchor = [opts.iconAnchorX, opts.iconAnchorY]; 1597 } 1598 1599 if (opts.shadowAnchorX) { 1600 opts.shadowAnchor = [opts.shadowAnchorX, opts.shadowAnchorY]; 1601 } 1602 1603 if (opts.popupAnchorX) { 1604 opts.popupAnchor = [opts.popupAnchorX, opts.popupAnchorY]; 1605 } 1606 1607 return new _leaflet2["default"].Icon(opts); 1608 }; 1609 } 1610 1611 if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) { 1612 var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(options).cbind(crosstalkOptions || {}); 1613 if (icon) icondf.effectiveLength = df.nrow(); 1614 addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) { 1615 var options = df.get(i); 1616 if (icon) options.icon = getIcon(i); 1617 return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options); 1618 }); 1619 } 1620}; 1621 1622methods.addAwesomeMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) { 1623 var icondf; 1624 var getIcon; 1625 1626 if (icon) { 1627 // This cbinds the icon URLs and any other icon options; they're all 1628 // present on the icon object. 1629 icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe. 1630 1631 getIcon = function getIcon(i) { 1632 var opts = icondf.get(i); 1633 1634 if (!opts) { 1635 return new _leaflet2["default"].AwesomeMarkers.icon(); 1636 } 1637 1638 if (opts.squareMarker) { 1639 opts.className = "awesome-marker awesome-marker-square"; 1640 } 1641 1642 return new _leaflet2["default"].AwesomeMarkers.icon(opts); 1643 }; 1644 } 1645 1646 if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) { 1647 var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(options).cbind(crosstalkOptions || {}); 1648 if (icon) icondf.effectiveLength = df.nrow(); 1649 addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) { 1650 var options = df.get(i); 1651 if (icon) options.icon = getIcon(i); 1652 return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options); 1653 }); 1654 } 1655}; 1656 1657function addLayers(map, category, df, layerFunc) { 1658 var _loop3 = function _loop3(i) { 1659 (function () { 1660 var layer = layerFunc(df, i); 1661 1662 if (!_jquery2["default"].isEmptyObject(layer)) { 1663 var thisId = df.get(i, "layerId"); 1664 var thisGroup = df.get(i, "group"); 1665 this.layerManager.addLayer(layer, category, thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true)); 1666 1667 if (layer.bindPopup) { 1668 var popup = df.get(i, "popup"); 1669 var popupOptions = df.get(i, "popupOptions"); 1670 1671 if (popup !== null) { 1672 if (popupOptions !== null) { 1673 layer.bindPopup(popup, popupOptions); 1674 } else { 1675 layer.bindPopup(popup); 1676 } 1677 } 1678 } 1679 1680 if (layer.bindTooltip) { 1681 var label = df.get(i, "label"); 1682 var labelOptions = df.get(i, "labelOptions"); 1683 1684 if (label !== null) { 1685 if (labelOptions !== null) { 1686 layer.bindTooltip(label, labelOptions); 1687 } else { 1688 layer.bindTooltip(label); 1689 } 1690 } 1691 } 1692 1693 layer.on("click", mouseHandler(this.id, thisId, thisGroup, category + "_click"), this);
1694 layer.on("mouseover", mouseHandler(this.id, thisId, thisGroup, category + "_mouseover"), this); 1695 layer.on("mouseout", mouseHandler(this.id, thisId, thisGroup, category + "_mouseout"), this); 1696 var highlightStyle = df.get(i, "highlightOptions"); 1697 1698 if (!_jquery2["default"].isEmptyObject(highlightStyle)) { 1699 var defaultStyle = {}; 1700 1701 _jquery2["default"].each(highlightStyle, function (k, v) { 1702 if (k != "bringToFront" && k != "sendToBack") { 1703 if (df.get(i, k)) { 1704 defaultStyle[k] = df.get(i, k); 1705 } 1706 } 1707 }); 1708 1709 layer.on("mouseover", function (e) { 1710 this.setStyle(highlightStyle); 1711 1712 if (highlightStyle.bringToFront) { 1713 this.bringToFront(); 1714 } 1715 }); 1716 layer.on("mouseout", function (e) { 1717 this.setStyle(defaultStyle); 1718 1719 if (highlightStyle.sendToBack) { 1720 this.bringToBack(); 1721 } 1722 }); 1723 } 1724 } 1725 }).call(map); 1726 }; 1727 1728 for (var i = 0; i < df.nrow(); i++) { 1729 _loop3(i); 1730 } 1731} 1732 1733methods.addGenericLayers = addLayers; 1734 1735methods.addCircles = function (lat, lng, radius, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions, crosstalkOptions) { 1736 if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) { 1737 var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("radius", radius).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options).cbind(crosstalkOptions || {}); 1738 addLayers(this, "shape", df, function (df, i) { 1739 if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng")) && _jquery2["default"].isNumeric(df.get(i, "radius"))) { 1740 return _leaflet2["default"].circle([df.get(i, "lat"), df.get(i, "lng")], df.get(i, "radius"), df.get(i)); 1741 } else { 1742 return null; 1743 } 1744 }); 1745 } 1746}; 1747 1748methods.addCircleMarkers = function (lat, lng, radius, layerId, group, options, clusterOptions, clusterId, popup, popupOptions, label, labelOptions, crosstalkOptions) { 1749 if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) { 1750 var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("radius", radius).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(crosstalkOptions || {}).cbind(options); 1751 addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) { 1752 return _leaflet2["default"].circleMarker([df.get(i, "lat"), df.get(i, "lng")], df.get(i)); 1753 }); 1754 } 1755}; 1756/* 1757 * @param lat Array of arrays of latitude coordinates for polylines 1758 * @param lng Array of arrays of longitude coordinates for polylines 1759 */ 1760 1761 1762methods.addPolylines = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) { 1763 if (polygons.length > 0) { 1764 var df = new _dataframe2["default"]().col("shapes", polygons).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options); 1765 addLayers(this, "shape", df, function (df, i) { 1766 var shapes = df.get(i, "shapes"); 1767 shapes = shapes.map(function (shape) { 1768 return _htmlwidgets2["default"].dataframeToD3(shape[0]); 1769 }); 1770 1771 if (shapes.length > 1) { 1772 return _leaflet2["default"].polyline(shapes, df.get(i)); 1773 } else { 1774 return _leaflet2["default"].polyline(shapes[0], df.get(i)); 1775 } 1776 }); 1777 } 1778}; 1779 1780methods.removeMarker = function (layerId) { 1781 this.layerManager.removeLayer("marker", layerId); 1782}; 1783 1784methods.clearMarkers = function () { 1785 this.layerManager.clearLayers("marker"); 1786}; 1787 1788methods.removeMarkerCluster = function (layerId) { 1789 this.layerManager.removeLayer("cluster", layerId); 1790}; 1791 1792methods.removeMarkerFromCluster = function (layerId, clusterId) { 1793 var cluster = this.layerManager.getLayer("cluster", clusterId); 1794 if (!cluster) return; 1795 cluster.clusterLayerStore.remove(layerId); 1796}; 1797 1798methods.clearMarkerClusters = function () { 1799 this.layerManager.clearLayers("cluster"); 1800}; 1801 1802methods.removeShape = function (layerId) { 1803 this.layerManager.removeLayer("shape", layerId); 1804}; 1805 1806methods.clearShapes = function () { 1807 this.layerManager.clearLayers("shape"); 1808}; 1809 1810methods.addRectangles = function (lat1, lng1, lat2, lng2, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1811 var df = new _dataframe2["default"]().col("lat1", lat1).col("lng1", lng1).col("lat2", lat2).col("lng2", lng2).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options); 1812 addLayers(this, "shape", df, function (df, i) { 1813 if (_jquery2["default"].isNumeric(df.get(i, "lat1")) && _jquery2["default"].isNumeric(df.get(i, "lng1")) && _jquery2["default"].isNumeric(df.get(i, "lat2")) && _jquery2["default"].isNumeric(df.get(i, "lng2"))) { 1814 return _leaflet2["default"].rectangle([[df.get(i, "lat1"), df.get(i, "lng1")], [df.get(i, "lat2"), df.get(i, "lng2")]], df.get(i)); 1815 } else { 1816 return null; 1817 } 1818 }); 1819}; 1820/* 1821 * @param lat Array of arrays of latitude coordinates for polygons 1822 * @param lng Array of arrays of longitude coordinates for polygons 1823 */ 1824 1825 1826methods.addPolygons = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) { 1827 if (polygons.length > 0) { 1828 var df = new _dataframe2["default"]().col("shapes", polygons).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options); 1829 addLayers(this, "shape", df, function (df, i) { 1830 // This code used to use L.multiPolygon, but that caused 1831 // double-click on a multipolygon to fail to zoom in on the 1832 // map. Surprisingly, putting all the rings in a single 1833 // polygon seems to still work; complicated multipolygons 1834 // are still rendered correctly. 1835 var shapes = df.get(i, "shapes").map(function (polygon) { 1836 return polygon.map(_htmlwidgets2["default"].dataframeToD3); 1837 }).reduce(function (acc, val) { 1838 return acc.concat(val); 1839 }, []); 1840 return _leaflet2["default"].polygon(shapes, df.get(i)); 1841 }); 1842 } 1843}; 1844 1845methods.addGeoJSON = function (data, layerId, group, style) { 1846 // This time, self is actually needed because the callbacks below need 1847 // to access both the inner and outer senses of "this" 1848 var self = this; 1849 1850 if (typeof data === "string") { 1851 data = JSON.parse(data); 1852 } 1853 1854 var globalStyle = _jquery2["default"].extend({}, style, data.style || {}); 1855 1856 var gjlayer = _leaflet2["default"].geoJson(data, { 1857 style: function style(feature) { 1858 if (feature.style || feature.properties.style) { 1859 return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style); 1860 } else { 1861 return globalStyle; 1862 } 1863 }, 1864 onEachFeature: function onEachFeature(feature, layer) { 1865 var extraInfo = { 1866 featureId: feature.id, 1867 properties: feature.properties 1868 }; 1869 var popup = feature.properties ? feature.properties.popup : null; 1870 if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup); 1871 layer.on("click", mouseHandler(self.id, layerId, group, "geojson_click", extraInfo), this); 1872 layer.on("mouseover", mouseHandler(self.id, layerId, group, "geojson_mouseover", extraInfo), this); 1873 layer.on("mouseout", mouseHandler(self.id, layerId, group, "geojson_mouseout", extraInfo), this); 1874 } 1875 }); 1876 1877 this.layerManager.addLayer(gjlayer, "geojson", layerId, group); 1878}; 1879 1880methods.removeGeoJSON = function (layerId) { 1881 this.layerManager.removeLayer("geojson", layerId); 1882}; 1883 1884methods.clearGeoJSON = function () { 1885 this.layerManager.clearLayers("geojson"); 1886}; 1887 1888methods.addTopoJSON = function (data, layerId, group, style) { 1889 // This time, self is actually needed because the callbacks below need 1890 // to access both the inner and outer senses of "this" 1891 var self = this; 1892 1893 if (typeof data === "string") { 1894 data = JSON.parse(data); 1895 } 1896 1897 var globalStyle = _jquery2["default"].extend({}, style, data.style || {}); 1898 1899 var gjlayer = _leaflet2["default"].geoJson(null, { 1900 style: function style(feature) { 1901 if (feature.style || feature.properties.style) { 1902 return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style); 1903 } else { 1904 return globalStyle; 1905 } 1906 }, 1907 onEachFeature: function onEachFeature(feature, layer) { 1908 var extraInfo = { 1909 featureId: feature.id, 1910 properties: feature.properties 1911 }; 1912 var popup = feature.properties.popup; 1913 if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup); 1914 layer.on("click", mouseHandler(self.id, layerId, group, "topojson_click", extraInfo), this);
1915 layer.on("mouseover", mouseHandler(self.id, layerId, group, "topojson_mouseover", extraInfo), this); 1916 layer.on("mouseout", mouseHandler(self.id, layerId, group, "topojson_mouseout", extraInfo), this); 1917 } 1918 }); 1919 1920 global.omnivore.topojson.parse(data, null, gjlayer); 1921 this.layerManager.addLayer(gjlayer, "topojson", layerId, group); 1922}; 1923 1924methods.removeTopoJSON = function (layerId) { 1925 this.layerManager.removeLayer("topojson", layerId); 1926}; 1927 1928methods.clearTopoJSON = function () { 1929 this.layerManager.clearLayers("topojson"); 1930}; 1931 1932methods.addControl = function (html, position, layerId, classes) { 1933 function onAdd(map) { 1934 var div = _leaflet2["default"].DomUtil.create("div", classes); 1935 1936 if (typeof layerId !== "undefined" && layerId !== null) { 1937 div.setAttribute("id", layerId); 1938 } 1939 1940 this._div = div; // It's possible for window.Shiny to be true but Shiny.initializeInputs to 1941 // not be, when a static leaflet widget is included as part of the shiny 1942 // UI directly (not through leafletOutput or uiOutput). In this case we 1943 // don't do the normal Shiny stuff as that will all happen when Shiny 1944 // itself loads and binds the entire doc. 1945 1946 if (window.Shiny && _shiny2["default"].initializeInputs) { 1947 _shiny2["default"].renderHtml(html, this._div); 1948 1949 _shiny2["default"].initializeInputs(this._div); 1950 1951 _shiny2["default"].bindAll(this._div); 1952 } else { 1953 this._div.innerHTML = html; 1954 } 1955 1956 return this._div; 1957 } 1958 1959 function onRemove(map) { 1960 if (window.Shiny && _shiny2["default"].unbindAll) { 1961 _shiny2["default"].unbindAll(this._div); 1962 } 1963 } 1964 1965 var Control = _leaflet2["default"].Control.extend({ 1966 options: { 1967 position: position 1968 }, 1969 onAdd: onAdd, 1970 onRemove: onRemove 1971 }); 1972 1973 this.controls.add(new Control(), layerId, html); 1974}; 1975 1976methods.addCustomControl = function (control, layerId) { 1977 this.controls.add(control, layerId); 1978}; 1979 1980methods.removeControl = function (layerId) { 1981 this.controls.remove(layerId); 1982}; 1983 1984methods.getControl = function (layerId) { 1985 this.controls.get(layerId); 1986}; 1987 1988methods.clearControls = function () { 1989 this.controls.clear(); 1990}; 1991 1992methods.addLegend = function (options) { 1993 var legend = _leaflet2["default"].control({ 1994 position: options.position 1995 }); 1996 1997 var gradSpan; 1998 1999 legend.onAdd = function (map) { 2000 var div = _leaflet2["default"].DomUtil.create("div", options.className), 2001 colors = options.colors, 2002 labels = options.labels, 2003 legendHTML = ""; 2004 2005 if (options.type === "numeric") { 2006 // # Formatting constants. 2007 var singleBinHeight = 20; // The distance between tick marks, in px 2008 2009 var vMargin = 8; // If 1st tick mark starts at top of gradient, how 2010 // many extra px are needed for the top half of the 2011 // 1st label? (ditto for last tick mark/label) 2012 2013 var tickWidth = 4; // How wide should tick marks be, in px? 2014 2015 var labelPadding = 6; // How much distance to reserve for tick mark? 2016 // (Must be >= tickWidth) 2017 // # Derived formatting parameters. 2018 // What's the height of a single bin, in percentage (of gradient height)? 2019 // It might not just be 1/(n-1), if the gradient extends past the tick 2020 // marks (which can be the case for pretty cut points). 2021 2022 var singleBinPct = (options.extra.p_n - options.extra.p_1) / (labels.length - 1); // Each bin is `singleBinHeight` high. How tall is the gradient? 2023 2024 var totalHeight = 1 / singleBinPct * singleBinHeight + 1; // How far should the first tick be shifted down, relative to the top 2025 // of the gradient? 2026 2027 var tickOffset = singleBinHeight / singleBinPct * options.extra.p_1; 2028 gradSpan = (0, _jquery2["default"])("<span/>").css({ 2029 "background": "linear-gradient(" + colors + ")", 2030 "opacity": options.opacity, 2031 "height": totalHeight + "px", 2032 "width": "18px", 2033 "display": "block", 2034 "margin-top": vMargin + "px" 2035 }); 2036 var leftDiv = (0, _jquery2["default"])("<div/>").css("float", "left"), 2037 rightDiv = (0, _jquery2["default"])("<div/>").css("float", "left"); 2038 leftDiv.append(gradSpan); 2039 (0, _jquery2["default"])(div).append(leftDiv).append(rightDiv).append((0, _jquery2["default"])("<br>")); // Have to attach the div to the body at this early point, so that the 2040 // svg text getComputedTextLength() actually works, below.
2041 2042 document.body.appendChild(div); 2043 var ns = "http://www.w3.org/2000/svg"; 2044 var svg = document.createElementNS(ns, "svg"); 2045 rightDiv.append(svg); 2046 var g = document.createElementNS(ns, "g"); 2047 (0, _jquery2["default"])(g).attr("transform", "translate(0, " + vMargin + ")"); 2048 svg.appendChild(g); // max label width needed to set width of svg, and right-justify text 2049 2050 var maxLblWidth = 0; // Create tick marks and labels 2051 2052 _jquery2["default"].each(labels, function (i, label) { 2053 var y = tickOffset + i * singleBinHeight + 0.5; 2054 var thisLabel = document.createElementNS(ns, "text"); 2055 (0, _jquery2["default"])(thisLabel).text(labels[i]).attr("y", y).attr("dx", labelPadding).attr("dy", "0.5ex"); 2056 g.appendChild(thisLabel); 2057 maxLblWidth = Math.max(maxLblWidth, thisLabel.getComputedTextLength()); 2058 var thisTick = document.createElementNS(ns, "line"); 2059 (0, _jquery2["default"])(thisTick).attr("x1", 0).attr("x2", tickWidth).attr("y1", y).attr("y2", y).attr("stroke-width", 1); 2060 g.appendChild(thisTick); 2061 }); // Now that we know the max label width, we can right-justify 2062 2063 2064 (0, _jquery2["default"])(svg).find("text").attr("dx", labelPadding + maxLblWidth).attr("text-anchor", "end"); // Final size for <svg> 2065 2066 (0, _jquery2["default"])(svg).css({ 2067 width: maxLblWidth + labelPadding + "px", 2068 height: totalHeight + vMargin * 2 + "px" 2069 }); 2070 2071 if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) { 2072 (0, _jquery2["default"])(div).append("<div><i style=\"" + "background:" + options.na_color + ";opacity:" + options.opacity + ";margin-right:" + labelPadding + "px" + ";\"></i>" + options.na_label + "</div>"); 2073 } 2074 } else { 2075 if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) { 2076 colors.push(options.na_color); 2077 labels.push(options.na_label); 2078 } 2079 2080 for (var i = 0; i < colors.length; i++) { 2081 legendHTML += "<i style=\"background:" + colors[i] + ";opacity:" + options.opacity + "\"></i> " + labels[i] + "<br>"; 2082 } 2083 2084 div.innerHTML = legendHTML; 2085 } 2086 2087 if (options.title) (0, _jquery2["default"])(div).prepend("<div style=\"margin-bottom:3px\"><strong>" + options.title + "</strong></div>"); 2088 return div; 2089 }; 2090 2091 if (options.group) { 2092 // Auto generate a layerID if not provided 2093 if (!options.layerId) { 2094 options.layerId = _leaflet2["default"].Util.stamp(legend); 2095 } 2096 2097 var map = this; 2098 map.on("overlayadd", function (e) { 2099 if (e.name === options.group) { 2100 map.controls.add(legend, options.layerId); 2101 } 2102 }); 2103 map.on("overlayremove", function (e) { 2104 if (e.name === options.group) { 2105 map.controls.remove(options.layerId); 2106 } 2107 }); 2108 map.on("groupadd", function (e) { 2109 if (e.name === options.group) { 2110 map.controls.add(legend, options.layerId); 2111 } 2112 }); 2113 map.on("groupremove", function (e) { 2114 if (e.name === options.group) { 2115 map.controls.remove(options.layerId); 2116 } 2117 }); 2118 } 2119 2120 this.controls.add(legend, options.layerId); 2121}; 2122 2123methods.addLayersControl = function (baseGroups, overlayGroups, options) { 2124 var _this4 = this; 2125 2126 // Only allow one layers control at a time 2127 methods.removeLayersControl.call(this); 2128 var firstLayer = true; 2129 var base = {}; 2130 2131 _jquery2["default"].each((0, _util.asArray)(baseGroups), function (i, g) { 2132 var layer = _this4.layerManager.getLayerGroup(g, true); 2133 2134 if (layer) { 2135 base[g] = layer; // Check if >1 base layers are visible; if so, hide all but the first one 2136 2137 if (_this4.hasLayer(layer)) { 2138 if (firstLayer) { 2139 firstLayer = false; 2140 } else { 2141 _this4.removeLayer(layer); 2142 } 2143 } 2144 } 2145 }); 2146 2147 var overlay = {}; 2148 2149 _jquery2["default"].each((0, _util.asArray)(overlayGroups), function (i, g) { 2150 var layer = _this4.layerManager.getLayerGroup(g, true); 2151 2152 if (layer) { 2153 overlay[g] = layer; 2154 } 2155 }); 2156 2157 this.currentLayersControl = _leaflet2["default"].control.layers(base, overlay, options); 2158 this.addControl(this.currentLayersControl); 2159}; 2160 2161methods.removeLayersControl = function () { 2162 if (this.currentLayersControl) { 2163 this.removeControl(this.currentLayersControl); 2164 this.currentLayersControl = null; 2165 } 2166}; 2167 2168methods.addScaleBar = function (options) { 2169 // Only allow one scale bar at a time 2170 methods.removeScaleBar.call(this); 2171 2172 var scaleBar = _leaflet2["default"].control.scale(options).addTo(this); 2173 2174 this.currentScaleBar = scaleBar; 2175}; 2176 2177methods.removeScaleBar = function () { 2178 if (this.currentScaleBar) { 2179 this.currentScaleBar.remove(); 2180 this.currentScaleBar = null; 2181 } 2182}; 2183 2184methods.hideGroup = function (group) { 2185 var _this5 = this; 2186 2187 _jquery2["default"].each((0, _util.asArray)(group), function (i, g) { 2188 var layer = _this5.layerManager.getLayerGroup(g, true); 2189 2190 if (layer) { 2191 _this5.removeLayer(layer); 2192 } 2193 }); 2194}; 2195 2196methods.showGroup = function (group) { 2197 var _this6 = this; 2198 2199 _jquery2["default"].each((0, _util.asArray)(group), function (i, g) { 2200 var layer = _this6.layerManager.getLayerGroup(g, true); 2201 2202 if (layer) { 2203 _this6.addLayer(layer); 2204 } 2205 }); 2206}; 2207 2208function setupShowHideGroupsOnZoom(map) { 2209 if (map.leafletr._hasInitializedShowHideGroups) { 2210 return; 2211 } 2212 2213 map.leafletr._hasInitializedShowHideGroups = true; 2214 2215 function setVisibility(layer, visible, group) { 2216 if (visible !== map.hasLayer(layer)) { 2217 if (visible) { 2218 map.addLayer(layer); 2219 map.fire("groupadd", { 2220 "name": group, 2221 "layer": layer 2222 }); 2223 } else { 2224 map.removeLayer(layer); 2225 map.fire("groupremove", { 2226 "name": group, 2227 "layer": layer 2228 }); 2229 } 2230 } 2231 } 2232 2233 function showHideGroupsOnZoom() { 2234 if (!map.layerManager) return; 2235 var zoom = map.getZoom();
2236 map.layerManager.getAllGroupNames().forEach(function (group) { 2237 var layer = map.layerManager.getLayerGroup(group, false); 2238 2239 if (layer && typeof layer.zoomLevels !== "undefined") { 2240 setVisibility(layer, layer.zoomLevels === true || layer.zoomLevels.indexOf(zoom) >= 0, group); 2241 } 2242 }); 2243 } 2244 2245 map.showHideGroupsOnZoom = showHideGroupsOnZoom; 2246 map.on("zoomend", showHideGroupsOnZoom); 2247} 2248 2249methods.setGroupOptions = function (group, options) { 2250 var _this7 = this; 2251 2252 _jquery2["default"].each((0, _util.asArray)(group), function (i, g) { 2253 var layer = _this7.layerManager.getLayerGroup(g, true); // This slightly tortured check is because 0 is a valid value for zoomLevels 2254 2255 2256 if (typeof options.zoomLevels !== "undefined" && options.zoomLevels !== null) { 2257 layer.zoomLevels = (0, _util.asArray)(options.zoomLevels); 2258 } 2259 }); 2260 2261 setupShowHideGroupsOnZoom(this); 2262 this.showHideGroupsOnZoom(); 2263}; 2264 2265methods.addRasterImage = function (uri, bounds, opacity, attribution, layerId, group) { 2266 // uri is a data URI containing an image. We want to paint this image as a 2267 // layer at (top-left) bounds[0] to (bottom-right) bounds[1]. 2268 // We can't simply use ImageOverlay, as it uses bilinear scaling which looks 2269 // awful as you zoom in (and sometimes shifts positions or disappears). 2270 // Instead, we'll use a TileLayer.Canvas to draw pieces of the image. 2271 // First, some helper functions. 2272 // degree2tile converts latitude, longitude, and zoom to x and y tile 2273 // numbers. The tile numbers returned can be non-integral, as there's no 2274 // reason to expect that the lat/lng inputs are exactly on the border of two 2275 // tiles. 2276 // 2277 // We'll use this to convert the bounds we got from the server, into coords 2278 // in tile-space at a given zoom level. Note that once we do the conversion, 2279 // we don't to do any more trigonometry to convert between pixel coordinates 2280 // and tile coordinates; the source image pixel coords, destination canvas 2281 // pixel coords, and tile coords all can be scaled linearly. 2282 function degree2tile(lat, lng, zoom) { 2283 // See http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames 2284 var latRad = lat * Math.PI / 180; 2285 var n = Math.pow(2, zoom); 2286 var x = (lng + 180) / 360 * n; 2287 var y = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * n; 2288 return { 2289 x: x, 2290 y: y 2291 }; 2292 }
2292 // Given a range [from,to) and either one or two numbers, returns true if 2293 // there is any overlap between [x,x1) and the range--or if x1 is omitted, 2294 // then returns true if x is within [from,to). 2295 2296 2297 function overlap(from, to, x, 2298 /* optional */ 2299 x1) { 2300 if (arguments.length == 3) x1 = x; 2301 return x < to && x1 >= from; 2302 } 2303 2304 function getCanvasSmoothingProperty(ctx) { 2305 var candidates = ["imageSmoothingEnabled", "mozImageSmoothingEnabled", "webkitImageSmoothingEnabled", "msImageSmoothingEnabled"]; 2306 2307 for (var i = 0; i < candidates.length; i++) { 2308 if (typeof ctx[candidates[i]] !== "undefined") { 2309 return candidates[i]; 2310 } 2311 } 2312 2313 return null; 2314 } // Our general strategy is to: 2315 // 1. Load the data URI in an Image() object, so we can get its pixel 2316 // dimensions and the underlying image data. (We could have done this 2317 // by not encoding as PNG at all but just send an array of RGBA values 2318 // from the server, but that would inflate the JSON too much.) 2319 // 2. Create a hidden canvas that we use just to extract the image data 2320 // from the Image (using Context2D.getImageData()). 2321 // 3. Create a TileLayer.Canvas and add it to the map. 2322 // We want to synchronously create and attach the TileLayer.Canvas (so an 2323 // immediate call to clearRasters() will be respected, for example), but 2324 // Image loads its data asynchronously. Fortunately we can resolve this 2325 // by putting TileLayer.Canvas into async mode, which will let us create 2326 // and attach the layer but have it wait until the image is loaded before 2327 // it actually draws anything. 2328 // These are the variables that we will populate once the image is loaded. 2329 2330 2331 var imgData = null; // 1d row-major array, four [0-255] integers per pixel 2332 2333 var imgDataMipMapper = null; 2334 var w = null; // image width in pixels 2335 2336 var h = null; // image height in pixels 2337 // We'll use this array to store callbacks that need to be invoked once 2338 // imgData, w, and h have been resolved. 2339 2340 var imgDataCallbacks = []; // Consumers of imgData, w, and h can call this to be notified when data 2341 // is available. 2342 2343 function getImageData(callback) { 2344 if (imgData != null) { 2345 // Must not invoke the callback immediately; it's too confusing and 2346 // fragile to have a function invoke the callback *either* immediately 2347 // or in the future. Better to be consistent here. 2348 setTimeout(function () { 2349 callback(imgData, w, h, imgDataMipMapper); 2350 }, 0); 2351 } else { 2352 imgDataCallbacks.push(callback); 2353 } 2354 } 2355 2356 var img = new Image(); 2357 2358 img.onload = function () { 2359 // Save size 2360 w = img.width; 2361 h = img.height; // Create a dummy canvas to extract the image data 2362 2363 var imgDataCanvas = document.createElement("canvas"); 2364 imgDataCanvas.width = w; 2365 imgDataCanvas.height = h; 2366 imgDataCanvas.style.display = "none"; 2367 document.body.appendChild(imgDataCanvas); 2368 var imgDataCtx = imgDataCanvas.getContext("2d"); 2369 imgDataCtx.drawImage(img, 0, 0); // Save the image data. 2370 2371 imgData = imgDataCtx.getImageData(0, 0, w, h).data; 2372 imgDataMipMapper = new _mipmapper2["default"](img); // Done with the canvas, remove it from the page so it can be gc'd. 2373 2374 document.body.removeChild(imgDataCanvas); // Alert any getImageData callers who are waiting. 2375 2376 for (var i = 0; i < imgDataCallbacks.length; i++) { 2377 imgDataCallbacks[i](imgData, w, h, imgDataMipMapper); 2378 } 2379 2380 imgDataCallbacks = []; 2381 }; 2382 2383 img.src = uri; 2384 2385 var canvasTiles = _leaflet2["default"].gridLayer({ 2386 opacity: opacity, 2387 attribution: attribution, 2388 detectRetina: true, 2389 async: true 2390 }); // NOTE: The done() function MUST NOT be invoked until after the current 2391 // tick; done() looks in Leaflet's tile cache for the current tile, and 2392 // since it's still being constructed, it won't be found. 2393 2394 2395 canvasTiles.createTile = function (tilePoint, done) { 2396 var zoom = tilePoint.z; 2397 2398 var canvas = _leaflet2["default"].DomUtil.create("canvas"); 2399 2400 var error; // setup tile width and height according to the options 2401 2402 var size = this.getTileSize(); 2403 canvas.width = size.x; 2404 canvas.height = size.y; 2405 getImageData(function (imgData, w, h, mipmapper) {
2406 try { 2407 // The Context2D we'll being drawing onto. It's always 256x256. 2408 var ctx = canvas.getContext("2d"); // Convert our image data's top-left and bottom-right locations into 2409 // x/y tile coordinates. This is essentially doing a spherical mercator 2410 // projection, then multiplying by 2^zoom. 2411 2412 var topLeft = degree2tile(bounds[0][0], bounds[0][1], zoom); 2413 var bottomRight = degree2tile(bounds[1][0], bounds[1][1], zoom); // The size of the image in x/y tile coordinates. 2414 2415 var extent = { 2416 x: bottomRight.x - topLeft.x, 2417 y: bottomRight.y - topLeft.y 2418 }; // Short circuit if tile is totally disjoint from image. 2419 2420 if (!overlap(tilePoint.x, tilePoint.x + 1, topLeft.x, bottomRight.x)) return; 2421 if (!overlap(tilePoint.y, tilePoint.y + 1, topLeft.y, bottomRight.y)) return; // The linear resolution of the tile we're drawing is always 256px per tile unit. 2422 // If the linear resolution (in either direction) of the image is less than 256px 2423 // per tile unit, then use nearest neighbor; otherwise, use the canvas's built-in 2424 // scaling. 2425 2426 var imgRes = { 2427 x: w / extent.x, 2428 y: h / extent.y 2429 }; // We can do the actual drawing in one of three ways: 2430 // - Call drawImage(). This is easy and fast, and results in smooth 2431 // interpolation (bilinear?). This is what we want when we are 2432 // reducing the image from its native size. 2433 // - Call drawImage() with imageSmoothingEnabled=false. This is easy 2434 // and fast and gives us nearest-neighbor interpolation, which is what 2435 // we want when enlarging the image. However, it's unsupported on many 2436 // browsers (including QtWebkit). 2437 // - Do a manual nearest-neighbor interpolation. This is what we'll fall 2438 // back to when enlarging, and imageSmoothingEnabled isn't supported. 2439 // In theory it's slower, but still pretty fast on my machine, and the 2440 // results look the same AFAICT. 2441 // Is imageSmoothingEnabled supported? If so, we can let canvas do 2442 // nearest-neighbor interpolation for us. 2443 2444 var smoothingProperty = getCanvasSmoothingProperty(ctx); 2445 2446 if (smoothingProperty || imgRes.x >= 256 && imgRes.y >= 256) { 2447 // Use built-in scaling 2448 // Turn off anti-aliasing if necessary 2449 if (smoothingProperty) { 2450 ctx[smoothingProperty] = imgRes.x >= 256 && imgRes.y >= 256; 2451 } // Don't necessarily draw with the full-size image; if we're 2452 // downscaling, use the mipmapper to get a pre-downscaled image 2453 // (see comments on Mipmapper class for why this matters). 2454 2455 2456 mipmapper.getBySize(extent.x * 256, extent.y * 256, function (mip) { 2457 // It's possible that the image will go off the edge of the canvas-- 2458 // that's OK, the canvas should clip appropriately. 2459 ctx.drawImage(mip, // Convert abs tile coords to rel tile coords, then *256 to convert 2460 // to rel pixel coords 2461 (topLeft.x - tilePoint.x) * 256, (topLeft.y - tilePoint.y) * 256, // Always draw the whole thing and let canvas clip; so we can just 2462 // convert from size in tile coords straight to pixels 2463 extent.x * 256, extent.y * 256); 2464 }); 2465 } else { 2466 // Use manual nearest-neighbor interpolation 2467 // Calculate the source image pixel coordinates that correspond with 2468 // the top-left and bottom-right of this tile. (If the source image 2469 // only partially overlaps the tile, we use max/min to limit the 2470 // sourceStart/End to only reflect the overlapping portion.) 2471 var sourceStart = { 2472 x: Math.max(0, Math.floor((tilePoint.x - topLeft.x) * imgRes.x)), 2473 y: Math.max(0, Math.floor((tilePoint.y - topLeft.y) * imgRes.y)) 2474 }; 2475 var sourceEnd = { 2476 x: Math.min(w, Math.ceil((tilePoint.x + 1 - topLeft.x) * imgRes.x)), 2477 y: Math.min(h, Math.ceil((tilePoint.y + 1 - topLeft.y) * imgRes.y)) 2478 }; // The size, in dest pixels, that each source pixel should occupy. 2479 // This might be greater or less than 1 (e.g. if x and y resolution 2480 // are very different). 2481 2482 var pixelSize = { 2483 x: 256 / imgRes.x, 2484 y: 256 / imgRes.y 2485 }; // For each pixel in the source image that overlaps the tile... 2486 2487 for (var row = sourceStart.y; row < sourceEnd.y; row++) { 2488 for (var col = sourceStart.x; col < sourceEnd.x; col++) { 2489 // ...extract the pixel data... 2490 var i = (row * w + col) * 4; 2491 var r = imgData[i]; 2492 var g = imgData[i + 1]; 2493 var b = imgData[i + 2]; 2494 var a = imgData[i + 3]; 2495 ctx.fillStyle = "rgba(" + [r, g, b, a / 255].join(",") + ")"; // ...calculate the corresponding pixel coord in the dest image 2496 // where it should be drawn... 2497 2498 var pixelPos = { 2499 x: (col / imgRes.x + topLeft.x - tilePoint.x) * 256, 2500 y: (row / imgRes.y + topLeft.y - tilePoint.y) * 256 2501 }; // ...and draw a rectangle there. 2502 2503 ctx.fillRect(Math.round(pixelPos.x), Math.round(pixelPos.y), // Looks crazy, but this is necessary to prevent roun
2503ding from 2504 // causing overlap between this rect and its neighbors. The 2505 // minuend is the location of the next pixel, while the 2506 // subtrahend is the position of the current pixel (to turn an 2507 // absolute coordinate to a width/height). Yes, I had to look 2508 // up minuend and subtrahend. 2509 Math.round(pixelPos.x + pixelSize.x) - Math.round(pixelPos.x), Math.round(pixelPos.y + pixelSize.y) - Math.round(pixelPos.y)); 2510 } 2511 } 2512 } 2513 } catch (e) { 2514 error = e; 2515 } finally { 2516 done(error, canvas); 2517 } 2518 }); 2519 return canvas; 2520 }; 2521 2522 this.layerManager.addLayer(canvasTiles, "image", layerId, group); 2523}; 2524 2525methods.removeImage = function (layerId) { 2526 this.layerManager.removeLayer("image", layerId); 2527}; 2528 2529methods.clearImages = function () { 2530 this.layerManager.clearLayers("image"); 2531}; 2532 2533methods.addMeasure = function (options) { 2534 // if a measureControl already exists, then remove it and 2535 // replace with a new one 2536 methods.removeMeasure.call(this); 2537 this.measureControl = _leaflet2["default"].control.measure(options); 2538 this.addControl(this.measureControl); 2539}; 2540 2541methods.removeMeasure = function () { 2542 if (this.measureControl) { 2543 this.removeControl(this.measureControl); 2544 this.measureControl = null; 2545 } 2546}; 2547 2548methods.addSelect = function (ctGroup) { 2549 var _this8 = this; 2550 2551 methods.removeSelect.call(this); 2552 this._selectButton = _leaflet2["default"].easyButton({ 2553 states: [{ 2554 stateName: "select-inactive", 2555 icon: "ion-qr-scanner", 2556 title: "Make a selection", 2557 onClick: function onClick(btn, map) { 2558 btn.state("select-active"); 2559 _this8._locationFilter = new _leaflet2["default"].LocationFilter2(); 2560 2561 if (ctGroup) { 2562 var selectionHandle = new global.crosstalk.SelectionHandle(ctGroup); 2563 selectionHandle.on("change", function (e) { 2564 if (e.sender !== selectionHandle) { 2565 if (_this8._locationFilter) { 2566 _this8._locationFilter.disable(); 2567 2568 btn.state("select-inactive"); 2569 } 2570 } 2571 }); 2572 2573 var handler = function handler(e) { 2574 _this8.layerManager.brush(_this8._locationFilter.getBounds(), { 2575 sender: selectionHandle 2576 }); 2577 }; 2578 2579 _this8._locationFilter.on("enabled", handler); 2580 2581 _this8._locationFilter.on("change", handler); 2582 2583 _this8._locationFilter.on("disabled", function () { 2584 selectionHandle.close(); 2585 _this8._locationFilter = null; 2586 }); 2587 } 2588 2589 _this8._locationFilter.addTo(map); 2590 } 2591 }, { 2592 stateName: "select-active", 2593 icon: "ion-close-round", 2594 title: "Dismiss selection", 2595 onClick: function onClick(btn, map) { 2596 btn.state("select-inactive"); 2597 2598 _this8._locationFilter.disable(); // If explicitly dismissed, clear the crosstalk selections 2599 2600 2601 _this8.layerManager.unbrush(); 2602 } 2603 }] 2604 }); 2605 2606 this._selectButton.addTo(this); 2607}; 2608 2609methods.removeSelect = function () { 2610 if (this._locationFilter) { 2611 this._locationFilter.disable(); 2612 } 2613 2614 if (this._selectButton) { 2615 this.removeControl(this._selectButton); 2616 this._selectButton = null; 2617 } 2618}; 2619 2620methods.createMapPane = function (name, zIndex) { 2621 this.createPane(name); 2622 this.getPane(name).style.zIndex = zIndex; 2623}; 2624 2625 2626}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 2627},{"./cluster-layer-store":1,"./crs_utils":3,"./dataframe":4,"./global/htmlwidgets":8,"./global/jquery":9,"./global/leaflet":10,"./global/shiny":12,"./mipmapper":16,"./util":17}],16:[function(require,module,exports){ 2628"use strict"; 2629 2630Object.defineProperty(exports, "__esModule", { 2631 value: true 2632}); 2633 2634function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2635 2636function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 2637 2638function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 2639 2640// This class simulates a mipmap, which shrinks images by powers of two. This 2641// stepwise reduction results in "pixel-perfect downscaling" (where every 2642// pixel of the original image has some contribution to the downscaled image) 2643// as opposed to a single-step downscaling which will discard a lot of data 2644// (and with sparse images at small scales can give very surprising results). 2645var Mipmapper = /*#__PURE__*/function () { 2646 function Mipmapper(img) { 2647 _classCallCheck(this, Mipmapper); 2648 2649 this._layers = [img]; 2650 } // The various functions on this class take a callback function BUT MAY OR MAY 2651 // NOT actually behave asynchronously. 2652 2653 2654 _createClass(Mipmapper, [{ 2655 key: "getBySize", 2656 value: function getBySize(desiredWidth, desiredHeight, callback) { 2657 var _this = this; 2658 2659 var i = 0; 2660 var lastImg = this._layers[0]; 2661 2662 var testNext = function testNext() { 2663 _this.getByIndex(i, function (img) {
2664 // If current image is invalid (i.e. too small to be rendered) or 2665 // it's smaller than what we wanted, return the last known good image. 2666 if (!img || img.width < desiredWidth || img.height < desiredHeight) { 2667 callback(lastImg); 2668 return; 2669 } else { 2670 lastImg = img; 2671 i++; 2672 testNext(); 2673 return; 2674 } 2675 }); 2676 }; 2677 2678 testNext(); 2679 } 2680 }, { 2681 key: "getByIndex", 2682 value: function getByIndex(i, callback) { 2683 var _this2 = this; 2684 2685 if (this._layers[i]) { 2686 callback(this._layers[i]); 2687 return; 2688 } 2689 2690 this.getByIndex(i - 1, function (prevImg) { 2691 if (!prevImg) { 2692 // prevImg could not be calculated (too small, possibly) 2693 callback(null); 2694 return; 2695 } 2696 2697 if (prevImg.width < 2 || prevImg.height < 2) { 2698 // Can't reduce this image any further 2699 callback(null); 2700 return; 2701 } // If reduce ever becomes truly asynchronous, we should stuff a promise or 2702 // something into this._layers[i] before calling this.reduce(), to prevent 2703 // redundant reduce operations from happening. 2704 2705 2706 _this2.reduce(prevImg, function (reducedImg) { 2707 _this2._layers[i] = reducedImg; 2708 callback(reducedImg); 2709 return; 2710 }); 2711 }); 2712 } 2713 }, { 2714 key: "reduce", 2715 value: function reduce(img, callback) { 2716 var imgDataCanvas = document.createElement("canvas"); 2717 imgDataCanvas.width = Math.ceil(img.width / 2); 2718 imgDataCanvas.height = Math.ceil(img.height / 2); 2719 imgDataCanvas.style.display = "none"; 2720 document.body.appendChild(imgDataCanvas); 2721 2722 try { 2723 var imgDataCtx = imgDataCanvas.getContext("2d"); 2724 imgDataCtx.drawImage(img, 0, 0, img.width / 2, img.height / 2); 2725 callback(imgDataCanvas); 2726 } finally { 2727 document.body.removeChild(imgDataCanvas); 2728 } 2729 } 2730 }]); 2731 2732 return Mipmapper; 2733}(); 2734 2735exports["default"] = Mipmapper; 2736 2737 2738},{}],17:[function(require,module,exports){ 2739"use strict"; 2740 2741Object.defineProperty(exports, "__esModule", { 2742 value: true 2743}); 2744exports.log = log; 2745exports.recycle = recycle; 2746exports.asArray = asArray; 2747 2748function log(message) { 2749 /* eslint-disable no-console */ 2750 if (console && console.log) console.log(message); 2751 /* eslint-enable no-console */ 2752} 2753 2754function recycle(values, length, inPlace) { 2755 if (length === 0 && !inPlace) return []; 2756 2757 if (!(values instanceof Array)) { 2758 if (inPlace) { 2759 throw new Error("Can't do in-place recycling of a non-Array value"); 2760 } 2761 2762 values = [values]; 2763 } 2764 2765 if (typeof length === "undefined") length = values.length; 2766 var dest = inPlace ? values : []; 2767 var origLength = values.length; 2768 2769 while (dest.length < length) { 2770 dest.push(values[dest.length % origLength]); 2771 } 2772 2773 if (dest.length > length) { 2774 dest.splice(length, dest.length - length); 2775 } 2776 2777 return dest; 2778} 2779 2780function asArray(value) { 2781 if (value instanceof Array) return value;else return [value]; 2782} 2783 2784 2785},{}]},{},[13]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.