Skip to content

Commit ef1ee79

Browse files
committed
add as a control
1 parent 218cb68 commit ef1ee79

File tree

7 files changed

+393
-126
lines changed

7 files changed

+393
-126
lines changed

css/widget.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,18 @@
1919
overflow: hidden;
2020
flex: 1 1 auto;
2121
}
22+
23+
.swiper-container {
24+
position: absolute;
25+
top: 10px;
26+
left: 10px;
27+
z-index: 1000;
28+
background: rgba(255, 255, 255, 0.8);
29+
padding: 5px;
30+
border-radius: 4px;
31+
}
32+
33+
.swipe {
34+
width: 100%;
35+
margin: 0;
36+
}

examples/RasterLayer.ipynb

Lines changed: 135 additions & 17 deletions
Large diffs are not rendered by default.

ipyopenlayers/Map.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ class HeatmapLayer(Layer):
6767
blur =Int(15).tag(sync=True)
6868
radius = Int(8).tag(sync=True)
6969

70-
71-
72-
7370
class BaseOverlay(DOMWidget):
7471

7572
_model_module = Unicode(module_name).tag(sync=True)
@@ -121,6 +118,14 @@ class MousePosition(BaseControl):
121118
_view_name = Unicode('MousePositionView').tag(sync=True)
122119
_model_name = Unicode('MousePositionModel').tag(sync=True)
123120

121+
class SplitMapControl(BaseControl):
122+
_model_name = Unicode('SplitMapControlModel').tag(sync=True)
123+
_view_name = Unicode('SplitMapControlView').tag(sync=True)
124+
left_layer = Instance(Layer).tag(sync=True, **widget_serialization)
125+
right_layer = Instance(Layer).tag(sync=True, **widget_serialization)
126+
swipe_position = Int(50).tag(sync=True)
127+
128+
124129

125130
class Map(DOMWidget):
126131
_model_name = Unicode('MapModel').tag(sync=True)
@@ -137,7 +142,6 @@ class Map(DOMWidget):
137142
controls=List(Instance(BaseControl)).tag(sync=True, **widget_serialization)
138143

139144

140-
141145
def __init__(self, center=None, zoom=None, **kwargs):
142146
super().__init__(**kwargs)
143147

@@ -166,4 +170,8 @@ def remove_control(self, control):
166170

167171

168172
def clear_layers(self):
169-
self.layers = []
173+
self.layers = []
174+
175+
176+
177+

src/rastertilelayer.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { MODULE_NAME, MODULE_VERSION } from './version';
55
import { MapView } from './widget';
66
import { LayerModel, LayerView } from './layer';
77

