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