UNPKG

jupyterlab-emrys

Version:

A computational environment for Jupyter. Powered by Emrys

155 lines (154 loc) 5.36 kB
// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var phosphor_widget_1 = require('phosphor-widget'); var docregistry_1 = require('../docregistry'); var json_1 = require('../notebook/common/json'); var leaflet = require('leaflet'); /** * The class name added to a map widget. */ var MAP_CLASS = 'jp-MapWidget'; /** * A widget for maps. */ var MapWidget = (function (_super) { __extends(MapWidget, _super); /** * Construct a new map widget. */ function MapWidget(context) { var _this = this; _super.call(this); this._fitted = false; this._sized = false; this._width = -1; this._height = -1; this._geojson = null; this._context = context; this.node.tabIndex = -1; this.addClass(MAP_CLASS); this._map = leaflet.map(this.node).fitWorld(); leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data (c) <a href="https://openstreetmap.org">OpenStreetMap</a> contributors', min_zoom: 0, max_zoom: 18, }).addTo(this._map); // Since we keep track of the widget size, we monkeypatch the map // to use our information instead of doing a DOM read every time it needs // the size info. We can stop monkeypatching when we have a size hint change // available from leaflet (cf. // https://github.com/Leaflet/Leaflet/issues/4200#issuecomment-233616337 and // https://github.com/jupyter/jupyterlab/pull/454#discussion_r71349224) this._map.getSize = function () { var map = _this._map; if (!map._size || map._sizeChanged) { if (_this._width < 0 || _this._height < 0) { return map.prototype.getSize.call(map); } map._size = new leaflet.Point(_this._width, _this._height); map._sizeChanged = false; } return map._size.clone(); }; context.model.contentChanged.connect(function () { _this.update(); }); context.pathChanged.connect(function () { _this.update(); }); } /** * Dispose of the resources used by the widget. */ MapWidget.prototype.dispose = function () { if (this.isDisposed) { return; } this._context = null; this._map.remove(); this._map = null; this._geojsonLayer = null; _super.prototype.dispose.call(this); }; /** * Handle `update-request` messages for the widget. */ MapWidget.prototype.onUpdateRequest = function (msg) { this.title.text = this._context.path.split('/').pop(); if (!this.isAttached) { return; } var content = this._context.model.toString(); var geojson = content ? JSON.parse(content) : content; if (json_1.deepEqual(geojson, this._geojson)) { return; } // we're attached to the DOM and have new layer content now if (this._geojsonLayer) { this._map.removeLayer(this._geojsonLayer); } this._geojson = geojson; this._geojsonLayer = null; if (geojson) { this._geojsonLayer = leaflet.geoJson(geojson, { pointToLayer: function (feature, latlng) { return leaflet.circleMarker(latlng); } }); this._map.addLayer(this._geojsonLayer); this._fitLayerBounds(); } }; /** * A message handler invoked on a 'resize' message. */ MapWidget.prototype.onResize = function (msg) { this._sized = true; this._width = msg.width; this._height = msg.height; this._map.invalidateSize(true); this._fitLayerBounds(); }; /** * Make the map fit the geojson layer bounds only once when all info is available. */ MapWidget.prototype._fitLayerBounds = function () { if (!this._fitted && this._sized && this._geojsonLayer) { this._map.fitBounds(this._geojsonLayer.getBounds()); this._fitted = true; } }; /** * A message handler after the widget is attached to the DOM. */ MapWidget.prototype.onAfterAttach = function () { this.update(); }; return MapWidget; }(phosphor_widget_1.Widget)); exports.MapWidget = MapWidget; /** * A widget factory for maps. */ var MapWidgetFactory = (function (_super) { __extends(MapWidgetFactory, _super); function MapWidgetFactory() { _super.apply(this, arguments); } /** * Create a new widget given a context. */ MapWidgetFactory.prototype.createNew = function (context, kernel) { var widget = new MapWidget(context); this.widgetCreated.emit(widget); return widget; }; return MapWidgetFactory; }(docregistry_1.ABCWidgetFactory)); exports.MapWidgetFactory = MapWidgetFactory;