Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use geoverview for GeoJSON renderer #276

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/geojson.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
declare module '*.png';
declare module 'geoverview';
106 changes: 5 additions & 101 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 @@ -172,15 +83,8 @@ 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