leaflet.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import logging
  2. from typing import Tuple
  3. from nicegui import ui
  4. class map(ui.card):
  5. def __init__(self) -> None:
  6. super().__init__()
  7. self.classes('osm-map').style('width:100%;height:300px')
  8. self.add_leaflet_js()
  9. async def set_location(self, location: Tuple[float, float]) -> None:
  10. print(location, flush=True)
  11. try:
  12. await ui.run_javascript(f'''
  13. window.target = L.latLng("{location[0]}", "{location[1]}");
  14. window.map.setView(target, 9);
  15. if (window.marker != undefined) window.map.removeLayer(window.marker);
  16. window.marker = L.marker(target);
  17. window.marker.addTo(window.map);
  18. ''', respond=False)
  19. except:
  20. logging.exception(f'could not update {location}')
  21. @staticmethod
  22. def add_leaflet_js():
  23. ui.add_head_html(r'''
  24. <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
  25. <link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>
  26. <script>
  27. function waitForElm(selector) {
  28. return new Promise(resolve => {
  29. if (document.querySelector(selector)) {
  30. return resolve(document.querySelector(selector));
  31. }
  32. const observer = new MutationObserver(mutations => {
  33. if (document.querySelector(selector)) {
  34. resolve(document.querySelector(selector));
  35. observer.disconnect();
  36. }
  37. });
  38. observer.observe(document.body, {
  39. childList: true,
  40. subtree: true,
  41. });
  42. });
  43. }
  44. document.addEventListener("DOMContentLoaded", function() {
  45. waitForElm('.osm-map').then((container) => {
  46. window.map = L.map(container);
  47. L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  48. attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  49. }).addTo(window.map);
  50. });
  51. });
  52. </script>
  53. ''')