1
0

leaflet_documentation.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from nicegui import ui
  2. from . import doc
  3. @doc.demo(ui.leaflet)
  4. def main_demo() -> None:
  5. m = ui.leaflet(center=(51.505, -0.09))
  6. ui.label().bind_text_from(m, 'center', lambda center: f'Center: {center[0]:.3f}, {center[1]:.3f}')
  7. ui.label().bind_text_from(m, 'zoom', lambda zoom: f'Zoom: {zoom}')
  8. with ui.grid(columns=2):
  9. ui.button('London', on_click=lambda: m.set_center((51.505, -0.090)))
  10. ui.button('Berlin', on_click=lambda: m.set_center((52.520, 13.405)))
  11. ui.button(icon='zoom_in', on_click=lambda: m.set_zoom(m.zoom + 1))
  12. ui.button(icon='zoom_out', on_click=lambda: m.set_zoom(m.zoom - 1))
  13. @doc.demo('Changing the Map Style', '''
  14. The default map style is OpenStreetMap.
  15. You can find more map styles at <https://leaflet-extras.github.io/leaflet-providers/preview/>.
  16. Each call to `tile_layer` stacks upon the previous ones.
  17. So if you want to change the map style, you have to remove the default one first.
  18. ''')
  19. def map_style() -> None:
  20. m = ui.leaflet(center=(51.505, -0.090), zoom=3)
  21. m.clear_layers()
  22. m.tile_layer(
  23. url_template=r'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
  24. options={
  25. 'maxZoom': 17,
  26. 'attribution':
  27. 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="https://viewfinderpanoramas.org/">SRTM</a> | '
  28. 'Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
  29. },
  30. )
  31. @doc.demo('Add Markers on Click', '''
  32. You can add markers to the map with `marker`.
  33. The `center` argument is a tuple of latitude and longitude.
  34. This demo adds markers by clicking on the map.
  35. Note that the "map-click" event refers to the click event of the map object,
  36. while the "click" event refers to the click event of the container div.
  37. ''')
  38. def markers() -> None:
  39. from nicegui import events
  40. m = ui.leaflet(center=(51.505, -0.09))
  41. def handle_click(e: events.GenericEventArguments):
  42. lat = e.args['latlng']['lat']
  43. lng = e.args['latlng']['lng']
  44. m.marker(latlng=(lat, lng))
  45. m.on('map-click', handle_click)
  46. @doc.demo('Move Markers', '''
  47. You can move markers with the `move` method.
  48. ''')
  49. def move_markers() -> None:
  50. m = ui.leaflet(center=(51.505, -0.09))
  51. marker = m.marker(latlng=m.center)
  52. ui.button('Move marker', on_click=lambda: marker.move(51.51, -0.09))
  53. @doc.demo('Vector Layers', '''
  54. Leaflet supports a set of [vector layers](https://leafletjs.com/reference.html#:~:text=VideoOverlay-,Vector%20Layers,-Path) like circle, polygon etc.
  55. These can be added with the `generic_layer` method.
  56. We are happy to review any pull requests to add more specific layers to simplify usage.
  57. ''')
  58. def vector_layers() -> None:
  59. m = ui.leaflet(center=(51.505, -0.09)).classes('h-32')
  60. m.generic_layer(name='circle', args=[m.center, {'color': 'red', 'radius': 300}])
  61. @doc.demo('Disable Pan and Zoom', '''
  62. There are [several options to configure the map in Leaflet](https://leafletjs.com/reference.html#map).
  63. This demo disables the pan and zoom controls.
  64. ''')
  65. def disable_pan_zoom() -> None:
  66. options = {
  67. 'zoomControl': False,
  68. 'scrollWheelZoom': False,
  69. 'doubleClickZoom': False,
  70. 'boxZoom': False,
  71. 'keyboard': False,
  72. 'dragging': False,
  73. }
  74. ui.leaflet(center=(51.505, -0.09), options=options)
  75. @doc.demo('Draw on Map', '''
  76. You can enable a toolbar to draw on the map.
  77. The `draw_control` can be used to configure the toolbar.
  78. This demo adds markers and polygons by clicking on the map.
  79. ''')
  80. def draw_on_map() -> None:
  81. from nicegui import events
  82. def handle_draw(e: events.GenericEventArguments):
  83. if e.args['layerType'] == 'marker':
  84. m.marker(latlng=(e.args['layer']['_latlng']['lat'],
  85. e.args['layer']['_latlng']['lng']))
  86. if e.args['layerType'] == 'polygon':
  87. m.generic_layer(name='polygon', args=[e.args['layer']['_latlngs']])
  88. draw_control = {
  89. 'draw': {
  90. 'polygon': True,
  91. 'marker': True,
  92. 'circle': False,
  93. 'rectangle': False,
  94. 'polyline': False,
  95. 'circlemarker': False,
  96. },
  97. 'edit': False,
  98. }
  99. m = ui.leaflet(center=(51.505, -0.09), zoom=13, draw_control=draw_control)
  100. m.on('draw:created', handle_draw)
  101. @doc.demo('Run Map Methods', '''
  102. You can run methods of the Leaflet map object with `run_map_method`.
  103. This demo shows how to fit the map to the whole world.
  104. ''')
  105. def run_map_methods() -> None:
  106. m = ui.leaflet(center=(51.505, -0.09)).classes('h-32')
  107. ui.button('Fit world', on_click=lambda: m.run_map_method('fitWorld'))
  108. @doc.demo('Run Layer Methods', '''
  109. You can run methods of the Leaflet layer objects with `run_layer_method`.
  110. This demo shows how to change the opacity of a marker or change its icon.
  111. ''')
  112. def run_layer_methods() -> None:
  113. m = ui.leaflet(center=(51.505, -0.09)).classes('h-32')
  114. marker = m.marker(latlng=m.center)
  115. ui.button('Hide', on_click=lambda: marker.run_method('setOpacity', 0.3))
  116. ui.button('Show', on_click=lambda: marker.run_method('setOpacity', 1.0))
  117. icon = 'L.icon({iconUrl: "https://leafletjs.com/examples/custom-icons/leaf-green.png"})'
  118. ui.button('Change icon', on_click=lambda: marker.run_method(':setIcon', icon))
  119. @doc.demo('Wait for Initialization', '''
  120. You can wait for the map to be initialized with the `initialized` method.
  121. This is necessary when you want to run methods like fitting the bounds of the map right after the map is created.
  122. ''')
  123. async def wait_for_init() -> None:
  124. m = ui.leaflet(zoom=5)
  125. central_park = m.generic_layer(name='polygon', args=[[
  126. (40.767809, -73.981249),
  127. (40.800273, -73.958291),
  128. (40.797011, -73.949683),
  129. (40.764704, -73.973741),
  130. ]])
  131. await m.initialized()
  132. bounds = await central_park.run_method('getBounds')
  133. m.run_map_method('fitBounds', [[bounds['_southWest'], bounds['_northEast']]])
  134. doc.reference(ui.leaflet)