From 43ce87578d34c1bf48db5a365dc8e068ce26b97d Mon Sep 17 00:00:00 2001 From: Nour-Cheour10 Date: Tue, 4 Jun 2024 15:01:41 +0200 Subject: [PATCH 01/10] widget implementation per overlay --- examples/introduction.ipynb | 177 +++++++++++++++++++----------------- ipyopenlayers/example.py | 15 ++- src/baseoverlay.ts | 66 ++++++++++++++ src/imageoverlay.ts | 56 ++++++++++++ src/popupoverlay.ts | 55 +++++++++++ src/tilelayer.ts | 4 +- src/video_overlay.ts | 61 +++++++++++++ src/widget.ts | 136 +-------------------------- 8 files changed, 347 insertions(+), 223 deletions(-) create mode 100644 src/baseoverlay.ts create mode 100644 src/imageoverlay.ts create mode 100644 src/popupoverlay.ts create mode 100644 src/video_overlay.ts diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index c06f769..d137ac2 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -24,7 +24,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "26ca977cf97241c0b29d81cb48500b97", + "model_id": "6db90e12cf764585b9fd87cc848167ad", "version_major": 2, "version_minor": 0 }, @@ -39,85 +39,107 @@ ], "source": [ "m = Map(center=[0.0, 0.0], zoom=2)\n", - "m" + "m " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, + "outputs": [], + "source": [ + "layer=TileLayer()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "m.add_layer(layer)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, "outputs": [ { "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "eca839e371ec41e5806221cd8bda94dd", - "version_major": 2, - "version_minor": 0 - }, "text/plain": [ - "TileLayer()" + "'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'" ] }, - "execution_count": 3, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "layer=TileLayer()\n", - "layer" + "layer.url" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "layer.url='https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'" + "layere=TileLayer()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "layere.url='https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "'https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'" ] }, - "execution_count": 5, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "m.layers" + "layere.url" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "m.add_layer(layer)" + "m.add_layer(layere)" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[TileLayer(url='https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png')]" + "[TileLayer(),\n", + " TileLayer(url='https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png')]" ] }, - "execution_count": 7, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -128,13 +150,22 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "m.remove_layer(layere)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6c598e65b1054e3d87e80d164ef8c5d0", + "model_id": "e656193ddf564562a5b90a27eb114169", "version_major": 2, "version_minor": 0 }, @@ -142,7 +173,7 @@ "ImageOverlay(position=[0, 0])" ] }, - "execution_count": 8, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -154,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -163,25 +194,25 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "image.image_url=\"\"" + "m.add_overlay(image)" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "m.add_overlay(image)" + "image.image_url=\"https://i.imgur.com/ZF6s192.png\"" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -190,16 +221,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[ImageOverlay(image_url='https://i.imgur.com/06Q1fSz.png', position=[-70, 70])]" + "[ImageOverlay(image_url='https://i.imgur.com/ZF6s192.png', position=[-70, 70])]" ] }, - "execution_count": 7, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -210,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -220,7 +251,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -229,42 +260,25 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ - "m.remove_overlay(image)" + "m.remove_overlay(imaget)" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 12, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "f7453e31240d4770986c2189b947d065", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VideoOverlay(position=[0, 0])" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "video=VideoOverlay()\n", - "video" + "video=VideoOverlay()" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -273,34 +287,34 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ - "video.video_url=\"https://www.mapbox.com/bites/00188/patricia_nasa.webm\"" + "m.add_overlay(video)" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ - "m.add_overlay(video)" + "video.video_url=\"https://www.mapbox.com/bites/00188/patricia_nasa.webm\"" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ - "video.position=[-70,70]" + "video.position=[-70,80]" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -310,40 +324,40 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ - "video2.position=[-80,70]" + "m.add_overlay(video2)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ - "m.add_overlay(video2)" + "m.remove_overlay(video)" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ - "m.remove_overlay(video)" + "m.remove_overlay(video2)" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "786f2fed9b174fa5bbc4829bffabe492", + "model_id": "516f2afa2a674a159e61815aa12ec034", "version_major": 2, "version_minor": 0 }, @@ -351,7 +365,7 @@ "PopupOverlay(position=[0, 0])" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -363,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -372,7 +386,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -381,19 +395,12 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "m.remove_overlay(popup)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/ipyopenlayers/example.py b/ipyopenlayers/example.py index 1282f9a..1eebc1a 100644 --- a/ipyopenlayers/example.py +++ b/ipyopenlayers/example.py @@ -24,25 +24,34 @@ class TileLayer(Widget): _view_module_version = Unicode(module_version).tag(sync=True) url = Unicode('https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png').tag(sync=True) -class BaseOverlay(DOMWidget): - _model_name = Unicode('BaseOverlayModel').tag(sync=True) +class BaseOverlay(DOMWidget): + _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) - _view_name = Unicode('BaseOverlayView').tag(sync=True) + _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) overlay_type = Unicode().tag(sync=True) position = List([0, 0]).tag(sync=True) class ImageOverlay (BaseOverlay): + _view_name = Unicode('ImageOverlayView').tag(sync=True) + _model_name = Unicode('ImageOverlayModel').tag(sync=True) + overlay_type = Unicode('image').tag(sync=True) image_url = Unicode('').tag(sync=True) class VideoOverlay (BaseOverlay): + _view_name = Unicode('VideoOverlayView').tag(sync=True) + _model_name = Unicode('VideoOverlayModel').tag(sync=True) + overlay_type = Unicode('video').tag(sync=True) video_url = Unicode('').tag(sync=True) class PopupOverlay (BaseOverlay): + _view_name = Unicode('PopupOverlayView').tag(sync=True) + _model_name = Unicode('PopupOverlayModel').tag(sync=True) + overlay_type = Unicode('popup').tag(sync=True) popup_content = Unicode('').tag(sync=True) diff --git a/src/baseoverlay.ts b/src/baseoverlay.ts new file mode 100644 index 0000000..b699874 --- /dev/null +++ b/src/baseoverlay.ts @@ -0,0 +1,66 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { + DOMWidgetModel, + DOMWidgetView, + ISerializers, +} from '@jupyter-widgets/base'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; +import Overlay from 'ol/Overlay'; + +export * from './tilelayer'; + +export class BaseOverlayModel extends DOMWidgetModel { + defaults() { + return { + ...super.defaults(), + _model_module: BaseOverlayModel.model_module, + _model_module_version: BaseOverlayModel.model_module_version, + _view_module: BaseOverlayModel.view_module, + _view_module_version: BaseOverlayModel.view_module_version, + overlay_type: '', + position: [0, 0], + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + }; + + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} + +export class BaseOverlayView extends DOMWidgetView { + overlay: Overlay; + element: HTMLElement; + + render() { + super.render(); + this.createOverlay(); + this.model_events(); + } + + createOverlay() { + const position = this.model.get('position'); + this.overlay = new Overlay({ + position: position, + element: this.element, + }); + return this.overlay; + } + + model_events() { + this.listenTo(this.model, 'change:position', this.updatePosition); + } + + updatePosition() { + const position = this.model.get('position'); + this.overlay.setPosition(position); + } +} diff --git a/src/imageoverlay.ts b/src/imageoverlay.ts new file mode 100644 index 0000000..e3e2780 --- /dev/null +++ b/src/imageoverlay.ts @@ -0,0 +1,56 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; +import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; + +export class ImageOverlayModel extends BaseOverlayModel { + defaults() { + return { + ...super.defaults(), + _model_name: ImageOverlayModel.model_name, + _model_module: ImageOverlayModel.model_module, + _model_module_version: ImageOverlayModel.model_module_version, + _view_name: ImageOverlayModel.view_name, + _view_module: ImageOverlayModel.view_module, + _view_module_version: ImageOverlayModel.view_module_version, + overlay_type: 'image', + image_url: '', + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'ImageOverlayModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'ImageOverlayView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} + +export class ImageOverlayView extends BaseOverlayView { + render() { + this.element = document.createElement('img'); + super.render(); + this.updateImageElement(); + } + + model_events() { + super.model_events(); + this.listenTo(this.model, 'change:image_url', this.updateImageElement); + } + + updateImageElement() { + const imageUrl = this.model.get('image_url'); + if (imageUrl) { + (this.element as HTMLImageElement).src = imageUrl; + } + } +} diff --git a/src/popupoverlay.ts b/src/popupoverlay.ts new file mode 100644 index 0000000..d45fb45 --- /dev/null +++ b/src/popupoverlay.ts @@ -0,0 +1,55 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; +import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; + +export class PopupOverlayModel extends BaseOverlayModel { + defaults() { + return { + ...super.defaults(), + _model_name: PopupOverlayModel.model_name, + _model_module: PopupOverlayModel.model_module, + _model_module_version: PopupOverlayModel.model_module_version, + _view_name: PopupOverlayModel.view_name, + _view_module: PopupOverlayModel.view_module, + _view_module_version: PopupOverlayModel.view_module_version, + overlay_type: 'image', + image_url: '', + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'PopupOverlayModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'PopupOverlayView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} +export class PopupOverlayView extends BaseOverlayView { + render() { + this.element = document.createElement('div'); + super.render(); + this.updatePopupElement(); + } + + model_events() { + super.model_events(); + this.listenTo(this.model, 'change:popup_content', this.updatePopupElement); + } + + updatePopupElement() { + const popupContent = this.model.get('popup_content'); + if (popupContent) { + this.element.innerHTML = popupContent; + } + } +} diff --git a/src/tilelayer.ts b/src/tilelayer.ts index a3bc72c..999c660 100644 --- a/src/tilelayer.ts +++ b/src/tilelayer.ts @@ -3,6 +3,7 @@ import TileLayer from 'ol/layer/Tile'; import XYZ from 'ol/source/XYZ'; import OSM from 'ol/source/OSM'; import { MODULE_NAME, MODULE_VERSION } from './version'; +import { MapView } from './widget'; export class TileLayerModel extends WidgetModel { defaults() { @@ -32,9 +33,9 @@ export class TileLayerModel extends WidgetModel { } export class TileLayerView extends WidgetView { + map: MapView; render() { super.render(); - console.log('test'); const url = this.model.get('url'); this.tileLayer = new TileLayer({ @@ -48,7 +49,6 @@ export class TileLayerView extends WidgetView { } urlChanged() { - console.log('test2'); const newUrl = this.model.get('url'); if (newUrl) { const newSource = new XYZ({ diff --git a/src/video_overlay.ts b/src/video_overlay.ts new file mode 100644 index 0000000..138bd32 --- /dev/null +++ b/src/video_overlay.ts @@ -0,0 +1,61 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; +import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; + +export * from './tilelayer'; + +export class VideoOverlayModel extends BaseOverlayModel { + defaults() { + return { + ...super.defaults(), + _model_name: VideoOverlayModel.model_name, + _model_module: VideoOverlayModel.model_module, + _model_module_version: VideoOverlayModel.model_module_version, + _view_name: VideoOverlayModel.view_name, + _view_module: VideoOverlayModel.view_module, + _view_module_version: VideoOverlayModel.view_module_version, + overlay_type: 'image', + image_url: '', + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'VideoOverlayModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'VideoOverlayVIew'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} +export class VideoOverlayView extends BaseOverlayView { + videoElement: HTMLVideoElement; + + render() { + this.element = document.createElement('div'); + this.videoElement = document.createElement('video'); + this.videoElement.controls = true; + this.element.appendChild(this.videoElement); + super.render(); + this.updateVideoElement(); + } + + model_events() { + super.model_events(); + this.listenTo(this.model, 'change:video_url', this.updateVideoElement); + } + + updateVideoElement() { + const videoUrl = this.model.get('video_url'); + if (videoUrl) { + this.videoElement.src = videoUrl; + } + } +} diff --git a/src/widget.ts b/src/widget.ts index 23e3bf1..75d5d34 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -3,26 +3,22 @@ import { DOMWidgetModel, DOMWidgetView, - WidgetModel, - WidgetView, ISerializers, unpack_models, ViewList, } from '@jupyter-widgets/base'; +import { TileLayerModel, TileLayerView } from './tilelayer'; +import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; 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 '../css/widget.css'; import { useGeographic } from 'ol/proj'; -import Overlay from 'ol/Overlay'; export * from './tilelayer'; -import { TileLayerModel, TileLayerView } from './tilelayer'; - const DEFAULT_LOCATION = [0.0, 0.0]; export class MapModel extends DOMWidgetModel { @@ -83,17 +79,12 @@ export class MapView extends DOMWidgetView { center: this.model.get('center'), zoom: this.model.get('zoom'), }), - layers: [ - new TileLayer({ - source: new OSM(), - }), - ], + layers: [new TileLayer()], }); this.layersChanged(); this.model.on('change:layers', this.layersChanged, this); this.model.on('change:overlays', this.overlayChanged, this); - //this.model.on('change:controls', this.controlChanged, this); this.model.on('change:zoom', this.zoomChanged, this); this.model.on('change:center', this.centerChanged, this); } @@ -138,9 +129,7 @@ export class MapView extends DOMWidgetView { const view = await this.create_child_view(child_model, { map_view: this, }); - console.log('add'); this.map.addLayer(view.tileLayer); - console.log('supp add'); this.displayed.then(() => { view.trigger('displayed', this); @@ -159,128 +148,9 @@ export class MapView extends DOMWidgetView { return view; } - imageElement: HTMLImageElement; mapContainer: HTMLDivElement; map: Map; layerViews: ViewList; overlayViews: ViewList; } - -export class BaseOverlayModel extends DOMWidgetModel { - defaults() { - return { - ...super.defaults(), - _model_name: BaseOverlayModel.model_name, - _model_module: BaseOverlayModel.model_module, - _model_module_version: BaseOverlayModel.model_module_version, - _view_name: BaseOverlayModel.view_name, - _view_module: BaseOverlayModel.view_module, - _view_module_version: BaseOverlayModel.view_module_version, - value: 'Hello World', - }; - } - - static serializers: ISerializers = { - ...DOMWidgetModel.serializers, - // Ajoutez ici tous les sérialiseurs supplémentaires - }; - - static model_name = 'BaseOverlayModel'; - static model_module = MODULE_NAME; - static model_module_version = MODULE_VERSION; - static view_name = 'BaseOverlayView'; - static view_module = MODULE_NAME; - static view_module_version = MODULE_VERSION; -} - -export class BaseOverlayView extends DOMWidgetView { - overlay: Overlay; - element: HTMLElement; - videoElement: HTMLVideoElement; - - render() { - super.render(); - this.updateElement(); - } - - initialize(parameters: WidgetView.IInitializeParameters) { - super.initialize(parameters); - this.initializeElement(); - this.createOverlay(); - this.model_events(); - } - - initializeElement() { - const overlayType = this.model.get('overlay_type'); - - if (overlayType === 'image') { - this.element = document.createElement('img'); - this.updateImageElement(); - } else if (overlayType === 'video') { - this.element = document.createElement('div'); - this.videoElement = document.createElement('video'); - this.videoElement.controls = true; - this.videoElement.src = this.model.get('video_url'); - this.element.appendChild(this.videoElement); - this.updateVideoElement(); - } else if (overlayType === 'popup') { - this.element = document.createElement('div'); - this.updatePopupElement(); - } - } - - createOverlay() { - const position = this.model.get('position'); - this.overlay = new Overlay({ - position: position, - element: this.element, - }); - return this.overlay; - } - - model_events() { - this.listenTo(this.model, 'change:overlay_type', this.initializeElement); - this.listenTo(this.model, 'change:image_url', this.updateImageElement); - this.listenTo(this.model, 'change:video_url', this.updateVideoElement); - this.listenTo(this.model, 'change:popup_content', this.updatePopupElement); - this.listenTo(this.model, 'change:position', this.updatePosition); - } - - updateElement() { - const overlayType = this.model.get('overlay_type'); - if (overlayType === 'image') { - this.updateImageElement(); - } else if (overlayType === 'video') { - this.updateVideoElement(); - } else if (overlayType === 'popup') { - this.updatePopupElement(); - } - } - - updateImageElement() { - const imageUrl = this.model.get('image_url'); - if (imageUrl) { - (this.element as HTMLImageElement).src = imageUrl; - } - } - - updateVideoElement() { - const videoUrl = this.model.get('video_url'); - if (videoUrl) { - this.videoElement.src = this.model.get('video_url'); - } - } - - updatePopupElement() { - const popupContent = this.model.get('popup_content'); - if (popupContent) { - this.element.innerHTML = popupContent; - } - } - - updatePosition() { - const position = this.model.get('position'); - this.overlay.setPosition(position); - } -} From faa1449ac77666152f031356fda93e35d8509428 Mon Sep 17 00:00:00 2001 From: Nour-Cheour10 Date: Thu, 6 Jun 2024 16:26:04 +0200 Subject: [PATCH 02/10] Draft --- examples/introduction.ipynb | 70 +++++++++++++++++++++----- ipyopenlayers/_frontend.py | 1 + ipyopenlayers/example.py | 50 +++++++++++++++++-- src/basecontrol.ts | 69 ++++++++++++++++++++++++++ src/baseoverlay.ts | 1 - src/imageoverlay.ts | 5 +- src/index.ts | 1 + src/popupoverlay.ts | 3 +- src/video_overlay.ts | 5 +- src/widget.ts | 39 +++++++++++++++ src/zoomslider.ts | 97 +++++++++++++++++++++++++++++++++++++ 11 files changed, 313 insertions(+), 28 deletions(-) create mode 100644 src/basecontrol.ts create mode 100644 src/zoomslider.ts diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index d137ac2..b0a462d 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "from ipyopenlayers import Map, TileLayer, ImageOverlay, VideoOverlay,PopupOverlay" + "from ipyopenlayers import Map, TileLayer, ImageOverlay, VideoOverlay,PopupOverlay, ZoomSlider" ] }, { @@ -24,7 +24,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6db90e12cf764585b9fd87cc848167ad", + "model_id": "a4861581bb7c408fa4a27cec4aaa8832", "version_major": 2, "version_minor": 0 }, @@ -62,7 +62,51 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b7c6ee99cd394c3b8df82702e57e34a9", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "ZoomSlider()" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "zoom=ZoomSlider()\n", + "zoom" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "m.add_control(zoom)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "zoom.active=True" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -71,7 +115,7 @@ "'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'" ] }, - "execution_count": 5, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -82,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -91,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -100,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -109,7 +153,7 @@ "'https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'" ] }, - "execution_count": 8, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -120,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -129,7 +173,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -139,7 +183,7 @@ " TileLayer(url='https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png')]" ] }, - "execution_count": 10, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -150,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -165,7 +209,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e656193ddf564562a5b90a27eb114169", + "model_id": "5e41abe9d11e438da7148502067fd253", "version_major": 2, "version_minor": 0 }, diff --git a/ipyopenlayers/_frontend.py b/ipyopenlayers/_frontend.py index da98667..1a3d741 100644 --- a/ipyopenlayers/_frontend.py +++ b/ipyopenlayers/_frontend.py @@ -10,3 +10,4 @@ module_name = "ipyopenlayers" module_version = "^0.1.0" + diff --git a/ipyopenlayers/example.py b/ipyopenlayers/example.py index 1eebc1a..47b1297 100644 --- a/ipyopenlayers/example.py +++ b/ipyopenlayers/example.py @@ -28,33 +28,64 @@ class BaseOverlay(DOMWidget): _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) - _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) - overlay_type = Unicode().tag(sync=True) position = List([0, 0]).tag(sync=True) class ImageOverlay (BaseOverlay): _view_name = Unicode('ImageOverlayView').tag(sync=True) _model_name = Unicode('ImageOverlayModel').tag(sync=True) - overlay_type = Unicode('image').tag(sync=True) image_url = Unicode('').tag(sync=True) class VideoOverlay (BaseOverlay): _view_name = Unicode('VideoOverlayView').tag(sync=True) _model_name = Unicode('VideoOverlayModel').tag(sync=True) - overlay_type = Unicode('video').tag(sync=True) video_url = Unicode('').tag(sync=True) class PopupOverlay (BaseOverlay): _view_name = Unicode('PopupOverlayView').tag(sync=True) _model_name = Unicode('PopupOverlayModel').tag(sync=True) - overlay_type = Unicode('popup').tag(sync=True) popup_content = Unicode('').tag(sync=True) +class BaseControl(DOMWidget): + _model_name = Unicode('BaseControlModel').tag(sync=True) + _model_module = Unicode(module_name).tag(sync=True) + _model_module_version = Unicode(module_version).tag(sync=True) + _view_name = Unicode('BaseControlView').tag(sync=True) + _view_module = Unicode(module_name).tag(sync=True) + _view_module_version = Unicode(module_version).tag(sync=True) + + control_name = Unicode().tag(sync=True) + active = Bool(False).tag(sync=True) + +class ZoomSlider(BaseControl): + control_name = Unicode('zoom_slider').tag(sync=True) + active = Bool(False).tag(sync=True) + + +'''' + +class ScaleLine(BaseControl): + _view_name = Unicode('ScaleLineView').tag(sync=True) + _model_name = Unicode('ScaleLineModel').tag(sync=True) + + control_name = Unicode('scale_line').tag(sync=True) + +class FullScreen(BaseControl): + _view_name = Unicode('FullScreenView').tag(sync=True) + _model_name = Unicode('FullScreenModel').tag(sync=True) + + control_name = Unicode('full_screen').tag(sync=True) + +class Coordinates(BaseControl): + _view_name = Unicode('CoordinatesView').tag(sync=True) + _model_name = Unicode('CoordinatesModel').tag(sync=True) + + control_name = Unicode('coordinates').tag(sync=True) +''' class Map(DOMWidget): _model_name = Unicode('MapModel').tag(sync=True) _model_module = Unicode(module_name).tag(sync=True) @@ -68,6 +99,8 @@ class Map(DOMWidget): zoom = CFloat(2).tag(sync=True, o=True) layers = List(Instance(TileLayer)).tag(sync=True, **widget_serialization) overlays=List(Instance(BaseOverlay)).tag(sync=True, **widget_serialization) + controls=List(Instance(BaseControl)).tag(sync=True, **widget_serialization) + def __init__(self, center=None, zoom=None, **kwargs): @@ -90,5 +123,12 @@ def remove_layer(self, layer): def remove_overlay(self, overlay): self.overlays = [x for x in self.overlays if x != overlay] + def add_control(self, control): + self.controls = self.controls + [control] + + def remove_control(self, control): + self.controls = [x for x in self.controls if x != control] + + def clear_layers(self): self.layers = [] \ No newline at end of file diff --git a/src/basecontrol.ts b/src/basecontrol.ts new file mode 100644 index 0000000..7248ca7 --- /dev/null +++ b/src/basecontrol.ts @@ -0,0 +1,69 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import Control from 'ol/control/Control.js'; +import 'ol/ol.css'; +import '../css/widget.css'; +import { + DOMWidgetModel, + DOMWidgetView, + //WidgetView, + ISerializers, +} from '@jupyter-widgets/base'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; + +export class BaseControlModel extends DOMWidgetModel { + defaults() { + return { + ...super.defaults(), + _model_name: BaseControlModel.model_name, + _model_module: BaseControlModel.model_module, + _model_module_version: BaseControlModel.model_module_version, + _view_name: BaseControlModel.view_name, + _view_module: BaseControlModel.view_module, + _view_module_version: BaseControlModel.view_module_version, + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + }; + + static model_name = 'BaseControlModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'BaseControlView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} + +export class BaseControlView extends DOMWidgetView { + map_view: any; + element: HTMLElement; + obj: Control; + render() { + super.render(); + this.create_obj(); + //this.model_events(); + } + create_obj() { + this.obj = new Control({ + element: this.element, + }); + return this.obj; + } + /* + model_events() { + } + + get_controls(): { [key: string]: any } { + const controls = this.model.get('controls') as string[]; + const result: { [key: string]: any } = {}; + controls.forEach((key: string) => { + result[key] = this.model.get(key); + }); + return result; + }*/ +} diff --git a/src/baseoverlay.ts b/src/baseoverlay.ts index b699874..f3d18f7 100644 --- a/src/baseoverlay.ts +++ b/src/baseoverlay.ts @@ -21,7 +21,6 @@ export class BaseOverlayModel extends DOMWidgetModel { _model_module_version: BaseOverlayModel.model_module_version, _view_module: BaseOverlayModel.view_module, _view_module_version: BaseOverlayModel.view_module_version, - overlay_type: '', position: [0, 0], }; } diff --git a/src/imageoverlay.ts b/src/imageoverlay.ts index e3e2780..e038a89 100644 --- a/src/imageoverlay.ts +++ b/src/imageoverlay.ts @@ -2,7 +2,6 @@ // Distributed under the terms of the Modified BSD License. import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; - import 'ol/ol.css'; import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; @@ -17,7 +16,6 @@ export class ImageOverlayModel extends BaseOverlayModel { _view_name: ImageOverlayModel.view_name, _view_module: ImageOverlayModel.view_module, _view_module_version: ImageOverlayModel.view_module_version, - overlay_type: 'image', image_url: '', }; } @@ -37,8 +35,9 @@ export class ImageOverlayModel extends BaseOverlayModel { export class ImageOverlayView extends BaseOverlayView { render() { - this.element = document.createElement('img'); super.render(); + console.log('hello'); + this.element = document.createElement('img'); this.updateImageElement(); } diff --git a/src/index.ts b/src/index.ts index ef0d215..0d5f5fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,3 +3,4 @@ export * from './version'; export * from './widget'; export * from './tilelayer'; +export * from './basecontrol'; diff --git a/src/popupoverlay.ts b/src/popupoverlay.ts index d45fb45..8d438bc 100644 --- a/src/popupoverlay.ts +++ b/src/popupoverlay.ts @@ -17,7 +17,6 @@ export class PopupOverlayModel extends BaseOverlayModel { _view_name: PopupOverlayModel.view_name, _view_module: PopupOverlayModel.view_module, _view_module_version: PopupOverlayModel.view_module_version, - overlay_type: 'image', image_url: '', }; } @@ -36,8 +35,8 @@ export class PopupOverlayModel extends BaseOverlayModel { } export class PopupOverlayView extends BaseOverlayView { render() { - this.element = document.createElement('div'); super.render(); + this.element = document.createElement('div'); this.updatePopupElement(); } diff --git a/src/video_overlay.ts b/src/video_overlay.ts index 138bd32..29579e8 100644 --- a/src/video_overlay.ts +++ b/src/video_overlay.ts @@ -6,8 +6,6 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; -export * from './tilelayer'; - export class VideoOverlayModel extends BaseOverlayModel { defaults() { return { @@ -18,7 +16,6 @@ export class VideoOverlayModel extends BaseOverlayModel { _view_name: VideoOverlayModel.view_name, _view_module: VideoOverlayModel.view_module, _view_module_version: VideoOverlayModel.view_module_version, - overlay_type: 'image', image_url: '', }; } @@ -39,11 +36,11 @@ export class VideoOverlayView extends BaseOverlayView { videoElement: HTMLVideoElement; render() { + super.render(); this.element = document.createElement('div'); this.videoElement = document.createElement('video'); this.videoElement.controls = true; this.element.appendChild(this.videoElement); - super.render(); this.updateVideoElement(); } diff --git a/src/widget.ts b/src/widget.ts index 1abf0c1..41a4a0a 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -9,6 +9,8 @@ import { } from '@jupyter-widgets/base'; import { TileLayerModel, TileLayerView } from './tilelayer'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; +import { BaseControlModel, BaseControlView } from './basecontrol'; +export * from './basecontrol'; import { Map } from 'ol'; import TileLayer from 'ol/layer/Tile'; @@ -42,6 +44,8 @@ export class MapModel extends DOMWidgetModel { ...DOMWidgetModel.serializers, layers: { deserialize: unpack_models }, overlays: { deserialize: unpack_models }, + controls: { deserialize: unpack_models }, + // Add any extra serializers here }; @@ -73,6 +77,12 @@ export class MapView extends DOMWidgetView { this.removeOverlayView, this, ); + + this.controlViews = new ViewList( + this.addControlModel, + this.removeControlView, + this, + ); this.map = new Map({ target: this.mapContainer, view: new View({ @@ -85,6 +95,7 @@ export class MapView extends DOMWidgetView { this.layersChanged(); this.model.on('change:layers', this.layersChanged, this); this.model.on('change:overlays', this.overlayChanged, this); + this.model.on('change:controls', this.controlChanged, this); this.model.on('change:zoom', this.zoomChanged, this); this.model.on('change:center', this.centerChanged, this); } @@ -99,6 +110,11 @@ export class MapView extends DOMWidgetView { this.overlayViews.update(overlay); } + controlChanged() { + const control = this.model.get('controls') as BaseOverlayModel[]; + this.controlViews.update(control); + } + zoomChanged() { const newZoom = this.model.get('zoom'); if (newZoom !== undefined && newZoom !== null) { @@ -125,6 +141,11 @@ export class MapView extends DOMWidgetView { child_view.remove(); } + removeControlView(child_view: BaseControlView) { + this.map.removeControl(child_view.obj); + child_view.remove(); + } + async addLayerModel(child_model: TileLayerModel) { const view = await this.create_child_view(child_model, { map_view: this, @@ -147,9 +168,27 @@ export class MapView extends DOMWidgetView { return view; } + async addControlModel(child_model: BaseControlModel) { + console.log('yes'); + const view = await this.create_child_view(child_model, { + map_view: this, + }); + console.log(view.obj); + this.map.addControl(view.obj); + console.log('is'); + + this.displayed.then(() => { + view.trigger('displayed', this); + }); + console.log('it'); + + return view; + } + imageElement: HTMLImageElement; mapContainer: HTMLDivElement; map: Map; layerViews: ViewList; overlayViews: ViewList; + controlViews: ViewList; } diff --git a/src/zoomslider.ts b/src/zoomslider.ts new file mode 100644 index 0000000..50daad8 --- /dev/null +++ b/src/zoomslider.ts @@ -0,0 +1,97 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { + DOMWidgetModel, + //WidgetView, + ISerializers, +} from '@jupyter-widgets/base'; +import { BaseControlModel, BaseControlView } from './basecontrol'; +import ZoomSlider from 'ol/control/ZoomSlider'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; + +export class ZoomSliderModel extends BaseControlModel { + defaults() { + return { + ...super.defaults(), + _model_name: ZoomSliderModel.model_name, + _model_module: ZoomSliderModel.model_module, + _model_module_version: ZoomSliderModel.model_module_version, + _view_name: ZoomSliderModel.view_name, + _view_module: ZoomSliderModel.view_module, + _view_module_version: ZoomSliderModel.view_module_version, + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'ZoomSliderModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'ZoomSliderView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} +export class ZoomSliderView extends BaseControlView { + render() { + super.render(); + this.element = document.createElement('div'); + console.log('hello'); + this.create_zoom_obj(); + } + + model_events() { + this.listenTo(this.model, 'change:active', this.create_zoom_obj); + } + create_zoom_obj() { + console.log('creating obj'); + this.element.className = 'ol-zoomslider'; + this.obj = new ZoomSlider({ + className: 'ol-zoomslider', + target: this.element, // Use the created element + }); + console.log('created obj'); + console.log(this.obj); + this.map_view.map.addControl(this.element); + } +} + +/* + + model_events() { + super.model_events(); + this.listenTo(this.model, 'change:popup_content', this.updatePopupElement); + } + + updatePopupElement() { + const popupContent = this.model.get('popup_content'); + if (popupContent) { + this.element.innerHTML = popupContent; + } + } +export class ZoomSliderView extends BaseControlView { + render() { + this.element = document.createElement('div'); + super.render(); + this.activateZoomSlider(); + } + + model_events() { + super.model_events(); + this.listenTo(this.model, 'change:zoom_slider', this.activateZoomSlider); + } + + activateZoomSlider() { + const nv_zoom_slider = this.model.get('zoom_slider'); + if (nv_zoom_slider !== undefined && nv_zoom_slider !== null) { + this.map.addControl(new olControl.ZoomSlider()); + } + } + map: MapView; +} +*/ From 48f0b7f96a2e035c5c1a4521ee2ba0482730609b Mon Sep 17 00:00:00 2001 From: Nour-Cheour10 Date: Fri, 7 Jun 2024 13:41:57 +0200 Subject: [PATCH 03/10] issue in displaying zoom_slider --- examples/introduction.ipynb | 19 +++++++++++++------ ipyopenlayers/example.py | 3 +++ src/basecontrol.ts | 2 +- src/tilelayer.ts | 2 ++ src/widget.ts | 33 +++++++++++++++++++++++++-------- src/zoomslider.ts | 2 +- 6 files changed, 45 insertions(+), 16 deletions(-) diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index b0a462d..63e607e 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -24,7 +24,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a4861581bb7c408fa4a27cec4aaa8832", + "model_id": "972168f954b045f88bb141544655dcfd", "version_major": 2, "version_minor": 0 }, @@ -62,13 +62,13 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b7c6ee99cd394c3b8df82702e57e34a9", + "model_id": "fce97fca841f4743b5b3134fb96be3e9", "version_major": 2, "version_minor": 0 }, @@ -76,7 +76,7 @@ "ZoomSlider()" ] }, - "execution_count": 8, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -88,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -97,7 +97,14 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ diff --git a/ipyopenlayers/example.py b/ipyopenlayers/example.py index 47b1297..3559b9b 100644 --- a/ipyopenlayers/example.py +++ b/ipyopenlayers/example.py @@ -62,6 +62,9 @@ class BaseControl(DOMWidget): active = Bool(False).tag(sync=True) class ZoomSlider(BaseControl): + _view_name = Unicode('ZoomSliderView').tag(sync=True) + _model_name = Unicode('ZoomSliderModel').tag(sync=True) + control_name = Unicode('zoom_slider').tag(sync=True) active = Bool(False).tag(sync=True) diff --git a/src/basecontrol.ts b/src/basecontrol.ts index 7248ca7..af5a875 100644 --- a/src/basecontrol.ts +++ b/src/basecontrol.ts @@ -54,7 +54,7 @@ export class BaseControlView extends DOMWidgetView { }); return this.obj; } - /* + /* model_events() { } diff --git a/src/tilelayer.ts b/src/tilelayer.ts index 999c660..91155dc 100644 --- a/src/tilelayer.ts +++ b/src/tilelayer.ts @@ -1,3 +1,5 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. import { WidgetModel, WidgetView, ISerializers } from '@jupyter-widgets/base'; import TileLayer from 'ol/layer/Tile'; import XYZ from 'ol/source/XYZ'; diff --git a/src/widget.ts b/src/widget.ts index 41a4a0a..1559e56 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -20,7 +20,14 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { useGeographic } from 'ol/proj'; +export * from './basecontrol'; +export * from './baseoverlay'; +export * from './imageoverlay'; +export * from './video_overlay'; +export * from './popupoverlay'; +export * from './zoomslider'; export * from './tilelayer'; + const DEFAULT_LOCATION = [0.0, 0.0]; export class MapModel extends DOMWidgetModel { @@ -169,18 +176,28 @@ export class MapView extends DOMWidgetView { } async addControlModel(child_model: BaseControlModel) { - console.log('yes'); + console.log('Initializing addControlModel...'); const view = await this.create_child_view(child_model, { map_view: this, }); - console.log(view.obj); - this.map.addControl(view.obj); - console.log('is'); - this.displayed.then(() => { - view.trigger('displayed', this); - }); - console.log('it'); + console.log('Child view created:', view); + console.log('Object in view:', view.obj); + + // Check if view.obj is defined before trying to add it to the map + if (view.obj) { + console.log('Adding control to map...'); + this.map.addControl(view.obj); + + // Trigger the 'displayed' event after the control is added to the map + this.displayed.then(() => { + console.log('Triggering displayed event for view...'); + view.trigger('displayed', this); + console.log('Control added to map successfully.'); + }); + } else { + console.error('view.obj is undefined. Control not added to map.'); + } return view; } diff --git a/src/zoomslider.ts b/src/zoomslider.ts index 50daad8..57c3705 100644 --- a/src/zoomslider.ts +++ b/src/zoomslider.ts @@ -57,7 +57,7 @@ export class ZoomSliderView extends BaseControlView { }); console.log('created obj'); console.log(this.obj); - this.map_view.map.addControl(this.element); + //this.map_view.map.addControl(this.element); } } From 538256290378ed6eff762734d38e425bb9c31fb0 Mon Sep 17 00:00:00 2001 From: Nour-Cheour10 Date: Mon, 10 Jun 2024 13:20:51 +0200 Subject: [PATCH 04/10] control added --- examples/introduction.ipynb | 61 ++++++++++++++++++++++++++++++++----- ipyopenlayers/example.py | 23 +++++--------- src/basecontrol.ts | 36 +++++++++++----------- src/fullscreen.ts | 51 +++++++++++++++++++++++++++++++ src/mouseposition.ts | 51 +++++++++++++++++++++++++++++++ src/scaleline.ts | 50 ++++++++++++++++++++++++++++++ src/widget.ts | 18 +++-------- src/zoomslider.ts | 56 ++-------------------------------- 8 files changed, 237 insertions(+), 109 deletions(-) create mode 100644 src/fullscreen.ts create mode 100644 src/mouseposition.ts create mode 100644 src/scaleline.ts diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index 63e607e..1851d6f 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "from ipyopenlayers import Map, TileLayer, ImageOverlay, VideoOverlay,PopupOverlay, ZoomSlider" + "from ipyopenlayers import Map, TileLayer, ImageOverlay, VideoOverlay,PopupOverlay, ZoomSlider,FullScreen,ScaleLine,MousePosition" ] }, { @@ -24,7 +24,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "972168f954b045f88bb141544655dcfd", + "model_id": "39f0e92a735d45c08d2abe1d75e2ee14", "version_major": 2, "version_minor": 0 }, @@ -68,7 +68,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "fce97fca841f4743b5b3134fb96be3e9", + "model_id": "8a02bcf4b2af40628fc1e461bf2e1b34", "version_major": 2, "version_minor": 0 }, @@ -97,18 +97,65 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d5362137f52648b3a712dd96f8bdb777", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "FullScreen()" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "full=FullScreen()\n", + "full" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "scale=ScaleLine()\n", + "coord=MousePosition()" + ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "m.add_control(scale)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "m.add_control(coord)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "zoom.active=True" + "m.add_control(full)" ] }, { diff --git a/ipyopenlayers/example.py b/ipyopenlayers/example.py index 3559b9b..4792ed9 100644 --- a/ipyopenlayers/example.py +++ b/ipyopenlayers/example.py @@ -57,38 +57,29 @@ class BaseControl(DOMWidget): _view_name = Unicode('BaseControlView').tag(sync=True) _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) - + control_name = Unicode().tag(sync=True) - active = Bool(False).tag(sync=True) class ZoomSlider(BaseControl): _view_name = Unicode('ZoomSliderView').tag(sync=True) _model_name = Unicode('ZoomSliderModel').tag(sync=True) - control_name = Unicode('zoom_slider').tag(sync=True) - active = Bool(False).tag(sync=True) - +class FullScreen(BaseControl): + _view_name = Unicode('FullScreenView').tag(sync=True) + _model_name = Unicode('FullScreenModel').tag(sync=True) -'''' class ScaleLine(BaseControl): _view_name = Unicode('ScaleLineView').tag(sync=True) _model_name = Unicode('ScaleLineModel').tag(sync=True) - control_name = Unicode('scale_line').tag(sync=True) -class FullScreen(BaseControl): - _view_name = Unicode('FullScreenView').tag(sync=True) - _model_name = Unicode('FullScreenModel').tag(sync=True) - control_name = Unicode('full_screen').tag(sync=True) +class MousePosition(BaseControl): + _view_name = Unicode('MousePositionView').tag(sync=True) + _model_name = Unicode('MousePositionModel').tag(sync=True) -class Coordinates(BaseControl): - _view_name = Unicode('CoordinatesView').tag(sync=True) - _model_name = Unicode('CoordinatesModel').tag(sync=True) - control_name = Unicode('coordinates').tag(sync=True) -''' class Map(DOMWidget): _model_name = Unicode('MapModel').tag(sync=True) _model_module = Unicode(module_name).tag(sync=True) diff --git a/src/basecontrol.ts b/src/basecontrol.ts index af5a875..4f38015 100644 --- a/src/basecontrol.ts +++ b/src/basecontrol.ts @@ -39,31 +39,29 @@ export class BaseControlModel extends DOMWidgetModel { static view_module_version = MODULE_VERSION; } -export class BaseControlView extends DOMWidgetView { +/*export class BaseControlView extends DOMWidgetView { map_view: any; element: HTMLElement; obj: Control; + render() { super.render(); - this.create_obj(); - //this.model_events(); + this.createObj(); } - create_obj() { - this.obj = new Control({ - element: this.element, - }); - return this.obj; + createObj() { + throw new Error('Not implemented'); } - /* - model_events() { +} +*/ +export abstract class BaseControlView extends DOMWidgetView { + map_view: any; + element: HTMLElement; + obj: Control; + + render() { + super.render(); + this.createObj(); } - - get_controls(): { [key: string]: any } { - const controls = this.model.get('controls') as string[]; - const result: { [key: string]: any } = {}; - controls.forEach((key: string) => { - result[key] = this.model.get(key); - }); - return result; - }*/ + + abstract createObj(): void; } diff --git a/src/fullscreen.ts b/src/fullscreen.ts new file mode 100644 index 0000000..b1796f0 --- /dev/null +++ b/src/fullscreen.ts @@ -0,0 +1,51 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { + DOMWidgetModel, + //WidgetView, + ISerializers, +} from '@jupyter-widgets/base'; +import { BaseControlModel, BaseControlView } from './basecontrol'; +import FullScreen from 'ol/control/FullScreen.js'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; + +export class FullScreenModel extends BaseControlModel { + defaults() { + return { + ...super.defaults(), + _model_name: FullScreenModel.model_name, + _model_module: FullScreenModel.model_module, + _model_module_version: FullScreenModel.model_module_version, + _view_name: FullScreenModel.view_name, + _view_module: FullScreenModel.view_module, + _view_module_version: FullScreenModel.view_module_version, + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'FullScreenModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'FullScreenView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} +export class FullScreenView extends BaseControlView { + render() { + super.render(); + this.element = document.createElement('div'); + this.createObj(); + } + createObj() { + this.obj = new FullScreen({ + className: 'ol-full-screen', + }); + } +} diff --git a/src/mouseposition.ts b/src/mouseposition.ts new file mode 100644 index 0000000..ac86e85 --- /dev/null +++ b/src/mouseposition.ts @@ -0,0 +1,51 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { + DOMWidgetModel, + //WidgetView, + ISerializers, +} from '@jupyter-widgets/base'; +import { BaseControlModel, BaseControlView } from './basecontrol'; +import MousePosition from 'ol/control/MousePosition.js'; + +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; + +export class MousePositionModel extends BaseControlModel { + defaults() { + return { + ...super.defaults(), + _model_name: MousePositionModel.model_name, + _model_module: MousePositionModel.model_module, + _model_module_version: MousePositionModel.model_module_version, + _view_name: MousePositionModel.view_name, + _view_module: MousePositionModel.view_module, + _view_module_version: MousePositionModel.view_module_version, + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'MousePositionModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'MousePositionView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} +export class MousePositionView extends BaseControlView { + render() { + super.render(); + this.element = document.createElement('div'); + this.createObj(); + } + createObj() { + this.obj = new MousePosition({ + className: 'ol-mouse-position', + }); + } +} diff --git a/src/scaleline.ts b/src/scaleline.ts new file mode 100644 index 0000000..b547e10 --- /dev/null +++ b/src/scaleline.ts @@ -0,0 +1,50 @@ +// Copyright (c) QuantStack +// Distributed under the terms of the Modified BSD License. +import { + DOMWidgetModel, + //WidgetView, + ISerializers, +} from '@jupyter-widgets/base'; +import { BaseControlModel, BaseControlView } from './basecontrol'; +import ScaleLine from 'ol/control/ScaleLine.js'; +import 'ol/ol.css'; +import { MODULE_NAME, MODULE_VERSION } from './version'; +import '../css/widget.css'; + +export class ScaleLineModel extends BaseControlModel { + defaults() { + return { + ...super.defaults(), + _model_name: ScaleLineModel.model_name, + _model_module: ScaleLineModel.model_module, + _model_module_version: ScaleLineModel.model_module_version, + _view_name: ScaleLineModel.view_name, + _view_module: ScaleLineModel.view_module, + _view_module_version: ScaleLineModel.view_module_version, + }; + } + + static serializers: ISerializers = { + ...DOMWidgetModel.serializers, + // Ajoutez ici tous les sérialiseurs supplémentaires + }; + + static model_name = 'ScaleLineModel'; + static model_module = MODULE_NAME; + static model_module_version = MODULE_VERSION; + static view_name = 'ScaleLineView'; + static view_module = MODULE_NAME; + static view_module_version = MODULE_VERSION; +} +export class ScaleLineView extends BaseControlView { + render() { + super.render(); + this.element = document.createElement('div'); + this.createObj(); + } + createObj() { + this.obj = new ScaleLine({ + className: 'ol-scale-bar', + }); + } +} diff --git a/src/widget.ts b/src/widget.ts index 1559e56..4259ca3 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -10,7 +10,6 @@ import { import { TileLayerModel, TileLayerView } from './tilelayer'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; import { BaseControlModel, BaseControlView } from './basecontrol'; -export * from './basecontrol'; import { Map } from 'ol'; import TileLayer from 'ol/layer/Tile'; @@ -20,12 +19,15 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { useGeographic } from 'ol/proj'; -export * from './basecontrol'; +//export * from './basecontrol'; export * from './baseoverlay'; export * from './imageoverlay'; export * from './video_overlay'; export * from './popupoverlay'; export * from './zoomslider'; +export * from './fullscreen'; +export * from './scaleline'; +export * from './mouseposition'; export * from './tilelayer'; const DEFAULT_LOCATION = [0.0, 0.0]; @@ -176,27 +178,15 @@ export class MapView extends DOMWidgetView { } async addControlModel(child_model: BaseControlModel) { - console.log('Initializing addControlModel...'); const view = await this.create_child_view(child_model, { map_view: this, }); - - console.log('Child view created:', view); - console.log('Object in view:', view.obj); - - // Check if view.obj is defined before trying to add it to the map if (view.obj) { - console.log('Adding control to map...'); this.map.addControl(view.obj); - // Trigger the 'displayed' event after the control is added to the map this.displayed.then(() => { - console.log('Triggering displayed event for view...'); view.trigger('displayed', this); - console.log('Control added to map successfully.'); }); - } else { - console.error('view.obj is undefined. Control not added to map.'); } return view; diff --git a/src/zoomslider.ts b/src/zoomslider.ts index 57c3705..21e165d 100644 --- a/src/zoomslider.ts +++ b/src/zoomslider.ts @@ -1,10 +1,6 @@ // Copyright (c) QuantStack // Distributed under the terms of the Modified BSD License. -import { - DOMWidgetModel, - //WidgetView, - ISerializers, -} from '@jupyter-widgets/base'; +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; import { BaseControlModel, BaseControlView } from './basecontrol'; import ZoomSlider from 'ol/control/ZoomSlider'; @@ -41,57 +37,11 @@ export class ZoomSliderView extends BaseControlView { render() { super.render(); this.element = document.createElement('div'); - console.log('hello'); - this.create_zoom_obj(); + this.createObj(); } - - model_events() { - this.listenTo(this.model, 'change:active', this.create_zoom_obj); - } - create_zoom_obj() { - console.log('creating obj'); - this.element.className = 'ol-zoomslider'; + createObj() { this.obj = new ZoomSlider({ className: 'ol-zoomslider', - target: this.element, // Use the created element }); - console.log('created obj'); - console.log(this.obj); - //this.map_view.map.addControl(this.element); - } -} - -/* - - model_events() { - super.model_events(); - this.listenTo(this.model, 'change:popup_content', this.updatePopupElement); - } - - updatePopupElement() { - const popupContent = this.model.get('popup_content'); - if (popupContent) { - this.element.innerHTML = popupContent; - } - } -export class ZoomSliderView extends BaseControlView { - render() { - this.element = document.createElement('div'); - super.render(); - this.activateZoomSlider(); - } - - model_events() { - super.model_events(); - this.listenTo(this.model, 'change:zoom_slider', this.activateZoomSlider); - } - - activateZoomSlider() { - const nv_zoom_slider = this.model.get('zoom_slider'); - if (nv_zoom_slider !== undefined && nv_zoom_slider !== null) { - this.map.addControl(new olControl.ZoomSlider()); - } } - map: MapView; } -*/ From 62cf3992768143fa513c9c470dedd5217243ece4 Mon Sep 17 00:00:00 2001 From: Nour Cheour <161816839+Nour-Cheour10@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:10:17 +0200 Subject: [PATCH 05/10] Update ipyopenlayers/example.py Co-authored-by: martinRenou --- ipyopenlayers/example.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ipyopenlayers/example.py b/ipyopenlayers/example.py index 4792ed9..5c9eaa7 100644 --- a/ipyopenlayers/example.py +++ b/ipyopenlayers/example.py @@ -51,10 +51,8 @@ class PopupOverlay (BaseOverlay): popup_content = Unicode('').tag(sync=True) class BaseControl(DOMWidget): - _model_name = Unicode('BaseControlModel').tag(sync=True) _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) - _view_name = Unicode('BaseControlView').tag(sync=True) _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) From f2ff9c4e0a6ea3045a0dedcaf55c5c8b6e9cd68f Mon Sep 17 00:00:00 2001 From: Nour Cheour <161816839+Nour-Cheour10@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:10:31 +0200 Subject: [PATCH 06/10] Update src/basecontrol.ts Co-authored-by: martinRenou --- src/basecontrol.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/basecontrol.ts b/src/basecontrol.ts index 4f38015..07a124f 100644 --- a/src/basecontrol.ts +++ b/src/basecontrol.ts @@ -39,20 +39,6 @@ export class BaseControlModel extends DOMWidgetModel { static view_module_version = MODULE_VERSION; } -/*export class BaseControlView extends DOMWidgetView { - map_view: any; - element: HTMLElement; - obj: Control; - - render() { - super.render(); - this.createObj(); - } - createObj() { - throw new Error('Not implemented'); - } -} -*/ export abstract class BaseControlView extends DOMWidgetView { map_view: any; element: HTMLElement; From 1824903c2941e778ef3866accde95683c6b02627 Mon Sep 17 00:00:00 2001 From: Nour Cheour <161816839+Nour-Cheour10@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:10:48 +0200 Subject: [PATCH 07/10] Update src/imageoverlay.ts Co-authored-by: martinRenou --- src/imageoverlay.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/imageoverlay.ts b/src/imageoverlay.ts index e038a89..2c35449 100644 --- a/src/imageoverlay.ts +++ b/src/imageoverlay.ts @@ -36,7 +36,6 @@ export class ImageOverlayModel extends BaseOverlayModel { export class ImageOverlayView extends BaseOverlayView { render() { super.render(); - console.log('hello'); this.element = document.createElement('img'); this.updateImageElement(); } From acd7690d3c3615c3a4ad823301cc926e026edaa0 Mon Sep 17 00:00:00 2001 From: Nour-Cheour10 Date: Tue, 11 Jun 2024 11:57:53 +0200 Subject: [PATCH 08/10] changed render function --- examples/introduction.ipynb | 112 +++++++++++++----------------------- src/basecontrol.ts | 1 - src/fullscreen.ts | 11 +--- src/imageoverlay.ts | 3 +- src/mouseposition.ts | 11 +--- src/popupoverlay.ts | 3 +- src/scaleline.ts | 11 +--- src/tilelayer.ts | 2 - src/video_overlay.ts | 4 +- src/widget.ts | 1 - src/zoomslider.ts | 5 -- 11 files changed, 48 insertions(+), 116 deletions(-) diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index 1851d6f..3cc0238 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -24,7 +24,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "39f0e92a735d45c08d2abe1d75e2ee14", + "model_id": "be83a201afd04d6092afa4c08da8c79e", "version_major": 2, "version_minor": 0 }, @@ -64,26 +64,9 @@ "cell_type": "code", "execution_count": 5, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "8a02bcf4b2af40628fc1e461bf2e1b34", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "ZoomSlider()" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "zoom=ZoomSlider()\n", - "zoom" + "zoom=ZoomSlider()" ] }, { @@ -99,26 +82,9 @@ "cell_type": "code", "execution_count": 7, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "d5362137f52648b3a712dd96f8bdb777", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "FullScreen()" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "full=FullScreen()\n", - "full" + "full=FullScreen()" ] }, { @@ -160,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -169,7 +135,7 @@ "'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -180,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -189,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -198,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -207,7 +173,7 @@ "'https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -218,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -257,13 +223,13 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5e41abe9d11e438da7148502067fd253", + "model_id": "96f6ebdbfbdf40758ddc3d6a7e1cfb0c", "version_major": 2, "version_minor": 0 }, @@ -271,7 +237,7 @@ "ImageOverlay(position=[0, 0])" ] }, - "execution_count": 5, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -283,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -292,7 +258,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -301,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -310,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -319,7 +285,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -328,7 +294,7 @@ "[ImageOverlay(image_url='https://i.imgur.com/ZF6s192.png', position=[-70, 70])]" ] }, - "execution_count": 17, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -339,7 +305,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -349,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -358,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -367,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -376,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -385,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -394,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -403,7 +369,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -412,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -422,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -431,7 +397,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -440,7 +406,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -449,13 +415,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "516f2afa2a674a159e61815aa12ec034", + "model_id": "90f1687285754dd8aefc8364d2d741d2", "version_major": 2, "version_minor": 0 }, @@ -463,7 +429,7 @@ "PopupOverlay(position=[0, 0])" ] }, - "execution_count": 16, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -475,7 +441,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -484,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 40, "metadata": {}, "outputs": [], "source": [ @@ -493,7 +459,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ diff --git a/src/basecontrol.ts b/src/basecontrol.ts index 07a124f..160967a 100644 --- a/src/basecontrol.ts +++ b/src/basecontrol.ts @@ -6,7 +6,6 @@ import '../css/widget.css'; import { DOMWidgetModel, DOMWidgetView, - //WidgetView, ISerializers, } from '@jupyter-widgets/base'; diff --git a/src/fullscreen.ts b/src/fullscreen.ts index b1796f0..ae10bc3 100644 --- a/src/fullscreen.ts +++ b/src/fullscreen.ts @@ -1,10 +1,6 @@ // Copyright (c) QuantStack // Distributed under the terms of the Modified BSD License. -import { - DOMWidgetModel, - //WidgetView, - ISerializers, -} from '@jupyter-widgets/base'; +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; import { BaseControlModel, BaseControlView } from './basecontrol'; import FullScreen from 'ol/control/FullScreen.js'; @@ -38,11 +34,6 @@ export class FullScreenModel extends BaseControlModel { static view_module_version = MODULE_VERSION; } export class FullScreenView extends BaseControlView { - render() { - super.render(); - this.element = document.createElement('div'); - this.createObj(); - } createObj() { this.obj = new FullScreen({ className: 'ol-full-screen', diff --git a/src/imageoverlay.ts b/src/imageoverlay.ts index 2c35449..b920bee 100644 --- a/src/imageoverlay.ts +++ b/src/imageoverlay.ts @@ -2,6 +2,7 @@ // Distributed under the terms of the Modified BSD License. import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; + import 'ol/ol.css'; import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; @@ -35,8 +36,8 @@ export class ImageOverlayModel extends BaseOverlayModel { export class ImageOverlayView extends BaseOverlayView { render() { - super.render(); this.element = document.createElement('img'); + super.render(); this.updateImageElement(); } diff --git a/src/mouseposition.ts b/src/mouseposition.ts index ac86e85..1b23a70 100644 --- a/src/mouseposition.ts +++ b/src/mouseposition.ts @@ -1,10 +1,6 @@ // Copyright (c) QuantStack // Distributed under the terms of the Modified BSD License. -import { - DOMWidgetModel, - //WidgetView, - ISerializers, -} from '@jupyter-widgets/base'; +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; import { BaseControlModel, BaseControlView } from './basecontrol'; import MousePosition from 'ol/control/MousePosition.js'; @@ -38,11 +34,6 @@ export class MousePositionModel extends BaseControlModel { static view_module_version = MODULE_VERSION; } export class MousePositionView extends BaseControlView { - render() { - super.render(); - this.element = document.createElement('div'); - this.createObj(); - } createObj() { this.obj = new MousePosition({ className: 'ol-mouse-position', diff --git a/src/popupoverlay.ts b/src/popupoverlay.ts index 8d438bc..fa87f5f 100644 --- a/src/popupoverlay.ts +++ b/src/popupoverlay.ts @@ -17,7 +17,6 @@ export class PopupOverlayModel extends BaseOverlayModel { _view_name: PopupOverlayModel.view_name, _view_module: PopupOverlayModel.view_module, _view_module_version: PopupOverlayModel.view_module_version, - image_url: '', }; } @@ -35,8 +34,8 @@ export class PopupOverlayModel extends BaseOverlayModel { } export class PopupOverlayView extends BaseOverlayView { render() { - super.render(); this.element = document.createElement('div'); + super.render(); this.updatePopupElement(); } diff --git a/src/scaleline.ts b/src/scaleline.ts index b547e10..8ae6faf 100644 --- a/src/scaleline.ts +++ b/src/scaleline.ts @@ -1,10 +1,6 @@ // Copyright (c) QuantStack // Distributed under the terms of the Modified BSD License. -import { - DOMWidgetModel, - //WidgetView, - ISerializers, -} from '@jupyter-widgets/base'; +import { DOMWidgetModel, ISerializers } from '@jupyter-widgets/base'; import { BaseControlModel, BaseControlView } from './basecontrol'; import ScaleLine from 'ol/control/ScaleLine.js'; import 'ol/ol.css'; @@ -37,11 +33,6 @@ export class ScaleLineModel extends BaseControlModel { static view_module_version = MODULE_VERSION; } export class ScaleLineView extends BaseControlView { - render() { - super.render(); - this.element = document.createElement('div'); - this.createObj(); - } createObj() { this.obj = new ScaleLine({ className: 'ol-scale-bar', diff --git a/src/tilelayer.ts b/src/tilelayer.ts index 91155dc..e780aed 100644 --- a/src/tilelayer.ts +++ b/src/tilelayer.ts @@ -5,7 +5,6 @@ import TileLayer from 'ol/layer/Tile'; import XYZ from 'ol/source/XYZ'; import OSM from 'ol/source/OSM'; import { MODULE_NAME, MODULE_VERSION } from './version'; -import { MapView } from './widget'; export class TileLayerModel extends WidgetModel { defaults() { @@ -35,7 +34,6 @@ export class TileLayerModel extends WidgetModel { } export class TileLayerView extends WidgetView { - map: MapView; render() { super.render(); const url = this.model.get('url'); diff --git a/src/video_overlay.ts b/src/video_overlay.ts index 29579e8..fc0f0f2 100644 --- a/src/video_overlay.ts +++ b/src/video_overlay.ts @@ -6,6 +6,8 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; +export * from './tilelayer'; + export class VideoOverlayModel extends BaseOverlayModel { defaults() { return { @@ -36,11 +38,11 @@ export class VideoOverlayView extends BaseOverlayView { videoElement: HTMLVideoElement; render() { - super.render(); this.element = document.createElement('div'); this.videoElement = document.createElement('video'); this.videoElement.controls = true; this.element.appendChild(this.videoElement); + super.render(); this.updateVideoElement(); } diff --git a/src/widget.ts b/src/widget.ts index 4259ca3..7e5d699 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -19,7 +19,6 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { useGeographic } from 'ol/proj'; -//export * from './basecontrol'; export * from './baseoverlay'; export * from './imageoverlay'; export * from './video_overlay'; diff --git a/src/zoomslider.ts b/src/zoomslider.ts index 21e165d..1a41bb4 100644 --- a/src/zoomslider.ts +++ b/src/zoomslider.ts @@ -34,11 +34,6 @@ export class ZoomSliderModel extends BaseControlModel { static view_module_version = MODULE_VERSION; } export class ZoomSliderView extends BaseControlView { - render() { - super.render(); - this.element = document.createElement('div'); - this.createObj(); - } createObj() { this.obj = new ZoomSlider({ className: 'ol-zoomslider', From 81fa0a7517d6d5137a295d5f5e449e14545df9db Mon Sep 17 00:00:00 2001 From: Nour-Cheour10 Date: Tue, 11 Jun 2024 13:51:26 +0200 Subject: [PATCH 09/10] make baseoverlay abstract --- examples/introduction.ipynb | 65 ++++++++++++++++++++----------------- src/baseoverlay.ts | 6 ++-- src/imageoverlay.ts | 5 +-- src/popupoverlay.ts | 4 ++- src/video_overlay.ts | 9 +++-- src/widget.ts | 1 - 6 files changed, 49 insertions(+), 41 deletions(-) diff --git a/examples/introduction.ipynb b/examples/introduction.ipynb index 3cc0238..b53d321 100644 --- a/examples/introduction.ipynb +++ b/examples/introduction.ipynb @@ -24,7 +24,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "be83a201afd04d6092afa4c08da8c79e", + "model_id": "a2c23fa0e6b94f6a88fa314ff02fe502", "version_major": 2, "version_minor": 0 }, @@ -223,13 +223,13 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "96f6ebdbfbdf40758ddc3d6a7e1cfb0c", + "model_id": "89eb9976b4ec4065a24275a247fe2318", "version_major": 2, "version_minor": 0 }, @@ -237,7 +237,7 @@ "ImageOverlay(position=[0, 0])" ] }, - "execution_count": 17, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -249,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -258,7 +258,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -267,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -276,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -285,16 +285,16 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[ImageOverlay(image_url='https://i.imgur.com/ZF6s192.png', position=[-70, 70])]" + "[ImageOverlay(image_url='https://i.imgur.com/06Q1fSz.png', position=[-70, 70])]" ] }, - "execution_count": 23, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -324,16 +324,16 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ - "m.remove_overlay(imaget)" + "m.remove_overlay(image)" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -342,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -351,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -360,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -369,7 +369,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -378,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -397,7 +397,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -406,7 +406,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -415,13 +415,13 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "90f1687285754dd8aefc8364d2d741d2", + "model_id": "5692329a9806438fbb2be2bc0334475e", "version_major": 2, "version_minor": 0 }, @@ -429,7 +429,7 @@ "PopupOverlay(position=[0, 0])" ] }, - "execution_count": 38, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -441,16 +441,16 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ - "popup.popup_content='hellooooo'" + "popup.popup_content='Maap'" ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -459,12 +459,19 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "m.remove_overlay(popup)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/src/baseoverlay.ts b/src/baseoverlay.ts index f3d18f7..08ca913 100644 --- a/src/baseoverlay.ts +++ b/src/baseoverlay.ts @@ -11,8 +11,6 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import Overlay from 'ol/Overlay'; -export * from './tilelayer'; - export class BaseOverlayModel extends DOMWidgetModel { defaults() { return { @@ -35,15 +33,17 @@ export class BaseOverlayModel extends DOMWidgetModel { static view_module_version = MODULE_VERSION; } -export class BaseOverlayView extends DOMWidgetView { +export abstract class BaseOverlayView extends DOMWidgetView { overlay: Overlay; element: HTMLElement; render() { super.render(); + this.createElement(); this.createOverlay(); this.model_events(); } + abstract createElement(): void; createOverlay() { const position = this.model.get('position'); diff --git a/src/imageoverlay.ts b/src/imageoverlay.ts index b920bee..753a5f5 100644 --- a/src/imageoverlay.ts +++ b/src/imageoverlay.ts @@ -36,11 +36,12 @@ export class ImageOverlayModel extends BaseOverlayModel { export class ImageOverlayView extends BaseOverlayView { render() { - this.element = document.createElement('img'); super.render(); this.updateImageElement(); } - + createElement() { + this.element = document.createElement('img'); + } model_events() { super.model_events(); this.listenTo(this.model, 'change:image_url', this.updateImageElement); diff --git a/src/popupoverlay.ts b/src/popupoverlay.ts index fa87f5f..f3fab71 100644 --- a/src/popupoverlay.ts +++ b/src/popupoverlay.ts @@ -34,10 +34,12 @@ export class PopupOverlayModel extends BaseOverlayModel { } export class PopupOverlayView extends BaseOverlayView { render() { - this.element = document.createElement('div'); super.render(); this.updatePopupElement(); } + createElement() { + this.element = document.createElement('div'); + } model_events() { super.model_events(); diff --git a/src/video_overlay.ts b/src/video_overlay.ts index fc0f0f2..4091b61 100644 --- a/src/video_overlay.ts +++ b/src/video_overlay.ts @@ -6,8 +6,6 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { BaseOverlayModel, BaseOverlayView } from './baseoverlay'; -export * from './tilelayer'; - export class VideoOverlayModel extends BaseOverlayModel { defaults() { return { @@ -18,7 +16,6 @@ export class VideoOverlayModel extends BaseOverlayModel { _view_name: VideoOverlayModel.view_name, _view_module: VideoOverlayModel.view_module, _view_module_version: VideoOverlayModel.view_module_version, - image_url: '', }; } @@ -38,12 +35,14 @@ export class VideoOverlayView extends BaseOverlayView { videoElement: HTMLVideoElement; render() { + super.render(); + this.updateVideoElement(); + } + createElement() { this.element = document.createElement('div'); this.videoElement = document.createElement('video'); this.videoElement.controls = true; this.element.appendChild(this.videoElement); - super.render(); - this.updateVideoElement(); } model_events() { diff --git a/src/widget.ts b/src/widget.ts index 7e5d699..c8a54f7 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -19,7 +19,6 @@ import { MODULE_NAME, MODULE_VERSION } from './version'; import '../css/widget.css'; import { useGeographic } from 'ol/proj'; -export * from './baseoverlay'; export * from './imageoverlay'; export * from './video_overlay'; export * from './popupoverlay'; From f0dfeb6d8fe83cf1f3b2f6afde18c4664f02c162 Mon Sep 17 00:00:00 2001 From: Nour Cheour <161816839+Nour-Cheour10@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:28:33 +0200 Subject: [PATCH 10/10] delete not used variables --- ipyopenlayers/example.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ipyopenlayers/example.py b/ipyopenlayers/example.py index 5c9eaa7..ab95c13 100644 --- a/ipyopenlayers/example.py +++ b/ipyopenlayers/example.py @@ -56,8 +56,6 @@ class BaseControl(DOMWidget): _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) - control_name = Unicode().tag(sync=True) - class ZoomSlider(BaseControl): _view_name = Unicode('ZoomSliderView').tag(sync=True) _model_name = Unicode('ZoomSliderModel').tag(sync=True)