").addClass(errClass).css("position", "absolute")
+ .css("top", el.offsetTop)
+ .css("left", el.offsetLeft)
+ // setting width can push out the page size, forcing otherwise
+ // unnecessary scrollbars to appear and making it impossible for
+ // the element to shrink; so use max-width instead
+ .css("maxWidth", el.offsetWidth)
+ .css("height", el.offsetHeight);
+ errorDiv.text(err.message);
+ $el.after(errorDiv);
+
+ // Really dumb way to keep the size/position of the error in sync with
+ // the parent element as the window is resized or whatever.
+ var intId = setInterval(function() {
+ if (!errorDiv[0].parentElement) {
+ clearInterval(intId);
+ return;
+ }
+ errorDiv
+ .css("top", el.offsetTop)
+ .css("left", el.offsetLeft)
+ .css("maxWidth", el.offsetWidth)
+ .css("height", el.offsetHeight);
+ }, 500);
+ }
+ }
+ },
+ clearError: function(el) {
+ var $el = $(el);
+ var display = $el.data("restore-display-mode");
+ $el.data("restore-display-mode", null);
+
+ if (display === "inline" || display === "inline-block") {
+ if (display)
+ $el.css("display", display);
+ $(el.nextSibling).filter(".htmlwidgets-error").remove();
+ } else if (display === "block"){
+ $el.css("visibility", "inherit");
+ $(el.nextSibling).filter(".htmlwidgets-error").remove();
+ }
+ },
+ sizing: {}
+ };
+
+ // Called by widget bindings to register a new type of widget. The definition
+ // object can contain the following properties:
+ // - name (required) - A string indicating the binding name, which will be
+ // used by default as the CSS classname to look for.
+ // - initialize (optional) - A function(el) that will be called once per
+ // widget element; if a value is returned, it will be passed as the third
+ // value to renderValue.
+ // - renderValue (required) - A function(el, data, initValue) that will be
+ // called with data. Static contexts will cause this to be called once per
+ // element; Shiny apps will cause this to be called multiple times per
+ // element, as the data changes.
+ window.HTMLWidgets.widget = function(definition) {
+ if (!definition.name) {
+ throw new Error("Widget must have a name");
+ }
+ if (!definition.type) {
+ throw new Error("Widget must have a type");
+ }
+ // Currently we only support output widgets
+ if (definition.type !== "output") {
+ throw new Error("Unrecognized widget type '" + definition.type + "'");
+ }
+ // TODO: Verify that .name is a valid CSS classname
+
+ // Support new-style instance-bound definitions. Old-style class-bound
+ // definitions have one widget "object" per widget per type/class of
+ // widget; the renderValue and resize methods on such widget objects
+ // take el and instance arguments, because the widget object can't
+ // store them. New-style instance-bound definitions have one widget
+ // object per widget instance; the definition that's passed in doesn't
+ // provide renderValue or resize methods at all, just the single method
+ // factory(el, width, height)
+ // which returns an object that has renderValue(x) and resize(w, h).
+ // This enables a far more natural programming style for the widget
+ // author, who can store per-instance state using either OO-style
+ // instance fields or functional-style closure variables (I guess this
+ // is in contrast to what can only be called C-style pseudo-OO which is
+ // what we required before).
+ if (definition.factory) {
+ definition = createLegacyDefinitionAdapter(definition);
+ }
+
+ if (!definition.renderValue) {
+ throw new Error("Widget must have a renderValue function");
+ }
+
+ // For static rendering (non-Shiny), use a simple widget registration
+ // scheme. We also use this scheme for Shiny apps/documents that also
+ // contain static widgets.
+ window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
+ // Merge defaults into the definition; don't mutate the original definition.
+ var staticBinding = extend({}, defaults, definition);
+ overrideMethod(staticBinding, "find", function(superfunc) {
+ return function(scope) {
+ var results = superfunc(scope);
+ // Filter out Shiny outputs, we only want the static kind
+ return filterByClass(results, "html-widget-output", false);
+ };
+ });
+ window.HTMLWidgets.widgets.push(staticBinding);
+
+ if (shinyMode) {
+ // Shiny is running. Register the definition with an output binding.
+ // The definition itself will not be the output binding, instead
+ // we will make an output binding object that delegates to the
+ // definition. This is because we foolishly used the same method
+ // name (renderValue) for htmlwidgets definition and Shiny bindings
+ // but they actually have quite different semantics (the Shiny
+ // bindings receive data that includes lots of metadata that it
+ // strips off before calling htmlwidgets renderValue). We can't
+ // just ignore the difference because in some widgets it's helpful
+ // to call this.renderValue() from inside of resize(), and if
+ // we're not delegating, then that call will go to the Shiny
+ // version instead of the htmlwidgets version.
+
+ // Merge defaults with definition, without mutating either.
+ var bindingDef = extend({}, defaults, definition);
+
+ // This object will be our actual Shiny binding.
+ var shinyBinding = new Shiny.OutputBinding();
+
+ // With a few exceptions, we'll want to simply use the bindingDef's
+ // version of methods if they are available, otherwise fall back to
+ // Shiny's defaults. NOTE: If Shiny's output bindings gain additional
+ // methods in the future, and we want them to be overrideable by
+ // HTMLWidget binding definitions, then we'll need to add them to this
+ // list.
+ delegateMethod(shinyBinding, bindingDef, "getId");
+ delegateMethod(shinyBinding, bindingDef, "onValueChange");
+ delegateMethod(shinyBinding, bindingDef, "onValueError");
+ delegateMethod(shinyBinding, bindingDef, "renderError");
+ delegateMethod(shinyBinding, bindingDef, "clearError");
+ delegateMethod(shinyBinding, bindingDef, "showProgress");
+
+ // The find, renderValue, and resize are handled differently, because we
+ // want to actually decorate the behavior of the bindingDef methods.
+
+ shinyBinding.find = function(scope) {
+ var results = bindingDef.find(scope);
+
+ // Only return elements that are Shiny outputs, not static ones
+ var dynamicResults = results.filter(".html-widget-output");
+
+ // It's possible that whatever caused Shiny to think there might be
+ // new dynamic outputs, also caused there to be new static outputs.
+ // Since there might be lots of different htmlwidgets bindings, we
+ // schedule execution for later--no need to staticRender multiple
+ // times.
+ if (results.length !== dynamicResults.length)
+ scheduleStaticRender();
+
+ return dynamicResults;
+ };
+
+ // Wrap renderValue to handle initialization, which unfortunately isn't
+ // supported natively by Shiny at the time of this writing.
+
+ shinyBinding.renderValue = function(el, data) {
+ Shiny.renderDependencies(data.deps);
+ // Resolve strings marked as javascript literals to objects
+ if (!(data.evals instanceof Array)) data.evals = [data.evals];
+ for (var i = 0; data.evals && i < data.evals.length; i++) {
+ window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
+ }
+ if (!bindingDef.renderOnNullValue) {
+ if (data.x === null) {
+ el.style.visibility = "hidden";
+ return;
+ } else {
+ el.style.visibility = "inherit";
+ }
+ }
+ if (!elementData(el, "initialized")) {
+ initSizing(el);
+
+ elementData(el, "initialized", true);
+ if (bindingDef.initialize) {
+ var rect = el.getBoundingClientRect();
+ var result = bindingDef.initialize(el, rect.width, rect.height);
+ elementData(el, "init_result", result);
+ }
+ }
+ bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
+ evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
+ };
+
+ // Only override resize if bindingDef implements it
+ if (bindingDef.resize) {
+ shinyBinding.resize = function(el, width, height) {
+ // Shiny can call resize before initialize/renderValue have been
+ // called, which doesn't make sense for widgets.
+ if (elementData(el, "initialized")) {
+ bindingDef.resize(el, width, height, elementData(el, "init_result"));
+ }
+ };
+ }
+
+ Shiny.outputBindings.register(shinyBinding, bindingDef.name);
+ }
+ };
+
+ var scheduleStaticRenderTimerId = null;
+ function scheduleStaticRender() {
+ if (!scheduleStaticRenderTimerId) {
+ scheduleStaticRenderTimerId = setTimeout(function() {
+ scheduleStaticRenderTimerId = null;
+ window.HTMLWidgets.staticRender();
+ }, 1);
+ }
+ }
+
+ // Render static widgets after the document finishes loading
+ // Statically render all elements that are of this widget's class
+ window.HTMLWidgets.staticRender = function() {
+ var bindings = window.HTMLWidgets.widgets || [];
+ forEach(bindings, function(binding) {
+ var matches = binding.find(document.documentElement);
+ forEach(matches, function(el) {
+ var sizeObj = initSizing(el, binding);
+
+ var getSize = function(el) {
+ if (sizeObj) {
+ return {w: sizeObj.getWidth(), h: sizeObj.getHeight()}
+ } else {
+ var rect = el.getBoundingClientRect();
+ return {w: rect.width, h: rect.height}
+ }
+ };
+
+ if (hasClass(el, "html-widget-static-bound"))
+ return;
+ el.className = el.className + " html-widget-static-bound";
+
+ var initResult;
+ if (binding.initialize) {
+ var size = getSize(el);
+ initResult = binding.initialize(el, size.w, size.h);
+ elementData(el, "init_result", initResult);
+ }
+
+ if (binding.resize) {
+ var lastSize = getSize(el);
+ var resizeHandler = function(e) {
+ var size = getSize(el);
+ if (size.w === 0 && size.h === 0)
+ return;
+ if (size.w === lastSize.w && size.h === lastSize.h)
+ return;
+ lastSize = size;
+ binding.resize(el, size.w, size.h, initResult);
+ };
+
+ on(window, "resize", resizeHandler);
+
+ // This is needed for cases where we're running in a Shiny
+ // app, but the widget itself is not a Shiny output, but
+ // rather a simple static widget. One example of this is
+ // an rmarkdown document that has runtime:shiny and widget
+ // that isn't in a render function. Shiny only knows to
+ // call resize handlers for Shiny outputs, not for static
+ // widgets, so we do it ourselves.
+ if (window.jQuery) {
+ window.jQuery(document).on(
+ "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
+ resizeHandler
+ );
+ window.jQuery(document).on(
+ "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
+ resizeHandler
+ );
+ }
+
+ // This is needed for the specific case of ioslides, which
+ // flips slides between display:none and display:block.
+ // Ideally we would not have to have ioslide-specific code
+ // here, but rather have ioslides raise a generic event,
+ // but the rmarkdown package just went to CRAN so the
+ // window to getting that fixed may be long.
+ if (window.addEventListener) {
+ // It's OK to limit this to window.addEventListener
+ // browsers because ioslides itself only supports
+ // such browsers.
+ on(document, "slideenter", resizeHandler);
+ on(document, "slideleave", resizeHandler);
+ }
+ }
+
+ var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
+ if (scriptData) {
+ var data = JSON.parse(scriptData.textContent || scriptData.text);
+ // Resolve strings marked as javascript literals to objects
+ if (!(data.evals instanceof Array)) data.evals = [data.evals];
+ for (var k = 0; data.evals && k < data.evals.length; k++) {
+ window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
+ }
+ binding.renderValue(el, data.x, initResult);
+ evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
+ }
+ });
+ });
+
+ invokePostRenderHandlers();
+ }
+
+
+ function has_jQuery3() {
+ if (!window.jQuery) {
+ return false;
+ }
+ var $version = window.jQuery.fn.jquery;
+ var $major_version = parseInt($version.split(".")[0]);
+ return $major_version >= 3;
+ }
+
+ /*
+ / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
+ / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
+ / really means $(setTimeout(fn)).
+ / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
+ /
+ / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
+ / one tick later than it did before, which means staticRender() is
+ / called renderValue() earlier than (advanced) widget authors might be expecting.
+ / https://github.com/rstudio/shiny/issues/2630
+ /
+ / For a concrete example, leaflet has some methods (e.g., updateBounds)
+ / which reference Shiny methods registered in initShiny (e.g., setInputValue).
+ / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
+ / delay execution of those methods (until Shiny methods are ready)
+ / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
+ /
+ / Ideally widget authors wouldn't need to use this setTimeout() hack that
+ / leaflet uses to call Shiny methods on a staticRender(). In the long run,
+ / the logic initShiny should be broken up so that method registration happens
+ / right away, but binding happens later.
+ */
+ function maybeStaticRenderLater() {
+ if (shinyMode && has_jQuery3()) {
+ window.jQuery(window.HTMLWidgets.staticRender);
+ } else {
+ window.HTMLWidgets.staticRender();
+ }
+ }
+
+ if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", function() {
+ document.removeEventListener("DOMContentLoaded", arguments.callee, false);
+ maybeStaticRenderLater();
+ }, false);
+ } else if (document.attachEvent) {
+ document.attachEvent("onreadystatechange", function() {
+ if (document.readyState === "complete") {
+ document.detachEvent("onreadystatechange", arguments.callee);
+ maybeStaticRenderLater();
+ }
+ });
+ }
+
+
+ window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
+ // If no key, default to the first item
+ if (typeof(key) === "undefined")
+ key = 1;
+
+ var link = document.getElementById(depname + "-" + key + "-attachment");
+ if (!link) {
+ throw new Error("Attachment " + depname + "/" + key + " not found in document");
+ }
+ return link.getAttribute("href");
+ };
+
+ window.HTMLWidgets.dataframeToD3 = function(df) {
+ var names = [];
+ var length;
+ for (var name in df) {
+ if (df.hasOwnProperty(name))
+ names.push(name);
+ if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
+ throw new Error("All fields must be arrays");
+ } else if (typeof(length) !== "undefined" && length !== df[name].length) {
+ throw new Error("All fields must be arrays of the same length");
+ }
+ length = df[name].length;
+ }
+ var results = [];
+ var item;
+ for (var row = 0; row < length; row++) {
+ item = {};
+ for (var col = 0; col < names.length; col++) {
+ item[names[col]] = df[names[col]][row];
+ }
+ results.push(item);
+ }
+ return results;
+ };
+
+ window.HTMLWidgets.transposeArray2D = function(array) {
+ if (array.length === 0) return array;
+ var newArray = array[0].map(function(col, i) {
+ return array.map(function(row) {
+ return row[i]
+ })
+ });
+ return newArray;
+ };
+ // Split value at splitChar, but allow splitChar to be escaped
+ // using escapeChar. Any other characters escaped by escapeChar
+ // will be included as usual (including escapeChar itself).
+ function splitWithEscape(value, splitChar, escapeChar) {
+ var results = [];
+ var escapeMode = false;
+ var currentResult = "";
+ for (var pos = 0; pos < value.length; pos++) {
+ if (!escapeMode) {
+ if (value[pos] === splitChar) {
+ results.push(currentResult);
+ currentResult = "";
+ } else if (value[pos] === escapeChar) {
+ escapeMode = true;
+ } else {
+ currentResult += value[pos];
+ }
+ } else {
+ currentResult += value[pos];
+ escapeMode = false;
+ }
+ }
+ if (currentResult !== "") {
+ results.push(currentResult);
+ }
+ return results;
+ }
+ // Function authored by Yihui/JJ Allaire
+ window.HTMLWidgets.evaluateStringMember = function(o, member) {
+ var parts = splitWithEscape(member, '.', '\\');
+ for (var i = 0, l = parts.length; i < l; i++) {
+ var part = parts[i];
+ // part may be a character or 'numeric' member name
+ if (o !== null && typeof o === "object" && part in o) {
+ if (i == (l - 1)) { // if we are at the end of the line then evalulate
+ if (typeof o[part] === "string")
+ o[part] = tryEval(o[part]);
+ } else { // otherwise continue to next embedded object
+ o = o[part];
+ }
+ }
+ }
+ };
+
+ // Retrieve the HTMLWidget instance (i.e. the return value of an
+ // HTMLWidget binding's initialize() or factory() function)
+ // associated with an element, or null if none.
+ window.HTMLWidgets.getInstance = function(el) {
+ return elementData(el, "init_result");
+ };
+
+ // Finds the first element in the scope that matches the selector,
+ // and returns the HTMLWidget instance (i.e. the return value of
+ // an HTMLWidget binding's initialize() or factory() function)
+ // associated with that element, if any. If no element matches the
+ // selector, or the first matching element has no HTMLWidget
+ // instance associated with it, then null is returned.
+ //
+ // The scope argument is optional, and defaults to window.document.
+ window.HTMLWidgets.find = function(scope, selector) {
+ if (arguments.length == 1) {
+ selector = scope;
+ scope = document;
+ }
+
+ var el = scope.querySelector(selector);
+ if (el === null) {
+ return null;
+ } else {
+ return window.HTMLWidgets.getInstance(el);
+ }
+ };
+
+ // Finds all elements in the scope that match the selector, and
+ // returns the HTMLWidget instances (i.e. the return values of
+ // an HTMLWidget binding's initialize() or factory() function)
+ // associated with the elements, in an array. If elements that
+ // match the selector don't have an associated HTMLWidget
+ // instance, the returned array will contain nulls.
+ //
+ // The scope argument is optional, and defaults to window.document.
+ window.HTMLWidgets.findAll = function(scope, selector) {
+ if (arguments.length == 1) {
+ selector = scope;
+ scope = document;
+ }
+
+ var nodes = scope.querySelectorAll(selector);
+ var results = [];
+ for (var i = 0; i < nodes.length; i++) {
+ results.push(window.HTMLWidgets.getInstance(nodes[i]));
+ }
+ return results;
+ };
+
+ var postRenderHandlers = [];
+ function invokePostRenderHandlers() {
+ while (postRenderHandlers.length) {
+ var handler = postRenderHandlers.shift();
+ if (handler) {
+ handler();
+ }
+ }
+ }
+
+ // Register the given callback function to be invoked after the
+ // next time static widgets are rendered.
+ window.HTMLWidgets.addPostRenderHandler = function(callback) {
+ postRenderHandlers.push(callback);
+ };
+
+ // Takes a new-style instance-bound definition, and returns an
+ // old-style class-bound definition. This saves us from having
+ // to rewrite all the logic in this file to accomodate both
+ // types of definitions.
+ function createLegacyDefinitionAdapter(defn) {
+ var result = {
+ name: defn.name,
+ type: defn.type,
+ initialize: function(el, width, height) {
+ return defn.factory(el, width, height);
+ },
+ renderValue: function(el, x, instance) {
+ return instance.renderValue(x);
+ },
+ resize: function(el, width, height, instance) {
+ return instance.resize(width, height);
+ }
+ };
+
+ if (defn.find)
+ result.find = defn.find;
+ if (defn.renderError)
+ result.renderError = defn.renderError;
+ if (defn.clearError)
+ result.clearError = defn.clearError;
+
+ return result;
+ }
+})();
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/layers-2x.png b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/layers-2x.png
new file mode 100644
index 0000000..200c333
Binary files /dev/null and b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/layers-2x.png differ
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/layers.png b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/layers.png
new file mode 100644
index 0000000..1a72e57
Binary files /dev/null and b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/layers.png differ
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-icon-2x.png b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-icon-2x.png
new file mode 100644
index 0000000..88f9e50
Binary files /dev/null and b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-icon-2x.png differ
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-icon.png b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-icon.png
new file mode 100644
index 0000000..950edf2
Binary files /dev/null and b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-icon.png differ
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-shadow.png b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-shadow.png
new file mode 100644
index 0000000..9fd2979
Binary files /dev/null and b/docs/articles/Articles/Applications_files/leaflet-1.3.1/images/marker-shadow.png differ
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/leaflet.css b/docs/articles/Articles/Applications_files/leaflet-1.3.1/leaflet.css
new file mode 100644
index 0000000..d1b47a1
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/leaflet-1.3.1/leaflet.css
@@ -0,0 +1,636 @@
+/* required styles */
+
+.leaflet-pane,
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-tile-container,
+.leaflet-pane > svg,
+.leaflet-pane > canvas,
+.leaflet-zoom-box,
+.leaflet-image-layer,
+.leaflet-layer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ }
+.leaflet-container {
+ overflow: hidden;
+ }
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ }
+/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
+.leaflet-safari .leaflet-tile {
+ image-rendering: -webkit-optimize-contrast;
+ }
+/* hack that prevents hw layers "stretching" when loading new tiles */
+.leaflet-safari .leaflet-tile-container {
+ width: 1600px;
+ height: 1600px;
+ -webkit-transform-origin: 0 0;
+ }
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+ display: block;
+ }
+/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
+/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
+.leaflet-container .leaflet-overlay-pane svg,
+.leaflet-container .leaflet-marker-pane img,
+.leaflet-container .leaflet-shadow-pane img,
+.leaflet-container .leaflet-tile-pane img,
+.leaflet-container img.leaflet-image-layer {
+ max-width: none !important;
+ max-height: none !important;
+ }
+
+.leaflet-container.leaflet-touch-zoom {
+ -ms-touch-action: pan-x pan-y;
+ touch-action: pan-x pan-y;
+ }
+.leaflet-container.leaflet-touch-drag {
+ -ms-touch-action: pinch-zoom;
+ /* Fallback for FF which doesn't support pinch-zoom */
+ touch-action: none;
+ touch-action: pinch-zoom;
+}
+.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.leaflet-container {
+ -webkit-tap-highlight-color: transparent;
+}
+.leaflet-container a {
+ -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
+}
+.leaflet-tile {
+ filter: inherit;
+ visibility: hidden;
+ }
+.leaflet-tile-loaded {
+ visibility: inherit;
+ }
+.leaflet-zoom-box {
+ width: 0;
+ height: 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ z-index: 800;
+ }
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
+.leaflet-overlay-pane svg {
+ -moz-user-select: none;
+ }
+
+.leaflet-pane { z-index: 400; }
+
+.leaflet-tile-pane { z-index: 200; }
+.leaflet-overlay-pane { z-index: 400; }
+.leaflet-shadow-pane { z-index: 500; }
+.leaflet-marker-pane { z-index: 600; }
+.leaflet-tooltip-pane { z-index: 650; }
+.leaflet-popup-pane { z-index: 700; }
+
+.leaflet-map-pane canvas { z-index: 100; }
+.leaflet-map-pane svg { z-index: 200; }
+
+.leaflet-vml-shape {
+ width: 1px;
+ height: 1px;
+ }
+.lvml {
+ behavior: url(#default#VML);
+ display: inline-block;
+ position: absolute;
+ }
+
+
+/* control positioning */
+
+.leaflet-control {
+ position: relative;
+ z-index: 800;
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+ pointer-events: auto;
+ }
+.leaflet-top,
+.leaflet-bottom {
+ position: absolute;
+ z-index: 1000;
+ pointer-events: none;
+ }
+.leaflet-top {
+ top: 0;
+ }
+.leaflet-right {
+ right: 0;
+ }
+.leaflet-bottom {
+ bottom: 0;
+ }
+.leaflet-left {
+ left: 0;
+ }
+.leaflet-control {
+ float: left;
+ clear: both;
+ }
+.leaflet-right .leaflet-control {
+ float: right;
+ }
+.leaflet-top .leaflet-control {
+ margin-top: 10px;
+ }
+.leaflet-bottom .leaflet-control {
+ margin-bottom: 10px;
+ }
+.leaflet-left .leaflet-control {
+ margin-left: 10px;
+ }
+.leaflet-right .leaflet-control {
+ margin-right: 10px;
+ }
+
+
+/* zoom and fade animations */
+
+.leaflet-fade-anim .leaflet-tile {
+ will-change: opacity;
+ }
+.leaflet-fade-anim .leaflet-popup {
+ opacity: 0;
+ -webkit-transition: opacity 0.2s linear;
+ -moz-transition: opacity 0.2s linear;
+ -o-transition: opacity 0.2s linear;
+ transition: opacity 0.2s linear;
+ }
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
+ opacity: 1;
+ }
+.leaflet-zoom-animated {
+ -webkit-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ transform-origin: 0 0;
+ }
+.leaflet-zoom-anim .leaflet-zoom-animated {
+ will-change: transform;
+ }
+.leaflet-zoom-anim .leaflet-zoom-animated {
+ -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
+ -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
+ -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
+ transition: transform 0.25s cubic-bezier(0,0,0.25,1);
+ }
+.leaflet-zoom-anim .leaflet-tile,
+.leaflet-pan-anim .leaflet-tile {
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+.leaflet-zoom-anim .leaflet-zoom-hide {
+ visibility: hidden;
+ }
+
+
+/* cursors */
+
+.leaflet-interactive {
+ cursor: pointer;
+ }
+.leaflet-grab {
+ cursor: -webkit-grab;
+ cursor: -moz-grab;
+ }
+.leaflet-crosshair,
+.leaflet-crosshair .leaflet-interactive {
+ cursor: crosshair;
+ }
+.leaflet-popup-pane,
+.leaflet-control {
+ cursor: auto;
+ }
+.leaflet-dragging .leaflet-grab,
+.leaflet-dragging .leaflet-grab .leaflet-interactive,
+.leaflet-dragging .leaflet-marker-draggable {
+ cursor: move;
+ cursor: -webkit-grabbing;
+ cursor: -moz-grabbing;
+ }
+
+/* marker & overlays interactivity */
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-image-layer,
+.leaflet-pane > svg path,
+.leaflet-tile-container {
+ pointer-events: none;
+ }
+
+.leaflet-marker-icon.leaflet-interactive,
+.leaflet-image-layer.leaflet-interactive,
+.leaflet-pane > svg path.leaflet-interactive {
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+ pointer-events: auto;
+ }
+
+/* visual tweaks */
+
+.leaflet-container {
+ background: #ddd;
+ outline: 0;
+ }
+.leaflet-container a {
+ color: #0078A8;
+ }
+.leaflet-container a.leaflet-active {
+ outline: 2px solid orange;
+ }
+.leaflet-zoom-box {
+ border: 2px dotted #38f;
+ background: rgba(255,255,255,0.5);
+ }
+
+
+/* general typography */
+.leaflet-container {
+ font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+ }
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+ box-shadow: 0 1px 5px rgba(0,0,0,0.65);
+ border-radius: 4px;
+ }
+.leaflet-bar a,
+.leaflet-bar a:hover {
+ background-color: #fff;
+ border-bottom: 1px solid #ccc;
+ width: 26px;
+ height: 26px;
+ line-height: 26px;
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: black;
+ }
+.leaflet-bar a,
+.leaflet-control-layers-toggle {
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+ display: block;
+ }
+.leaflet-bar a:hover {
+ background-color: #f4f4f4;
+ }
+.leaflet-bar a:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ }
+.leaflet-bar a:last-child {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom: none;
+ }
+.leaflet-bar a.leaflet-disabled {
+ cursor: default;
+ background-color: #f4f4f4;
+ color: #bbb;
+ }
+
+.leaflet-touch .leaflet-bar a {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+ }
+.leaflet-touch .leaflet-bar a:first-child {
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ }
+.leaflet-touch .leaflet-bar a:last-child {
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+ }
+
+/* zoom control */
+
+.leaflet-control-zoom-in,
+.leaflet-control-zoom-out {
+ font: bold 18px 'Lucida Console', Monaco, monospace;
+ text-indent: 1px;
+ }
+
+.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
+ font-size: 22px;
+ }
+
+
+/* layers control */
+
+.leaflet-control-layers {
+ box-shadow: 0 1px 5px rgba(0,0,0,0.4);
+ background: #fff;
+ border-radius: 5px;
+ }
+.leaflet-control-layers-toggle {
+ background-image: url(images/layers.png);
+ width: 36px;
+ height: 36px;
+ }
+.leaflet-retina .leaflet-control-layers-toggle {
+ background-image: url(images/layers-2x.png);
+ background-size: 26px 26px;
+ }
+.leaflet-touch .leaflet-control-layers-toggle {
+ width: 44px;
+ height: 44px;
+ }
+.leaflet-control-layers .leaflet-control-layers-list,
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
+ display: none;
+ }
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
+ display: block;
+ position: relative;
+ }
+.leaflet-control-layers-expanded {
+ padding: 6px 10px 6px 6px;
+ color: #333;
+ background: #fff;
+ }
+.leaflet-control-layers-scrollbar {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ padding-right: 5px;
+ }
+.leaflet-control-layers-selector {
+ margin-top: 2px;
+ position: relative;
+ top: 1px;
+ }
+.leaflet-control-layers label {
+ display: block;
+ }
+.leaflet-control-layers-separator {
+ height: 0;
+ border-top: 1px solid #ddd;
+ margin: 5px -10px 5px -6px;
+ }
+
+/* Default icon URLs */
+.leaflet-default-icon-path {
+ background-image: url(images/marker-icon.png);
+ }
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.7);
+ margin: 0;
+ }
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+ padding: 0 5px;
+ color: #333;
+ }
+.leaflet-control-attribution a {
+ text-decoration: none;
+ }
+.leaflet-control-attribution a:hover {
+ text-decoration: underline;
+ }
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+ font-size: 11px;
+ }
+.leaflet-left .leaflet-control-scale {
+ margin-left: 5px;
+ }
+.leaflet-bottom .leaflet-control-scale {
+ margin-bottom: 5px;
+ }
+.leaflet-control-scale-line {
+ border: 2px solid #777;
+ border-top: none;
+ line-height: 1.1;
+ padding: 2px 5px 1px;
+ font-size: 11px;
+ white-space: nowrap;
+ overflow: hidden;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+
+ background: #fff;
+ background: rgba(255, 255, 255, 0.5);
+ }
+.leaflet-control-scale-line:not(:first-child) {
+ border-top: 2px solid #777;
+ border-bottom: none;
+ margin-top: -2px;
+ }
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
+ border-bottom: 2px solid #777;
+ }
+
+.leaflet-touch .leaflet-control-attribution,
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+ box-shadow: none;
+ }
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+ border: 2px solid rgba(0,0,0,0.2);
+ background-clip: padding-box;
+ }
+
+
+/* popup */
+
+.leaflet-popup {
+ position: absolute;
+ text-align: center;
+ margin-bottom: 20px;
+ }
+.leaflet-popup-content-wrapper {
+ padding: 1px;
+ text-align: left;
+ border-radius: 12px;
+ }
+.leaflet-popup-content {
+ margin: 13px 19px;
+ line-height: 1.4;
+ }
+.leaflet-popup-content p {
+ margin: 18px 0;
+ }
+.leaflet-popup-tip-container {
+ width: 40px;
+ height: 20px;
+ position: absolute;
+ left: 50%;
+ margin-left: -20px;
+ overflow: hidden;
+ pointer-events: none;
+ }
+.leaflet-popup-tip {
+ width: 17px;
+ height: 17px;
+ padding: 1px;
+
+ margin: -10px auto 0;
+
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg);
+ }
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
+ background: white;
+ color: #333;
+ box-shadow: 0 3px 14px rgba(0,0,0,0.4);
+ }
+.leaflet-container a.leaflet-popup-close-button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 4px 4px 0 0;
+ border: none;
+ text-align: center;
+ width: 18px;
+ height: 14px;
+ font: 16px/14px Tahoma, Verdana, sans-serif;
+ color: #c3c3c3;
+ text-decoration: none;
+ font-weight: bold;
+ background: transparent;
+ }
+.leaflet-container a.leaflet-popup-close-button:hover {
+ color: #999;
+ }
+.leaflet-popup-scrolled {
+ overflow: auto;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ }
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+ zoom: 1;
+ }
+.leaflet-oldie .leaflet-popup-tip {
+ width: 24px;
+ margin: 0 auto;
+
+ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
+ filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
+ }
+.leaflet-oldie .leaflet-popup-tip-container {
+ margin-top: -1px;
+ }
+
+.leaflet-oldie .leaflet-control-zoom,
+.leaflet-oldie .leaflet-control-layers,
+.leaflet-oldie .leaflet-popup-content-wrapper,
+.leaflet-oldie .leaflet-popup-tip {
+ border: 1px solid #999;
+ }
+
+
+/* div icon */
+
+.leaflet-div-icon {
+ background: #fff;
+ border: 1px solid #666;
+ }
+
+
+/* Tooltip */
+/* Base styles for the element that has a tooltip */
+.leaflet-tooltip {
+ position: absolute;
+ padding: 6px;
+ background-color: #fff;
+ border: 1px solid #fff;
+ border-radius: 3px;
+ color: #222;
+ white-space: nowrap;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ pointer-events: none;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.4);
+ }
+.leaflet-tooltip.leaflet-clickable {
+ cursor: pointer;
+ pointer-events: auto;
+ }
+.leaflet-tooltip-top:before,
+.leaflet-tooltip-bottom:before,
+.leaflet-tooltip-left:before,
+.leaflet-tooltip-right:before {
+ position: absolute;
+ pointer-events: none;
+ border: 6px solid transparent;
+ background: transparent;
+ content: "";
+ }
+
+/* Directions */
+
+.leaflet-tooltip-bottom {
+ margin-top: 6px;
+}
+.leaflet-tooltip-top {
+ margin-top: -6px;
+}
+.leaflet-tooltip-bottom:before,
+.leaflet-tooltip-top:before {
+ left: 50%;
+ margin-left: -6px;
+ }
+.leaflet-tooltip-top:before {
+ bottom: 0;
+ margin-bottom: -12px;
+ border-top-color: #fff;
+ }
+.leaflet-tooltip-bottom:before {
+ top: 0;
+ margin-top: -12px;
+ margin-left: -6px;
+ border-bottom-color: #fff;
+ }
+.leaflet-tooltip-left {
+ margin-left: -6px;
+}
+.leaflet-tooltip-right {
+ margin-left: 6px;
+}
+.leaflet-tooltip-left:before,
+.leaflet-tooltip-right:before {
+ top: 50%;
+ margin-top: -6px;
+ }
+.leaflet-tooltip-left:before {
+ right: 0;
+ margin-right: -12px;
+ border-left-color: #fff;
+ }
+.leaflet-tooltip-right:before {
+ left: 0;
+ margin-left: -12px;
+ border-right-color: #fff;
+ }
diff --git a/docs/articles/Articles/Applications_files/leaflet-1.3.1/leaflet.js b/docs/articles/Articles/Applications_files/leaflet-1.3.1/leaflet.js
new file mode 100644
index 0000000..4eca8af
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/leaflet-1.3.1/leaflet.js
@@ -0,0 +1,5 @@
+/* @preserve
+ * Leaflet 1.3.1+Detached: ba6f97fff8647e724e4dfe66d2ed7da11f908989.ba6f97f, a JS library for interactive maps. https://leafletjs.com
+ * (c) 2010-2017 Vladimir Agafonkin, (c) 2010-2011 CloudMade
+ */
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e
=0}function I(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function B(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(Qi,n,!1):"touchmove"===i?t.removeEventListener(te,n,!1):"touchend"===i&&(t.removeEventListener(ie,n,!1),t.removeEventListener(ee,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(ne.indexOf(t.target.tagName)<0))return;$(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(Qi,o,!1),se||(document.documentElement.addEventListener(Qi,R,!0),document.documentElement.addEventListener(te,D,!0),document.documentElement.addEventListener(ie,N,!0),document.documentElement.addEventListener(ee,N,!0),se=!0)}function R(t){oe[t.pointerId]=t,re++}function D(t){oe[t.pointerId]&&(oe[t.pointerId]=t)}function N(t){delete oe[t.pointerId],re--}function j(t,i){t.touches=[];for(var e in oe)t.touches.push(oe[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(te,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener(ie,n,!1),t.addEventListener(ee,n,!1)}function F(t,i,e){function n(t){var i;if(Ui){if(!Pi||"mouse"===t.pointerType)return;i=re}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Ui){if(!Pi||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[ue+ae+e]=n,t[ue+he+e]=o,t[ue+"dblclick"+e]=i,t.addEventListener(ae,n,!1),t.addEventListener(he,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[ue+ae+i],n=t[ue+he+i],o=t[ue+"dblclick"+i];return t.removeEventListener(ae,e,!1),t.removeEventListener(he,n,!1),Pi||t.removeEventListener("dblclick",o,!1),this}function V(t,i,e,n){if("object"==typeof i)for(var o in i)G(t,o,i[o],e);else for(var s=0,r=(i=u(i)).length;s100&&n<500||t.target._simulatedClick&&!t._simulated?Q(t):(pi=e,i(t))}function rt(t){return"string"==typeof t?document.getElementById(t):t}function at(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function ht(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function ut(t){var i=t.parentNode;i&&i.removeChild(t)}function lt(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function ct(t){var i=t.parentNode;i.lastChild!==t&&i.appendChild(t)}function _t(t){var i=t.parentNode;i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function dt(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=gt(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function pt(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;nh&&(s=r,h=a);h>e&&(i[s]=1,Et(t,i,e,n,s),Et(t,i,e,s,o))}function kt(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;ni&&(e.push(t[n]),o=n);return oi.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function Ot(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Rt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function Dt(t){return!ei(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Nt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),Dt(t)}function jt(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o0?Math.floor(t):Math.ceil(t)};x.prototype={clone:function(){return new x(this.x,this.y)},add:function(t){return this.clone()._add(w(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(w(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new x(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new x(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=li(this.x),this.y=li(this.y),this},distanceTo:function(t){var i=(t=w(t)).x-this.x,e=t.y-this.y;return Math.sqrt(i*i+e*e)},equals:function(t){return(t=w(t)).x===this.x&&t.y===this.y},contains:function(t){return t=w(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+a(this.x)+", "+a(this.y)+")"}},P.prototype={extend:function(t){return t=w(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new x((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new x(this.min.x,this.max.y)},getTopRight:function(){return new x(this.max.x,this.min.y)},getTopLeft:function(){return this.min},getBottomRight:function(){return this.max},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var i,e;return(t="number"==typeof t[0]||t instanceof x?w(t):b(t))instanceof P?(i=t.min,e=t.max):i=e=t,i.x>=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng1,Yi=!!document.createElement("canvas").getContext,Xi=!(!document.createElementNS||!E("svg").createSVGRect),Ji=!Xi&&function(){try{var t=document.createElement("div");t.innerHTML=' ';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),$i=(Object.freeze||Object)({ie:wi,ielt9:Li,edge:Pi,webkit:bi,android:Ti,android23:zi,androidStock:Ci,opera:Zi,chrome:Si,gecko:Ei,safari:ki,phantom:Ai,opera12:Ii,win:Bi,ie3d:Oi,webkit3d:Ri,gecko3d:Di,any3d:Ni,mobile:ji,mobileWebkit:Wi,mobileWebkit3d:Hi,msPointer:Fi,pointer:Ui,touch:Vi,mobileOpera:qi,mobileGecko:Gi,retina:Ki,canvas:Yi,svg:Xi,vml:Ji}),Qi=Fi?"MSPointerDown":"pointerdown",te=Fi?"MSPointerMove":"pointermove",ie=Fi?"MSPointerUp":"pointerup",ee=Fi?"MSPointerCancel":"pointercancel",ne=["INPUT","SELECT","OPTION"],oe={},se=!1,re=0,ae=Fi?"MSPointerDown":Ui?"pointerdown":"touchstart",he=Fi?"MSPointerUp":Ui?"pointerup":"touchend",ue="_leaflet_",le="_leaflet_events",ce=Bi&&Si?2*window.devicePixelRatio:Ei?window.devicePixelRatio:1,_e={},de=(Object.freeze||Object)({on:V,off:q,stopPropagation:Y,disableScrollPropagation:X,disableClickPropagation:J,preventDefault:$,stop:Q,getMousePosition:tt,getWheelDelta:it,fakeStop:et,skipped:nt,isExternalTarget:ot,addListener:V,removeListener:q}),pe=xt(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]),me=xt(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),fe="webkitTransition"===me||"OTransition"===me?me+"End":"transitionend";if("onselectstart"in document)mi=function(){V(window,"selectstart",$)},fi=function(){q(window,"selectstart",$)};else{var ge=xt(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);mi=function(){if(ge){var t=document.documentElement.style;gi=t[ge],t[ge]="none"}},fi=function(){ge&&(document.documentElement.style[ge]=gi,gi=void 0)}}var ve,ye,xe=(Object.freeze||Object)({TRANSFORM:pe,TRANSITION:me,TRANSITION_END:fe,get:rt,getStyle:at,create:ht,remove:ut,empty:lt,toFront:ct,toBack:_t,hasClass:dt,addClass:pt,removeClass:mt,setClass:ft,getClass:gt,setOpacity:vt,testProp:xt,setTransform:wt,setPosition:Lt,getPosition:Pt,disableTextSelection:mi,enableTextSelection:fi,disableImageDrag:bt,enableImageDrag:Tt,preventOutline:zt,restoreOutline:Mt}),we=ui.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=Pt(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;ithis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),ut(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)ut(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=ht("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=Ni?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return tt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=rt(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");V(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&Ni,pt(t,"leaflet-container"+(Vi?" leaflet-touch":"")+(Ki?" leaflet-retina":"")+(Li?" leaflet-oldie":"")+(ki?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=at(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Lt(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(pt(t.markerPane,"leaflet-zoom-hide"),pt(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){Lt(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n,!1)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t,i){return t&&this.fire("zoomstart"),i||this.fire("movestart"),this},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Lt(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[n(this._container)]=this;var i=t?q:V;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),Ni&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!ot(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!ot(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!nt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||zt(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&$(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.getLatLng&&(!s._radius||s._radius<=10);r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=Ni?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){mt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._trunc();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=ht("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=pe,e=this._proxy.style[i];wt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();wt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){ut(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){this._mapPane&&(n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,pt(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&mt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),Pe=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return pt(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(ut(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),be=function(t){return new Pe(t)};Le.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=ht("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=ht("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)ut(this._controlCorners[t]);ut(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Te=Pe.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e=' ",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),V(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&ni.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),ze=Pe.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=ht("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=ht("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),J(s),V(s,"click",Q),V(s,"click",o,this),V(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";mt(this._zoomInButton,i),mt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&pt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&pt(this._zoomInButton,i)}});Le.mergeOptions({zoomControl:!0}),Le.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new ze,this.addControl(this.zoomControl))});var Me=Pe.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=ht("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=ht("div",i,e)),t.imperial&&(this._iScale=ht("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Ce=Pe.extend({options:{position:"bottomright",prefix:'Leaflet '},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=ht("div","leaflet-control-attribution"),J(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});Le.mergeOptions({attributionControl:!0}),Le.addInitHook(function(){this.options.attributionControl&&(new Ce).addTo(this)});Pe.Layers=Te,Pe.Zoom=ze,Pe.Scale=Me,Pe.Attribution=Ce,be.layers=function(t,i,e){return new Te(t,i,e)},be.zoom=function(t){return new ze(t)},be.scale=function(t){return new Me(t)},be.attribution=function(t){return new Ce(t)};var Ze=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});Ze.addTo=function(t,i){return t.addHandler(i,this),this};var Se,Ee={Events:hi},ke=Vi?"touchstart mousedown":"mousedown",Ae={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Ie={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},Be=ui.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(V(this._dragStartTarget,ke,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Be._dragging===this&&this.finishDrag(),q(this._dragStartTarget,ke,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!dt(this._element,"leaflet-zoom-anim")&&!(Be._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(Be._dragging=this,this._preventOutline&&zt(this._element),bt(),mi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t;this._startPoint=new x(i.clientX,i.clientY),V(document,Ie[t.type],this._onMove,this),V(document,Ae[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY).subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},je=(Object.freeze||Object)({LonLat:De,Mercator:Ne,SphericalMercator:di}),We=i({},_i,{code:"EPSG:3395",projection:Ne,transformation:function(){var t=.5/(Math.PI*Ne.R);return S(t,.5,-t,.5)}()}),He=i({},_i,{code:"EPSG:4326",projection:De,transformation:S(1/180,1,-1/180,.5)}),Fe=i({},ci,{projection:De,transformation:S(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});ci.Earth=_i,ci.EPSG3395=We,ci.EPSG3857=vi,ci.EPSG900913=yi,ci.EPSG4326=He,ci.Simple=Fe;var Ue=ui.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});Le.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?ei(t)?t:[t]:[]).length;ithis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return Dt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=Dt(t),n=0,o=t.length;n=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){tn.prototype._setLatLngs.call(this,t),Dt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return Dt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;ot.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||tn.prototype._containsPoint.call(this,t,!0)}}),nn=qe.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=ei(t)?t:t.features;if(o){for(i=0,e=o.length;i0?o:[i.src]}else{ei(this._url)||(this._url=[this._url]),i.autoplay=!!this.options.autoplay,i.loop=!!this.options.loop;for(var a=0;ao?(i.height=o+"px",pt(t,"leaflet-popup-scrolled")):mt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();Lt(this._container,i.add(e))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,i=parseInt(at(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(Pt(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Q(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});Le.mergeOptions({closePopupOnClick:!0}),Le.include({openPopup:function(t,i,e){return t instanceof un||(t=new un(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),Ue.include({bindPopup:function(t,i){return t instanceof un?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new un(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){if(t instanceof Ue||(i=t,t=this),t instanceof qe)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Q(t),i instanceof Je?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var ln=hn.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){hn.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){hn.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=hn.prototype.getEvents.call(this);return Vi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=ht("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||en&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1this.options.maxZoom||void 0!==this.options.minZoom&&o1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);if(d.z=this._tileZoom,this._isValidTile(d)){var p=this._tiles[this._tileCoordsToKey(d)];p?p.current=!0:r.push(d)}}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var m=document.createDocumentFragment();for(_=0;_e.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new T(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(Ci||i.el.setAttribute("src",ni),ut(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){pt(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,Li&&this.options.opacity<1&&vt(t,this.options.opacity),Ti&&!zi&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),Lt(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){if(this._map){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(vt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(pt(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),Li||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),dn=_n.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Ki&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZoom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),Ti||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return V(n,"load",e(this._tileOnLoad,this,i,n)),V(n,"error",e(this._tileOnError,this,i,n)),this.options.crossOrigin&&(n.crossOrigin=""),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Ki?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){Li?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.getAttribute("src")!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=ni,ut(i),delete this._tiles[t]))}}),pn=dn.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);var s=(e=l(this,e)).detectRetina&&Ki?2:1,r=this.getTileSize();n.width=r.x*s,n.height=r.y*s,this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,dn.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToNwSe(t),e=this._crs,n=b(e.project(i[0]),e.project(i[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===He?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=L.TileLayer.prototype.getTileUrl.call(this,t);return a+c(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});dn.WMS=pn,Yt.wms=function(t,i){return new pn(t,i)};var mn=Ue.extend({options:{padding:.1,tolerance:0},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&pt(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=Pt(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);Ni?wt(this._container,a,e):Lt(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),fn=mn.extend({getEvents:function(){var t=mn.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){mn.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");V(t,"mousemove",o(this._onMouseMove,32,this),this),V(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),V(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){delete this._ctx,ut(this._container),q(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},mn.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Ki?2:1;Lt(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Ki&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){mn.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,n=i.prev;e?e.prev=n:this._drawLast=n,n?n.next=e:this._drawFirst=e,delete t._order,delete this._layers[L.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var i,e=t.options.dashArray.split(","),n=[];for(i=0;i')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),vn={_initContainer:function(){this._container=ht("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(mn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=gn("shape");pt(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=gn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;ut(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=gn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=ei(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=gn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){ct(t._container)},_bringToBack:function(t){_t(t._container)}},yn=Ji?gn:E,xn=mn.extend({getEvents:function(){var t=mn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=yn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=yn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){ut(this._container),q(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){mn.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),Lt(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=yn("path");t.options.className&&pt(i,t.options.className),t.options.interactive&&pt(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){ut(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){ct(t._path)},_bringToBack:function(t){_t(t._path)}});Ji&&xn.include(vn),Le.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this.options.preferCanvas&&Xt()||Jt()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=xn&&Jt({pane:t})||fn&&Xt({pane:t}),this._paneRenderers[t]=i),i}});var wn=en.extend({initialize:function(t,i){en.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});xn.create=yn,xn.pointsToPath=k,nn.geometryToLayer=Wt,nn.coordsToLatLng=Ht,nn.coordsToLatLngs=Ft,nn.latLngToCoords=Ut,nn.latLngsToCoords=Vt,nn.getFeature=qt,nn.asFeature=Gt,Le.mergeOptions({boxZoom:!0});var Ln=Ze.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){V(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){q(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){ut(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),mi(),bt(),this._startPoint=this._map.mouseEventToContainerPoint(t),V(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=ht("div","leaflet-zoom-box",this._container),pt(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();Lt(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(ut(this._box),mt(this._container,"leaflet-crosshair")),fi(),Tt(),q(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});Le.addInitHook("addHandler","boxZoom",Ln),Le.mergeOptions({doubleClickZoom:!0});var Pn=Ze.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});Le.addInitHook("addHandler","doubleClickZoom",Pn),Le.mergeOptions({dragging:!0,inertia:!zi,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var bn=Ze.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Be(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}pt(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){mt(this._map._container,"leaflet-grab"),mt(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.xi.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});Le.addInitHook("addHandler","scrollWheelZoom",zn),Le.mergeOptions({tap:!0,tapTolerance:15});var Mn=Ze.extend({addHooks:function(){V(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){q(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if($(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&pt(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),V(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),q(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&mt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});Vi&&!Ui&&Le.addInitHook("addHandler","tap",Mn),Le.mergeOptions({touchZoom:Vi&&!zi,bounceAtZoomLimits:!0});var Cn=Ze.extend({addHooks:function(){pt(this._map._container,"leaflet-touch-zoom"),V(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){mt(this._map._container,"leaflet-touch-zoom"),q(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),V(document,"touchmove",this._onTouchMove,this),V(document,"touchend",this._onTouchEnd,this),$(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoomi.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0,!1),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),$(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),q(document,"touchmove",this._onTouchMove),q(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});Le.addInitHook("addHandler","touchZoom",Cn),Le.BoxZoom=Ln,Le.DoubleClickZoom=Pn,Le.Drag=bn,Le.Keyboard=Tn,Le.ScrollWheelZoom=zn,Le.Tap=Mn,Le.TouchZoom=Cn;var Zn=window.L;window.L=t,Object.freeze=$t,t.version="1.3.1+HEAD.ba6f97f",t.noConflict=function(){return window.L=Zn,this},t.Control=Pe,t.control=be,t.Browser=$i,t.Evented=ui,t.Mixin=Ee,t.Util=ai,t.Class=v,t.Handler=Ze,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=de,t.DomUtil=xe,t.PosAnimation=we,t.Draggable=Be,t.LineUtil=Oe,t.PolyUtil=Re,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=Z,t.transformation=S,t.Projection=je,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=ci,t.GeoJSON=nn,t.geoJSON=Kt,t.geoJson=sn,t.Layer=Ue,t.LayerGroup=Ve,t.layerGroup=function(t,i){return new Ve(t,i)},t.FeatureGroup=qe,t.featureGroup=function(t){return new qe(t)},t.ImageOverlay=rn,t.imageOverlay=function(t,i,e){return new rn(t,i,e)},t.VideoOverlay=an,t.videoOverlay=function(t,i,e){return new an(t,i,e)},t.DivOverlay=hn,t.Popup=un,t.popup=function(t,i){return new un(t,i)},t.Tooltip=ln,t.tooltip=function(t,i){return new ln(t,i)},t.Icon=Ge,t.icon=function(t){return new Ge(t)},t.DivIcon=cn,t.divIcon=function(t){return new cn(t)},t.Marker=Xe,t.marker=function(t,i){return new Xe(t,i)},t.TileLayer=dn,t.tileLayer=Yt,t.GridLayer=_n,t.gridLayer=function(t){return new _n(t)},t.SVG=xn,t.svg=Jt,t.Renderer=mn,t.Canvas=fn,t.canvas=Xt,t.Path=Je,t.CircleMarker=$e,t.circleMarker=function(t,i){return new $e(t,i)},t.Circle=Qe,t.circle=function(t,i,e){return new Qe(t,i,e)},t.Polyline=tn,t.polyline=function(t,i){return new tn(t,i)},t.Polygon=en,t.polygon=function(t,i){return new en(t,i)},t.Rectangle=wn,t.rectangle=function(t,i){return new wn(t,i)},t.Map=Le,t.map=function(t,i){return new Le(t,i)}});
\ No newline at end of file
diff --git a/docs/articles/Articles/Applications_files/leaflet-binding-2.2.3/leaflet.js b/docs/articles/Articles/Applications_files/leaflet-binding-2.2.3/leaflet.js
new file mode 100644
index 0000000..79dbe71
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/leaflet-binding-2.2.3/leaflet.js
@@ -0,0 +1,2787 @@
+(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 this.effectiveLength) throw new Error("Row argument was out of bounds: " + row + " > " + this.effectiveLength);
+ var colIndex = -1;
+
+ if (typeof col === "undefined") {
+ var rowData = {};
+ this.colnames.forEach(function (name, i) {
+ rowData[name] = _this3.columns[i][row % _this3.columns[i].length];
+ });
+ return rowData;
+ } else if (typeof col === "string") {
+ colIndex = this._colIndex(col);
+ } else if (typeof col === "number") {
+ colIndex = col;
+ }
+
+ if (colIndex < 0 || colIndex > this.columns.length) {
+ if (missingOK) return void 0;else throw new Error("Unknown column index: " + col);
+ }
+
+ return this.columns[colIndex][row % this.columns[colIndex].length];
+ }
+ }, {
+ key: "nrow",
+ value: function nrow() {
+ return this.effectiveLength;
+ }
+ }]);
+
+ return DataFrame;
+}();
+
+exports["default"] = DataFrame;
+
+
+},{"./util":17}],5:[function(require,module,exports){
+"use strict";
+
+var _leaflet = require("./global/leaflet");
+
+var _leaflet2 = _interopRequireDefault(_leaflet);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+// In RMarkdown's self-contained mode, we don't have a way to carry around the
+// images that Leaflet needs but doesn't load into the page. Instead, we'll use
+// the unpkg CDN.
+if (typeof _leaflet2["default"].Icon.Default.imagePath === "undefined") {
+ _leaflet2["default"].Icon.Default.imagePath = "https://unpkg.com/leaflet@1.3.1/dist/images/";
+}
+
+
+},{"./global/leaflet":10}],6:[function(require,module,exports){
+"use strict";
+
+var _leaflet = require("./global/leaflet");
+
+var _leaflet2 = _interopRequireDefault(_leaflet);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+// add texxtsize, textOnly, and style
+_leaflet2["default"].Tooltip.prototype.options.textsize = "10px";
+_leaflet2["default"].Tooltip.prototype.options.textOnly = false;
+_leaflet2["default"].Tooltip.prototype.options.style = null; // copy original layout to not completely stomp it.
+
+var initLayoutOriginal = _leaflet2["default"].Tooltip.prototype._initLayout;
+
+_leaflet2["default"].Tooltip.prototype._initLayout = function () {
+ initLayoutOriginal.call(this);
+ this._container.style.fontSize = this.options.textsize;
+
+ if (this.options.textOnly) {
+ _leaflet2["default"].DomUtil.addClass(this._container, "leaflet-tooltip-text-only");
+ }
+
+ if (this.options.style) {
+ for (var property in this.options.style) {
+ this._container.style[property] = this.options.style[property];
+ }
+ }
+};
+
+
+},{"./global/leaflet":10}],7:[function(require,module,exports){
+"use strict";
+
+var _leaflet = require("./global/leaflet");
+
+var _leaflet2 = _interopRequireDefault(_leaflet);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+var protocolRegex = /^\/\//;
+
+var upgrade_protocol = function upgrade_protocol(urlTemplate) {
+ if (protocolRegex.test(urlTemplate)) {
+ if (window.location.protocol === "file:") {
+ // if in a local file, support http
+ // http should auto upgrade if necessary
+ urlTemplate = "http:" + urlTemplate;
+ }
+ }
+
+ return urlTemplate;
+};
+
+var originalLTileLayerInitialize = _leaflet2["default"].TileLayer.prototype.initialize;
+
+_leaflet2["default"].TileLayer.prototype.initialize = function (urlTemplate, options) {
+ urlTemplate = upgrade_protocol(urlTemplate);
+ originalLTileLayerInitialize.call(this, urlTemplate, options);
+};
+
+var originalLTileLayerWMSInitialize = _leaflet2["default"].TileLayer.WMS.prototype.initialize;
+
+_leaflet2["default"].TileLayer.WMS.prototype.initialize = function (urlTemplate, options) {
+ urlTemplate = upgrade_protocol(urlTemplate);
+ originalLTileLayerWMSInitialize.call(this, urlTemplate, options);
+};
+
+
+},{"./global/leaflet":10}],8:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports["default"] = global.HTMLWidgets;
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],9:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports["default"] = global.jQuery;
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],10:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports["default"] = global.L;
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],11:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports["default"] = global.L.Proj;
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],12:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports["default"] = global.Shiny;
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],13:[function(require,module,exports){
+"use strict";
+
+var _jquery = require("./global/jquery");
+
+var _jquery2 = _interopRequireDefault(_jquery);
+
+var _leaflet = require("./global/leaflet");
+
+var _leaflet2 = _interopRequireDefault(_leaflet);
+
+var _shiny = require("./global/shiny");
+
+var _shiny2 = _interopRequireDefault(_shiny);
+
+var _htmlwidgets = require("./global/htmlwidgets");
+
+var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets);
+
+var _util = require("./util");
+
+var _crs_utils = require("./crs_utils");
+
+var _controlStore = require("./control-store");
+
+var _controlStore2 = _interopRequireDefault(_controlStore);
+
+var _layerManager = require("./layer-manager");
+
+var _layerManager2 = _interopRequireDefault(_layerManager);
+
+var _methods = require("./methods");
+
+var _methods2 = _interopRequireDefault(_methods);
+
+require("./fixup-default-icon");
+
+require("./fixup-default-tooltip");
+
+require("./fixup-url-protocol");
+
+var _dataframe = require("./dataframe");
+
+var _dataframe2 = _interopRequireDefault(_dataframe);
+
+var _clusterLayerStore = require("./cluster-layer-store");
+
+var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+window.LeafletWidget = {};
+window.LeafletWidget.utils = {};
+
+var methods = window.LeafletWidget.methods = _jquery2["default"].extend({}, _methods2["default"]);
+
+window.LeafletWidget.DataFrame = _dataframe2["default"];
+window.LeafletWidget.ClusterLayerStore = _clusterLayerStore2["default"];
+window.LeafletWidget.utils.getCRS = _crs_utils.getCRS; // Send updated bounds back to app. Takes a leaflet event object as input.
+
+function updateBounds(map) {
+ var id = map.getContainer().id;
+ var bounds = map.getBounds();
+
+ _shiny2["default"].onInputChange(id + "_bounds", {
+ north: bounds.getNorthEast().lat,
+ east: bounds.getNorthEast().lng,
+ south: bounds.getSouthWest().lat,
+ west: bounds.getSouthWest().lng
+ });
+
+ _shiny2["default"].onInputChange(id + "_center", {
+ lng: map.getCenter().lng,
+ lat: map.getCenter().lat
+ });
+
+ _shiny2["default"].onInputChange(id + "_zoom", map.getZoom());
+}
+
+function preventUnintendedZoomOnScroll(map) {
+ // Prevent unwanted scroll capturing. Similar in purpose to
+ // https://github.com/CliffCloud/Leaflet.Sleep but with a
+ // different set of heuristics.
+ // The basic idea is that when a mousewheel/DOMMouseScroll
+ // event is seen, we disable scroll wheel zooming until the
+ // user moves their mouse cursor or clicks on the map. This
+ // is slightly trickier than just listening for mousemove,
+ // because mousemove is fired when the page is scrolled,
+ // even if the user did not physically move the mouse. We
+ // handle this by examining the mousemove event's screenX
+ // and screenY properties; if they change, we know it's a
+ // "true" move.
+ // lastScreen can never be null, but its x and y can.
+ var lastScreen = {
+ x: null,
+ y: null
+ };
+ (0, _jquery2["default"])(document).on("mousewheel DOMMouseScroll", "*", function (e) {
+ // Disable zooming (until the mouse moves or click)
+ map.scrollWheelZoom.disable(); // Any mousemove events at this screen position will be ignored.
+
+ lastScreen = {
+ x: e.originalEvent.screenX,
+ y: e.originalEvent.screenY
+ };
+ });
+ (0, _jquery2["default"])(document).on("mousemove", "*", function (e) {
+ // Did the mouse really move?
+ if (map.options.scrollWheelZoom) {
+ if (lastScreen.x !== null && e.screenX !== lastScreen.x || e.screenY !== lastScreen.y) {
+ // It really moved. Enable zooming.
+ map.scrollWheelZoom.enable();
+ lastScreen = {
+ x: null,
+ y: null
+ };
+ }
+ }
+ });
+ (0, _jquery2["default"])(document).on("mousedown", ".leaflet", function (e) {
+ // Clicking always enables zooming.
+ if (map.options.scrollWheelZoom) {
+ map.scrollWheelZoom.enable();
+ lastScreen = {
+ x: null,
+ y: null
+ };
+ }
+ });
+}
+
+_htmlwidgets2["default"].widget({
+ name: "leaflet",
+ type: "output",
+ factory: function factory(el, width, height) {
+ var map = null;
+ return {
+ // we need to store our map in our returned object.
+ getMap: function getMap() {
+ return map;
+ },
+ renderValue: function renderValue(data) {
+ // Create an appropriate CRS Object if specified
+ if (data && data.options && data.options.crs) {
+ data.options.crs = (0, _crs_utils.getCRS)(data.options.crs);
+ } // As per https://github.com/rstudio/leaflet/pull/294#discussion_r79584810
+
+
+ if (map) {
+ map.remove();
+
+ map = function () {
+ return;
+ }(); // undefine map
+
+ }
+
+ if (data.options.mapFactory && typeof data.options.mapFactory === "function") {
+ map = data.options.mapFactory(el, data.options);
+ } else {
+ map = _leaflet2["default"].map(el, data.options);
+ }
+
+ preventUnintendedZoomOnScroll(map); // Store some state in the map object
+
+ map.leafletr = {
+ // Has the map ever rendered successfully?
+ hasRendered: false,
+ // Data to be rendered when resize is called with area != 0
+ pendingRenderData: null
+ }; // Check if the map is rendered statically (no output binding)
+
+ if (_htmlwidgets2["default"].shinyMode && /\bshiny-bound-output\b/.test(el.className)) {
+ map.id = el.id; // Store the map on the element so we can find it later by ID
+
+ (0, _jquery2["default"])(el).data("leaflet-map", map); // When the map is clicked, send the coordinates back to the app
+
+ map.on("click", function (e) {
+ _shiny2["default"].onInputChange(map.id + "_click", {
+ lat: e.latlng.lat,
+ lng: e.latlng.lng,
+ ".nonce": Math.random() // Force reactivity if lat/lng hasn't changed
+
+ });
+ });
+ var groupTimerId = null;
+ map.on("moveend", function (e) {
+ updateBounds(e.target);
+ }).on("layeradd layerremove", function (e) {
+ // If the layer that's coming or going is a group we created, tell
+ // the server.
+ if (map.layerManager.getGroupNameFromLayerGroup(e.layer)) {
+ // But to avoid chattiness, coalesce events
+ if (groupTimerId) {
+ clearTimeout(groupTimerId);
+ groupTimerId = null;
+ }
+
+ groupTimerId = setTimeout(function () {
+ groupTimerId = null;
+
+ _shiny2["default"].onInputChange(map.id + "_groups", map.layerManager.getVisibleGroups());
+ }, 100);
+ }
+ });
+ }
+
+ this.doRenderValue(data, map);
+ },
+ doRenderValue: function doRenderValue(data, map) {
+ // Leaflet does not behave well when you set up a bunch of layers when
+ // the map is not visible (width/height == 0). Popups get misaligned
+ // relative to their owning markers, and the fitBounds calculations
+ // are off. Therefore we wait until the map is actually showing to
+ // render the value (we rely on the resize() callback being invoked
+ // at the appropriate time).
+ if (el.offsetWidth === 0 || el.offsetHeight === 0) {
+ map.leafletr.pendingRenderData = data;
+ return;
+ }
+
+ map.leafletr.pendingRenderData = null; // Merge data options into defaults
+
+ var options = _jquery2["default"].extend({
+ zoomToLimits: "always"
+ }, data.options);
+
+ if (!map.layerManager) {
+ map.controls = new _controlStore2["default"](map);
+ map.layerManager = new _layerManager2["default"](map);
+ } else {
+ map.controls.clear();
+ map.layerManager.clear();
+ }
+
+ var explicitView = false;
+
+ if (data.setView) {
+ explicitView = true;
+ map.setView.apply(map, data.setView);
+ }
+
+ if (data.fitBounds) {
+ explicitView = true;
+ methods.fitBounds.apply(map, data.fitBounds);
+ }
+
+ if (data.flyTo) {
+ if (!explicitView && !map.leafletr.hasRendered) {
+ // must be done to give a initial starting point
+ map.fitWorld();
+ }
+
+ explicitView = true;
+ map.flyTo.apply(map, data.flyTo);
+ }
+
+ if (data.flyToBounds) {
+ if (!explicitView && !map.leafletr.hasRendered) {
+ // must be done to give a initial starting point
+ map.fitWorld();
+ }
+
+ explicitView = true;
+ methods.flyToBounds.apply(map, data.flyToBounds);
+ }
+
+ if (data.options.center) {
+ explicitView = true;
+ } // Returns true if the zoomToLimits option says that the map should be
+ // zoomed to map elements.
+
+
+ function needsZoom() {
+ return options.zoomToLimits === "always" || options.zoomToLimits === "first" && !map.leafletr.hasRendered;
+ }
+
+ if (!explicitView && needsZoom() && !map.getZoom()) {
+ if (data.limits && !_jquery2["default"].isEmptyObject(data.limits)) {
+ // Use the natural limits of what's being drawn on the map
+ // If the size of the bounding box is 0, leaflet gets all weird
+ var pad = 0.006;
+
+ if (data.limits.lat[0] === data.limits.lat[1]) {
+ data.limits.lat[0] = data.limits.lat[0] - pad;
+ data.limits.lat[1] = data.limits.lat[1] + pad;
+ }
+
+ if (data.limits.lng[0] === data.limits.lng[1]) {
+ data.limits.lng[0] = data.limits.lng[0] - pad;
+ data.limits.lng[1] = data.limits.lng[1] + pad;
+ }
+
+ map.fitBounds([[data.limits.lat[0], data.limits.lng[0]], [data.limits.lat[1], data.limits.lng[1]]]);
+ } else {
+ map.fitWorld();
+ }
+ }
+
+ for (var i = 0; data.calls && i < data.calls.length; i++) {
+ var call = data.calls[i];
+ if (methods[call.method]) methods[call.method].apply(map, call.args);else (0, _util.log)("Unknown method " + call.method);
+ }
+
+ map.leafletr.hasRendered = true;
+
+ if (_htmlwidgets2["default"].shinyMode) {
+ setTimeout(function () {
+ updateBounds(map);
+ }, 1);
+ }
+ },
+ resize: function resize(width, height) {
+ if (map) {
+ map.invalidateSize();
+
+ if (map.leafletr.pendingRenderData) {
+ this.doRenderValue(map.leafletr.pendingRenderData, map);
+ }
+ }
+ }
+ };
+ }
+});
+
+if (_htmlwidgets2["default"].shinyMode) {
+ _shiny2["default"].addCustomMessageHandler("leaflet-calls", function (data) {
+ var id = data.id;
+ var el = document.getElementById(id);
+ var map = el ? (0, _jquery2["default"])(el).data("leaflet-map") : null;
+
+ if (!map) {
+ (0, _util.log)("Couldn't find map with id " + id);
+ return;
+ } // If the map has not rendered, stash the proposed `leafletProxy()` calls
+ // in `pendingRenderData.calls` to be run on display via `doRenderValue()`.
+ // This is necessary if the map has not been rendered.
+ // If new pendingRenderData is set via a new `leaflet()`, the previous calls will be discarded.
+
+
+ if (!map.leafletr.hasRendered) {
+ map.leafletr.pendingRenderData.calls = map.leafletr.pendingRenderData.calls.concat(data.calls);
+ return;
+ }
+
+ for (var i = 0; i < data.calls.length; i++) {
+ var call = data.calls[i];
+ var args = call.args;
+
+ for (var _i = 0; _i < call.evals.length; _i++) {
+ window.HTMLWidgets.evaluateStringMember(args, call.evals[_i]);
+ }
+
+ if (call.dependencies) {
+ _shiny2["default"].renderDependencies(call.dependencies);
+ }
+
+ if (methods[call.method]) methods[call.method].apply(map, args);else (0, _util.log)("Unknown method " + call.method);
+ }
+ });
+}
+
+
+},{"./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":14,"./methods":15,"./util":17}],14:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports["default"] = undefined;
+
+var _jquery = require("./global/jquery");
+
+var _jquery2 = _interopRequireDefault(_jquery);
+
+var _leaflet = require("./global/leaflet");
+
+var _leaflet2 = _interopRequireDefault(_leaflet);
+
+var _util = require("./util");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _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); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var LayerManager = /*#__PURE__*/function () {
+ function LayerManager(map) {
+ _classCallCheck(this, LayerManager);
+
+ this._map = map; // BEGIN layer indices
+ // {: {: layer}}
+
+ this._byGroup = {}; // {: {: layer}}
+
+ this._byCategory = {}; // {: layer}
+
+ this._byLayerId = {}; // {: {
+ // "group": ,
+ // "layerId": ,
+ // "category": ,
+ // "container":
+ // }
+ // }
+
+ this._byStamp = {}; // {: {: [, , ...], ...}}
+
+ this._byCrosstalkGroup = {}; // END layer indices
+ // {: L.layerGroup}
+
+ this._categoryContainers = {}; // {: L.layerGroup}
+
+ this._groupContainers = {};
+ }
+
+ _createClass(LayerManager, [{
+ key: "addLayer",
+ value: function addLayer(layer, category, layerId, group, ctGroup, ctKey) {
+ var _this = this;
+
+ // Was a group provided?
+ var hasId = typeof layerId === "string";
+ var grouped = typeof group === "string";
+ var stamp = _leaflet2["default"].Util.stamp(layer) + ""; // This will be the default layer group to add the layer to.
+ // We may overwrite this let before using it (i.e. if a group is assigned).
+ // This one liner creates the _categoryContainers[category] entry if it
+ // doesn't already exist.
+
+ var container = this._categoryContainers[category] = this._categoryContainers[category] || _leaflet2["default"].layerGroup().addTo(this._map);
+
+ var oldLayer = null;
+
+ if (hasId) {
+ // First, remove any layer with the same category and layerId
+ var prefixedLayerId = this._layerIdKey(category, layerId);
+
+ oldLayer = this._byLayerId[prefixedLayerId];
+
+ if (oldLayer) {
+ this._removeLayer(oldLayer);
+ } // Update layerId index
+
+
+ this._byLayerId[prefixedLayerId] = layer;
+ } // Update group index
+
+
+ if (grouped) {
+ this._byGroup[group] = this._byGroup[group] || {};
+ this._byGroup[group][stamp] = layer; // Since a group is assigned, don't add the layer to the category's layer
+ // group; instead, use the group's layer group.
+ // This one liner creates the _groupContainers[group] entry if it doesn't
+ // already exist.
+
+ container = this.getLayerGroup(group, true);
+ } // Update category index
+
+
+ this._byCategory[category] = this._byCategory[category] || {};
+ this._byCategory[category][stamp] = layer; // Update stamp index
+
+ var layerInfo = this._byStamp[stamp] = {
+ layer: layer,
+ group: group,
+ ctGroup: ctGroup,
+ ctKey: ctKey,
+ layerId: layerId,
+ category: category,
+ container: container,
+ hidden: false
+ }; // Update crosstalk group index
+
+ if (ctGroup) {
+ if (layer.setStyle) {
+ // Need to save this info so we know what to set opacity to later
+ layer.options.origOpacity = typeof layer.options.opacity !== "undefined" ? layer.options.opacity : 0.5;
+ layer.options.origFillOpacity = typeof layer.options.fillOpacity !== "undefined" ? layer.options.fillOpacity : 0.2;
+ }
+
+ var ctg = this._byCrosstalkGroup[ctGroup];
+
+ if (!ctg) {
+ ctg = this._byCrosstalkGroup[ctGroup] = {};
+ var crosstalk = global.crosstalk;
+
+ var handleFilter = function handleFilter(e) {
+ if (!e.value) {
+ var groupKeys = Object.keys(ctg);
+
+ for (var i = 0; i < groupKeys.length; i++) {
+ var key = groupKeys[i];
+ var _layerInfo = _this._byStamp[ctg[key]];
+
+ _this._setVisibility(_layerInfo, true);
+ }
+ } else {
+ var selectedKeys = {};
+
+ for (var _i = 0; _i < e.value.length; _i++) {
+ selectedKeys[e.value[_i]] = true;
+ }
+
+ var _groupKeys = Object.keys(ctg);
+
+ for (var _i2 = 0; _i2 < _groupKeys.length; _i2++) {
+ var _key = _groupKeys[_i2];
+ var _layerInfo2 = _this._byStamp[ctg[_key]];
+
+ _this._setVisibility(_layerInfo2, selectedKeys[_groupKeys[_i2]]);
+ }
+ }
+ };
+
+ var filterHandle = new crosstalk.FilterHandle(ctGroup);
+ filterHandle.on("change", handleFilter);
+
+ var handleSelection = function handleSelection(e) {
+ if (!e.value || !e.value.length) {
+ var groupKeys = Object.keys(ctg);
+
+ for (var i = 0; i < groupKeys.length; i++) {
+ var key = groupKeys[i];
+ var _layerInfo3 = _this._byStamp[ctg[key]];
+
+ _this._setOpacity(_layerInfo3, 1.0);
+ }
+ } else {
+ var selectedKeys = {};
+
+ for (var _i3 = 0; _i3 < e.value.length; _i3++) {
+ selectedKeys[e.value[_i3]] = true;
+ }
+
+ var _groupKeys2 = Object.keys(ctg);
+
+ for (var _i4 = 0; _i4 < _groupKeys2.length; _i4++) {
+ var _key2 = _groupKeys2[_i4];
+ var _layerInfo4 = _this._byStamp[ctg[_key2]];
+
+ _this._setOpacity(_layerInfo4, selectedKeys[_groupKeys2[_i4]] ? 1.0 : 0.2);
+ }
+ }
+ };
+
+ var selHandle = new crosstalk.SelectionHandle(ctGroup);
+ selHandle.on("change", handleSelection);
+ setTimeout(function () {
+ handleFilter({
+ value: filterHandle.filteredKeys
+ });
+ handleSelection({
+ value: selHandle.value
+ });
+ }, 100);
+ }
+
+ if (!ctg[ctKey]) ctg[ctKey] = [];
+ ctg[ctKey].push(stamp);
+ } // Add to container
+
+
+ if (!layerInfo.hidden) container.addLayer(layer);
+ return oldLayer;
+ }
+ }, {
+ key: "brush",
+ value: function brush(bounds, extraInfo) {
+ var _this2 = this;
+
+ /* eslint-disable no-console */
+ // For each Crosstalk group...
+ Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) {
+ var ctg = _this2._byCrosstalkGroup[ctGroupName];
+ var selection = []; // ...iterate over each Crosstalk key (each of which may have multiple
+ // layers)...
+
+ Object.keys(ctg).forEach(function (ctKey) {
+ // ...and for each layer...
+ ctg[ctKey].forEach(function (stamp) {
+ var layerInfo = _this2._byStamp[stamp]; // ...if it's something with a point...
+
+ if (layerInfo.layer.getLatLng) {
+ // ... and it's inside the selection bounds...
+ // TODO: Use pixel containment, not lat/lng containment
+ if (bounds.contains(layerInfo.layer.getLatLng())) {
+ // ...add the key to the selection.
+ selection.push(ctKey);
+ }
+ }
+ });
+ });
+ new global.crosstalk.SelectionHandle(ctGroupName).set(selection, extraInfo);
+ });
+ }
+ }, {
+ key: "unbrush",
+ value: function unbrush(extraInfo) {
+ Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) {
+ new global.crosstalk.SelectionHandle(ctGroupName).clear(extraInfo);
+ });
+ }
+ }, {
+ key: "_setVisibility",
+ value: function _setVisibility(layerInfo, visible) {
+ if (layerInfo.hidden ^ visible) {
+ return;
+ } else if (visible) {
+ layerInfo.container.addLayer(layerInfo.layer);
+ layerInfo.hidden = false;
+ } else {
+ layerInfo.container.removeLayer(layerInfo.layer);
+ layerInfo.hidden = true;
+ }
+ }
+ }, {
+ key: "_setOpacity",
+ value: function _setOpacity(layerInfo, opacity) {
+ if (layerInfo.layer.setOpacity) {
+ layerInfo.layer.setOpacity(opacity);
+ } else if (layerInfo.layer.setStyle) {
+ layerInfo.layer.setStyle({
+ opacity: opacity * layerInfo.layer.options.origOpacity,
+ fillOpacity: opacity * layerInfo.layer.options.origFillOpacity
+ });
+ }
+ }
+ }, {
+ key: "getLayer",
+ value: function getLayer(category, layerId) {
+ return this._byLayerId[this._layerIdKey(category, layerId)];
+ }
+ }, {
+ key: "removeLayer",
+ value: function removeLayer(category, layerIds) {
+ var _this3 = this;
+
+ // Find layer info
+ _jquery2["default"].each((0, _util.asArray)(layerIds), function (i, layerId) {
+ var layer = _this3._byLayerId[_this3._layerIdKey(category, layerId)];
+
+ if (layer) {
+ _this3._removeLayer(layer);
+ }
+ });
+ }
+ }, {
+ key: "clearLayers",
+ value: function clearLayers(category) {
+ var _this4 = this;
+
+ // Find all layers in _byCategory[category]
+ var catTable = this._byCategory[category];
+
+ if (!catTable) {
+ return false;
+ } // Remove all layers. Make copy of keys to avoid mutating the collection
+ // behind the iterator you're accessing.
+
+
+ var stamps = [];
+
+ _jquery2["default"].each(catTable, function (k, v) {
+ stamps.push(k);
+ });
+
+ _jquery2["default"].each(stamps, function (i, stamp) {
+ _this4._removeLayer(stamp);
+ });
+ }
+ }, {
+ key: "getLayerGroup",
+ value: function getLayerGroup(group, ensureExists) {
+ var g = this._groupContainers[group];
+
+ if (ensureExists && !g) {
+ this._byGroup[group] = this._byGroup[group] || {};
+ g = this._groupContainers[group] = _leaflet2["default"].featureGroup();
+ g.groupname = group;
+ g.addTo(this._map);
+ }
+
+ return g;
+ }
+ }, {
+ key: "getGroupNameFromLayerGroup",
+ value: function getGroupNameFromLayerGroup(layerGroup) {
+ return layerGroup.groupname;
+ }
+ }, {
+ key: "getVisibleGroups",
+ value: function getVisibleGroups() {
+ var _this5 = this;
+
+ var result = [];
+
+ _jquery2["default"].each(this._groupContainers, function (k, v) {
+ if (_this5._map.hasLayer(v)) {
+ result.push(k);
+ }
+ });
+
+ return result;
+ }
+ }, {
+ key: "getAllGroupNames",
+ value: function getAllGroupNames() {
+ var result = [];
+
+ _jquery2["default"].each(this._groupContainers, function (k, v) {
+ result.push(k);
+ });
+
+ return result;
+ }
+ }, {
+ key: "clearGroup",
+ value: function clearGroup(group) {
+ var _this6 = this;
+
+ // Find all layers in _byGroup[group]
+ var groupTable = this._byGroup[group];
+
+ if (!groupTable) {
+ return false;
+ } // Remove all layers. Make copy of keys to avoid mutating the collection
+ // behind the iterator you're accessing.
+
+
+ var stamps = [];
+
+ _jquery2["default"].each(groupTable, function (k, v) {
+ stamps.push(k);
+ });
+
+ _jquery2["default"].each(stamps, function (i, stamp) {
+ _this6._removeLayer(stamp);
+ });
+ }
+ }, {
+ key: "clear",
+ value: function clear() {
+ function clearLayerGroup(key, layerGroup) {
+ layerGroup.clearLayers();
+ } // Clear all indices and layerGroups
+
+
+ this._byGroup = {};
+ this._byCategory = {};
+ this._byLayerId = {};
+ this._byStamp = {};
+ this._byCrosstalkGroup = {};
+
+ _jquery2["default"].each(this._categoryContainers, clearLayerGroup);
+
+ this._categoryContainers = {};
+
+ _jquery2["default"].each(this._groupContainers, clearLayerGroup);
+
+ this._groupContainers = {};
+ }
+ }, {
+ key: "_removeLayer",
+ value: function _removeLayer(layer) {
+ var stamp;
+
+ if (typeof layer === "string") {
+ stamp = layer;
+ } else {
+ stamp = _leaflet2["default"].Util.stamp(layer);
+ }
+
+ var layerInfo = this._byStamp[stamp];
+
+ if (!layerInfo) {
+ return false;
+ }
+
+ layerInfo.container.removeLayer(stamp);
+
+ if (typeof layerInfo.group === "string") {
+ delete this._byGroup[layerInfo.group][stamp];
+ }
+
+ if (typeof layerInfo.layerId === "string") {
+ delete this._byLayerId[this._layerIdKey(layerInfo.category, layerInfo.layerId)];
+ }
+
+ delete this._byCategory[layerInfo.category][stamp];
+ delete this._byStamp[stamp];
+
+ if (layerInfo.ctGroup) {
+ var ctGroup = this._byCrosstalkGroup[layerInfo.ctGroup];
+ var layersForKey = ctGroup[layerInfo.ctKey];
+ var idx = layersForKey ? layersForKey.indexOf(stamp) : -1;
+
+ if (idx >= 0) {
+ if (layersForKey.length === 1) {
+ delete ctGroup[layerInfo.ctKey];
+ } else {
+ layersForKey.splice(idx, 1);
+ }
+ }
+ }
+ }
+ }, {
+ key: "_layerIdKey",
+ value: function _layerIdKey(category, layerId) {
+ return category + "\n" + layerId;
+ }
+ }]);
+
+ return LayerManager;
+}();
+
+exports["default"] = LayerManager;
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./global/jquery":9,"./global/leaflet":10,"./util":17}],15:[function(require,module,exports){
+(function (global){(function (){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _jquery = require("./global/jquery");
+
+var _jquery2 = _interopRequireDefault(_jquery);
+
+var _leaflet = require("./global/leaflet");
+
+var _leaflet2 = _interopRequireDefault(_leaflet);
+
+var _shiny = require("./global/shiny");
+
+var _shiny2 = _interopRequireDefault(_shiny);
+
+var _htmlwidgets = require("./global/htmlwidgets");
+
+var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets);
+
+var _util = require("./util");
+
+var _crs_utils = require("./crs_utils");
+
+var _dataframe = require("./dataframe");
+
+var _dataframe2 = _interopRequireDefault(_dataframe);
+
+var _clusterLayerStore = require("./cluster-layer-store");
+
+var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore);
+
+var _mipmapper = require("./mipmapper");
+
+var _mipmapper2 = _interopRequireDefault(_mipmapper);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+var methods = {};
+exports["default"] = methods;
+
+function mouseHandler(mapId, layerId, group, eventName, extraInfo) {
+ return function (e) {
+ if (!_htmlwidgets2["default"].shinyMode) return;
+ var latLng = e.target.getLatLng ? e.target.getLatLng() : e.latlng;
+
+ if (latLng) {
+ // retrieve only lat, lon values to remove prototype
+ // and extra parameters added by 3rd party modules
+ // these objects are for json serialization, not javascript
+ var latLngVal = _leaflet2["default"].latLng(latLng); // make sure it has consistent shape
+
+
+ latLng = {
+ lat: latLngVal.lat,
+ lng: latLngVal.lng
+ };
+ }
+
+ var eventInfo = _jquery2["default"].extend({
+ id: layerId,
+ ".nonce": Math.random() // force reactivity
+
+ }, group !== null ? {
+ group: group
+ } : null, latLng, extraInfo);
+
+ _shiny2["default"].onInputChange(mapId + "_" + eventName, eventInfo);
+ };
+}
+
+methods.mouseHandler = mouseHandler;
+
+methods.clearGroup = function (group) {
+ var _this = this;
+
+ _jquery2["default"].each((0, _util.asArray)(group), function (i, v) {
+ _this.layerManager.clearGroup(v);
+ });
+};
+
+methods.setView = function (center, zoom, options) {
+ this.setView(center, zoom, options);
+};
+
+methods.fitBounds = function (lat1, lng1, lat2, lng2, options) {
+ this.fitBounds([[lat1, lng1], [lat2, lng2]], options);
+};
+
+methods.flyTo = function (center, zoom, options) {
+ this.flyTo(center, zoom, options);
+};
+
+methods.flyToBounds = function (lat1, lng1, lat2, lng2, options) {
+ this.flyToBounds([[lat1, lng1], [lat2, lng2]], options);
+};
+
+methods.setMaxBounds = function (lat1, lng1, lat2, lng2) {
+ this.setMaxBounds([[lat1, lng1], [lat2, lng2]]);
+};
+
+methods.addPopups = function (lat, lng, popup, layerId, group, options) {
+ var _this2 = this;
+
+ var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("popup", popup).col("layerId", layerId).col("group", group).cbind(options);
+
+ var _loop = function _loop(i) {
+ if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) {
+ (function () {
+ var popup = _leaflet2["default"].popup(df.get(i)).setLatLng([df.get(i, "lat"), df.get(i, "lng")]).setContent(df.get(i, "popup"));
+
+ var thisId = df.get(i, "layerId");
+ var thisGroup = df.get(i, "group");
+ this.layerManager.addLayer(popup, "popup", thisId, thisGroup);
+ }).call(_this2);
+ }
+ };
+
+ for (var i = 0; i < df.nrow(); i++) {
+ _loop(i);
+ }
+};
+
+methods.removePopup = function (layerId) {
+ this.layerManager.removeLayer("popup", layerId);
+};
+
+methods.clearPopups = function () {
+ this.layerManager.clearLayers("popup");
+};
+
+methods.addTiles = function (urlTemplate, layerId, group, options) {
+ this.layerManager.addLayer(_leaflet2["default"].tileLayer(urlTemplate, options), "tile", layerId, group);
+};
+
+methods.removeTiles = function (layerId) {
+ this.layerManager.removeLayer("tile", layerId);
+};
+
+methods.clearTiles = function () {
+ this.layerManager.clearLayers("tile");
+};
+
+methods.addWMSTiles = function (baseUrl, layerId, group, options) {
+ if (options && options.crs) {
+ options.crs = (0, _crs_utils.getCRS)(options.crs);
+ }
+
+ this.layerManager.addLayer(_leaflet2["default"].tileLayer.wms(baseUrl, options), "tile", layerId, group);
+}; // Given:
+// {data: ["a", "b", "c"], index: [0, 1, 0, 2]}
+// returns:
+// ["a", "b", "a", "c"]
+
+
+function unpackStrings(iconset) {
+ if (!iconset) {
+ return iconset;
+ }
+
+ if (typeof iconset.index === "undefined") {
+ return iconset;
+ }
+
+ iconset.data = (0, _util.asArray)(iconset.data);
+ iconset.index = (0, _util.asArray)(iconset.index);
+ return _jquery2["default"].map(iconset.index, function (e, i) {
+ return iconset.data[e];
+ });
+}
+
+function addMarkers(map, df, group, clusterOptions, clusterId, markerFunc) {
+ (function () {
+ var _this3 = this;
+
+ var clusterGroup = this.layerManager.getLayer("cluster", clusterId),
+ cluster = clusterOptions !== null;
+
+ if (cluster && !clusterGroup) {
+ clusterGroup = _leaflet2["default"].markerClusterGroup.layerSupport(clusterOptions);
+
+ if (clusterOptions.freezeAtZoom) {
+ var freezeAtZoom = clusterOptions.freezeAtZoom;
+ delete clusterOptions.freezeAtZoom;
+ clusterGroup.freezeAtZoom(freezeAtZoom);
+ }
+
+ clusterGroup.clusterLayerStore = new _clusterLayerStore2["default"](clusterGroup);
+ }
+
+ var extraInfo = cluster ? {
+ clusterId: clusterId
+ } : {};
+
+ var _loop2 = function _loop2(i) {
+ if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) {
+ (function () {
+ var marker = markerFunc(df, i);
+ var thisId = df.get(i, "layerId");
+ var thisGroup = cluster ? null : df.get(i, "group");
+
+ if (cluster) {
+ clusterGroup.clusterLayerStore.add(marker, thisId);
+ } else {
+ this.layerManager.addLayer(marker, "marker", thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true));
+ }
+
+ var popup = df.get(i, "popup");
+ var popupOptions = df.get(i, "popupOptions");
+
+ if (popup !== null) {
+ if (popupOptions !== null) {
+ marker.bindPopup(popup, popupOptions);
+ } else {
+ marker.bindPopup(popup);
+ }
+ }
+
+ var label = df.get(i, "label");
+ var labelOptions = df.get(i, "labelOptions");
+
+ if (label !== null) {
+ if (labelOptions !== null) {
+ if (labelOptions.permanent) {
+ marker.bindTooltip(label, labelOptions).openTooltip();
+ } else {
+ marker.bindTooltip(label, labelOptions);
+ }
+ } else {
+ marker.bindTooltip(label);
+ }
+ }
+
+ marker.on("click", mouseHandler(this.id, thisId, thisGroup, "marker_click", extraInfo), this);
+ marker.on("mouseover", mouseHandler(this.id, thisId, thisGroup, "marker_mouseover", extraInfo), this);
+ marker.on("mouseout", mouseHandler(this.id, thisId, thisGroup, "marker_mouseout", extraInfo), this);
+ marker.on("dragend", mouseHandler(this.id, thisId, thisGroup, "marker_dragend", extraInfo), this);
+ }).call(_this3);
+ }
+ };
+
+ for (var i = 0; i < df.nrow(); i++) {
+ _loop2(i);
+ }
+
+ if (cluster) {
+ this.layerManager.addLayer(clusterGroup, "cluster", clusterId, group);
+ }
+ }).call(map);
+}
+
+methods.addGenericMarkers = addMarkers;
+
+methods.addMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) {
+ var icondf;
+ var getIcon;
+
+ if (icon) {
+ // Unpack icons
+ icon.iconUrl = unpackStrings(icon.iconUrl);
+ icon.iconRetinaUrl = unpackStrings(icon.iconRetinaUrl);
+ icon.shadowUrl = unpackStrings(icon.shadowUrl);
+ icon.shadowRetinaUrl = unpackStrings(icon.shadowRetinaUrl); // This cbinds the icon URLs and any other icon options; they're all
+ // present on the icon object.
+
+ icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe.
+
+ getIcon = function getIcon(i) {
+ var opts = icondf.get(i);
+
+ if (!opts.iconUrl) {
+ return new _leaflet2["default"].Icon.Default();
+ } // Composite options (like points or sizes) are passed from R with each
+ // individual component as its own option. We need to combine them now
+ // into their composite form.
+
+
+ if (opts.iconWidth) {
+ opts.iconSize = [opts.iconWidth, opts.iconHeight];
+ }
+
+ if (opts.shadowWidth) {
+ opts.shadowSize = [opts.shadowWidth, opts.shadowHeight];
+ }
+
+ if (opts.iconAnchorX) {
+ opts.iconAnchor = [opts.iconAnchorX, opts.iconAnchorY];
+ }
+
+ if (opts.shadowAnchorX) {
+ opts.shadowAnchor = [opts.shadowAnchorX, opts.shadowAnchorY];
+ }
+
+ if (opts.popupAnchorX) {
+ opts.popupAnchor = [opts.popupAnchorX, opts.popupAnchorY];
+ }
+
+ return new _leaflet2["default"].Icon(opts);
+ };
+ }
+
+ if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
+ 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 || {});
+ if (icon) icondf.effectiveLength = df.nrow();
+ addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
+ var options = df.get(i);
+ if (icon) options.icon = getIcon(i);
+ return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options);
+ });
+ }
+};
+
+methods.addAwesomeMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) {
+ var icondf;
+ var getIcon;
+
+ if (icon) {
+ // This cbinds the icon URLs and any other icon options; they're all
+ // present on the icon object.
+ icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe.
+
+ getIcon = function getIcon(i) {
+ var opts = icondf.get(i);
+
+ if (!opts) {
+ return new _leaflet2["default"].AwesomeMarkers.icon();
+ }
+
+ if (opts.squareMarker) {
+ opts.className = "awesome-marker awesome-marker-square";
+ }
+
+ return new _leaflet2["default"].AwesomeMarkers.icon(opts);
+ };
+ }
+
+ if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
+ 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 || {});
+ if (icon) icondf.effectiveLength = df.nrow();
+ addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
+ var options = df.get(i);
+ if (icon) options.icon = getIcon(i);
+ return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options);
+ });
+ }
+};
+
+function addLayers(map, category, df, layerFunc) {
+ var _loop3 = function _loop3(i) {
+ (function () {
+ var layer = layerFunc(df, i);
+
+ if (!_jquery2["default"].isEmptyObject(layer)) {
+ var thisId = df.get(i, "layerId");
+ var thisGroup = df.get(i, "group");
+ this.layerManager.addLayer(layer, category, thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true));
+
+ if (layer.bindPopup) {
+ var popup = df.get(i, "popup");
+ var popupOptions = df.get(i, "popupOptions");
+
+ if (popup !== null) {
+ if (popupOptions !== null) {
+ layer.bindPopup(popup, popupOptions);
+ } else {
+ layer.bindPopup(popup);
+ }
+ }
+ }
+
+ if (layer.bindTooltip) {
+ var label = df.get(i, "label");
+ var labelOptions = df.get(i, "labelOptions");
+
+ if (label !== null) {
+ if (labelOptions !== null) {
+ layer.bindTooltip(label, labelOptions);
+ } else {
+ layer.bindTooltip(label);
+ }
+ }
+ }
+
+ layer.on("click", mouseHandler(this.id, thisId, thisGroup, category + "_click"), this);
+ layer.on("mouseover", mouseHandler(this.id, thisId, thisGroup, category + "_mouseover"), this);
+ layer.on("mouseout", mouseHandler(this.id, thisId, thisGroup, category + "_mouseout"), this);
+ var highlightStyle = df.get(i, "highlightOptions");
+
+ if (!_jquery2["default"].isEmptyObject(highlightStyle)) {
+ var defaultStyle = {};
+
+ _jquery2["default"].each(highlightStyle, function (k, v) {
+ if (k != "bringToFront" && k != "sendToBack") {
+ if (df.get(i, k)) {
+ defaultStyle[k] = df.get(i, k);
+ }
+ }
+ });
+
+ layer.on("mouseover", function (e) {
+ this.setStyle(highlightStyle);
+
+ if (highlightStyle.bringToFront) {
+ this.bringToFront();
+ }
+ });
+ layer.on("mouseout", function (e) {
+ this.setStyle(defaultStyle);
+
+ if (highlightStyle.sendToBack) {
+ this.bringToBack();
+ }
+ });
+ }
+ }
+ }).call(map);
+ };
+
+ for (var i = 0; i < df.nrow(); i++) {
+ _loop3(i);
+ }
+}
+
+methods.addGenericLayers = addLayers;
+
+methods.addCircles = function (lat, lng, radius, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions, crosstalkOptions) {
+ if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
+ 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 || {});
+ addLayers(this, "shape", df, function (df, i) {
+ if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng")) && _jquery2["default"].isNumeric(df.get(i, "radius"))) {
+ return _leaflet2["default"].circle([df.get(i, "lat"), df.get(i, "lng")], df.get(i, "radius"), df.get(i));
+ } else {
+ return null;
+ }
+ });
+ }
+};
+
+methods.addCircleMarkers = function (lat, lng, radius, layerId, group, options, clusterOptions, clusterId, popup, popupOptions, label, labelOptions, crosstalkOptions) {
+ if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
+ 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);
+ addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
+ return _leaflet2["default"].circleMarker([df.get(i, "lat"), df.get(i, "lng")], df.get(i));
+ });
+ }
+};
+/*
+ * @param lat Array of arrays of latitude coordinates for polylines
+ * @param lng Array of arrays of longitude coordinates for polylines
+ */
+
+
+methods.addPolylines = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
+ if (polygons.length > 0) {
+ 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);
+ addLayers(this, "shape", df, function (df, i) {
+ var shapes = df.get(i, "shapes");
+ shapes = shapes.map(function (shape) {
+ return _htmlwidgets2["default"].dataframeToD3(shape[0]);
+ });
+
+ if (shapes.length > 1) {
+ return _leaflet2["default"].polyline(shapes, df.get(i));
+ } else {
+ return _leaflet2["default"].polyline(shapes[0], df.get(i));
+ }
+ });
+ }
+};
+
+methods.removeMarker = function (layerId) {
+ this.layerManager.removeLayer("marker", layerId);
+};
+
+methods.clearMarkers = function () {
+ this.layerManager.clearLayers("marker");
+};
+
+methods.removeMarkerCluster = function (layerId) {
+ this.layerManager.removeLayer("cluster", layerId);
+};
+
+methods.removeMarkerFromCluster = function (layerId, clusterId) {
+ var cluster = this.layerManager.getLayer("cluster", clusterId);
+ if (!cluster) return;
+ cluster.clusterLayerStore.remove(layerId);
+};
+
+methods.clearMarkerClusters = function () {
+ this.layerManager.clearLayers("cluster");
+};
+
+methods.removeShape = function (layerId) {
+ this.layerManager.removeLayer("shape", layerId);
+};
+
+methods.clearShapes = function () {
+ this.layerManager.clearLayers("shape");
+};
+
+methods.addRectangles = function (lat1, lng1, lat2, lng2, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
+ 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);
+ addLayers(this, "shape", df, function (df, i) {
+ 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"))) {
+ return _leaflet2["default"].rectangle([[df.get(i, "lat1"), df.get(i, "lng1")], [df.get(i, "lat2"), df.get(i, "lng2")]], df.get(i));
+ } else {
+ return null;
+ }
+ });
+};
+/*
+ * @param lat Array of arrays of latitude coordinates for polygons
+ * @param lng Array of arrays of longitude coordinates for polygons
+ */
+
+
+methods.addPolygons = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
+ if (polygons.length > 0) {
+ 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);
+ addLayers(this, "shape", df, function (df, i) {
+ // This code used to use L.multiPolygon, but that caused
+ // double-click on a multipolygon to fail to zoom in on the
+ // map. Surprisingly, putting all the rings in a single
+ // polygon seems to still work; complicated multipolygons
+ // are still rendered correctly.
+ var shapes = df.get(i, "shapes").map(function (polygon) {
+ return polygon.map(_htmlwidgets2["default"].dataframeToD3);
+ }).reduce(function (acc, val) {
+ return acc.concat(val);
+ }, []);
+ return _leaflet2["default"].polygon(shapes, df.get(i));
+ });
+ }
+};
+
+methods.addGeoJSON = function (data, layerId, group, style) {
+ // This time, self is actually needed because the callbacks below need
+ // to access both the inner and outer senses of "this"
+ var self = this;
+
+ if (typeof data === "string") {
+ data = JSON.parse(data);
+ }
+
+ var globalStyle = _jquery2["default"].extend({}, style, data.style || {});
+
+ var gjlayer = _leaflet2["default"].geoJson(data, {
+ style: function style(feature) {
+ if (feature.style || feature.properties.style) {
+ return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style);
+ } else {
+ return globalStyle;
+ }
+ },
+ onEachFeature: function onEachFeature(feature, layer) {
+ var extraInfo = {
+ featureId: feature.id,
+ properties: feature.properties
+ };
+ var popup = feature.properties ? feature.properties.popup : null;
+ if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup);
+ layer.on("click", mouseHandler(self.id, layerId, group, "geojson_click", extraInfo), this);
+ layer.on("mouseover", mouseHandler(self.id, layerId, group, "geojson_mouseover", extraInfo), this);
+ layer.on("mouseout", mouseHandler(self.id, layerId, group, "geojson_mouseout", extraInfo), this);
+ }
+ });
+
+ this.layerManager.addLayer(gjlayer, "geojson", layerId, group);
+};
+
+methods.removeGeoJSON = function (layerId) {
+ this.layerManager.removeLayer("geojson", layerId);
+};
+
+methods.clearGeoJSON = function () {
+ this.layerManager.clearLayers("geojson");
+};
+
+methods.addTopoJSON = function (data, layerId, group, style) {
+ // This time, self is actually needed because the callbacks below need
+ // to access both the inner and outer senses of "this"
+ var self = this;
+
+ if (typeof data === "string") {
+ data = JSON.parse(data);
+ }
+
+ var globalStyle = _jquery2["default"].extend({}, style, data.style || {});
+
+ var gjlayer = _leaflet2["default"].geoJson(null, {
+ style: function style(feature) {
+ if (feature.style || feature.properties.style) {
+ return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style);
+ } else {
+ return globalStyle;
+ }
+ },
+ onEachFeature: function onEachFeature(feature, layer) {
+ var extraInfo = {
+ featureId: feature.id,
+ properties: feature.properties
+ };
+ var popup = feature.properties.popup;
+ if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup);
+ layer.on("click", mouseHandler(self.id, layerId, group, "topojson_click", extraInfo), this);
+ layer.on("mouseover", mouseHandler(self.id, layerId, group, "topojson_mouseover", extraInfo), this);
+ layer.on("mouseout", mouseHandler(self.id, layerId, group, "topojson_mouseout", extraInfo), this);
+ }
+ });
+
+ global.omnivore.topojson.parse(data, null, gjlayer);
+ this.layerManager.addLayer(gjlayer, "topojson", layerId, group);
+};
+
+methods.removeTopoJSON = function (layerId) {
+ this.layerManager.removeLayer("topojson", layerId);
+};
+
+methods.clearTopoJSON = function () {
+ this.layerManager.clearLayers("topojson");
+};
+
+methods.addControl = function (html, position, layerId, classes) {
+ function onAdd(map) {
+ var div = _leaflet2["default"].DomUtil.create("div", classes);
+
+ if (typeof layerId !== "undefined" && layerId !== null) {
+ div.setAttribute("id", layerId);
+ }
+
+ this._div = div; // It's possible for window.Shiny to be true but Shiny.initializeInputs to
+ // not be, when a static leaflet widget is included as part of the shiny
+ // UI directly (not through leafletOutput or uiOutput). In this case we
+ // don't do the normal Shiny stuff as that will all happen when Shiny
+ // itself loads and binds the entire doc.
+
+ if (window.Shiny && _shiny2["default"].initializeInputs) {
+ _shiny2["default"].renderHtml(html, this._div);
+
+ _shiny2["default"].initializeInputs(this._div);
+
+ _shiny2["default"].bindAll(this._div);
+ } else {
+ this._div.innerHTML = html;
+ }
+
+ return this._div;
+ }
+
+ function onRemove(map) {
+ if (window.Shiny && _shiny2["default"].unbindAll) {
+ _shiny2["default"].unbindAll(this._div);
+ }
+ }
+
+ var Control = _leaflet2["default"].Control.extend({
+ options: {
+ position: position
+ },
+ onAdd: onAdd,
+ onRemove: onRemove
+ });
+
+ this.controls.add(new Control(), layerId, html);
+};
+
+methods.addCustomControl = function (control, layerId) {
+ this.controls.add(control, layerId);
+};
+
+methods.removeControl = function (layerId) {
+ this.controls.remove(layerId);
+};
+
+methods.getControl = function (layerId) {
+ this.controls.get(layerId);
+};
+
+methods.clearControls = function () {
+ this.controls.clear();
+};
+
+methods.addLegend = function (options) {
+ var legend = _leaflet2["default"].control({
+ position: options.position
+ });
+
+ var gradSpan;
+
+ legend.onAdd = function (map) {
+ var div = _leaflet2["default"].DomUtil.create("div", options.className),
+ colors = options.colors,
+ labels = options.labels,
+ legendHTML = "";
+
+ if (options.type === "numeric") {
+ // # Formatting constants.
+ var singleBinHeight = 20; // The distance between tick marks, in px
+
+ var vMargin = 8; // If 1st tick mark starts at top of gradient, how
+ // many extra px are needed for the top half of the
+ // 1st label? (ditto for last tick mark/label)
+
+ var tickWidth = 4; // How wide should tick marks be, in px?
+
+ var labelPadding = 6; // How much distance to reserve for tick mark?
+ // (Must be >= tickWidth)
+ // # Derived formatting parameters.
+ // What's the height of a single bin, in percentage (of gradient height)?
+ // It might not just be 1/(n-1), if the gradient extends past the tick
+ // marks (which can be the case for pretty cut points).
+
+ var singleBinPct = (options.extra.p_n - options.extra.p_1) / (labels.length - 1); // Each bin is `singleBinHeight` high. How tall is the gradient?
+
+ var totalHeight = 1 / singleBinPct * singleBinHeight + 1; // How far should the first tick be shifted down, relative to the top
+ // of the gradient?
+
+ var tickOffset = singleBinHeight / singleBinPct * options.extra.p_1;
+ gradSpan = (0, _jquery2["default"])(" ").css({
+ "background": "linear-gradient(" + colors + ")",
+ "opacity": options.opacity,
+ "height": totalHeight + "px",
+ "width": "18px",
+ "display": "block",
+ "margin-top": vMargin + "px"
+ });
+ var leftDiv = (0, _jquery2["default"])("
").css("float", "left"),
+ rightDiv = (0, _jquery2["default"])("
").css("float", "left");
+ leftDiv.append(gradSpan);
+ (0, _jquery2["default"])(div).append(leftDiv).append(rightDiv).append((0, _jquery2["default"])(" ")); // Have to attach the div to the body at this early point, so that the
+ // svg text getComputedTextLength() actually works, below.
+
+ document.body.appendChild(div);
+ var ns = "http://www.w3.org/2000/svg";
+ var svg = document.createElementNS(ns, "svg");
+ rightDiv.append(svg);
+ var g = document.createElementNS(ns, "g");
+ (0, _jquery2["default"])(g).attr("transform", "translate(0, " + vMargin + ")");
+ svg.appendChild(g); // max label width needed to set width of svg, and right-justify text
+
+ var maxLblWidth = 0; // Create tick marks and labels
+
+ _jquery2["default"].each(labels, function (i, label) {
+ var y = tickOffset + i * singleBinHeight + 0.5;
+ var thisLabel = document.createElementNS(ns, "text");
+ (0, _jquery2["default"])(thisLabel).text(labels[i]).attr("y", y).attr("dx", labelPadding).attr("dy", "0.5ex");
+ g.appendChild(thisLabel);
+ maxLblWidth = Math.max(maxLblWidth, thisLabel.getComputedTextLength());
+ var thisTick = document.createElementNS(ns, "line");
+ (0, _jquery2["default"])(thisTick).attr("x1", 0).attr("x2", tickWidth).attr("y1", y).attr("y2", y).attr("stroke-width", 1);
+ g.appendChild(thisTick);
+ }); // Now that we know the max label width, we can right-justify
+
+
+ (0, _jquery2["default"])(svg).find("text").attr("dx", labelPadding + maxLblWidth).attr("text-anchor", "end"); // Final size for
+
+ (0, _jquery2["default"])(svg).css({
+ width: maxLblWidth + labelPadding + "px",
+ height: totalHeight + vMargin * 2 + "px"
+ });
+
+ if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) {
+ (0, _jquery2["default"])(div).append(" " + options.na_label + "
");
+ }
+ } else {
+ if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) {
+ colors.push(options.na_color);
+ labels.push(options.na_label);
+ }
+
+ for (var i = 0; i < colors.length; i++) {
+ legendHTML += " " + labels[i] + " ";
+ }
+
+ div.innerHTML = legendHTML;
+ }
+
+ if (options.title) (0, _jquery2["default"])(div).prepend("" + options.title + "
");
+ return div;
+ };
+
+ if (options.group) {
+ // Auto generate a layerID if not provided
+ if (!options.layerId) {
+ options.layerId = _leaflet2["default"].Util.stamp(legend);
+ }
+
+ var map = this;
+ map.on("overlayadd", function (e) {
+ if (e.name === options.group) {
+ map.controls.add(legend, options.layerId);
+ }
+ });
+ map.on("overlayremove", function (e) {
+ if (e.name === options.group) {
+ map.controls.remove(options.layerId);
+ }
+ });
+ map.on("groupadd", function (e) {
+ if (e.name === options.group) {
+ map.controls.add(legend, options.layerId);
+ }
+ });
+ map.on("groupremove", function (e) {
+ if (e.name === options.group) {
+ map.controls.remove(options.layerId);
+ }
+ });
+ }
+
+ this.controls.add(legend, options.layerId);
+};
+
+methods.addLayersControl = function (baseGroups, overlayGroups, options) {
+ var _this4 = this;
+
+ // Only allow one layers control at a time
+ methods.removeLayersControl.call(this);
+ var firstLayer = true;
+ var base = {};
+
+ _jquery2["default"].each((0, _util.asArray)(baseGroups), function (i, g) {
+ var layer = _this4.layerManager.getLayerGroup(g, true);
+
+ if (layer) {
+ base[g] = layer; // Check if >1 base layers are visible; if so, hide all but the first one
+
+ if (_this4.hasLayer(layer)) {
+ if (firstLayer) {
+ firstLayer = false;
+ } else {
+ _this4.removeLayer(layer);
+ }
+ }
+ }
+ });
+
+ var overlay = {};
+
+ _jquery2["default"].each((0, _util.asArray)(overlayGroups), function (i, g) {
+ var layer = _this4.layerManager.getLayerGroup(g, true);
+
+ if (layer) {
+ overlay[g] = layer;
+ }
+ });
+
+ this.currentLayersControl = _leaflet2["default"].control.layers(base, overlay, options);
+ this.addControl(this.currentLayersControl);
+};
+
+methods.removeLayersControl = function () {
+ if (this.currentLayersControl) {
+ this.removeControl(this.currentLayersControl);
+ this.currentLayersControl = null;
+ }
+};
+
+methods.addScaleBar = function (options) {
+ // Only allow one scale bar at a time
+ methods.removeScaleBar.call(this);
+
+ var scaleBar = _leaflet2["default"].control.scale(options).addTo(this);
+
+ this.currentScaleBar = scaleBar;
+};
+
+methods.removeScaleBar = function () {
+ if (this.currentScaleBar) {
+ this.currentScaleBar.remove();
+ this.currentScaleBar = null;
+ }
+};
+
+methods.hideGroup = function (group) {
+ var _this5 = this;
+
+ _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
+ var layer = _this5.layerManager.getLayerGroup(g, true);
+
+ if (layer) {
+ _this5.removeLayer(layer);
+ }
+ });
+};
+
+methods.showGroup = function (group) {
+ var _this6 = this;
+
+ _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
+ var layer = _this6.layerManager.getLayerGroup(g, true);
+
+ if (layer) {
+ _this6.addLayer(layer);
+ }
+ });
+};
+
+function setupShowHideGroupsOnZoom(map) {
+ if (map.leafletr._hasInitializedShowHideGroups) {
+ return;
+ }
+
+ map.leafletr._hasInitializedShowHideGroups = true;
+
+ function setVisibility(layer, visible, group) {
+ if (visible !== map.hasLayer(layer)) {
+ if (visible) {
+ map.addLayer(layer);
+ map.fire("groupadd", {
+ "name": group,
+ "layer": layer
+ });
+ } else {
+ map.removeLayer(layer);
+ map.fire("groupremove", {
+ "name": group,
+ "layer": layer
+ });
+ }
+ }
+ }
+
+ function showHideGroupsOnZoom() {
+ if (!map.layerManager) return;
+ var zoom = map.getZoom();
+ map.layerManager.getAllGroupNames().forEach(function (group) {
+ var layer = map.layerManager.getLayerGroup(group, false);
+
+ if (layer && typeof layer.zoomLevels !== "undefined") {
+ setVisibility(layer, layer.zoomLevels === true || layer.zoomLevels.indexOf(zoom) >= 0, group);
+ }
+ });
+ }
+
+ map.showHideGroupsOnZoom = showHideGroupsOnZoom;
+ map.on("zoomend", showHideGroupsOnZoom);
+}
+
+methods.setGroupOptions = function (group, options) {
+ var _this7 = this;
+
+ _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
+ var layer = _this7.layerManager.getLayerGroup(g, true); // This slightly tortured check is because 0 is a valid value for zoomLevels
+
+
+ if (typeof options.zoomLevels !== "undefined" && options.zoomLevels !== null) {
+ layer.zoomLevels = (0, _util.asArray)(options.zoomLevels);
+ }
+ });
+
+ setupShowHideGroupsOnZoom(this);
+ this.showHideGroupsOnZoom();
+};
+
+methods.addRasterImage = function (uri, bounds, layerId, group, options) {
+ // uri is a data URI containing an image. We want to paint this image as a
+ // layer at (top-left) bounds[0] to (bottom-right) bounds[1].
+ // We can't simply use ImageOverlay, as it uses bilinear scaling which looks
+ // awful as you zoom in (and sometimes shifts positions or disappears).
+ // Instead, we'll use a TileLayer.Canvas to draw pieces of the image.
+ // First, some helper functions.
+ // degree2tile converts latitude, longitude, and zoom to x and y tile
+ // numbers. The tile numbers returned can be non-integral, as there's no
+ // reason to expect that the lat/lng inputs are exactly on the border of two
+ // tiles.
+ //
+ // We'll use this to convert the bounds we got from the server, into coords
+ // in tile-space at a given zoom level. Note that once we do the conversion,
+ // we don't to do any more trigonometry to convert between pixel coordinates
+ // and tile coordinates; the source image pixel coords, destination canvas
+ // pixel coords, and tile coords all can be scaled linearly.
+ function degree2tile(lat, lng, zoom) {
+ // See http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
+ var latRad = lat * Math.PI / 180;
+ var n = Math.pow(2, zoom);
+ var x = (lng + 180) / 360 * n;
+ var y = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * n;
+ return {
+ x: x,
+ y: y
+ };
+ } // Given a range [from,to) and either one or two numbers, returns true if
+ // there is any overlap between [x,x1) and the range--or if x1 is omitted,
+ // then returns true if x is within [from,to).
+
+
+ function overlap(from, to, x,
+ /* optional */
+ x1) {
+ if (arguments.length == 3) x1 = x;
+ return x < to && x1 >= from;
+ }
+
+ function getCanvasSmoothingProperty(ctx) {
+ var candidates = ["imageSmoothingEnabled", "mozImageSmoothingEnabled", "webkitImageSmoothingEnabled", "msImageSmoothingEnabled"];
+
+ for (var i = 0; i < candidates.length; i++) {
+ if (typeof ctx[candidates[i]] !== "undefined") {
+ return candidates[i];
+ }
+ }
+
+ return null;
+ } // Our general strategy is to:
+ // 1. Load the data URI in an Image() object, so we can get its pixel
+ // dimensions and the underlying image data. (We could have done this
+ // by not encoding as PNG at all but just send an array of RGBA values
+ // from the server, but that would inflate the JSON too much.)
+ // 2. Create a hidden canvas that we use just to extract the image data
+ // from the Image (using Context2D.getImageData()).
+ // 3. Create a TileLayer.Canvas and add it to the map.
+ // We want to synchronously create and attach the TileLayer.Canvas (so an
+ // immediate call to clearRasters() will be respected, for example), but
+ // Image loads its data asynchronously. Fortunately we can resolve this
+ // by putting TileLayer.Canvas into async mode, which will let us create
+ // and attach the layer but have it wait until the image is loaded before
+ // it actually draws anything.
+ // These are the variables that we will populate once the image is loaded.
+
+
+ var imgData = null; // 1d row-major array, four [0-255] integers per pixel
+
+ var imgDataMipMapper = null;
+ var w = null; // image width in pixels
+
+ var h = null; // image height in pixels
+ // We'll use this array to store callbacks that need to be invoked once
+ // imgData, w, and h have been resolved.
+
+ var imgDataCallbacks = []; // Consumers of imgData, w, and h can call this to be notified when data
+ // is available.
+
+ function getImageData(callback) {
+ if (imgData != null) {
+ // Must not invoke the callback immediately; it's too confusing and
+ // fragile to have a function invoke the callback *either* immediately
+ // or in the future. Better to be consistent here.
+ setTimeout(function () {
+ callback(imgData, w, h, imgDataMipMapper);
+ }, 0);
+ } else {
+ imgDataCallbacks.push(callback);
+ }
+ }
+
+ var img = new Image();
+
+ img.onload = function () {
+ // Save size
+ w = img.width;
+ h = img.height; // Create a dummy canvas to extract the image data
+
+ var imgDataCanvas = document.createElement("canvas");
+ imgDataCanvas.width = w;
+ imgDataCanvas.height = h;
+ imgDataCanvas.style.display = "none";
+ document.body.appendChild(imgDataCanvas);
+ var imgDataCtx = imgDataCanvas.getContext("2d");
+ imgDataCtx.drawImage(img, 0, 0); // Save the image data.
+
+ imgData = imgDataCtx.getImageData(0, 0, w, h).data;
+ imgDataMipMapper = new _mipmapper2["default"](img); // Done with the canvas, remove it from the page so it can be gc'd.
+
+ document.body.removeChild(imgDataCanvas); // Alert any getImageData callers who are waiting.
+
+ for (var i = 0; i < imgDataCallbacks.length; i++) {
+ imgDataCallbacks[i](imgData, w, h, imgDataMipMapper);
+ }
+
+ imgDataCallbacks = [];
+ };
+
+ img.src = uri;
+
+ var canvasTiles = _leaflet2["default"].gridLayer(Object.assign({}, options, {
+ detectRetina: true,
+ async: true
+ })); // NOTE: The done() function MUST NOT be invoked until after the current
+ // tick; done() looks in Leaflet's tile cache for the current tile, and
+ // since it's still being constructed, it won't be found.
+
+
+ canvasTiles.createTile = function (tilePoint, done) {
+ var zoom = tilePoint.z;
+
+ var canvas = _leaflet2["default"].DomUtil.create("canvas");
+
+ var error; // setup tile width and height according to the options
+
+ var size = this.getTileSize();
+ canvas.width = size.x;
+ canvas.height = size.y;
+ getImageData(function (imgData, w, h, mipmapper) {
+ try {
+ // The Context2D we'll being drawing onto. It's always 256x256.
+ var ctx = canvas.getContext("2d"); // Convert our image data's top-left and bottom-right locations into
+ // x/y tile coordinates. This is essentially doing a spherical mercator
+ // projection, then multiplying by 2^zoom.
+
+ var topLeft = degree2tile(bounds[0][0], bounds[0][1], zoom);
+ var bottomRight = degree2tile(bounds[1][0], bounds[1][1], zoom); // The size of the image in x/y tile coordinates.
+
+ var extent = {
+ x: bottomRight.x - topLeft.x,
+ y: bottomRight.y - topLeft.y
+ }; // Short circuit if tile is totally disjoint from image.
+
+ if (!overlap(tilePoint.x, tilePoint.x + 1, topLeft.x, bottomRight.x)) return;
+ 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.
+ // If the linear resolution (in either direction) of the image is less than 256px
+ // per tile unit, then use nearest neighbor; otherwise, use the canvas's built-in
+ // scaling.
+
+ var imgRes = {
+ x: w / extent.x,
+ y: h / extent.y
+ }; // We can do the actual drawing in one of three ways:
+ // - Call drawImage(). This is easy and fast, and results in smooth
+ // interpolation (bilinear?). This is what we want when we are
+ // reducing the image from its native size.
+ // - Call drawImage() with imageSmoothingEnabled=false. This is easy
+ // and fast and gives us nearest-neighbor interpolation, which is what
+ // we want when enlarging the image. However, it's unsupported on many
+ // browsers (including QtWebkit).
+ // - Do a manual nearest-neighbor interpolation. This is what we'll fall
+ // back to when enlarging, and imageSmoothingEnabled isn't supported.
+ // In theory it's slower, but still pretty fast on my machine, and the
+ // results look the same AFAICT.
+ // Is imageSmoothingEnabled supported? If so, we can let canvas do
+ // nearest-neighbor interpolation for us.
+
+ var smoothingProperty = getCanvasSmoothingProperty(ctx);
+
+ if (smoothingProperty || imgRes.x >= 256 && imgRes.y >= 256) {
+ // Use built-in scaling
+ // Turn off anti-aliasing if necessary
+ if (smoothingProperty) {
+ ctx[smoothingProperty] = imgRes.x >= 256 && imgRes.y >= 256;
+ } // Don't necessarily draw with the full-size image; if we're
+ // downscaling, use the mipmapper to get a pre-downscaled image
+ // (see comments on Mipmapper class for why this matters).
+
+
+ mipmapper.getBySize(extent.x * 256, extent.y * 256, function (mip) {
+ // It's possible that the image will go off the edge of the canvas--
+ // that's OK, the canvas should clip appropriately.
+ ctx.drawImage(mip, // Convert abs tile coords to rel tile coords, then *256 to convert
+ // to rel pixel coords
+ (topLeft.x - tilePoint.x) * 256, (topLeft.y - tilePoint.y) * 256, // Always draw the whole thing and let canvas clip; so we can just
+ // convert from size in tile coords straight to pixels
+ extent.x * 256, extent.y * 256);
+ });
+ } else {
+ // Use manual nearest-neighbor interpolation
+ // Calculate the source image pixel coordinates that correspond with
+ // the top-left and bottom-right of this tile. (If the source image
+ // only partially overlaps the tile, we use max/min to limit the
+ // sourceStart/End to only reflect the overlapping portion.)
+ var sourceStart = {
+ x: Math.max(0, Math.floor((tilePoint.x - topLeft.x) * imgRes.x)),
+ y: Math.max(0, Math.floor((tilePoint.y - topLeft.y) * imgRes.y))
+ };
+ var sourceEnd = {
+ x: Math.min(w, Math.ceil((tilePoint.x + 1 - topLeft.x) * imgRes.x)),
+ y: Math.min(h, Math.ceil((tilePoint.y + 1 - topLeft.y) * imgRes.y))
+ }; // The size, in dest pixels, that each source pixel should occupy.
+ // This might be greater or less than 1 (e.g. if x and y resolution
+ // are very different).
+
+ var pixelSize = {
+ x: 256 / imgRes.x,
+ y: 256 / imgRes.y
+ }; // For each pixel in the source image that overlaps the tile...
+
+ for (var row = sourceStart.y; row < sourceEnd.y; row++) {
+ for (var col = sourceStart.x; col < sourceEnd.x; col++) {
+ // ...extract the pixel data...
+ var i = (row * w + col) * 4;
+ var r = imgData[i];
+ var g = imgData[i + 1];
+ var b = imgData[i + 2];
+ var a = imgData[i + 3];
+ ctx.fillStyle = "rgba(" + [r, g, b, a / 255].join(",") + ")"; // ...calculate the corresponding pixel coord in the dest image
+ // where it should be drawn...
+
+ var pixelPos = {
+ x: (col / imgRes.x + topLeft.x - tilePoint.x) * 256,
+ y: (row / imgRes.y + topLeft.y - tilePoint.y) * 256
+ }; // ...and draw a rectangle there.
+
+ ctx.fillRect(Math.round(pixelPos.x), Math.round(pixelPos.y), // Looks crazy, but this is necessary to prevent rounding from
+ // causing overlap between this rect and its neighbors. The
+ // minuend is the location of the next pixel, while the
+ // subtrahend is the position of the current pixel (to turn an
+ // absolute coordinate to a width/height). Yes, I had to look
+ // up minuend and subtrahend.
+ Math.round(pixelPos.x + pixelSize.x) - Math.round(pixelPos.x), Math.round(pixelPos.y + pixelSize.y) - Math.round(pixelPos.y));
+ }
+ }
+ }
+ } catch (e) {
+ error = e;
+ } finally {
+ done(error, canvas);
+ }
+ });
+ return canvas;
+ };
+
+ this.layerManager.addLayer(canvasTiles, "image", layerId, group);
+};
+
+methods.removeImage = function (layerId) {
+ this.layerManager.removeLayer("image", layerId);
+};
+
+methods.clearImages = function () {
+ this.layerManager.clearLayers("image");
+};
+
+methods.addMeasure = function (options) {
+ // if a measureControl already exists, then remove it and
+ // replace with a new one
+ methods.removeMeasure.call(this);
+ this.measureControl = _leaflet2["default"].control.measure(options);
+ this.addControl(this.measureControl);
+};
+
+methods.removeMeasure = function () {
+ if (this.measureControl) {
+ this.removeControl(this.measureControl);
+ this.measureControl = null;
+ }
+};
+
+methods.addSelect = function (ctGroup) {
+ var _this8 = this;
+
+ methods.removeSelect.call(this);
+ this._selectButton = _leaflet2["default"].easyButton({
+ states: [{
+ stateName: "select-inactive",
+ icon: "ion-qr-scanner",
+ title: "Make a selection",
+ onClick: function onClick(btn, map) {
+ btn.state("select-active");
+ _this8._locationFilter = new _leaflet2["default"].LocationFilter2();
+
+ if (ctGroup) {
+ var selectionHandle = new global.crosstalk.SelectionHandle(ctGroup);
+ selectionHandle.on("change", function (e) {
+ if (e.sender !== selectionHandle) {
+ if (_this8._locationFilter) {
+ _this8._locationFilter.disable();
+
+ btn.state("select-inactive");
+ }
+ }
+ });
+
+ var handler = function handler(e) {
+ _this8.layerManager.brush(_this8._locationFilter.getBounds(), {
+ sender: selectionHandle
+ });
+ };
+
+ _this8._locationFilter.on("enabled", handler);
+
+ _this8._locationFilter.on("change", handler);
+
+ _this8._locationFilter.on("disabled", function () {
+ selectionHandle.close();
+ _this8._locationFilter = null;
+ });
+ }
+
+ _this8._locationFilter.addTo(map);
+ }
+ }, {
+ stateName: "select-active",
+ icon: "ion-close-round",
+ title: "Dismiss selection",
+ onClick: function onClick(btn, map) {
+ btn.state("select-inactive");
+
+ _this8._locationFilter.disable(); // If explicitly dismissed, clear the crosstalk selections
+
+
+ _this8.layerManager.unbrush();
+ }
+ }]
+ });
+
+ this._selectButton.addTo(this);
+};
+
+methods.removeSelect = function () {
+ if (this._locationFilter) {
+ this._locationFilter.disable();
+ }
+
+ if (this._selectButton) {
+ this.removeControl(this._selectButton);
+ this._selectButton = null;
+ }
+};
+
+methods.createMapPane = function (name, zIndex) {
+ this.createPane(name);
+ this.getPane(name).style.zIndex = zIndex;
+};
+
+
+}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./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){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _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); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+// This class simulates a mipmap, which shrinks images by powers of two. This
+// stepwise reduction results in "pixel-perfect downscaling" (where every
+// pixel of the original image has some contribution to the downscaled image)
+// as opposed to a single-step downscaling which will discard a lot of data
+// (and with sparse images at small scales can give very surprising results).
+var Mipmapper = /*#__PURE__*/function () {
+ function Mipmapper(img) {
+ _classCallCheck(this, Mipmapper);
+
+ this._layers = [img];
+ } // The various functions on this class take a callback function BUT MAY OR MAY
+ // NOT actually behave asynchronously.
+
+
+ _createClass(Mipmapper, [{
+ key: "getBySize",
+ value: function getBySize(desiredWidth, desiredHeight, callback) {
+ var _this = this;
+
+ var i = 0;
+ var lastImg = this._layers[0];
+
+ var testNext = function testNext() {
+ _this.getByIndex(i, function (img) {
+ // If current image is invalid (i.e. too small to be rendered) or
+ // it's smaller than what we wanted, return the last known good image.
+ if (!img || img.width < desiredWidth || img.height < desiredHeight) {
+ callback(lastImg);
+ return;
+ } else {
+ lastImg = img;
+ i++;
+ testNext();
+ return;
+ }
+ });
+ };
+
+ testNext();
+ }
+ }, {
+ key: "getByIndex",
+ value: function getByIndex(i, callback) {
+ var _this2 = this;
+
+ if (this._layers[i]) {
+ callback(this._layers[i]);
+ return;
+ }
+
+ this.getByIndex(i - 1, function (prevImg) {
+ if (!prevImg) {
+ // prevImg could not be calculated (too small, possibly)
+ callback(null);
+ return;
+ }
+
+ if (prevImg.width < 2 || prevImg.height < 2) {
+ // Can't reduce this image any further
+ callback(null);
+ return;
+ } // If reduce ever becomes truly asynchronous, we should stuff a promise or
+ // something into this._layers[i] before calling this.reduce(), to prevent
+ // redundant reduce operations from happening.
+
+
+ _this2.reduce(prevImg, function (reducedImg) {
+ _this2._layers[i] = reducedImg;
+ callback(reducedImg);
+ return;
+ });
+ });
+ }
+ }, {
+ key: "reduce",
+ value: function reduce(img, callback) {
+ var imgDataCanvas = document.createElement("canvas");
+ imgDataCanvas.width = Math.ceil(img.width / 2);
+ imgDataCanvas.height = Math.ceil(img.height / 2);
+ imgDataCanvas.style.display = "none";
+ document.body.appendChild(imgDataCanvas);
+
+ try {
+ var imgDataCtx = imgDataCanvas.getContext("2d");
+ imgDataCtx.drawImage(img, 0, 0, img.width / 2, img.height / 2);
+ callback(imgDataCanvas);
+ } finally {
+ document.body.removeChild(imgDataCanvas);
+ }
+ }
+ }]);
+
+ return Mipmapper;
+}();
+
+exports["default"] = Mipmapper;
+
+
+},{}],17:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.log = log;
+exports.recycle = recycle;
+exports.asArray = asArray;
+
+function log(message) {
+ /* eslint-disable no-console */
+ if (console && console.log) console.log(message);
+ /* eslint-enable no-console */
+}
+
+function recycle(values, length, inPlace) {
+ if (length === 0 && !inPlace) return [];
+
+ if (!(values instanceof Array)) {
+ if (inPlace) {
+ throw new Error("Can't do in-place recycling of a non-Array value");
+ }
+
+ values = [values];
+ }
+
+ if (typeof length === "undefined") length = values.length;
+ var dest = inPlace ? values : [];
+ var origLength = values.length;
+
+ while (dest.length < length) {
+ dest.push(values[dest.length % origLength]);
+ }
+
+ if (dest.length > length) {
+ dest.splice(length, dest.length - length);
+ }
+
+ return dest;
+}
+
+function asArray(value) {
+ if (value instanceof Array) return value;else return [value];
+}
+
+
+},{}]},{},[13]);
diff --git a/docs/articles/Articles/Applications_files/leaflet-providers-2.0.0/leaflet-providers_2.0.0.js b/docs/articles/Articles/Applications_files/leaflet-providers-2.0.0/leaflet-providers_2.0.0.js
new file mode 100644
index 0000000..bcde1ed
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/leaflet-providers-2.0.0/leaflet-providers_2.0.0.js
@@ -0,0 +1,1178 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['leaflet'], factory);
+ } else if (typeof modules === 'object' && module.exports) {
+ // define a Common JS module that relies on 'leaflet'
+ module.exports = factory(require('leaflet'));
+ } else {
+ // Assume Leaflet is loaded into global object L already
+ factory(L);
+ }
+}(this, function (L) {
+ 'use strict';
+
+ L.TileLayer.Provider = L.TileLayer.extend({
+ initialize: function (arg, options) {
+ var providers = L.TileLayer.Provider.providers;
+
+ var parts = arg.split('.');
+
+ var providerName = parts[0];
+ var variantName = parts[1];
+
+ if (!providers[providerName]) {
+ throw 'No such provider (' + providerName + ')';
+ }
+
+ var provider = {
+ url: providers[providerName].url,
+ options: providers[providerName].options
+ };
+
+ // overwrite values in provider from variant.
+ if (variantName && 'variants' in providers[providerName]) {
+ if (!(variantName in providers[providerName].variants)) {
+ throw 'No such variant of ' + providerName + ' (' + variantName + ')';
+ }
+ var variant = providers[providerName].variants[variantName];
+ var variantOptions;
+ if (typeof variant === 'string') {
+ variantOptions = {
+ variant: variant
+ };
+ } else {
+ variantOptions = variant.options;
+ }
+ provider = {
+ url: variant.url || provider.url,
+ options: L.Util.extend({}, provider.options, variantOptions)
+ };
+ }
+
+ // replace attribution placeholders with their values from toplevel provider attribution,
+ // recursively
+ var attributionReplacer = function (attr) {
+ if (attr.indexOf('{attribution.') === -1) {
+ return attr;
+ }
+ return attr.replace(/\{attribution.(\w*)\}/g,
+ function (match, attributionName) {
+ return attributionReplacer(providers[attributionName].options.attribution);
+ }
+ );
+ };
+ provider.options.attribution = attributionReplacer(provider.options.attribution);
+
+ // Compute final options combining provider options with any user overrides
+ var layerOpts = L.Util.extend({}, provider.options, options);
+ L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts);
+ }
+ });
+
+ /**
+ * Definition of providers.
+ * see http://leafletjs.com/reference.html#tilelayer for options in the options map.
+ */
+
+ L.TileLayer.Provider.providers = {
+ OpenStreetMap: {
+ url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 19,
+ attribution:
+ '© OpenStreetMap contributors'
+ },
+ variants: {
+ Mapnik: {},
+ DE: {
+ url: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 18
+ }
+ },
+ CH: {
+ url: 'https://tile.osm.ch/switzerland/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 18,
+ bounds: [[45, 5], [48, 11]]
+ }
+ },
+ France: {
+ url: 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 20,
+ attribution: '© OpenStreetMap France | {attribution.OpenStreetMap}'
+ }
+ },
+ HOT: {
+ url: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
+ options: {
+ attribution:
+ '{attribution.OpenStreetMap}, ' +
+ 'Tiles style by Humanitarian OpenStreetMap Team ' +
+ 'hosted by OpenStreetMap France '
+ }
+ },
+ BZH: {
+ url: 'https://tile.openstreetmap.bzh/br/{z}/{x}/{y}.png',
+ options: {
+ attribution: '{attribution.OpenStreetMap}, Tiles courtesy of Breton OpenStreetMap Team ',
+ bounds: [[46.2, -5.5], [50, 0.7]]
+ }
+ }
+ }
+ },
+ MapTilesAPI: {
+ url: 'https://maptiles.p.rapidapi.com/{variant}/{z}/{x}/{y}.png?rapidapi-key={apikey}',
+ options: {
+ attribution:
+ '© MapTiles API , {attribution.OpenStreetMap}',
+ variant: 'en/map/v1',
+ // Get your own MapTiles API access token here : https://www.maptilesapi.com/
+ // NB : this is a demonstration key that comes with no guarantee and not to be used in production
+ apikey: '',
+ maxZoom: 19
+ },
+ variants: {
+ OSMEnglish: {
+ options: {
+ variant: 'en/map/v1'
+ }
+ },
+ OSMFrancais: {
+ options: {
+ variant: 'fr/map/v1'
+ }
+ },
+ OSMEspagnol: {
+ options: {
+ variant: 'es/map/v1'
+ }
+ }
+ }
+ },
+ OpenSeaMap: {
+ url: 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
+ options: {
+ attribution: 'Map data: © OpenSeaMap contributors'
+ }
+ },
+ OPNVKarte: {
+ url: 'https://tileserver.memomaps.de/tilegen/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 18,
+ attribution: 'Map memomaps.de CC-BY-SA , map data {attribution.OpenStreetMap}'
+ }
+ },
+ OpenTopoMap: {
+ url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 17,
+ attribution: 'Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA )'
+ }
+ },
+ OpenRailwayMap: {
+ url: 'https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 19,
+ attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © OpenRailwayMap (CC-BY-SA )'
+ }
+ },
+ OpenFireMap: {
+ url: 'http://openfiremap.org/hytiles/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 19,
+ attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © OpenFireMap (CC-BY-SA )'
+ }
+ },
+ SafeCast: {
+ url: 'https://s3.amazonaws.com/te512.safecast.org/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 16,
+ attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © SafeCast (CC-BY-SA )'
+ }
+ },
+ Stadia: {
+ url: 'https://tiles.stadiamaps.com/tiles/{variant}/{z}/{x}/{y}{r}.{ext}',
+ options: {
+ minZoom: 0,
+ maxZoom: 20,
+ attribution:
+ '© Stadia Maps ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'alidade_smooth',
+ ext: 'png'
+ },
+ variants: {
+ AlidadeSmooth: 'alidade_smooth',
+ AlidadeSmoothDark: 'alidade_smooth_dark',
+ OSMBright: 'osm_bright',
+ Outdoors: 'outdoors',
+ StamenToner: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_toner'
+ }
+ },
+ StamenTonerBackground: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_toner_background'
+ }
+ },
+ StamenTonerLines: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_toner_lines'
+ }
+ },
+ StamenTonerLabels: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_toner_labels'
+ }
+ },
+ StamenTonerLite: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_toner_lite'
+ }
+ },
+ StamenWatercolor: {
+ url: 'https://tiles.stadiamaps.com/tiles/{variant}/{z}/{x}/{y}.{ext}',
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_watercolor',
+ ext: 'jpg',
+ minZoom: 1,
+ maxZoom: 16
+ }
+ },
+ StamenTerrain: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_terrain',
+ minZoom: 0,
+ maxZoom: 18
+ }
+ },
+ StamenTerrainBackground: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_terrain_background',
+ minZoom: 0,
+ maxZoom: 18
+ }
+ },
+ StamenTerrainLabels: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_terrain_labels',
+ minZoom: 0,
+ maxZoom: 18
+ }
+ },
+ StamenTerrainLines: {
+ options: {
+ attribution:
+ '© Stadia Maps ' +
+ '© Stamen Design ' +
+ '© OpenMapTiles ' +
+ '{attribution.OpenStreetMap}',
+ variant: 'stamen_terrain_lines',
+ minZoom: 0,
+ maxZoom: 18
+ }
+ }
+ }
+ },
+ Thunderforest: {
+ url: 'https://{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png?apikey={apikey}',
+ options: {
+ attribution:
+ '© Thunderforest , {attribution.OpenStreetMap}',
+ variant: 'cycle',
+ apikey: '',
+ maxZoom: 22
+ },
+ variants: {
+ OpenCycleMap: 'cycle',
+ Transport: {
+ options: {
+ variant: 'transport'
+ }
+ },
+ TransportDark: {
+ options: {
+ variant: 'transport-dark'
+ }
+ },
+ SpinalMap: {
+ options: {
+ variant: 'spinal-map'
+ }
+ },
+ Landscape: 'landscape',
+ Outdoors: 'outdoors',
+ Pioneer: 'pioneer',
+ MobileAtlas: 'mobile-atlas',
+ Neighbourhood: 'neighbourhood'
+ }
+ },
+ CyclOSM: {
+ url: 'https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 20,
+ attribution: 'CyclOSM | Map data: {attribution.OpenStreetMap}'
+ }
+ },
+ Jawg: {
+ url: 'https://{s}.tile.jawg.io/{variant}/{z}/{x}/{y}{r}.png?access-token={accessToken}',
+ options: {
+ attribution:
+ '© Jawg Maps ' +
+ '{attribution.OpenStreetMap}',
+ minZoom: 0,
+ maxZoom: 22,
+ subdomains: 'abcd',
+ variant: 'jawg-terrain',
+ // Get your own Jawg access token here : https://www.jawg.io/lab/
+ // NB : this is a demonstration key that comes with no guarantee
+ accessToken: '',
+ },
+ variants: {
+ Streets: 'jawg-streets',
+ Terrain: 'jawg-terrain',
+ Sunny: 'jawg-sunny',
+ Dark: 'jawg-dark',
+ Light: 'jawg-light',
+ Matrix: 'jawg-matrix'
+ }
+ },
+ MapBox: {
+ url: 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}{r}?access_token={accessToken}',
+ options: {
+ attribution:
+ '© Mapbox ' +
+ '{attribution.OpenStreetMap} ' +
+ 'Improve this map ',
+ tileSize: 512,
+ maxZoom: 18,
+ zoomOffset: -1,
+ id: 'mapbox/streets-v11',
+ accessToken: '',
+ }
+ },
+ MapTiler: {
+ url: 'https://api.maptiler.com/maps/{variant}/{z}/{x}/{y}{r}.{ext}?key={key}',
+ options: {
+ attribution:
+ '© MapTiler © OpenStreetMap contributors ',
+ variant: 'streets',
+ ext: 'png',
+ key: '',
+ tileSize: 512,
+ zoomOffset: -1,
+ minZoom: 0,
+ maxZoom: 21
+ },
+ variants: {
+ Streets: 'streets',
+ Basic: 'basic',
+ Bright: 'bright',
+ Pastel: 'pastel',
+ Positron: 'positron',
+ Hybrid: {
+ options: {
+ variant: 'hybrid',
+ ext: 'jpg'
+ }
+ },
+ Toner: 'toner',
+ Topo: 'topo',
+ Voyager: 'voyager'
+ }
+ },
+ TomTom: {
+ url: 'https://{s}.api.tomtom.com/map/1/tile/{variant}/{style}/{z}/{x}/{y}.{ext}?key={apikey}',
+ options: {
+ variant: 'basic',
+ maxZoom: 22,
+ attribution:
+ '© 1992 - ' + new Date().getFullYear() + ' TomTom. ',
+ subdomains: 'abcd',
+ style: 'main',
+ ext: 'png',
+ apikey: '',
+ },
+ variants: {
+ Basic: 'basic',
+ Hybrid: 'hybrid',
+ Labels: 'labels'
+ }
+ },
+ Esri: {
+ url: 'https://server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}',
+ options: {
+ variant: 'World_Street_Map',
+ attribution: 'Tiles © Esri'
+ },
+ variants: {
+ WorldStreetMap: {
+ options: {
+ attribution:
+ '{attribution.Esri} — ' +
+ 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
+ }
+ },
+ DeLorme: {
+ options: {
+ variant: 'Specialty/DeLorme_World_Base_Map',
+ minZoom: 1,
+ maxZoom: 11,
+ attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme'
+ }
+ },
+ WorldTopoMap: {
+ options: {
+ variant: 'World_Topo_Map',
+ attribution:
+ '{attribution.Esri} — ' +
+ 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
+ }
+ },
+ WorldImagery: {
+ options: {
+ variant: 'World_Imagery',
+ attribution:
+ '{attribution.Esri} — ' +
+ 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
+ }
+ },
+ WorldTerrain: {
+ options: {
+ variant: 'World_Terrain_Base',
+ maxZoom: 13,
+ attribution:
+ '{attribution.Esri} — ' +
+ 'Source: USGS, Esri, TANA, DeLorme, and NPS'
+ }
+ },
+ WorldShadedRelief: {
+ options: {
+ variant: 'World_Shaded_Relief',
+ maxZoom: 13,
+ attribution: '{attribution.Esri} — Source: Esri'
+ }
+ },
+ WorldPhysical: {
+ options: {
+ variant: 'World_Physical_Map',
+ maxZoom: 8,
+ attribution: '{attribution.Esri} — Source: US National Park Service'
+ }
+ },
+ OceanBasemap: {
+ options: {
+ variant: 'Ocean/World_Ocean_Base',
+ maxZoom: 13,
+ attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'
+ }
+ },
+ NatGeoWorldMap: {
+ options: {
+ variant: 'NatGeo_World_Map',
+ maxZoom: 16,
+ attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC'
+ }
+ },
+ WorldGrayCanvas: {
+ options: {
+ variant: 'Canvas/World_Light_Gray_Base',
+ maxZoom: 16,
+ attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ'
+ }
+ }
+ }
+ },
+ OpenWeatherMap: {
+ url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png?appid={apiKey}',
+ options: {
+ maxZoom: 19,
+ attribution: 'Map data © OpenWeatherMap ',
+ apiKey: '',
+ opacity: 0.5
+ },
+ variants: {
+ Clouds: 'clouds',
+ CloudsClassic: 'clouds_cls',
+ Precipitation: 'precipitation',
+ PrecipitationClassic: 'precipitation_cls',
+ Rain: 'rain',
+ RainClassic: 'rain_cls',
+ Pressure: 'pressure',
+ PressureContour: 'pressure_cntr',
+ Wind: 'wind',
+ Temperature: 'temp',
+ Snow: 'snow'
+ }
+ },
+ HERE: {
+ /*
+ * HERE maps, formerly Nokia maps.
+ * These basemaps are free, but you need an api id and app key. Please sign up at
+ * https://developer.here.com/plans
+ */
+ url:
+ 'https://{s}.{base}.maps.api.here.com/maptile/2.1/' +
+ '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' +
+ 'app_id={app_id}&app_code={app_code}&lg={language}',
+ options: {
+ attribution:
+ 'Map © 1987-' + new Date().getFullYear() + ' HERE ',
+ subdomains: '1234',
+ mapID: 'newest',
+ 'app_id': '',
+ 'app_code': '',
+ base: 'base',
+ variant: 'normal.day',
+ maxZoom: 20,
+ type: 'maptile',
+ language: 'eng',
+ format: 'png8',
+ size: '256'
+ },
+ variants: {
+ normalDay: 'normal.day',
+ normalDayCustom: 'normal.day.custom',
+ normalDayGrey: 'normal.day.grey',
+ normalDayMobile: 'normal.day.mobile',
+ normalDayGreyMobile: 'normal.day.grey.mobile',
+ normalDayTransit: 'normal.day.transit',
+ normalDayTransitMobile: 'normal.day.transit.mobile',
+ normalDayTraffic: {
+ options: {
+ variant: 'normal.traffic.day',
+ base: 'traffic',
+ type: 'traffictile'
+ }
+ },
+ normalNight: 'normal.night',
+ normalNightMobile: 'normal.night.mobile',
+ normalNightGrey: 'normal.night.grey',
+ normalNightGreyMobile: 'normal.night.grey.mobile',
+ normalNightTransit: 'normal.night.transit',
+ normalNightTransitMobile: 'normal.night.transit.mobile',
+ reducedDay: 'reduced.day',
+ reducedNight: 'reduced.night',
+ basicMap: {
+ options: {
+ type: 'basetile'
+ }
+ },
+ mapLabels: {
+ options: {
+ type: 'labeltile',
+ format: 'png'
+ }
+ },
+ trafficFlow: {
+ options: {
+ base: 'traffic',
+ type: 'flowtile'
+ }
+ },
+ carnavDayGrey: 'carnav.day.grey',
+ hybridDay: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.day'
+ }
+ },
+ hybridDayMobile: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.day.mobile'
+ }
+ },
+ hybridDayTransit: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.day.transit'
+ }
+ },
+ hybridDayGrey: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.grey.day'
+ }
+ },
+ hybridDayTraffic: {
+ options: {
+ variant: 'hybrid.traffic.day',
+ base: 'traffic',
+ type: 'traffictile'
+ }
+ },
+ pedestrianDay: 'pedestrian.day',
+ pedestrianNight: 'pedestrian.night',
+ satelliteDay: {
+ options: {
+ base: 'aerial',
+ variant: 'satellite.day'
+ }
+ },
+ terrainDay: {
+ options: {
+ base: 'aerial',
+ variant: 'terrain.day'
+ }
+ },
+ terrainDayMobile: {
+ options: {
+ base: 'aerial',
+ variant: 'terrain.day.mobile'
+ }
+ }
+ }
+ },
+ HEREv3: {
+ /*
+ * HERE maps API Version 3.
+ * These basemaps are free, but you need an API key. Please sign up at
+ * https://developer.here.com/plans
+ * Version 3 deprecates the app_id and app_code access in favor of apiKey
+ *
+ * Supported access methods as of 2019/12/21:
+ * @see https://developer.here.com/faqs#access-control-1--how-do-you-control-access-to-here-location-services
+ */
+ url:
+ 'https://{s}.{base}.maps.ls.hereapi.com/maptile/2.1/' +
+ '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' +
+ 'apiKey={apiKey}&lg={language}',
+ options: {
+ attribution:
+ 'Map © 1987-' + new Date().getFullYear() + ' HERE ',
+ subdomains: '1234',
+ mapID: 'newest',
+ apiKey: '',
+ base: 'base',
+ variant: 'normal.day',
+ maxZoom: 20,
+ type: 'maptile',
+ language: 'eng',
+ format: 'png8',
+ size: '256'
+ },
+ variants: {
+ normalDay: 'normal.day',
+ normalDayCustom: 'normal.day.custom',
+ normalDayGrey: 'normal.day.grey',
+ normalDayMobile: 'normal.day.mobile',
+ normalDayGreyMobile: 'normal.day.grey.mobile',
+ normalDayTransit: 'normal.day.transit',
+ normalDayTransitMobile: 'normal.day.transit.mobile',
+ normalNight: 'normal.night',
+ normalNightMobile: 'normal.night.mobile',
+ normalNightGrey: 'normal.night.grey',
+ normalNightGreyMobile: 'normal.night.grey.mobile',
+ normalNightTransit: 'normal.night.transit',
+ normalNightTransitMobile: 'normal.night.transit.mobile',
+ reducedDay: 'reduced.day',
+ reducedNight: 'reduced.night',
+ basicMap: {
+ options: {
+ type: 'basetile'
+ }
+ },
+ mapLabels: {
+ options: {
+ type: 'labeltile',
+ format: 'png'
+ }
+ },
+ trafficFlow: {
+ options: {
+ base: 'traffic',
+ type: 'flowtile'
+ }
+ },
+ carnavDayGrey: 'carnav.day.grey',
+ hybridDay: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.day'
+ }
+ },
+ hybridDayMobile: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.day.mobile'
+ }
+ },
+ hybridDayTransit: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.day.transit'
+ }
+ },
+ hybridDayGrey: {
+ options: {
+ base: 'aerial',
+ variant: 'hybrid.grey.day'
+ }
+ },
+ pedestrianDay: 'pedestrian.day',
+ pedestrianNight: 'pedestrian.night',
+ satelliteDay: {
+ options: {
+ base: 'aerial',
+ variant: 'satellite.day'
+ }
+ },
+ terrainDay: {
+ options: {
+ base: 'aerial',
+ variant: 'terrain.day'
+ }
+ },
+ terrainDayMobile: {
+ options: {
+ base: 'aerial',
+ variant: 'terrain.day.mobile'
+ }
+ }
+ }
+ },
+ FreeMapSK: {
+ url: 'https://{s}.freemap.sk/T/{z}/{x}/{y}.jpeg',
+ options: {
+ minZoom: 8,
+ maxZoom: 16,
+ subdomains: 'abcd',
+ bounds: [[47.204642, 15.996093], [49.830896, 22.576904]],
+ attribution:
+ '{attribution.OpenStreetMap}, visualization CC-By-SA 2.0 Freemap.sk '
+ }
+ },
+ MtbMap: {
+ url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png',
+ options: {
+ attribution:
+ '{attribution.OpenStreetMap} & USGS'
+ }
+ },
+ CartoDB: {
+ url: 'https://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}{r}.png',
+ options: {
+ attribution: '{attribution.OpenStreetMap} © CARTO ',
+ subdomains: 'abcd',
+ maxZoom: 20,
+ variant: 'light_all'
+ },
+ variants: {
+ Positron: 'light_all',
+ PositronNoLabels: 'light_nolabels',
+ PositronOnlyLabels: 'light_only_labels',
+ DarkMatter: 'dark_all',
+ DarkMatterNoLabels: 'dark_nolabels',
+ DarkMatterOnlyLabels: 'dark_only_labels',
+ Voyager: 'rastertiles/voyager',
+ VoyagerNoLabels: 'rastertiles/voyager_nolabels',
+ VoyagerOnlyLabels: 'rastertiles/voyager_only_labels',
+ VoyagerLabelsUnder: 'rastertiles/voyager_labels_under'
+ }
+ },
+ HikeBike: {
+ url: 'https://tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 19,
+ attribution: '{attribution.OpenStreetMap}',
+ variant: 'hikebike'
+ },
+ variants: {
+ HikeBike: {},
+ HillShading: {
+ options: {
+ maxZoom: 15,
+ variant: 'hillshading'
+ }
+ }
+ }
+ },
+ BasemapAT: {
+ url: 'https://mapsneu.wien.gv.at/basemap/{variant}/{type}/google3857/{z}/{y}/{x}.{format}',
+ options: {
+ maxZoom: 19,
+ attribution: 'Datenquelle: basemap.at ',
+ type: 'normal',
+ format: 'png',
+ bounds: [[46.358770, 8.782379], [49.037872, 17.189532]],
+ variant: 'geolandbasemap'
+ },
+ variants: {
+ basemap: {
+ options: {
+ maxZoom: 20, // currently only in Vienna
+ variant: 'geolandbasemap'
+ }
+ },
+ grau: 'bmapgrau',
+ overlay: 'bmapoverlay',
+ terrain: {
+ options: {
+ variant: 'bmapgelaende',
+ type: 'grau',
+ format: 'jpeg'
+ }
+ },
+ surface: {
+ options: {
+ variant: 'bmapoberflaeche',
+ type: 'grau',
+ format: 'jpeg'
+ }
+ },
+ highdpi: {
+ options: {
+ variant: 'bmaphidpi',
+ format: 'jpeg'
+ }
+ },
+ orthofoto: {
+ options: {
+ maxZoom: 20, // currently only in Vienna
+ variant: 'bmaporthofoto30cm',
+ format: 'jpeg'
+ }
+ }
+ }
+ },
+ nlmaps: {
+ url: 'https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/{variant}/EPSG:3857/{z}/{x}/{y}.png',
+ options: {
+ minZoom: 6,
+ maxZoom: 19,
+ bounds: [[50.5, 3.25], [54, 7.6]],
+ attribution: 'Kaartgegevens © Kadaster '
+ },
+ variants: {
+ 'standaard': 'standaard',
+ 'pastel': 'pastel',
+ 'grijs': 'grijs',
+ 'water': 'water',
+ 'luchtfoto': {
+ 'url': 'https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0/Actueel_ortho25/EPSG:3857/{z}/{x}/{y}.jpeg',
+ }
+ }
+ },
+ NASAGIBS: {
+ url: 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}',
+ options: {
+ attribution:
+ 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' +
+ '(ESDIS ) with funding provided by NASA/HQ.',
+ bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]],
+ minZoom: 1,
+ maxZoom: 9,
+ format: 'jpg',
+ time: '',
+ tilematrixset: 'GoogleMapsCompatible_Level'
+ },
+ variants: {
+ ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_TrueColor',
+ ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367',
+ ViirsEarthAtNight2012: {
+ options: {
+ variant: 'VIIRS_CityLights_2012',
+ maxZoom: 8
+ }
+ },
+ ModisTerraLSTDay: {
+ options: {
+ variant: 'MODIS_Terra_Land_Surface_Temp_Day',
+ format: 'png',
+ maxZoom: 7,
+ opacity: 0.75
+ }
+ },
+ ModisTerraSnowCover: {
+ options: {
+ variant: 'MODIS_Terra_NDSI_Snow_Cover',
+ format: 'png',
+ maxZoom: 8,
+ opacity: 0.75
+ }
+ },
+ ModisTerraAOD: {
+ options: {
+ variant: 'MODIS_Terra_Aerosol',
+ format: 'png',
+ maxZoom: 6,
+ opacity: 0.75
+ }
+ },
+ ModisTerraChlorophyll: {
+ options: {
+ variant: 'MODIS_Terra_Chlorophyll_A',
+ format: 'png',
+ maxZoom: 7,
+ opacity: 0.75
+ }
+ }
+ }
+ },
+ NLS: {
+ // NLS maps are copyright National library of Scotland.
+ // http://maps.nls.uk/projects/api/index.html
+ // Please contact NLS for anything other than non-commercial low volume usage
+ //
+ // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s
+ // z0-9 - 1:1m
+ // z10-11 - quarter inch (1:253440)
+ // z12-18 - one inch (1:63360)
+ url: 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg',
+ options: {
+ attribution: 'National Library of Scotland Historic Maps ',
+ bounds: [[49.6, -12], [61.7, 3]],
+ minZoom: 1,
+ maxZoom: 18,
+ subdomains: '0123',
+ }
+ },
+ JusticeMap: {
+ // Justice Map (http://www.justicemap.org/)
+ // Visualize race and income data for your community, county and country.
+ // Includes tools for data journalists, bloggers and community activists.
+ url: 'https://www.justicemap.org/tile/{size}/{variant}/{z}/{x}/{y}.png',
+ options: {
+ attribution: 'Justice Map ',
+ // one of 'county', 'tract', 'block'
+ size: 'county',
+ // Bounds for USA, including Alaska and Hawaii
+ bounds: [[14, -180], [72, -56]]
+ },
+ variants: {
+ income: 'income',
+ americanIndian: 'indian',
+ asian: 'asian',
+ black: 'black',
+ hispanic: 'hispanic',
+ multi: 'multi',
+ nonWhite: 'nonwhite',
+ white: 'white',
+ plurality: 'plural'
+ }
+ },
+ GeoportailFrance: {
+ url: 'https://wxs.ign.fr/{apikey}/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE={style}&TILEMATRIXSET=PM&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}',
+ options: {
+ attribution: 'Geoportail France ',
+ bounds: [[-75, -180], [81, 180]],
+ minZoom: 2,
+ maxZoom: 18,
+ // Get your own geoportail apikey here : http://professionnels.ign.fr/ign/contrats/
+ // NB : 'choisirgeoportail' is a demonstration key that comes with no guarantee
+ apikey: 'choisirgeoportail',
+ format: 'image/png',
+ style: 'normal',
+ variant: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2'
+ },
+ variants: {
+ plan: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2',
+ parcels: {
+ options: {
+ variant: 'CADASTRALPARCELS.PARCELLAIRE_EXPRESS',
+ style: 'PCI vecteur',
+ maxZoom: 20
+ }
+ },
+ orthos: {
+ options: {
+ maxZoom: 19,
+ format: 'image/jpeg',
+ variant: 'ORTHOIMAGERY.ORTHOPHOTOS'
+ }
+ }
+ }
+ },
+ OneMapSG: {
+ url: 'https://maps-{s}.onemap.sg/v3/{variant}/{z}/{x}/{y}.png',
+ options: {
+ variant: 'Default',
+ minZoom: 11,
+ maxZoom: 18,
+ bounds: [[1.56073, 104.11475], [1.16, 103.502]],
+ attribution: ' New OneMap | Map data © contributors, Singapore Land Authority '
+ },
+ variants: {
+ Default: 'Default',
+ Night: 'Night',
+ Original: 'Original',
+ Grey: 'Grey',
+ LandLot: 'LandLot'
+ }
+ },
+ USGS: {
+ url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}',
+ options: {
+ maxZoom: 20,
+ attribution: 'Tiles courtesy of the U.S. Geological Survey '
+ },
+ variants: {
+ USTopo: {},
+ USImagery: {
+ url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}'
+ },
+ USImageryTopo: {
+ url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}'
+ }
+ }
+ },
+ WaymarkedTrails: {
+ url: 'https://tile.waymarkedtrails.org/{variant}/{z}/{x}/{y}.png',
+ options: {
+ maxZoom: 18,
+ attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © waymarkedtrails.org (CC-BY-SA )'
+ },
+ variants: {
+ hiking: 'hiking',
+ cycling: 'cycling',
+ mtb: 'mtb',
+ slopes: 'slopes',
+ riding: 'riding',
+ skating: 'skating'
+ }
+ },
+ OpenAIP: {
+ url: 'https://{s}.tile.maps.openaip.net/geowebcache/service/tms/1.0.0/openaip_basemap@EPSG%3A900913@png/{z}/{x}/{y}.{ext}',
+ options: {
+ attribution: 'openAIP Data (CC-BY-NC-SA )',
+ ext: 'png',
+ minZoom: 4,
+ maxZoom: 14,
+ tms: true,
+ detectRetina: true,
+ subdomains: '12'
+ }
+ },
+ OpenSnowMap: {
+ url: 'https://tiles.opensnowmap.org/{variant}/{z}/{x}/{y}.png',
+ options: {
+ minZoom: 9,
+ maxZoom: 18,
+ attribution: 'Map data: {attribution.OpenStreetMap} & ODbL, © www.opensnowmap.org CC-BY-SA '
+ },
+ variants: {
+ pistes: 'pistes',
+ }
+ },
+ AzureMaps: {
+ url:
+ 'https://atlas.microsoft.com/map/tile?api-version={apiVersion}'+
+ '&tilesetId={variant}&x={x}&y={y}&zoom={z}&language={language}'+
+ '&subscription-key={subscriptionKey}',
+ options: {
+ attribution: 'See https://docs.microsoft.com/en-us/rest/api/maps/render-v2/get-map-tile for details.',
+ apiVersion: '2.0',
+ variant: 'microsoft.imagery',
+ subscriptionKey: '',
+ language: 'en-US',
+ },
+ variants: {
+ MicrosoftImagery: 'microsoft.imagery',
+ MicrosoftBaseDarkGrey: 'microsoft.base.darkgrey',
+ MicrosoftBaseRoad: 'microsoft.base.road',
+ MicrosoftBaseHybridRoad: 'microsoft.base.hybrid.road',
+ MicrosoftTerraMain: 'microsoft.terra.main',
+ MicrosoftWeatherInfraredMain: {
+ url:
+ 'https://atlas.microsoft.com/map/tile?api-version={apiVersion}'+
+ '&tilesetId={variant}&x={x}&y={y}&zoom={z}'+
+ '&timeStamp={timeStamp}&language={language}' +
+ '&subscription-key={subscriptionKey}',
+ options: {
+ timeStamp: '2021-05-08T09:03:00Z',
+ attribution: 'See https://docs.microsoft.com/en-us/rest/api/maps/render-v2/get-map-tile#uri-parameters for details.',
+ variant: 'microsoft.weather.infrared.main',
+ },
+ },
+ MicrosoftWeatherRadarMain: {
+ url:
+ 'https://atlas.microsoft.com/map/tile?api-version={apiVersion}'+
+ '&tilesetId={variant}&x={x}&y={y}&zoom={z}'+
+ '&timeStamp={timeStamp}&language={language}' +
+ '&subscription-key={subscriptionKey}',
+ options: {
+ timeStamp: '2021-05-08T09:03:00Z',
+ attribution: 'See https://docs.microsoft.com/en-us/rest/api/maps/render-v2/get-map-tile#uri-parameters for details.',
+ variant: 'microsoft.weather.radar.main',
+ },
+ }
+ },
+ },
+ SwissFederalGeoportal: {
+ url: 'https://wmts.geo.admin.ch/1.0.0/{variant}/default/current/3857/{z}/{x}/{y}.jpeg',
+ options: {
+ attribution: '© swisstopo ',
+ minZoom: 2,
+ maxZoom: 18,
+ bounds: [[45.398181, 5.140242], [48.230651, 11.47757]]
+ },
+ variants: {
+ NationalMapColor: 'ch.swisstopo.pixelkarte-farbe',
+ NationalMapGrey: 'ch.swisstopo.pixelkarte-grau',
+ SWISSIMAGE: {
+ options: {
+ variant: 'ch.swisstopo.swissimage',
+ maxZoom: 19
+ }
+ }
+ }
+ }
+ };
+
+ L.tileLayer.provider = function (provider, options) {
+ return new L.TileLayer.Provider(provider, options);
+ };
+
+ return L;
+}));
diff --git a/docs/articles/Articles/Applications_files/leaflet-providers-plugin-2.2.3/leaflet-providers-plugin.js b/docs/articles/Articles/Applications_files/leaflet-providers-plugin-2.2.3/leaflet-providers-plugin.js
new file mode 100644
index 0000000..82cd630
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/leaflet-providers-plugin-2.2.3/leaflet-providers-plugin.js
@@ -0,0 +1,3 @@
+LeafletWidget.methods.addProviderTiles = function(provider, layerId, group, options) {
+ this.layerManager.addLayer(L.tileLayer.provider(provider, options), "tile", layerId, group);
+};
diff --git a/docs/articles/Articles/Applications_files/leafletfix-1.0.0/leafletfix.css b/docs/articles/Articles/Applications_files/leafletfix-1.0.0/leafletfix.css
new file mode 100644
index 0000000..466d868
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/leafletfix-1.0.0/leafletfix.css
@@ -0,0 +1,36 @@
+/* Work around CSS properties introduced on img by bootstrap */
+img.leaflet-tile {
+ padding: 0;
+ margin: 0;
+ border-radius: 0;
+ border: none;
+}
+.leaflet .info {
+ padding: 6px 8px;
+ font: 14px/16px Arial, Helvetica, sans-serif;
+ background: white;
+ background: rgba(255,255,255,0.8);
+ box-shadow: 0 0 15px rgba(0,0,0,0.2);
+ border-radius: 5px;
+}
+.leaflet .legend {
+ line-height: 18px;
+ color: #555;
+}
+.leaflet .legend svg text {
+ fill: #555;
+}
+.leaflet .legend svg line {
+ stroke: #555;
+}
+.leaflet .legend i {
+ width: 18px;
+ height: 18px;
+ margin-right: 4px;
+ opacity: 0.7;
+ display: inline-block;
+ vertical-align: top;
+ /*For IE 7*/
+ zoom: 1;
+ *display: inline;
+}
diff --git a/docs/articles/Articles/Applications_files/mapviewCSS-0.0.1/mapview-popup.css b/docs/articles/Articles/Applications_files/mapviewCSS-0.0.1/mapview-popup.css
new file mode 100644
index 0000000..ead6a8e
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/mapviewCSS-0.0.1/mapview-popup.css
@@ -0,0 +1,102 @@
+/* table class css */
+table.mapview-popup {
+ overflow: scroll;
+ width: auto;
+ height: auto;
+ border-collapse: collapse;
+}
+
+/*
+table.mapview-popup tr:first-child td {
+ background: #A8E6A8;
+}
+*/
+
+table.mapview-popup tr:nth-child(even) {
+ background: #D1E0FF;
+}
+
+table.mapview-popup tr:nth-child(odd) {
+ background: #ebf1ff;
+}
+
+table.mapview-popup, th, td {
+ border-bottom: 1px solid #ffffff;
+}
+
+/*
+table.tab tr:hover {
+ background: #00ffff;
+}
+*/
+
+
+/* general leaflet popup css '*/
+.leaflet-popup-content {
+ margin: 1px 1px 1px 1px;
+ line-height: 1.5;
+ overflow-y: auto;
+ overflow-x: scoll;
+}
+
+.leaflet-container a.leaflet-popup-close-button {
+ position: absolute;
+ top: 0;
+ right: -20px;
+ padding: 3px 0 0 0;
+ text-align: center;
+ width: 18px;
+ height: 14px;
+ font: 16px/14px Tahoma, Verdana, sans-serif;
+ font-weight: bold;
+ color: #c3c3c3;
+ text-decoration: none;
+ background: transparent;
+}
+
+.leaflet-container a.leaflet-popup-close-button:hover {
+ color: #999;
+}
+
+.leaflet-popup-content-wrapper, .leaflet-popup-tip {
+ padding: 1px;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+ background: #ffffff; /*#4c4c4c;*/
+ box-shadow: 0 3px 14px rgba(0,0,0,0.4);
+}
+
+
+div::-webkit-scrollbar {
+ width: 5px;
+ height: 5px;
+}
+div::-webkit-scrollbar-button {
+ width: 0;
+ height: 0;
+}
+div::-webkit-scrollbar-thumb {
+ background: #666666;
+ border: 0 none #ffffff;
+ border-radius: 0;
+}
+div::-webkit-scrollbar-thumb:hover {
+ background: #333333;
+}
+div::-webkit-scrollbar-thumb:active {
+ background: #333333;
+}
+div::-webkit-scrollbar-track {
+ background: #e1e1e1;
+ border: 0 none #ffffff;
+ border-radius: 50px;
+}
+div::-webkit-scrollbar-track:hover {
+ background: #e1e1e1;
+}
+div::-webkit-scrollbar-track:active {
+ background: #e1e1e1;
+}
+div::-webkit-scrollbar-corner {
+ background: transparent;
+}
diff --git a/docs/articles/Articles/Applications_files/mapviewCSS-0.0.1/mapview.css b/docs/articles/Articles/Applications_files/mapviewCSS-0.0.1/mapview.css
new file mode 100644
index 0000000..ac08791
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/mapviewCSS-0.0.1/mapview.css
@@ -0,0 +1 @@
+.leaflet-control br {clear: both;}
diff --git a/docs/articles/Articles/Applications_files/proj4-2.6.2/proj4.min.js b/docs/articles/Articles/Applications_files/proj4-2.6.2/proj4.min.js
new file mode 100644
index 0000000..99865a5
--- /dev/null
+++ b/docs/articles/Articles/Applications_files/proj4-2.6.2/proj4.min.js
@@ -0,0 +1 @@
+!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?module.exports=s():"function"==typeof define&&define.amd?define(s):t.proj4=s()}(this,function(){"use strict";function k(t,s){if(t[s])return t[s];for(var i,a=Object.keys(t),h=s.toLowerCase().replace(H,""),e=-1;++eMath.PI&&(r-=2*Math.PI),h=Math.sin(o),n=Math.cos(o),e=h*h,{x:((a=i/Math.sqrt(1-s*e))+l)*n*Math.cos(r),y:(a+l)*n*Math.sin(r),z:(a*(1-s)+l)*h}}function c(t,s,i,a){var h,e,n,r,o,l,M,c,u,f,m,p,d,y=t.x,_=t.y,x=t.z?t.z:0,g=Math.sqrt(y*y+_*_),b=Math.sqrt(y*y+_*_+x*x);if(g/i<1e-12){if(p=0,b/i<1e-12)return d=-a,{x:t.x,y:t.y,z:t.z}}else p=Math.atan2(_,y);for(h=x/b,l=(e=g/b)*(1-s)*(n=1/Math.sqrt(1-s*(2-s)*e*e)),M=h*n,m=0;m++,r=s*(o=i/Math.sqrt(1-s*M*M))/(o+(d=g*l+x*M-o*(1-s*M*M))),f=(u=h*(n=1/Math.sqrt(1-r*(2-r)*e*e)))*l-(c=e*(1-r)*n)*M,l=c,M=u,1e-24=this.text.length)return;t=this.text[this.place++]}switch(this.state){case K:return this.neutral(t);case 2:return this.keyword(t);case 4:return this.quoted(t);case 5:return this.afterquote(t);case 3:return this.number(t);case-1:return}},e.prototype.afterquote=function(t){if('"'===t)return this.word+='"',void(this.state=4);if($.test(t))return this.word=this.word.trim(),void this.afterItem(t);throw new Error("havn't handled \""+t+'" in afterquote yet, index '+this.place)},e.prototype.afterItem=function(t){return","===t?(null!==this.word&&this.currentObject.push(this.word),this.word=null,void(this.state=K)):"]"===t?(this.level--,null!==this.word&&(this.currentObject.push(this.word),this.word=null),this.state=K,this.currentObject=this.stack.pop(),void(this.currentObject||(this.state=-1))):void 0},e.prototype.number=function(t){if(!tt.test(t)){if($.test(t))return this.word=parseFloat(this.word),void this.afterItem(t);throw new Error("havn't handled \""+t+'" in number yet, index '+this.place)}this.word+=t},e.prototype.quoted=function(t){'"'!==t?this.word+=t:this.state=5},e.prototype.keyword=function(t){if(Y.test(t))this.word+=t;else{if("["===t){var s=[];return s.push(this.word),this.level++,null===this.root?this.root=s:this.currentObject.push(s),this.stack.push(this.currentObject),this.currentObject=s,void(this.state=K)}if(!$.test(t))throw new Error("havn't handled \""+t+'" in keyword yet, index '+this.place);this.afterItem(t)}},e.prototype.neutral=function(t){if(Z.test(t))return this.word=t,void(this.state=2);if('"'===t)return this.word="",void(this.state=4);if(tt.test(t))return this.word=t,void(this.state=3);if(!$.test(t))throw new Error("havn't handled \""+t+'" in neutral yet, index '+this.place);this.afterItem(t)},e.prototype.output=function(){for(;this.placeD?Math.tan(i):0,c=Math.pow(M,2),u=Math.pow(c,2),f=1-this.es*Math.pow(h,2);n/=Math.sqrt(f);var m=Gt(i,h,e,this.en),p=this.a*(this.k0*n*(1+r/6*(1-c+o+r/20*(5-18*c+u+14*o-58*c*o+r/42*(61+179*u-u*c-479*c)))))+this.x0,d=this.a*(this.k0*(m-this.ml0+h*a*n/2*(1+r/12*(5-c+9*o+4*l+r/30*(61+u-58*c+270*o-330*c*o+r/56*(1385+543*u-u*c-3111*c))))))+this.y0}else{var y=e*Math.sin(a);if(Math.abs(Math.abs(y)-1)D?Math.tan(s):0,e=this.ep2*Math.pow(a,2),n=Math.pow(e,2),r=Math.pow(h,2),o=Math.pow(r,2),l=1-this.es*Math.pow(i,2),M=_*Math.sqrt(l)/this.k0,u=s-(l*=h)*(c=Math.pow(M,2))/(1-this.es)*.5*(1-c/12*(5+3*r-9*e*r+e-4*n-c/30*(61+90*r-252*e*r+45*o+46*e-c/56*(1385+3633*r+4095*o+1574*o*r)))),nt(this.long0+M*(1-c/6*(1+2*r+e-c/20*(5+28*r+24*o+8*e*r+6*e-c/42*(61+662*r+1320*o+720*o*r))))/a)):(u=z*et(x),0)):(p=.5*((m=Math.exp(_/this.k0))-1/m),d=this.lat0+x/this.k0,y=Math.cos(d),l=Math.sqrt((1-Math.pow(y,2))/(1+Math.pow(p,2))),u=Math.asin(l),x<0&&(u=-u),0==p&&0===y?0:nt(Math.atan2(p,y)+this.long0)),t.x=f,t.y=u,t},names:["Transverse_Mercator","Transverse Mercator","tmerc"]},is={init:function(){if(void 0===this.es||this.es<=0)throw new Error("incorrect elliptical usage");this.x0=void 0!==this.x0?this.x0:0,this.y0=void 0!==this.y0?this.y0:0,this.long0=void 0!==this.long0?this.long0:0,this.lat0=void 0!==this.lat0?this.lat0:0,this.cgb=[],this.cbg=[],this.utg=[],this.gtu=[];var t=this.es/(1+Math.sqrt(1-this.es)),s=t/(2-t),i=s;this.cgb[0]=s*(2+s*(-2/3+s*(s*(116/45+s*(26/45+-2854/675*s))-2))),this.cbg[0]=s*(s*(2/3+s*(4/3+s*(-82/45+s*(32/45+4642/4725*s))))-2),i*=s,this.cgb[1]=i*(7/3+s*(s*(-227/45+s*(2704/315+2323/945*s))-1.6)),this.cbg[1]=i*(5/3+s*(-16/15+s*(-13/9+s*(904/315+-1522/945*s)))),i*=s,this.cgb[2]=i*(56/15+s*(-136/35+s*(-1262/105+73814/2835*s))),this.cbg[2]=i*(-26/15+s*(34/21+s*(1.6+-12686/2835*s))),i*=s,this.cgb[3]=i*(4279/630+s*(-332/35+-399572/14175*s)),this.cbg[3]=i*(1237/630+s*(-24832/14175*s-2.4)),i*=s,this.cgb[4]=i*(4174/315+-144838/6237*s),this.cbg[4]=i*(-734/315+109598/31185*s),i*=s,this.cgb[5]=i*(601676/22275),this.cbg[5]=i*(444337/155925),i=Math.pow(s,2),this.Qn=this.k0/(1+s)*(1+i*(.25+i*(1/64+i/256))),this.utg[0]=s*(s*(2/3+s*(-37/96+s*(1/360+s*(81/512+-96199/604800*s))))-.5),this.gtu[0]=s*(.5+s*(-2/3+s*(5/16+s*(41/180+s*(-127/288+7891/37800*s))))),this.utg[1]=i*(-1/48+s*(-1/15+s*(437/1440+s*(-46/105+1118711/3870720*s)))),this.gtu[1]=i*(13/48+s*(s*(557/1440+s*(281/630+-1983433/1935360*s))-.6)),i*=s,this.utg[2]=i*(-17/480+s*(37/840+s*(209/4480+-5569/90720*s))),this.gtu[2]=i*(61/240+s*(-103/140+s*(15061/26880+167603/181440*s))),i*=s,this.utg[3]=i*(-4397/161280+s*(11/504+830251/7257600*s)),this.gtu[3]=i*(49561/161280+s*(-179/168+6601661/7257600*s)),i*=s,this.utg[4]=i*(-4583/161280+108847/3991680*s),this.gtu[4]=i*(34729/80640+-3418889/1995840*s),i*=s,this.utg[5]=-.03233083094085698*i,this.gtu[5]=.6650675310896665*i;var a=Tt(this.cbg,this.lat0);this.Zb=-this.Qn*(a+function(t,s){for(var i,a=2*Math.cos(s),h=t.length-1,e=t[h],n=0;0<=--h;)i=a*e-n+t[h],n=e,e=i;return Math.sin(s)*i}(this.gtu,2*a))},forward:function(t){var s=nt(t.x-this.long0),i=t.y,i=Tt(this.cbg,i),a=Math.sin(i),h=Math.cos(i),e=Math.sin(s),n=Math.cos(s);i=Math.atan2(a,n*h),s=Math.atan2(e*h,Rt(a,h*n)),s=Lt(Math.tan(s));var r,o,l=Dt(this.gtu,2*i,2*s);return i+=l[0],s+=l[1],o=Math.abs(s)<=2.623395162778?(r=this.a*(this.Qn*s)+this.x0,this.a*(this.Qn*i+this.Zb)+this.y0):r=1/0,t.x=r,t.y=o,t},inverse:function(t){var s,i,a,h,e,n,r,o=(t.x-this.x0)*(1/this.a),l=(t.y-this.y0)*(1/this.a);return l=(l-this.Zb)/this.Qn,o/=this.Qn,r=Math.abs(o)<=2.623395162778?(l+=(s=Dt(this.utg,2*l,2*o))[0],o+=s[1],o=Math.atan(zt(o)),i=Math.sin(l),a=Math.cos(l),h=Math.sin(o),e=Math.cos(o),l=Math.atan2(i*e,Rt(h,e*a)),o=Math.atan2(h,e*a),n=nt(o+this.long0),Tt(this.cgb,l)):n=1/0,t.x=n,t.y=r,t},names:["Extended_Transverse_Mercator","Extended Transverse Mercator","etmerc"]},as={init:function(){var t=function(t,s){if(void 0===t){if((t=Math.floor(30*(nt(s)+Math.PI)/Math.PI)+1)<0)return 0;if(60D?this.ns=Math.log(a/r)/Math.log(h/o):this.ns=s,isNaN(this.ns)&&(this.ns=s),this.f0=a/(this.ns*Math.pow(h,this.ns)),this.rh=this.a*this.f0*Math.pow(l,this.ns),this.title||(this.title="Lambert Conformal Conic"))},forward:function(t){var s=t.x,i=t.y;Math.abs(2*Math.abs(i)-Math.PI)<=D&&(i=et(i)*(z-2*D));var a,h,e=Math.abs(Math.abs(i)-z);if(DD?this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1):this.ns0=this.con,this.c=this.ms1*this.ms1+this.ns0*this.qs1,this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0)},forward:function(t){var s=t.x,i=t.y;this.sin_phi=Math.sin(i),this.cos_phi=Math.cos(i);var a=Vt(this.e3,this.sin_phi,this.cos_phi),h=this.a*Math.sqrt(this.c-this.ns0*a)/this.ns0,e=this.ns0*nt(s-this.long0),n=h*Math.sin(e)+this.x0,r=this.rh-h*Math.cos(e)+this.y0;return t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n;return t.x-=this.x0,t.y=this.rh-t.y+this.y0,a=0<=this.ns0?(s=Math.sqrt(t.x*t.x+t.y*t.y),1):(s=-Math.sqrt(t.x*t.x+t.y*t.y),-1),(h=0)!==s&&(h=Math.atan2(a*t.x,a*t.y)),a=s*this.ns0/this.a,n=this.sphere?Math.asin((this.c-a*a)/(2*this.ns0)):(i=(this.c-a*a)/this.ns0,this.phi1z(this.e3,i)),e=nt(h/this.ns0+this.long0),t.x=e,t.y=n,t},names:["Albers_Conic_Equal_Area","Albers","aea"],phi1z:function(t,s){var i,a,h,e,n=Zt(.5*s);if(tMath.PI&&(a=Math.PI),i=(2*s+Math.sin(2*s))/Math.PI,12*z*this.a)return;return i=s/this.a,a=Math.sin(i),h=Math.cos(i),e=this.long0,Math.abs(s)<=D?n=this.lat0:(n=Zt(h*this.sin_p12+t.y*a*this.cos_p12/s),r=Math.abs(this.lat0)-z,e=nt(Math.abs(r)<=D?0<=this.lat0?this.long0+Math.atan2(t.x,-t.y):this.long0-Math.atan2(-t.x,t.y):this.long0+Math.atan2(t.x*a,s*this.cos_p12*h-t.y*this.sin_p12*a))),t.x=e,t.y=n,t}return o=Ft(this.es),l=Qt(this.es),M=Wt(this.es),c=Xt(this.es),Math.abs(this.sin_p12-1)<=D?(u=this.a*Ut(o,l,M,c,z),s=Math.sqrt(t.x*t.x+t.y*t.y),n=Kt((u-s)/this.a,o,l,M,c),e=nt(this.long0+Math.atan2(t.x,-1*t.y))):Math.abs(this.sin_p12+1)<=D?(u=this.a*Ut(o,l,M,c,z),s=Math.sqrt(t.x*t.x+t.y*t.y),n=Kt((s-u)/this.a,o,l,M,c),e=nt(this.long0+Math.atan2(t.x,t.y))):(s=Math.sqrt(t.x*t.x+t.y*t.y),p=Math.atan2(t.x,t.y),f=Ht(this.a,this.e,this.sin_p12),d=Math.cos(p),_=-(y=this.e*this.cos_p12*d)*y/(1-this.es),x=3*this.es*(1-_)*this.sin_p12*this.cos_p12*d/(1-this.es),v=1-_*(b=(g=s/f)-_*(1+_)*Math.pow(g,3)/6-x*(1+3*_)*Math.pow(g,4)/24)*b/2-g*b*b*b/6,m=Math.asin(this.sin_p12*Math.cos(b)+this.cos_p12*Math.sin(b)*d),e=nt(this.long0+Math.asin(Math.sin(p)*Math.sin(b)/Math.cos(m))),w=Math.sin(m),n=Math.atan2((w-this.es*v*this.sin_p12)*Math.tan(m),w*(1-this.es))),t.x=e,t.y=n,t},names:["Azimuthal_Equidistant","aeqd"]},Ps={init:function(){this.sin_p14=Math.sin(this.lat0),this.cos_p14=Math.cos(this.lat0)},forward:function(t){var s,i,a,h=t.x,e=t.y,n=nt(h-this.long0),r=Math.sin(e),o=Math.cos(e),l=Math.cos(n);return(0<(s=this.sin_p14*r+this.cos_p14*o*l)||Math.abs(s)<=D)&&(i=this.a*o*Math.sin(n),a=this.y0+this.a*(this.cos_p14*r-this.sin_p14*o*l)),t.x=i,t.y=a,t},inverse:function(t){var s,i,a,h,e,n,r;return t.x-=this.x0,t.y-=this.y0,s=Math.sqrt(t.x*t.x+t.y*t.y),i=Zt(s/this.a),a=Math.sin(i),h=Math.cos(i),n=this.long0,Math.abs(s)<=D?r=this.lat0:(r=Zt(h*this.sin_p14+t.y*a*this.cos_p14/s),e=Math.abs(this.lat0)-z,n=Math.abs(e)<=D?nt(0<=this.lat0?this.long0+Math.atan2(t.x,-t.y):this.long0-Math.atan2(-t.x,t.y)):nt(this.long0+Math.atan2(t.x*a,s*this.cos_p14*h-t.y*this.sin_p14*a))),t.x=n,t.y=r,t},names:["ortho"]},Ss=1,Ns=2,ks=3,Es=4,qs=5,Is=6,Os=1,As=2,Gs=3,js=4,zs={init:function(){this.x0=this.x0||0,this.y0=this.y0||0,this.lat0=this.lat0||0,this.long0=this.long0||0,this.lat_ts=this.lat_ts||0,this.title=this.title||"Quadrilateralized Spherical Cube",this.lat0>=z-U/2?this.face=qs:this.lat0<=-(z-U/2)?this.face=Is:Math.abs(this.long0)<=U?this.face=Ss:Math.abs(this.long0)<=z+U?this.face=0=Math.abs(t.y)?y.value=Os:0<=t.y&&t.y>=Math.abs(t.x)?(y.value=As,s-=z):t.x<0&&-t.x>=Math.abs(t.y)?(y.value=Gs,s=s<0?s+Q:s-Q):(y.value=js,s+=z),c=Q/12*Math.tan(s),e=Math.sin(c)/(Math.cos(c)-1/Math.sqrt(2)),n=Math.atan(e),(r=1-(a=Math.cos(s))*a*(h=Math.tan(i))*h*(1-Math.cos(Math.atan(1/Math.cos(n)))))<-1?r=-1:1a.y)--s;else{if(!(Ls[s+1][0]<=a.y))break;++s}var h=Ls[s],i=function(t,s,i,a){for(var h=s;a;--a){var e=t(h);if(h-=e,Math.abs(e)
+
+
+
+
+
+
+Getting Started • StreamCatTools
+
+
+
+
+
+
+
+
+
+
+
+
+ Skip to contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
StreamCat API
+
+
We can pull data into R from the StreamCat
+API by simply passing a URL to extract from json. We have to
+hard-wire parameters though and are limited in the number of records
+returned through a GET request.
+
+res <- jsonlite :: fromJSON ( "https://api.epa.gov/StreamCat/streams/metrics?name=fert&areaOfInterest=cat&comid=179" )
+res $ items
+
+
+
List API parameters
+
+
List StreamCat parameters: Get a list of available StreamCat values
+for certain parameters using the sc_get_params function via
+the API
+
+library ( StreamCatTools )
+region_params <- sc_get_params ( param= 'aoi' )
+
+name_params <- sc_get_params ( param= 'metric_names' )
+
+print ( paste0 ( 'region parameters are: ' , paste ( region_params ,collapse = ', ' ) ) )
+#> [1] "region parameters are: cat, catrp100, other, ws, wsrp100"
+print ( paste0 ( 'A selection of available StreamCat metrics include: ' ,paste ( name_params [ 1 : 10 ] ,collapse = ', ' ) ) )
+#> [1] "A selection of available StreamCat metrics include: agkffact, al2o3, bankfulldepth, bankfullwidth, bfi, canaldens, cao, cbnf, chem, clay"
+
We can also see what metrics are available for what areas of interest
+and what years using the sc_get_params function (which
+returns a tibble of information about StreamCat metrics):
+
+var_info <- sc_get_params ( param= 'variable_info' )
+head ( var_info )
+#> # A tibble: 6 × 13
+#> category metric aoi year short_description long_description units dsid
+#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
+#> 1 Anthropogen… NABD_… Cat,… NA NABD Dam Density Density of geor… Coun… 33
+#> 2 Anthropogen… NABD_… Cat,… NA NABD NID Reservo… Volume all rese… Cubi… 33
+#> 3 Anthropogen… NABD_… Cat,… NA NABD Normal Rese… Volume all rese… Cubi… 33
+#> 4 Natural Preci… Cat,… NA Surplus Precipit… This dataset re… Kilo… 75
+#> 5 Soils Rckde… Cat,… NA Mean Bedrock Dep… Mean depth (cm)… Cent… 56
+#> 6 Soils agkff… Cat,… NA Ag Soil Erodibil… Mean of STATSGO… Unit… 28
+#> # ℹ 5 more variables: dataset <chr>, source_name <chr>, source_URL <chr>,
+#> # ACTIVE <dbl>, DSNAME <chr>
+
We can look up the display name or names for a metric using the
+sc_fullname function via the API
+
+metric = 'pcthbwet2011'
+fullname <- sc_fullname ( metric )
+fullname
+#> [1] "Herbaceous Wetland Percentage 2011"
+
+metric = 'pctdecid2019,fert'
+fullname <- sc_fullname ( metric )
+fullname
+#> character(0)
+
We can additionally get a data frame of state FIPS codes,
+abbreviations and names, and the same information for counties as well
+using sc_get_params:
+
+states <- sc_get_params ( param= 'state' )
+head ( states )
+#> st_fips st_abbr st_name
+#> 30 01 AL Alabama
+#> 8 04 AZ Arizona
+#> 25 05 AR Arkansas
+#> 6 06 CA California
+#> 15 08 CO Colorado
+#> 50 09 CT Connecticut
+
+counties <- sc_get_params ( param= 'county' )
+head ( counties )
+#> fips state county_name
+#> 752 01001 AL Autauga County
+#> 713 01003 AL Baldwin County
+#> 655 01005 AL Barbour County
+#> 755 01007 AL Bibb County
+#> 748 01009 AL Blount County
+#> 656 01011 AL Bullock County
+
+
+
+
We can also filter metric names and information by the metric
+year(s), the indicator categories for metrics, the metric data set
+names, or the Areas of Interest the metrics are available for.
+
+metrics <- sc_get_metric_names ( category = c ( 'Deposition' ,'Climate' ) ,aoi= c ( 'Cat' ,'Ws' ) )
+head ( metrics )
+#> # A tibble: 6 × 9
+#> Category Metric AOI Year Short_Name Metric_Description Units Source Dataset
+#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
+#> 1 Climate bfi[A… Cat,… NA Base Flow… Base flow is the … Perc… USGS … Base F…
+#> 2 Deposit… inorg… Cat,… 2008 Mean Annu… Annual gradient m… Kilo… NADP NADP
+#> 3 Deposit… nh4[Y… Cat,… 2008 Mean annu… Annual gradient m… Kilo… NADP NADP
+#> 4 Deposit… no3[Y… Cat,… 2008 Mean Annu… Annual gradient m… Kilo… NADP NADP
+#> 5 Climate preci… Cat,… NA 30-year M… PRISM climate dat… Mill… PRISM PRISM
+#> 6 Climate preci… Cat,… 1991… 30-year M… PRISM climate dat… Mill… PRISM PRISM
+
+
+
Get data for COMIDs
+
+
In this example we access several variables, for several areas of
+interest, and for several COMIDs using the sc_get_data
+function. Loads data into a tibble we can view.
+
+df <- sc_get_data ( metric= 'pcturbmd2006,damdens,tridens' , aoi= 'rp100cat,cat,ws' , comid= '179,1337,1337420' )
+knitr :: kable ( df )
+
+
+
+
+
+
+
+
+
+
+
+
+
+179
+0
+0
+0.00
+0
+0.00
+0.0000
+
+
+1337
+0
+0
+0.07
+0
+0.07
+0.0000
+
+
+1337420
+0
+0
+0.00
+0
+0.01
+0.0329
+
+
+
+
+
+
Get data for county
+
+
In this example we access a couple variables at the watershed scale
+for the area of interest of a county (Benton County in this case) using
+the sc_get_data function.
+
+
+
+
+
+23762961
+1.11
+
+
+23762985
+0.84
+
+
+23762915
+1.14
+
+
+23762959
+1.14
+
+
+23762967
+1.10
+
+
+23762761
+1.72
+
+
+
+
+
+
Get all metrics for COMIDs or an Area of Interest
+
+
We can also get all StreamCat metrics for a set of COMIDs or an area
+of interest. Please do not request metric=‘all’ and aoi=‘conus’
+in order not to overload requests to the server. Requesting metric=‘all’
+for a state or multiple states or hydroregions will also take a long
+time to process .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+179
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1.117
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+3.17
+3.17
+0
+3.17
+0
+3.17
+0
+0
+2102.561
+1675.837
+0
+4.89
+1.52
+3.87
+0.05
+1.09
+1.04
+0
+49.06
+0.05
+0.91
+0
+0
+0
+0
+37.52
+0
+0
+0
+0
+0
+0
+88.2995
+0
+0
+0
+0
+0
+0
+0.4413
+3.17
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+4.89
+1.52
+3.85
+0.13
+1.09
+1.09
+0
+49.04
+0.13
+0.89
+0
+0
+0
+0
+37.39
+0
+4.91
+1.54
+3.7
+0.35
+1.09
+0.71
+0
+49.54
+0
+0.25
+0
+0
+0
+0
+37.9
+878.2494
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1.34e-05
+0
+0
+0
+NA
+NA
+NA
+NA
+NA
+NA
+NA
+NA
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+64.3313
+169.6366
+0
+NA
+37.57
+0
+196.1233
+0
+0
+0.998
+6.3799
+0
+5.5091
+0
+0.0506
+4.89
+0.23
+0
+0
+0
+8e-04
+0
+100
+0
+12.28701
+0
+0.1
+0
+36.89
+5.032428
+0
+1.52
+0
+0
+0
+0
+1.95
+1.0772
+0
+4.852966
+0
+3.8
+0.9958425
+0.972
+0
+0.08
+0
+342.1452
+0
+0
+0
+4.89
+0
+4.885117
+7.9453
+0
+NA
+0
+49.16
+1.0557
+0
+0
+0
+1059.078
+1.09
+0
+37.29
+0
+0
+0
+0
+0
+1108.386
+0
+0
+0
+49.21784
+40.52718
+0
+48.76
+5.130848
+0.9983122
+8.874548
+0
+10.276
+0
+52
+49.01
+1
+1.09
+10.59572
+2.4653
+0
+5.910425
+0.0161
+0.1545
+1.01
+0
+1.3213
+2.2883
+0.13
+0
+0
+0
+0.81
+0
+0
+0.997
+0
+0
+1.438
+0
+-0.8263614
+1.22
+0
+4.89
+0
+0
+0
+0.94
+0
+3.8
+0.73
+1254.539
+22.33772
+0
+14.35371
+0
+3.82
+1.52
+0
+646
+0.08
+0
+134.9983
+0.2044
+1.24
+0.5276
+1.52
+4.91
+0
+1.54
+3.87
+0.05
+1.09
+0.71
+0
+49.67
+0
+0.25
+0
+0
+0
+0
+37.9
+133875
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+4.89
+1.52
+3.77
+0.05
+1.09
+0.76
+0
+49.7
+0
+0.38
+0
+0
+0
+0
+37.85
+0
+0
+0
+0
+0.71
+0
+0
+0.35
+0.03
+0
+0
+0
+0
+0
+0
+0.23
+0
+1152.678
+10.56534
+5.015274
+-0.5362276
+3.17
+0
+3.17
+0
+3.17
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+8016.374
+8243.797
+8542.023
+8787.955
+9007.697
+9287.582
+9438.607
+9722.905
+9996.046
+10686.69
+11330.88
+12057.65
+12981.15
+13353.16
+13811.05
+14472.36
+15211.29
+16194.87
+17547.07
+19142.33
+20611
+22116.82
+23411.37
+24590.54
+24772.69
+25101.07
+25575.9
+26197.07
+26964.96
+27879.69
+11011.91
+11171.62
+11383.85
+11564.13
+11738.34
+11915.36
+12000.95
+12203.13
+12392.89
+12464.94
+12537.05
+12605.38
+12721.52
+12932.75
+13172.6
+13492.15
+13836.86
+14248.79
+14793.05
+15395.81
+15956.26
+16542.52
+17068.58
+17624.04
+17758.03
+17917.15
+18101.46
+18310.91
+18545.61
+18805.58
+
+
+
+
+
Get NLCD data
+
+
In this example we access National Land Cover Dataset (NLCD) data for
+2001, just at the catchment level for several COMIDs using the
+sc_nlcd function. Loads data into a tibble we can view.
+
+df <- sc_nlcd ( year= '2001' , aoi= 'cat' ,
+ comid= '179,1337,1337420' )
+knitr :: kable ( df )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+179
+0
+0.23
+36.89
+1.52
+0.0
+1.95
+0.00
+0
+48.76
+0.00
+0
+1.22
+4.89
+0.73
+0.00
+3.82
+
+
+1337
+0
+1.60
+20.75
+0.00
+0.1
+0.56
+0.28
+0
+51.55
+0.24
+0
+2.83
+5.65
+0.66
+3.98
+11.79
+
+
+1337420
+0
+0.87
+0.95
+0.00
+0.0
+1.64
+0.00
+0
+3.77
+0.40
+0
+0.11
+4.06
+3.38
+1.77
+83.06
+
+
+
+
We can also pass a couple years for a different area of interest for
+another region like a county.
+
+df <- sc_nlcd ( year= '2006, 2019' , aoi= 'ws' ,
+ county= '41003' )
+knitr :: kable ( head ( df ) )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+23762961
+0.01
+36.68
+4.65
+1.03
+1.51
+33.28
+3.44
+0
+7.32
+0.08
+3.99
+0.10
+1.69
+0.30
+3.46
+2.46
+0
+5.85
+3.00
+35.58
+3.44
+0.01
+26.93
+1.11
+5.74
+0.09
+0.23
+10.78
+4.79
+0.66
+1.67
+0.11
+
+
+23762985
+0.00
+51.52
+1.58
+1.03
+2.21
+20.06
+0.84
+0
+9.14
+0.04
+6.06
+0.05
+1.46
+0.24
+4.60
+1.18
+0
+7.16
+1.05
+21.16
+4.62
+0.01
+37.51
+0.84
+8.44
+0.04
+0.19
+15.78
+1.22
+0.51
+1.44
+0.04
+
+
+23762915
+0.01
+55.83
+0.01
+1.58
+2.74
+6.60
+0.40
+0
+18.61
+0.05
+7.45
+0.01
+0.60
+0.14
+4.65
+1.33
+0
+19.10
+0.01
+6.87
+4.63
+0.01
+49.77
+1.14
+4.71
+0.01
+0.12
+11.15
+0.58
+1.27
+0.58
+0.05
+
+
+23762959
+0.01
+36.29
+4.66
+1.02
+1.50
+33.72
+3.51
+0
+7.24
+0.09
+3.95
+0.10
+1.68
+0.30
+3.43
+2.51
+0
+5.79
+3.02
+36.01
+3.41
+0.01
+26.64
+1.14
+5.68
+0.09
+0.23
+10.66
+4.88
+0.66
+1.66
+0.12
+
+
+23762967
+0.01
+38.81
+3.54
+1.04
+1.60
+31.71
+3.49
+0
+7.53
+0.09
+4.30
+0.09
+1.65
+0.29
+3.40
+2.47
+0
+5.98
+2.42
+33.49
+3.39
+0.01
+28.48
+1.10
+6.20
+0.08
+0.23
+11.36
+4.86
+0.64
+1.64
+0.13
+
+
+23762761
+0.00
+57.44
+0.40
+1.90
+3.08
+2.45
+0.27
+0
+20.77
+0.01
+6.65
+0.00
+0.31
+0.07
+4.89
+1.76
+0
+19.15
+0.05
+2.84
+4.91
+0.00
+38.13
+1.72
+7.95
+0.00
+0.04
+23.53
+0.31
+1.06
+0.29
+0.01
+
+
+
+
+
+
Get COMIDs
+
+
In this example we use the sc_get_comid function to find
+COMIDs for USGS stream gages we load into R. We use a .csv file with
+coordinate columns and a known coordinate reference system.
+
+gages = readr :: read_csv ( system.file ( "extdata" ,"Gages_flowdata.csv" , package = "StreamCatTools" ) ,show_col_types = FALSE )
+# we'll just grab a few variables to keep things simple
+gages <- gages [ ,c ( 'SOURCE_FEA' ,'STATION_NM' ,'LON_SITE' ,'LAT_SITE' ) ]
+gages_coms <- sc_get_comid ( gages , xcoord= 'LON_SITE' , ycoord= 'LAT_SITE' , crsys= 4269 )
+
+# Add the COMID we found back to gages data frame
+gages $ COMID <- strsplit ( gages_coms , "," ) [[ 1 ] ]
+df <- sc_get_data ( metric= 'huden2010' , aoi= 'ws' , comid= gages_coms )
+df $ COMID <- as.character ( df $ comid )
+gages <- dplyr :: left_join ( gages , df , by= 'COMID' )
+knitr :: kable ( head ( gages ) )
+
+
+
Get data for a hydroregion
+
+
In this example we access a couple watershed-only metrics for a
+particular NHDPlus hydroregion using the sc_get_data
+function.
+
+
+
+
+
+22988611
+0.99
+
+
+24114311
+0.29
+
+
+24114309
+0.27
+
+
+24116239
+0.42
+
+
+22988639
+0.00
+
+
+22988711
+0.02
+
+
+
+
+
+
Get data for CONUS
+
+
In this example we access a metric for conus using the
+sc_get_data function - this is shown for demonstration but
+not run as it takes a bit of time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/articles/Articles/LakeCat.html b/docs/articles/Articles/LakeCat.html
new file mode 100644
index 0000000..48244e5
--- /dev/null
+++ b/docs/articles/Articles/LakeCat.html
@@ -0,0 +1,428 @@
+
+
+
+
+
+
+
+Working with LakeCat data • StreamCatTools
+
+
+
+
+
+
+
+
+
+
+
+
+ Skip to contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Accessing and working with LakeCat
+
+
The StreamCatTools package was designed to simplify the
+use of StreamCat
+data in R, leveraging the new API for
+StreamCat . We now have functionality in the StreamCat API
+for accessing and working with LakeCat data and have added functions in
+StreamCatTools to access LakeCata data in R using the
+API.
+
We can actually pull data into R from LakeCat by simply passing a URL
+to extract from json. We have to hard-wire parameters and are limited in
+the number of records returned through a GET request.
+
+res <- jsonlite :: fromJSON ( "https://api.epa.gov/StreamCat/lakes/metrics?name=pcturbmd2006&areaOfInterest=cat&comid=22538788" )
+res $ items
+
+
+
List LakeCat API parameters
+
+
List LakeCat parameters: Get a list of available LakeCat values for
+certain parameters using the lc_get_params function (right
+now just metric names and areas of interest for this function) via the
+API
+
+library ( StreamCatTools )
+region_params <- lc_get_params ( param= 'aoi' )
+
+name_params <- lc_get_params ( param= 'metric_names' )
+
+print ( paste0 ( 'region parameters are: ' , paste ( region_params ,collapse = ', ' ) ) )
+#> [1] "region parameters are: cat, ws"
+print ( paste0 ( 'A selection of available LakrCat metrics include: ' ,paste ( name_params [ 1 : 10 ] ,collapse = ', ' ) ) )
+#> [1] "A selection of available LakrCat metrics include: agkffact, al2o3, bfi, canaldens, cao, cbnf, clay, coalminedens, compstrgth, damdens"
+
We can also see what metrics are available for what areas of interest
+and what years using the sc_get_params function (which
+returns a tibble of information about StreamCat metrics):
+
+var_info <- lc_get_params ( param= 'variable_info' )
+head ( var_info )
+#> # A tibble: 6 × 13
+#> category metric aoi year short_description long_description units dsid
+#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
+#> 1 Soils agkff… Cat,… NA Ag Soil Erodibil… Mean of STATSGO… Unit… 10
+#> 2 Natural al2o3… Cat,… NA Mean Lithologica… Mean % of litho… Perc… 11
+#> 3 Base areas… Ws NA Watershed Area S… Watershed area … Squa… NA
+#> 4 Climate bfi[A… Cat,… NA Base Flow Index Base flow is th… Perc… 12
+#> 5 Anthropogen… canal… Cat,… NA Canal Density Density of NHDP… Kilo… 13
+#> 6 Natural cao[A… Cat,… NA Mean Lithologica… Mean % of litho… Perc… 11
+#> # ℹ 5 more variables: dataset <chr>, source_name <chr>, source_URL <chr>,
+#> # ACTIVE <dbl>, DSNAME <chr>
+
Look up the display name or names for a metric using the
+lc_fullname function via the API
+
+metric = 'pcthbwet2016'
+fullname <- lc_fullname ( metric )
+fullname
+#> [1] "Herbaceous Wetland Percentage 2016"
+
+metric = c ( 'pctdecid2019' ,'fert' )
+fullname <- lc_fullname ( metric )
+fullname
+#> [1] "Deciduous Forest Percentage 2019"
+#> [2] "Synthetic Nitrogen Fertilizer Application Mean Rate"
+
+
+
+
We can also filter metric names and information by the metric
+year(s), the indicator categories for metrics, the metric data set
+names, or the Areas of Interest the metrics are available for.
+
+metrics <- lc_get_metric_names ( category = c ( 'Anthropogenic' ,'Natural' ) , aoi= c ( 'Cat' ,'Ws' ) )
+head ( metrics )
+#> # A tibble: 6 × 9
+#> Category Metric AOI Year Short_Name Metric_Description Units Source Dataset
+#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
+#> 1 Natural al2o3… Cat,… NA Mean Lith… Mean % of litholo… Perc… USGS … USGS G…
+#> 2 Anthrop… canal… Cat,… NA Canal Den… Density of NHDPlu… Kilo… Falco… Canal …
+#> 3 Natural cao[A… Cat,… NA Mean Lith… Mean % of litholo… Perc… USGS … USGS G…
+#> 4 Anthrop… cbnf[… Cat,… NA Cultivate… Mean rate of biol… Kilo… Envir… Agricu…
+#> 5 Anthrop… coalm… Cat,… NA Coal Mine… Density of coal m… Coun… USGS … Coal M…
+#> 6 Natural comps… Cat,… NA Mean Lith… Mean lithological… Perc… USGS … USGS G…
+
+
+
Get Waterbody COMIDs
+
+
In this example we use the lc_get_comid function to find
+COMIDs for a set of example lake locations we load into
+R.lc_get_comid is just a simple wrapper for
+get_waterbodies in the nhdplusTools R
+package. We can then use the COMIDs we derive for our lake locations to
+get LakeCat metrics for these lakes as we show in after this.
+
+
+
+
Get data for COMIDs
+
+
In this example we access several variables, for several areas of
+interest, and for several COMIDs using the lc_get_data
+function. We’ll show using both the COMIDS we derived with
+lc_get_comid function in previous chunk as well as with
+known COMIDS for NHDPlus waterbodies. Loads data into a tibble we can
+view.
+
+df <- lc_get_data ( metric= 'pcturbmd2006,damdens' , aoi= 'cat,ws' , comid= comids )
+knitr :: kable ( df )
+
+
+
+
+23756298
+0.0000000
+0.0000000
+0.0293228
+0.0293228
+
+
+120054065
+0.0000000
+0.0007270
+0.4348181
+0.1451495
+
+
+167120863
+0.0243986
+0.0243986
+0.2086078
+0.2086078
+
+
+
+
+df <- lc_get_data ( metric= 'pcturbmd2006,damdens' , aoi= 'cat,ws' , comid= '23783629,23794487,23812618' )
+knitr :: kable ( df )
+
+
+
+
+23783629
+0.0192097
+0.0008875
+0.2091942
+0.0213267
+
+
+23794487
+0.0000000
+0.2433268
+0.1958225
+0.8832762
+
+
+23812618
+0.0320852
+0.0071455
+0.0115507
+0.0032155
+
+
+
+
+
+
Get data for county
+
+
In this example we access a couple variables at the watershed scale
+for the area of interest of a county (Benton County in this case) using
+the sc_get_data function.
+
+
+
+
+
+23768945
+0.1662971
+
+
+23768987
+0.0000000
+
+
+23888156
+0.4161465
+
+
+23768895
+0.1344990
+
+
+23769007
+1.0194538
+
+
+23768947
+0.5524862
+
+
+
+
+
+
Get NLCD data
+
+
In this example we access National Land Cover Dataset (NLCD) data for
+2019, just at the catchment level for several COMIDs using the
+lc_nlcd function. Loads data into a tibble we can view.
+
+df <- lc_nlcd ( comid= '23783629,23794487,23812618' , year= '2019' , aoi= 'ws' )
+knitr :: kable ( df )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+23783629
+1.5601274
+82.8417931
+0.00000
+0.0627022
+3.3679487
+0.0007988
+0.0228444
+0.2318785
+0.1064740
+1.500061
+9.2003748
+0.0027956
+0.0838692
+0.0232438
+0.8217587
+0.1733297
+
+
+23794487
+0.0000000
+0.4014892
+31.64465
+1.8176509
+0.1167968
+42.3096576
+11.9132783
+0.0000000
+3.0878166
+1.744653
+0.2043945
+0.2627929
+3.6718009
+1.0146726
+1.6351559
+0.1751953
+
+
+23812618
+0.0006431
+84.9302559
+0.00000
+0.0623806
+0.9241336
+0.0000000
+0.5498498
+0.0000000
+0.0032155
+4.111976
+5.2984945
+0.0000000
+0.0533772
+0.0032155
+1.8714187
+2.1910391
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/articles/Introduction.html b/docs/articles/Introduction.html
index cf82cfc..627bdd4 100644
--- a/docs/articles/Introduction.html
+++ b/docs/articles/Introduction.html
@@ -25,7 +25,11 @@
StreamCatTools
+<<<<<<< HEAD
+ 0.9.0.9000
+=======
0.9.0
+>>>>>>> master
diff --git a/docs/articles/LakeCat.html b/docs/articles/LakeCat.html
index e7eef58..44c67aa 100644
--- a/docs/articles/LakeCat.html
+++ b/docs/articles/LakeCat.html
@@ -25,7 +25,11 @@
StreamCatTools
+<<<<<<< HEAD
+ 0.9.0.9000
+=======
0.9.0
+>>>>>>> master
diff --git a/docs/articles/StartHere.html b/docs/articles/StartHere.html
new file mode 100644
index 0000000..f2a7624
--- /dev/null
+++ b/docs/articles/StartHere.html
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+Start Here • StreamCatTools
+
+
+
+
+
+
+
+
+
+
+
+
+ Skip to contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
To install, you can install from CRAN:
+
+
Or you can install from GitHub:
+
+
After installing load the library
+
+
+
+
Background
+
+
The StreamCatTools package was designed to simplify the
+use of StreamCat
+data in R, leveraging the new API for
+StreamCat .
+
+
+
+
There are three additional vignettes in StreamCatTools
+that are available on our website here under the
+“Articles” tab:
+
+Introduction
+
+
+An overview of the basic fucntionality of the package
+
+
+LakeCat
+
+
+An overview of accessing data for lakes within the package and
+functions to do so
+
+
+Applications
+
+
+A more in depth walk through with specific use-case examples and
+demonstrations
+
+
These vignettes cover some of the core functions (and arguments
+within those functions) in StreamCatTools. Help files for a
+particular function are viewable by running ?function_name
+after loading StreamCatTools. For example, to learn more
+about the sc_get_data() function, run
+?sc-get_data.
+
+
+
+
If you use StreamCatTools in your work, please cite it.
+You can view the most recent citation by running
+
+citation ( "StreamCatTools" )
+#> To cite package 'StreamCatTools' in publications use:
+#>
+#> Weber M (????). _StreamCatTools: 'StreamCatTools'_. R package version
+#> 0.9.1, https://github.com/USEPA/StreamCatTools,
+#> <https://usepa.github.io/StreamCatTools/>.
+#>
+#> A BibTeX entry for LaTeX users is
+#>
+#> @Manual{,
+#> title = {StreamCatTools: 'StreamCatTools'},
+#> author = {Marc Weber},
+#> note = {R package version 0.9.1, https://github.com/USEPA/StreamCatTools},
+#> url = {https://usepa.github.io/StreamCatTools/},
+#> }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/articles/index.html b/docs/articles/index.html
index 8474719..c4ed669 100644
--- a/docs/articles/index.html
+++ b/docs/articles/index.html
@@ -1,5 +1,5 @@
-Articles • StreamCatTools
+Articles • StreamCatTools
Skip to contents
@@ -7,7 +7,7 @@
StreamCatTools
- 0.9.0
+ 0.9.1
@@ -18,9 +18,10 @@
diff --git a/docs/authors.html b/docs/authors.html
index 624ae03..6f2387a 100644
--- a/docs/authors.html
+++ b/docs/authors.html
@@ -1,5 +1,5 @@
-