8+
/*
89
type WebGLEvent = {
910
context: WebGLRenderingContext;
1011
};
11-
12+
*/
1213
export class RasterTileLayerModel extends LayerModel {
1314
defaults() {
1415
return {
@@ -44,31 +45,31 @@ export class RasterTileLayerModel extends LayerModel {
4445
export class RasterTileLayerView extends LayerView {
4546
map_view: MapView;
4647
tileLayer: WebGLTileLayer;
47-
48+
/*
4849
private prerenderListener: (event: WebGLEvent) => void;
4950
private postrenderListener: (event: WebGLEvent) => void;
5051
private previousSwipePosition: number | undefined;
5152
52-
constructor(options: any) {
53+
constructor(options: any) {
5354
super(options);
5455
this.map_view = options.options.map_view;
5556
this.prerenderListener = this.map_view.handlePrerender.bind(this.map_view);
5657
this.postrenderListener = this.map_view.handlePostrender.bind(
5758
this.map_view,
5859
);
5960
this.previousSwipePosition = undefined;
60-
}
61+
}*/
6162

6263
render() {
6364
super.render();
6465
this.urlChanged();
6566
this.model.on('change:url', this.urlChanged, this);
66-
this.model.on(
67+
/*this.model.on(
6768
'change:swipe_position',
6869
this.handleSwipePositionChanged,
6970
this,
70-
);
71-
this.updateEventListeners();
71+
);*/
72+
//this.updateEventListeners();
7273
}
7374

7475
create_obj() {
@@ -97,7 +98,7 @@ export class RasterTileLayerView extends LayerView {
9798
}
9899
}
99100

100-
handleSwipePositionChanged() {
101+
/*handleSwipePositionChanged() {
101102
const swipePosition = this.model.get('swipe_position');
102103
console.log('Swipe Position Changed:', swipePosition);
103104
@@ -119,5 +120,5 @@ export class RasterTileLayerView extends LayerView {
119120
(this.tileLayer as any).on('postcompose', this.postrenderListener);
120121
}
121122
console.log('Event listeners updated');
122-
}
123+
}*/
123124
}

src/splitcontrol.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) QuantStack
2+
// Distributed under the terms of the Modified BSD License.
3+
import Control from 'ol/control/Control';
4+
import { getRenderPixel } from 'ol/render';
5+
import 'ol/ol.css';
6+
import '../css/widget.css';
7+
import { MapView } from './widget';
8+
9+
// Interface for SplitMapControl options
10+
interface SplitMapControlOptions {
11+
target?: string;
12+
map_view?: MapView;
13+
swipe_position?: number; // Ajoutez swipe_position en tant que nombre
14+
}
15+
export default class SplitMapControl extends Control {
16+
swipe: HTMLInputElement;
17+
leftLayer: any;
18+
rightLayer: any;
19+
map_view: MapView;
20+
swipe_position: any;
21+
constructor(
22+
leftLayer: any,
23+
rightLayer: any,
24+
options: SplitMapControlOptions = {},
25+
) {
26+
const element = document.createElement('div');
27+
element.className = 'ol-unselectable ol-control split-map-control';
28+
29+
super({
30+
element: element,
31+
target: options.target,
32+
});
33+
34+
this.leftLayer = leftLayer;
35+
this.rightLayer = rightLayer;
36+
37+
console.log('Initializing SplitMapControl...');
38+
console.log(options);
39+
if (options.map_view) {
40+
this.map_view = options.map_view;
41+
console.log('MapView initialized:', this.map_view);
42+
} else {
43+
throw new Error('MapView is required for SplitMapControl.');
44+
}
45+
if (options.swipe_position) {
46+
this.swipe_position = options.swipe_position;
47+
console.log('swipe_position initialized:', this.swipe_position);
48+
} else {
49+
throw new Error('swipe_position is required for SplitMapControl.');
50+
}
51+
52+
const swiperContainer = document.createElement('div');
53+
swiperContainer.className = 'swiper-container';
54+
55+
this.swipe = document.createElement('input');
56+
this.swipe.type = 'range';
57+
this.swipe.className = 'swipe';
58+
(this.swipe.value = this.swipe_position),
59+
swiperContainer.appendChild(this.swipe);
60+
console.log('this.map_view.map_container', this.map_view.map_container);
61+
this.map_view.map_container.appendChild(swiperContainer);
62+
this.handleSwipe();
63+
}
64+
65+
handleSwipe(event?: Event) {
66+
console.log('Handling swipe event...');
67+
console.log(this.swipe.value);
68+
if (!this.leftLayer.hasListener('prerender')) {
69+
console.log('1');
70+
this.leftLayer.on('prerender', this.prerender.bind(this));
71+
}
72+
73+
if (!this.leftLayer.hasListener('postrender')) {
74+
console.log('2');
75+
//this.leftLayer.on('postrender', this.postrender.bind(this));
76+
}
77+
78+
if (!this.rightLayer.hasListener('prerender')) {
79+
console.log('3');
80+
81+
//this.rightLayer.on('prerender', this.prerender.bind(this));
82+
}
83+
84+
if (!this.rightLayer.hasListener('postrender')) {
85+
console.log('4');
86+
87+
this.rightLayer.on('postrender', this.postrender.bind(this));
88+
}
89+
90+
console.log('ok');
91+
}
92+
93+
prerender(event: any) {
94+
console.log('Prerender event triggered.');
95+
96+
const gl = event.context; // Get WebGL context
97+
gl.enable(gl.SCISSOR_TEST); // Enable scissor test
98+
99+
const mapSize = this.map_view.getSize(); // Get the size of the map
100+
if (!mapSize) {
101+
console.warn('Map size is undefined.');
102+
return;
103+
}
104+
105+
// Get render pixels for the bottom left and top right corners
106+
const bottomLeft = getRenderPixel(event, [0, mapSize[1]]);
107+
const topRight = getRenderPixel(event, [mapSize[0], 0]);
108+
109+
// Get the swipe value from the input element
110+
const swipeValue = this.swipe.value;
111+
console.log('swipeValue', swipeValue);
112+
113+
// Calculate the width and height for the scissor test
114+
const width = Math.round(
115+
(topRight[0] - bottomLeft[0]) * (Number(swipeValue) / 100),
116+
);
117+
const height = topRight[1] - bottomLeft[1];
118+
119+
// Define the scissor box
120+
gl.scissor(bottomLeft[0], bottomLeft[1], width, height);
121+
}
122+
123+
postrender(event: any) {
124+
console.log('Postrender event triggered.');
125+
126+
const gl = event.context; // Get WebGL context
127+
gl.disable(gl.SCISSOR_TEST); // Disable scissor test
128+
}
129+
}

src/splitmapcontrol.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright (c) QuantStack
2+
// Distributed under the terms of the Modified BSD License.
3+
import { unpack_models } from '@jupyter-widgets/base';
4+
import { BaseControlModel, BaseControlView } from './basecontrol';
5+
import 'ol/ol.css';
6+
import '../css/widget.css';
7+
import SplitMapControl from './splitcontrol';
8+
9+
// Modèle pour le contrôle de carte divisée
10+
export class SplitMapControlModel extends BaseControlModel {
11+
defaults() {
12+
return {
13+
...super.defaults(),
14+
_view_name: 'SplitMapControlView',
15+
_model_name: 'SplitMapControlModel',
16+
left_layer: undefined,
17+
right_layer: undefined,
18+
swipe_position: 50,
19+
};
20+
}
21+
}
22+
23+
SplitMapControlModel.serializers = {
24+
...BaseControlModel.serializers,
25+
left_layer: { deserialize: unpack_models },
26+
right_layer: { deserialize: unpack_models },
27+
};
28+
29+
function asArray(arg: any) {
30+
return Array.isArray(arg) ? arg : [arg];
31+
}
32+
33+
export class SplitMapControlView extends BaseControlView {
34+
swipe_position: number;
35+
initialize(parameters: any) {
36+
super.initialize(parameters);
37+
this.map_view = this.options.map_view;
38+
this.map_view.layer_views = this.options.map_view.layerViews;
39+
console.log('hello');
40+
if (this.map_view && !this.map_view.layerViews) {
41+
console.warn(
42+
'Layer views is not initialized. Ensure it is properly set.',
43+
);
44+
}
45+
}
46+
47+
createObj() {
48+
console.log('Creating SplitMapControl object...');
49+
const left_models = asArray(this.model.get('left_layer'));
50+
51+
const right_models = asArray(this.model.get('right_layer'));
52+
53+
let layersModel = this.map_view.model.get('layers');
54+
55+
layersModel = layersModel.concat(left_models, right_models);
56+
57+
return this.map_view.layer_views.update(layersModel).then((views: any) => {
58+
const left_views: any[] = [];
59+
console.log(left_views);
60+
const right_views: any[] = [];
61+
console.log(right_views);
62+
63+
views.forEach((view: any) => {
64+
if (left_models.indexOf(view.model) !== -1) {
65+
left_views.push(view.obj);
66+
}
67+
if (right_models.indexOf(view.model) !== -1) {
68+
right_views.push(view.obj);
69+
}
70+
});
71+
72+
console.log('Left views:', left_views);
73+
console.log('Right views:', right_views);
74+
this.swipe_position = this.model.get('swipe_position');
75+
console.log('swipe_position:', this.swipe_position);
76+
77+
this.obj = new SplitMapControl(left_views[0], right_views[0], {
78+
map_view: this.map_view,
79+
swipe_position: this.swipe_position,
80+
});
81+
console.log('SplitMapControl created:', this.obj);
82+
});
83+
}
84+
}

0 commit comments

Comments
 (0)