Skip to content

Commit

Permalink
Merge pull request #1 from martinRenou/add_openlayers_dependency
Browse files Browse the repository at this point in the history
Introduce Map widget and TileLayer widget
  • Loading branch information
martinRenou authored Apr 26, 2024
2 parents 5444888 + 19e5567 commit dd1747d
Show file tree
Hide file tree
Showing 8 changed files with 8,827 additions and 29 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,5 @@ ipyopenlayers/nbextension/index.*

# Packed lab extensions
ipyopenlayers/labextension

.yarn
1 change: 0 additions & 1 deletion css/widget.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.custom-widget {
background-color: lightseagreen;
padding: 0px 2px;
}
52 changes: 45 additions & 7 deletions examples/introduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"metadata": {},
"outputs": [],
"source": [
"import ipyopenlayers"
"from ipyopenlayers import Map, TileLayer"
]
},
{
Expand All @@ -22,8 +22,8 @@
"metadata": {},
"outputs": [],
"source": [
"w = ipyopenlayers.ExampleWidget()\n",
"w"
"m = Map()\n",
"m"
]
},
{
Expand All @@ -32,13 +32,51 @@
"metadata": {},
"outputs": [],
"source": [
"assert w.value == 'Hello World'"
"m.layers"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"layer = TileLayer()\n",
"layer.url = 'wdqjwndqwnd.png'\n",
"layer.url"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.add_layer(layer)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.layers"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.layers = []"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -52,9 +90,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}
2 changes: 1 addition & 1 deletion ipyopenlayers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Copyright (c) QuantStack.
# Distributed under the terms of the Modified BSD License.

from .example import ExampleWidget
from .example import *
from ._version import __version__, version_info

def _jupyter_labextension_paths():
Expand Down
28 changes: 23 additions & 5 deletions ipyopenlayers/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,37 @@
TODO: Add module docstring
"""

from ipywidgets import DOMWidget
from traitlets import Unicode
from ipywidgets import DOMWidget, Widget, widget_serialization
from traitlets import Unicode, List, Instance
from ._frontend import module_name, module_version


class ExampleWidget(DOMWidget):
class TileLayer(Widget):

_model_name = Unicode('TileLayerModel').tag(sync=True)
_model_module = Unicode(module_name).tag(sync=True)
_model_module_version = Unicode(module_version).tag(sync=True)
_view_name = Unicode('TileLayerView').tag(sync=True)
_view_module = Unicode(module_name).tag(sync=True)
_view_module_version = Unicode(module_version).tag(sync=True)

url = Unicode().tag(sync=True)


class Map(DOMWidget):
"""TODO: Add docstring here
"""
_model_name = Unicode('ExampleModel').tag(sync=True)
_model_name = Unicode('MapModel').tag(sync=True)
_model_module = Unicode(module_name).tag(sync=True)
_model_module_version = Unicode(module_version).tag(sync=True)
_view_name = Unicode('ExampleView').tag(sync=True)
_view_name = Unicode('MapView').tag(sync=True)
_view_module = Unicode(module_name).tag(sync=True)
_view_module_version = Unicode(module_version).tag(sync=True)

value = Unicode('Hello World').tag(sync=True)

layers = List(Instance(TileLayer)).tag(sync=True, **widget_serialization)

def add_layer(self, layer):
# Copy layers (workaround ipywidgets issue)
self.layers = self.layers + [layer]
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"watch:labextension": "jupyter labextension watch ."
},
"dependencies": {
"@jupyter-widgets/base": "^1.1.10 || ^2 || ^3 || ^4 || ^5 || ^6"
"@jupyter-widgets/base": "^1.1.10 || ^2 || ^3 || ^4 || ^5 || ^6",
"ol": "^9.1.0"
},
"devDependencies": {
"@babel/core": "^7.23.7",
Expand Down
138 changes: 124 additions & 14 deletions src/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,160 @@
import {
DOMWidgetModel,
DOMWidgetView,
WidgetModel,
WidgetView,
ISerializers,
unpack_models,
ViewList,
} from '@jupyter-widgets/base';

import { Map } from 'ol';
import OSM from 'ol/source/OSM';
import TileLayer from 'ol/layer/Tile';
import View from 'ol/View';

import 'ol/ol.css';


import { MODULE_NAME, MODULE_VERSION } from './version';

// Import the CSS
import '../css/widget.css';

export class ExampleModel extends DOMWidgetModel {
export class MapModel extends DOMWidgetModel {
defaults() {
return {
...super.defaults(),
_model_name: ExampleModel.model_name,
_model_module: ExampleModel.model_module,
_model_module_version: ExampleModel.model_module_version,
_view_name: ExampleModel.view_name,
_view_module: ExampleModel.view_module,
_view_module_version: ExampleModel.view_module_version,
_model_name: MapModel.model_name,
_model_module: MapModel.model_module,
_model_module_version: MapModel.model_module_version,
_view_name: MapModel.view_name,
_view_module: MapModel.view_module,
_view_module_version: MapModel.view_module_version,
value: 'Hello World',
layers: [],
};
}

static serializers: ISerializers = {
...DOMWidgetModel.serializers,
layers: { deserialize: unpack_models },
// Add any extra serializers here
};

static model_name = 'ExampleModel';
static model_name = 'MapModel';
static model_module = MODULE_NAME;
static model_module_version = MODULE_VERSION;
static view_name = 'ExampleView'; // Set to null if no view
static view_name = 'MapView'; // Set to null if no view
static view_module = MODULE_NAME; // Set to null if no view
static view_module_version = MODULE_VERSION;
}

export class ExampleView extends DOMWidgetView {
export class MapView extends DOMWidgetView {
render() {
this.el.classList.add('custom-widget');

this.value_changed();
this.model.on('change:value', this.value_changed, this);
this.mapContainer = document.createElement('div');
this.mapContainer.style.height = '500px';

this.el.appendChild(this.mapContainer);

this.layer_views = new ViewList(
this.add_layer_model,
this.remove_layer_view,
this
);

this.layers_changed();
this.model.on('change:layers', this.layers_changed, this);

this.map = new Map({
target: this.mapContainer,
view: new View({
center: [0, 0],
zoom: 2,
}),
});
}

layers_changed() {
const layers = this.model.get('layers') as TileLayerModel[];

this.layer_views.update(layers);
}

remove_layer_view(child_view: TileLayerView) {
// TODO Implement layer removal
console.log('Trying to remove TileLayerView', child_view);

child_view.remove();
}

async add_layer_model(child_model: TileLayerModel) {
const view = await this.create_child_view<TileLayerView>(child_model, {
map_view: this,
});

this.map.addLayer(view.tileLayer);

this.displayed.then(() => {
view.trigger('displayed', this);
});
return view;
}

mapContainer: HTMLDivElement;

map: Map;

layer_views: ViewList<TileLayerView>;
}


export class TileLayerModel extends WidgetModel {
defaults() {
return {
...super.defaults(),
_model_name: TileLayerModel.model_name,
_model_module: TileLayerModel.model_module,
_model_module_version: TileLayerModel.model_module_version,
_view_name: TileLayerModel.view_name,
_view_module: TileLayerModel.view_module,
_view_module_version: TileLayerModel.view_module_version,
value: 'Hello World',
};
}

value_changed() {
this.el.textContent = this.model.get('value');
static serializers: ISerializers = {
...WidgetModel.serializers,
// Add any extra serializers here
};

static model_name = 'TileLayerModel';
static model_module = MODULE_NAME;
static model_module_version = MODULE_VERSION;
static view_name = 'TileLayerView'; // Set to null if no view
static view_module = MODULE_NAME; // Set to null if no view
static view_module_version = MODULE_VERSION;
}

export class TileLayerView extends WidgetView {
render() {
super.render();

// TODO Support url setting

this.tileLayer = new TileLayer({
source: new OSM(),
});

this.url_changed();
this.model.on('change:url', this.url_changed, this);
}

url_changed() {
// TODO React on url change!!
}

tileLayer: TileLayer<OSM>;
}
Loading

0 comments on commit dd1747d

Please sign in to comment.