Skip to content

Commit

Permalink
Use geoverview for GeoJSON renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
davidbrochart committed Jun 23, 2022
1 parent 602568f commit 2a50f03
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 101 deletions.
3 changes: 1 addition & 2 deletions packages/geojson-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@
"@jupyterlab/rendermime-interfaces": "^3.2.8",
"@lumino/messaging": "^1.10.1",
"@lumino/widgets": "^1.31.1",
"leaflet": "^1.5.0"
"geoverview": "^1.2.0"
},
"devDependencies": {
"@jupyterlab/builder": "^3.2.8",
"@types/leaflet": "^1.4.0",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
"typescript": "~4.1.3"
Expand Down
1 change: 1 addition & 0 deletions packages/geojson-extension/src/geoverview.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'geoverview';
104 changes: 5 additions & 99 deletions packages/geojson-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,10 @@ import { Message } from '@lumino/messaging';

import { IRenderMime } from '@jupyterlab/rendermime-interfaces';

import { defaultSanitizer } from '@jupyterlab/apputils';

import leaflet from 'leaflet';

import 'leaflet/dist/leaflet.css';
import {view} from 'geoverview';

import '../style/index.css';

import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';

/**
* The CSS class to add to the GeoJSON Widget.
*/
Expand All @@ -34,40 +26,6 @@ const CSS_ICON_CLASS = 'jp-MaterialIcon jp-GeoJSONIcon';
*/
export const MIME_TYPE = 'application/geo+json';

/**
* Set base path for leaflet images.
*/

// https://github.com/Leaflet/Leaflet/issues/4968
// Marker file names are hard-coded in the leaflet source causing
// issues with webpack.
// This workaround allows webpack to inline all marker URLs.

delete (leaflet.Icon.Default.prototype as any)['_getIconUrl'];

leaflet.Icon.Default.mergeOptions({
iconRetinaUrl: iconRetinaUrl,
iconUrl: iconUrl,
shadowUrl: shadowUrl,
});

/**
* The url template that leaflet tile layers.
* See http://leafletjs.com/reference-1.0.3.html#tilelayer
*/
const URL_TEMPLATE = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';

/**
* The options for leaflet tile layers.
* See http://leafletjs.com/reference-1.0.3.html#tilelayer
*/
const LAYER_OPTIONS: leaflet.TileLayerOptions = {
attribution:
'Map data (c) <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',
minZoom: 0,
maxZoom: 18,
};

export class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
/**
* Create a new widget for rendering GeoJSON.
Expand All @@ -76,59 +34,24 @@ export class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
super();
this.addClass(CSS_CLASS);
this._mimeType = options.mimeType;
// Create leaflet map object
// trackResize option set to false as it is not needed to track
// window.resize events since we have individual phosphor resize
// events.
this._map = leaflet.map(this.node, {
trackResize: false,
});
}

/**
* Dispose of the widget.
*/
dispose(): void {
// Dispose of leaflet map
this._map.remove();
this._map = null;
super.dispose();
}

/**
* Render GeoJSON into this widget's node.
*/
renderModel(model: IRenderMime.IMimeModel): Promise<void> {
const data = model.data[this._mimeType] as any | GeoJSON.GeoJsonObject;
const metadata = (model.metadata[this._mimeType] as any) || {};
const data = model.data[this._mimeType] as any;
return new Promise<void>((resolve, reject) => {
// Add leaflet tile layer to map
leaflet
.tileLayer(
metadata.url_template || URL_TEMPLATE,
metadata.layer_options || LAYER_OPTIONS
)
.addTo(this._map);
// Create GeoJSON layer from data and add to map
this._geoJSONLayer = leaflet
.geoJSON(data, {
onEachFeature: function (feature, layer) {
if (feature.properties) {
let popupContent = '<table>';
for (const p in feature.properties) {
popupContent +=
'<tr><td>' +
p +
':</td><td><b>' +
feature.properties[p] +
'</b></td></tr>';
}
popupContent += '</table>';
layer.bindPopup(defaultSanitizer.sanitize(popupContent));
}
},
})
.addTo(this._map);
const map = view(data);
this.node.appendChild(map.next().value);
map.next();
this.update();
resolve();
});
Expand All @@ -138,18 +61,6 @@ export class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
* A message handler invoked on an `'after-attach'` message.
*/
protected onAfterAttach(msg: Message): void {
if (this.parent.hasClass('jp-OutputArea-child')) {
// Disable scroll zoom by default to avoid conflicts with notebook scroll
this._map.scrollWheelZoom.disable();
// Enable scroll zoom on map focus
this._map.on('blur', (event) => {
this._map.scrollWheelZoom.disable();
});
// Disable scroll zoom on blur
this._map.on('focus', (event) => {
this._map.scrollWheelZoom.enable();
});
}
this.update();
}

Expand All @@ -173,14 +84,9 @@ export class RenderedGeoJSON extends Widget implements IRenderMime.IRenderer {
protected onUpdateRequest(msg: Message): void {
// Update map size after update
if (this.isVisible) {
this._map.invalidateSize();
}
// Update map size after panel/window is resized
this._map.fitBounds(this._geoJSONLayer.getBounds());
}

private _map: leaflet.Map;
private _geoJSONLayer: leaflet.GeoJSON;
private _mimeType: string;
}

Expand Down

0 comments on commit 2a50f03

Please sign in to comment.