Skip to content

Commit a594e1e

Browse files
committed
changed on click
1 parent 432f40c commit a594e1e

File tree

6 files changed

+51
-59
lines changed

6 files changed

+51
-59
lines changed

docs/source/_static/embed-bundle.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/source/_static/embed-bundle.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/RasterLayer.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
"name": "python",
111111
"nbconvert_exporter": "python",
112112
"pygments_lexer": "ipython3",
113-
"version": "3.9.19"
113+
"version": "3.12.4"
114114
}
115115
},
116116
"nbformat": 4,

examples/map.ipynb

+31-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
{
1212
"cell_type": "code",
13-
"execution_count": 7,
13+
"execution_count": 1,
1414
"id": "94284d6e",
1515
"metadata": {
1616
"vscode": {
@@ -21,15 +21,15 @@
2121
{
2222
"data": {
2323
"application/vnd.jupyter.widget-view+json": {
24-
"model_id": "d279d658374d48db8f6a0459ccdba5e1",
24+
"model_id": "ddc2f32ae8ce49c7b79b26a3e9ab4f85",
2525
"version_major": 2,
2626
"version_minor": 0
2727
},
2828
"text/plain": [
29-
"Map(center=[0.0, 0.0], layers=[RasterTileLayer()])"
29+
"Map(center=[0.0, 0.0], zoom=2.0)"
3030
]
3131
},
32-
"execution_count": 7,
32+
"execution_count": 1,
3333
"metadata": {},
3434
"output_type": "execute_result"
3535
}
@@ -46,7 +46,7 @@
4646
},
4747
{
4848
"cell_type": "code",
49-
"execution_count": 8,
49+
"execution_count": 2,
5050
"id": "6ecd0ff6-93f3-4cd8-bc0a-8520aab07a84",
5151
"metadata": {},
5252
"outputs": [],
@@ -59,31 +59,52 @@
5959
},
6060
{
6161
"cell_type": "code",
62-
"execution_count": 9,
63-
"id": "9ec9cfaa-9f30-4aef-a817-3ef1143d8004",
62+
"execution_count": 3,
63+
"id": "c2a997b5-3f80-4e9c-8956-5dba704f7eae",
6464
"metadata": {},
6565
"outputs": [],
6666
"source": [
6767
"import requests\n",
6868
"import unicodedata\n",
69+
"import configparser\n",
70+
"\n",
6971
"\n",
70-
"def get_country_from_coordinates_geoapify(lat, lon): \n",
72+
"def get_country_from_coordinates_geoapify(**kwargs):\n",
73+
" # Extract latitude and longitude from kwargs\n",
74+
" lon = kwargs.get('lon')\n",
75+
" lat = kwargs.get('lat')\n",
76+
" if lon is None or lat is None:\n",
77+
" print(\"Latitude and longitude must be provided.\")\n",
78+
" return\n",
79+
" \n",
80+
" # Define Geoapify API URL\n",
7181
" url = f\"https://api.geoapify.com/v1/geocode/reverse?lat={lat}&lon={lon}&apiKey={api_key}\"\n",
82+
" \n",
83+
" # Make the API request\n",
7284
" response = requests.get(url)\n",
7385
" data = response.json()\n",
86+
" \n",
87+
" # Extract country from the API response\n",
7488
" features = data.get('features', [])\n",
75-
"\n",
7689
" if features:\n",
7790
" first_feature = features[0]\n",
7891
" properties = first_feature.get('properties', {})\n",
7992
" country = properties.get('country', None)\n",
8093
" normalized_name = country.split(' ')[0]\n",
8194
" normalized_name = unicodedata.normalize('NFKD', normalized_name)\n",
8295
" normalized_name = normalized_name.encode('ASCII', 'ignore').decode('utf-8')\n",
83-
" print(normalized_name)\n",
96+
" print(f\"Country: {normalized_name}\")\n",
8497
"\n",
8598
"m.on_click(get_country_from_coordinates_geoapify)"
8699
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": null,
104+
"id": "94b36482-ce0c-406f-8da9-46d6c4896000",
105+
"metadata": {},
106+
"outputs": [],
107+
"source": []
87108
}
88109
],
89110
"metadata": {

ipyopenlayers/openlayers.py

+14-47
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
# Copyright (c) QuantStack.
55
# Distributed under the terms of the Modified BSD License.
66

7-
from ipywidgets import DOMWidget, Widget, widget_serialization
7+
from ipywidgets import DOMWidget, Widget, widget_serialization, CallbackDispatcher
8+
89
from traitlets import Unicode, List, Instance, CFloat, Bool, Dict, Int, Float
910
from ._frontend import module_name, module_version
1011
import requests
@@ -46,7 +47,7 @@ class TileLayer(Layer):
4647
Additional format options for the tile source.
4748
"""
4849

49-
url = Unicode('').tag(sync=True)
50+
url = Unicode('https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png').tag(sync=True)
5051
attribution = Unicode("").tag(sync=True)
5152
opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True)
5253
visible = Bool(True).tag(sync=True)
@@ -266,6 +267,8 @@ class Map(DOMWidget):
266267
layers = List(Instance(Layer)).tag(sync=True, **widget_serialization)
267268
overlays=List(Instance(BaseOverlay)).tag(sync=True, **widget_serialization)
268269
controls=List(Instance(BaseControl)).tag(sync=True, **widget_serialization)
270+
_click_callbacks = Instance(CallbackDispatcher, ())
271+
269272

270273

271274

@@ -280,6 +283,7 @@ def __init__(self, center=None, zoom=None, **kwargs):
280283
The initial zoom level of the map.
281284
"""
282285
super().__init__(**kwargs)
286+
self.on_msg(self._handle_mouse_events)
283287
if center is not None:
284288
self.center = center
285289
if zoom is not None:
@@ -356,54 +360,17 @@ def clear_layers(self):
356360
"""
357361
self.layers = []
358362

359-
def on_msg(self, callback):
360-
"""Register a callback for receiving messages from the frontend."""
361-
self._msg_callback = callback
362-
363-
def _handle_msg(self, msg):
364-
"""Handle a message received from the frontend."""
365-
if hasattr(self, '_msg_callback'):
366-
content = msg.get('content', {})
367-
buffers = msg.get('buffers', [])
368-
self._msg_callback(self, content, buffers)
369-
370-
def _handle_click(self, lat, lon):
371-
"""Handle click events and trigger registered callbacks."""
372-
373-
374-
callbacks = self._click_callbacks.get_callbacks()
375-
for callback in callbacks:
376-
if callable(callback):
377-
callback(lat, lon)
378-
379-
def on_click(self, callback):
363+
def _handle_mouse_events(self, _, content, buffers):
364+
"""Handle mouse events and trigger click callbacks.
380365
"""
381-
Register a callback to handle click events on the map.
382-
366+
event_type = content.get("type", "")
367+
if event_type == "click":
368+
self._click_callbacks(**content)
383369

384-
Parameters
385-
----------
386-
callback : function
387-
Function that accepts two arguments: lon (longitude) and lat (latitude) of the clicked position.
370+
def on_click(self, callback, remove=False):
371+
"""Add a click event listener.
388372
"""
373+
self._click_callbacks.register_callback(callback, remove=remove)
389374

390-
self._click_callback = callback
391-
392-
393-
def handle_frontend_event(widget, content, buffers):
394-
"""Handle the click event from the frontend."""
395-
data = content.get('data', {})
396-
method = data.get('method', '')
397-
398-
399-
if method == 'custom':
400-
event_data = data.get('content', {})
401-
lon = event_data.get('lon')
402-
lat = event_data.get('lat')
403-
404-
if callable(self._click_callback):
405-
self._click_callback(lat, lon)
406-
407-
self.on_msg(handle_frontend_event)
408375

409376

src/widget.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ export class MapView extends DOMWidgetView {
152152
handleMapClick(event: MapBrowserEvent<MouseEvent>) {
153153
const coordinate = event.coordinate;
154154
const [lon, lat] = coordinate;
155-
this.send({ lon, lat });
155+
this.send({ type: 'click', lon, lat });
156156
}
157157
layersChanged() {
158158
const layers = this.model.get('layers') as LayerModel[];

0 commit comments

Comments
 (0)