Skip to content

Commit 92830d6

Browse files
author
Stefan Kuethe
committed
Send view state
1 parent 270f883 commit 92830d6

File tree

7 files changed

+140
-49
lines changed

7 files changed

+140
-49
lines changed

notebooks/layers/Untitled.ipynb

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
{
5353
"data": {
5454
"application/vnd.jupyter.widget-view+json": {
55-
"model_id": "ee4ebb74b08d4764ba14f4b4330800a8",
55+
"model_id": "a745492caf154ef2ae3c8d43386174ed",
5656
"version_major": 2,
5757
"version_minor": 1
5858
},
@@ -69,6 +69,55 @@
6969
"m"
7070
]
7171
},
72+
{
73+
"cell_type": "code",
74+
"execution_count": 12,
75+
"id": "705018de-ed98-4e03-9db6-5ddf35011282",
76+
"metadata": {},
77+
"outputs": [
78+
{
79+
"data": {
80+
"text/plain": [
81+
"{'layers': [{'id': 'carto-dark-all', 'type': 'TileLayer'},\n",
82+
" {'id': '8554b6c6-07b0-4016-a100-b03b889cf7d6', 'type': 'WebGLVectorLayer'}],\n",
83+
" 'controls': [{'id': '09cfeacc-b435-473c-8dc2-5624b8fafe59',\n",
84+
" 'type': 'ZoomSliderControl'},\n",
85+
" {'id': 'MyNiceCtrl', 'type': 'OverviewMapControl'}]}"
86+
]
87+
},
88+
"execution_count": 12,
89+
"metadata": {},
90+
"output_type": "execute_result"
91+
}
92+
],
93+
"source": [
94+
"m.map_metadata"
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": 14,
100+
"id": "8bc59002-4b1a-4caa-9b67-a64cd83a60c1",
101+
"metadata": {},
102+
"outputs": [
103+
{
104+
"data": {
105+
"text/plain": [
106+
"{'center': [873750.6090347767, 9696804.421408108],\n",
107+
" 'projection': 'EPSG:3857',\n",
108+
" 'zoom': 3.573608880492306,\n",
109+
" 'center_lonlat': [7.849035266046803, 65.33362816204604]}"
110+
]
111+
},
112+
"execution_count": 14,
113+
"metadata": {},
114+
"output_type": "execute_result"
115+
}
116+
],
117+
"source": [
118+
"m.map_view_state"
119+
]
120+
},
72121
{
73122
"cell_type": "code",
74123
"execution_count": 7,
@@ -77,8 +126,8 @@
77126
"outputs": [],
78127
"source": [
79128
"ctrl_id = \"MyNiceCtrl\"\n",
80-
"# m.add_control(ol.controls.OverviewMapControl(id=ctrl_id))\n",
81-
"m.remove_control(control_id=ctrl_id)"
129+
"m.add_control(ol.controls.OverviewMapControl(id=ctrl_id))\n",
130+
"# m.remove_control(control_id=ctrl_id)"
82131
]
83132
},
84133
{
@@ -104,7 +153,7 @@
104153
},
105154
{
106155
"cell_type": "code",
107-
"execution_count": 8,
156+
"execution_count": 6,
108157
"id": "1aa4155d",
109158
"metadata": {},
110159
"outputs": [],
@@ -115,14 +164,14 @@
115164
},
116165
{
117166
"cell_type": "code",
118-
"execution_count": 10,
167+
"execution_count": 7,
119168
"id": "2e7cee1d",
120169
"metadata": {},
121170
"outputs": [],
122171
"source": [
123-
"# m.add_layer(countries)\n",
172+
"m.add_layer(countries)\n",
124173
"\n",
125-
"m.remove_layer(countries.id)\n",
174+
"# m.remove_layer(countries.id)\n",
126175
"# m.add_tooltip()\n",
127176
"#import geopandas as gpd\n",
128177
"#from openlayers.geopandas import OLGeoDataFrame"

src/openlayers/anywidget.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ class MapWidget(Map, AnyWidget):
2222
calls = traitlets.List().tag(sync=True)
2323
map_created = traitlets.Bool().tag(sync=True)
2424
map_options = traitlets.Dict().tag(sync=True)
25-
map_clicked = traitlets.Dict().tag(sync=True)
26-
debug_data = traitlets.Dict().tag(sync=True)
25+
# map_clicked = traitlets.Dict().tag(sync=True)
26+
map_view_state = traitlets.Dict().tag(sync=True)
27+
map_metadata = traitlets.Dict().tag(sync=True)
28+
# debug_data = traitlets.Dict().tag(sync=True)
2729

2830
def __init__(
2931
self,

src/openlayers/js/openlayers.anywidget.js

Lines changed: 32 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/openlayers/js/openlayers.standalone.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

srcjs/ipywidget-ts/anywidget.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
import "ol/ol.css";
22

33
import MapWidget from "./map";
4-
import { parseClickEvent } from "./utils";
4+
import { parseClickEvent, parseView } from "./utils";
55

66
// --- Types
77
import type { AnyModel } from "@anywidget/types";
8+
import type { Map } from "ol";
89

910
// --- Main function
1011
function render({ model, el }: { model: AnyModel; el: HTMLElement }): void {
12+
function updateModelMetadata(): void {
13+
model.set("map_metadata", mapWidget.getMetadata());
14+
model.save_changes();
15+
}
16+
17+
function updateModelViewState(): void {
18+
const view = map.getView();
19+
const value = parseView(view);
20+
model.set("map_view_state", value);
21+
model.save_changes()
22+
}
23+
24+
// --- Main
1125
console.log("Welcome to ol-anywidget", el);
1226

1327
const height = model.get("height") || "400px";
@@ -18,7 +32,7 @@ function render({ model, el }: { model: AnyModel; el: HTMLElement }): void {
1832
// ...
1933
const mapOptions = model.get("map_options");
2034
console.log("mapOptions", mapOptions);
21-
const mapWidget = (window as any).anywidgetMapWidget = new MapWidget(mapElement, mapOptions);
35+
const mapWidget = (window as any).anywidgetMapWidget = new MapWidget(mapElement, mapOptions, model);
2236

2337
model.set("map_created", true);
2438
model.save_changes();
@@ -30,7 +44,15 @@ function render({ model, el }: { model: AnyModel; el: HTMLElement }): void {
3044
mapWidget[call.method](...call.args);
3145
}
3246

47+
updateModelMetadata();
48+
3349
const map = mapWidget.getMap();
50+
updateModelViewState();
51+
map.on("moveend", (e) => {
52+
// console.log("change event", map.getView());
53+
updateModelViewState();
54+
})
55+
3456
/*
3557
map.on("click", (e) => {
3658
const info = parseClickEvent(e);
@@ -46,6 +68,7 @@ function render({ model, el }: { model: AnyModel; el: HTMLElement }): void {
4668
try {
4769
// @ts-expect-error
4870
mapWidget[msg.method](...msg.args);
71+
updateModelMetadata();
4972
} catch (error) {
5073
console.log("error in anywidget msg call", error);
5174
}

srcjs/ipywidget-ts/map.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import type WebGLVectorLayer from "ol/layer/WebGLVector";
1515
import type { Coordinate } from "ol/coordinate";
1616
import type { MyMapOptions } from ".";
1717

18+
import type { AnyModel } from "@anywidget/types";
19+
1820
type Metadata = {
1921
layers: any[];
2022
controls: any[];
@@ -62,8 +64,11 @@ export default class MapWidget {
6264
_container: HTMLElement;
6365
_map: Map;
6466
_metadata: Metadata = { layers: [], controls: [] };
67+
_model: AnyModel | undefined;
68+
69+
constructor(mapElement: HTMLElement, mapOptions: MyMapOptions, model?: AnyModel | undefined) {
70+
this._model = model;
6571

66-
constructor(mapElement: HTMLElement, mapOptions: MyMapOptions) {
6772
const view = parseViewDef(mapOptions.view);
6873
let baseControls: Control[] = [];
6974
let baseLayers: Layer[] = [];

srcjs/ipywidget-ts/utils.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
import type { MapBrowserEvent } from "ol";
22
import type { FeatureLike } from "ol/Feature";
33
import type { FeatureProps } from ".";
4+
import type { View } from "ol";
45

5-
import { transform as transformProj, toLonLat } from "ol/proj";
6+
import { toLonLat } from "ol/proj";
67

8+
// TODO: get 'info' from 'parseView'
79
function parseClickEvent(e: MapBrowserEvent): any {
810
const view = e.target.getView();
911
const projectionCode = view.getProjection().getCode();
1012
const info = {
1113
center: view.getCenter(),
1214
projection: projectionCode,
1315
zoom: view.getZoom(),
14-
// lnglat: transformProj(e.coordinate, projectionCode, "EPSG:4326")
15-
lonLat: toLonLat(e.coordinate)
16+
centerLonLat: toLonLat(e.coordinate)
1617
};
1718
return info;
1819
}
1920

21+
function parseView(view: View): any {
22+
const center = view.getCenter() || [];
23+
const projectionCode = view.getProjection().getCode();
24+
return {
25+
center: center,
26+
projection: projectionCode,
27+
zoom: view.getZoom(),
28+
center_lonlat: toLonLat(center)
29+
};
30+
}
31+
2032
function getFeatureProperties(feature: FeatureLike): FeatureProps {
2133
let { geometry, ...props } = feature.getProperties();
2234
return props;
2335
}
2436

25-
export { parseClickEvent, getFeatureProperties }
37+
export { parseClickEvent, getFeatureProperties, parseView }

0 commit comments

Comments
 (0)