Skip to content

Commit 3174b0d

Browse files
author
Stefan Kuethe
committed
Send draw features to model
1 parent 7d5172c commit 3174b0d

File tree

6 files changed

+150
-10
lines changed

6 files changed

+150
-10
lines changed

notebooks/layers/draw-control.ipynb

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "fcb43a68-346f-4232-9183-0cabe421e51c",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"import openlayers as ol"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": 2,
16+
"id": "0ba32ac6-7715-4a3a-bbcc-4ff9022e006a",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"m = ol.MapWidget(controls=[ol.DrawControl()])"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 3,
26+
"id": "4bb4306a-4035-45f7-8203-54b8b5e8ce09",
27+
"metadata": {},
28+
"outputs": [
29+
{
30+
"data": {
31+
"application/vnd.jupyter.widget-view+json": {
32+
"model_id": "f28e2ec3d4ba4f1dbd065b551135ac32",
33+
"version_major": 2,
34+
"version_minor": 1
35+
},
36+
"text/plain": [
37+
"MapWidget(height='400px', options={'view': {'center': (0.0, 0.0), 'zoom': 0, 'projection': 'EPSG:3857', '@@typ…"
38+
]
39+
},
40+
"execution_count": 3,
41+
"metadata": {},
42+
"output_type": "execute_result"
43+
}
44+
],
45+
"source": [
46+
"m"
47+
]
48+
},
49+
{
50+
"cell_type": "code",
51+
"execution_count": 14,
52+
"id": "d6efd311-8f02-4620-859d-41bda81157dc",
53+
"metadata": {},
54+
"outputs": [
55+
{
56+
"data": {
57+
"text/plain": [
58+
"{'type': 'FeatureCollection',\n",
59+
" 'features': ['{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-125.89665252189707,29.8693128204649]},\"properties\":null}',\n",
60+
" '{\"type\":\"Feature\",\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[-72.22592198459827,-15.295776076177518],[15.286438185068512,6.9778786803578186],[39.08133814625181,26.13486798336824],[-72.22592198459827,17.80716486393308]]},\"properties\":null}',\n",
61+
" '{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-121.93083586169986,21.048396117389515],[-107.12510859433377,-7.001741395883869],[-37.062359333479414,35.431295097579664],[-85.18092894255743,39.419363549282394],[-106.86073255295044,31.68662445230116],[-121.93083586169986,21.048396117389515]]]},\"properties\":null}']}"
62+
]
63+
},
64+
"execution_count": 14,
65+
"metadata": {},
66+
"output_type": "execute_result"
67+
}
68+
],
69+
"source": [
70+
"fc = dict(type=\"FeatureCollection\", features=m.features[\"features\"])\n",
71+
"fc"
72+
]
73+
},
74+
{
75+
"cell_type": "code",
76+
"execution_count": 15,
77+
"id": "695ca685-c6b8-477a-8f7d-c7f725cab774",
78+
"metadata": {},
79+
"outputs": [
80+
{
81+
"ename": "TypeError",
82+
"evalue": "string indices must be integers, not 'str'",
83+
"output_type": "error",
84+
"traceback": [
85+
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
86+
"\u001b[31mTypeError\u001b[39m Traceback (most recent call last)",
87+
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[15]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mol\u001b[49m\u001b[43m.\u001b[49m\u001b[43mGeoDataFrame\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_features\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfc\u001b[49m\u001b[43m)\u001b[49m\n",
88+
"\u001b[36mFile \u001b[39m\u001b[32m~/projects/internal/data-products/py-openlayers/.venv/lib/python3.11/site-packages/geopandas/geodataframe.py:737\u001b[39m, in \u001b[36mGeoDataFrame.from_features\u001b[39m\u001b[34m(cls, features, crs, columns)\u001b[39m\n\u001b[32m 734\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(feature, \u001b[33m\"\u001b[39m\u001b[33m__geo_interface__\u001b[39m\u001b[33m\"\u001b[39m):\n\u001b[32m 735\u001b[39m feature = feature.__geo_interface__\n\u001b[32m 736\u001b[39m row = {\n\u001b[32m--> \u001b[39m\u001b[32m737\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mgeometry\u001b[39m\u001b[33m\"\u001b[39m: shape(feature[\u001b[33m\"\u001b[39m\u001b[33mgeometry\u001b[39m\u001b[33m\"\u001b[39m]) \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mfeature\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mgeometry\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 738\u001b[39m }\n\u001b[32m 739\u001b[39m \u001b[38;5;66;03m# load properties\u001b[39;00m\n\u001b[32m 740\u001b[39m properties = feature[\u001b[33m\"\u001b[39m\u001b[33mproperties\u001b[39m\u001b[33m\"\u001b[39m]\n",
89+
"\u001b[31mTypeError\u001b[39m: string indices must be integers, not 'str'"
90+
]
91+
}
92+
],
93+
"source": [
94+
"ol.GeoDataFrame.from_features(fc)"
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": null,
100+
"id": "838b802f-f001-43d2-95e6-25c1c454d200",
101+
"metadata": {},
102+
"outputs": [],
103+
"source": []
104+
}
105+
],
106+
"metadata": {
107+
"kernelspec": {
108+
"display_name": "Python 3 (ipykernel)",
109+
"language": "python",
110+
"name": "python3"
111+
},
112+
"language_info": {
113+
"codemirror_mode": {
114+
"name": "ipython",
115+
"version": 3
116+
},
117+
"file_extension": ".py",
118+
"mimetype": "text/x-python",
119+
"name": "python",
120+
"nbconvert_exporter": "python",
121+
"pygments_lexer": "ipython3",
122+
"version": "3.11.11"
123+
}
124+
},
125+
"nbformat": 4,
126+
"nbformat_minor": 5
127+
}

src/openlayers/anywidget.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ class MapWidget(Map, AnyWidget):
2828
# clicked = traitlets.Dict().tag(sync=True)
2929
view_state = traitlets.Dict().tag(sync=True)
3030
metadata = traitlets.Dict().tag(sync=True)
31+
32+
# TODO: Move to features as well
3133
features_selected = traitlets.List().tag(sync=True)
34+
features = traitlets.Dict().tag(sync=True)
3235

3336
def __init__(
3437
self,

src/openlayers/js/openlayers.anywidget.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.

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/events.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function filter(obj: any): any {
1515
function addEventListernersToMapWidget(mapWidget: MapWidget): void {
1616
const map = mapWidget.getMap();
1717
const metadata = mapWidget.getMetadata();
18+
// const features = mapWidget._features;
1819
const model = mapWidget.getAnywidgetModel();
1920

2021
const updateModel = (): void => {
@@ -47,14 +48,17 @@ function addEventListernersToMapWidget(mapWidget: MapWidget): void {
4748
// if (control.get("type") === "DrawControl")
4849
if (control instanceof DrawControl) {
4950
control.onAdd();
50-
// TODO: `if (model)`!
51-
if (true) {
52-
for (const event of ["addfeature", "changefeature"]) {
53-
// @ts-expect-error
54-
control.getLayer().getSource()?.on(event, (e) => {
55-
console.log(control.getGeoJSONFeatures());
56-
});
57-
}
51+
for (const event of ["addfeature", "changefeature"]) {
52+
const layer = control.getLayer();
53+
// @ts-expect-error
54+
layer.getSource()?.on(event, (e) => {
55+
const features = control.getGeoJSONFeatures();
56+
console.log(features);
57+
if (model) {
58+
model.set("features", { [layer.get("id")]: features });
59+
model.save_changes();
60+
}
61+
});
5862
}
5963
}
6064

srcjs/ipywidget-ts/map.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ type Metadata = {
3535
controls: any[];
3636
};
3737

38+
// TODO: Rename to something like `FeatureStore`
39+
type Features = {
40+
[key: string]: any[];
41+
}
42+
3843
const jsonConverter = new JSONConverter();
3944

4045
// --- Use geographic coordinates (WGS-84) in all methods
@@ -64,6 +69,7 @@ export default class MapWidget {
6469
_container: HTMLElement;
6570
_map: Map;
6671
_metadata: Metadata = { layers: [], controls: [] };
72+
// _features: Features = {};
6773
_model: AnyModel | undefined;
6874

6975
constructor(mapElement: HTMLElement, mapOptions: MyMapOptions, model?: AnyModel | undefined) {

0 commit comments

Comments
 (0)