|
7 | 7 | "outputs": [], |
8 | 8 | "source": [ |
9 | 9 | "from math import pow, cos, pi, radians, degrees, atan, tan, sinh, log\n", |
10 | | - "from ipywidgets import Image, Output, IntSlider\n", |
11 | | - "from ipycanvas import Canvas, MultiCanvas\n", |
| 10 | + "\n", |
| 11 | + "from ipywidgets import Image, IntSlider\n", |
| 12 | + "\n", |
12 | 13 | "from ipyevents import Event\n", |
13 | | - "import asyncio" |
| 14 | + "\n", |
| 15 | + "from ipycanvas import Canvas, MultiCanvas, hold_canvas" |
14 | 16 | ] |
15 | 17 | }, |
16 | 18 | { |
|
19 | 21 | "metadata": {}, |
20 | 22 | "outputs": [], |
21 | 23 | "source": [ |
| 24 | + "import asyncio\n", |
| 25 | + "\n", |
22 | 26 | "class Timer:\n", |
23 | 27 | " def __init__(self, timeout, callback):\n", |
24 | 28 | " self._timeout = timeout\n", |
|
34 | 38 | "\n", |
35 | 39 | "def debounce(wait):\n", |
36 | 40 | " \"\"\" Decorator that will postpone a function's\n", |
37 | | - " execution until after wait seconds\n", |
| 41 | + " execution until after `wait` seconds\n", |
38 | 42 | " have elapsed since the last time it was invoked. \"\"\"\n", |
39 | 43 | " def decorator(fn):\n", |
| 44 | + " timer = None\n", |
40 | 45 | " def debounced(*args, **kwargs):\n", |
| 46 | + " nonlocal timer\n", |
41 | 47 | " def call_it():\n", |
42 | 48 | " fn(*args, **kwargs)\n", |
43 | | - " try:\n", |
44 | | - " debounced.t.cancel()\n", |
45 | | - " except(AttributeError):\n", |
46 | | - " pass\n", |
47 | | - " debounced.t = Timer(wait, call_it)\n", |
| 49 | + " if timer is not None:\n", |
| 50 | + " timer.cancel()\n", |
| 51 | + " timer = Timer(wait, call_it)\n", |
48 | 52 | " return debounced\n", |
49 | 53 | " return decorator" |
50 | 54 | ] |
|
150 | 154 | " return {'pix': xys, 'tile': xyn}" |
151 | 155 | ] |
152 | 156 | }, |
153 | | - { |
154 | | - "cell_type": "code", |
155 | | - "execution_count": null, |
156 | | - "metadata": {}, |
157 | | - "outputs": [], |
158 | | - "source": [ |
159 | | - "out = Output(layout={'border': '1px solid black'})" |
160 | | - ] |
161 | | - }, |
162 | 157 | { |
163 | 158 | "cell_type": "code", |
164 | 159 | "execution_count": null, |
|
184 | 179 | " self[1].on_mouse_move(self.mouse_move_handler)\n", |
185 | 180 | " self[1].on_mouse_up(self.mouse_up_handler)\n", |
186 | 181 | " self[1].on_mouse_out(self.mouse_out_handler)\n", |
187 | | - " \n", |
188 | | - " #@out.capture()\n", |
| 182 | + "\n", |
189 | 183 | " def show(self, lat=None, lon=None):\n", |
190 | 184 | " if lat is None:\n", |
191 | 185 | " lat = self.lat\n", |
192 | 186 | " if lon is None:\n", |
193 | 187 | " lon = self.lon\n", |
194 | 188 | " x, y = latlon2xy(lat, lon, self.z)\n", |
195 | 189 | " grid = get_tile_grid(x, y, self.width, self.height, self.tile_nb)\n", |
196 | | - " for i, row in enumerate(grid['pix']):\n", |
197 | | - " for j, col in enumerate(row):\n", |
198 | | - " dx, dy = col\n", |
199 | | - " x, y = grid['tile'][i][j]\n", |
200 | | - " url = f'https://tile.openstreetmap.org/{self.z}/{x}/{y}.png'\n", |
201 | | - " tile = Image.from_url(url)\n", |
202 | | - " self[0].draw_image(tile, dx, dy)\n", |
| 190 | + " \n", |
| 191 | + " with hold_canvas(self):\n", |
| 192 | + " self[0].fill_style = '#aad3df'\n", |
| 193 | + " self[0].fill_rect(0, 0, self.size[0], self.size[1])\n", |
| 194 | + "\n", |
| 195 | + " for i, row in enumerate(grid['pix']):\n", |
| 196 | + " for j, col in enumerate(row):\n", |
| 197 | + " dx, dy = col\n", |
| 198 | + " x, y = grid['tile'][i][j]\n", |
| 199 | + " url = f'https://tile.openstreetmap.org/{self.z}/{x}/{y}.png'\n", |
| 200 | + " tile = Image.from_url(url)\n", |
| 201 | + " self[0].draw_image(tile, dx, dy)\n", |
| 202 | + "\n", |
203 | 203 | " def mouse_down_handler(self, pixel_x, pixel_y):\n", |
204 | 204 | " self.dragging = True\n", |
205 | 205 | " self.x_mouse = pixel_x\n", |
|
237 | 237 | "m = Map(788, 788, 7, 49, 2)\n", |
238 | 238 | "m" |
239 | 239 | ] |
240 | | - }, |
241 | | - { |
242 | | - "cell_type": "code", |
243 | | - "execution_count": null, |
244 | | - "metadata": {}, |
245 | | - "outputs": [], |
246 | | - "source": [ |
247 | | - "d = Event(source=m, watched_events=['wheel'])\n", |
248 | | - "\n", |
249 | | - "@out.capture()\n", |
250 | | - "def zoom(event):\n", |
251 | | - " m.z -= event['deltaY'] // 3\n", |
252 | | - " m.z = max(m.z, 1)\n", |
253 | | - " m.z = min(m.z, 19)\n", |
254 | | - " print(m.z)\n", |
255 | | - " m.tile_nb = numTiles(m.z)\n", |
256 | | - " m.x, m.y = latlon2xy(m.lat, m.lon, m.z)\n", |
257 | | - " m.show()\n", |
258 | | - "\n", |
259 | | - "d.on_dom_event(zoom)" |
260 | | - ] |
261 | | - }, |
262 | | - { |
263 | | - "cell_type": "code", |
264 | | - "execution_count": null, |
265 | | - "metadata": {}, |
266 | | - "outputs": [], |
267 | | - "source": [ |
268 | | - "out" |
269 | | - ] |
270 | 240 | } |
271 | 241 | ], |
272 | 242 | "metadata": { |
|
0 commit comments