Skip to content

maplibre module

Map

Bases: AnyWidget

Create a MapLibre map widget.

Source code in mapwidget/maplibre.py
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
class Map(anywidget.AnyWidget):
    """Create a MapLibre map widget."""

    _cwd = os.path.dirname(os.path.abspath(__file__))
    _esm = pathlib.Path(os.path.join(_cwd, "js", "maplibre.js"))
    _css = pathlib.Path(os.path.join(_cwd, "css", "maplibre.css"))
    center = traitlets.List([0, 20]).tag(sync=True, o=True)
    zoom = traitlets.Float(2).tag(sync=True, o=True)
    bearing = traitlets.Float(0).tag(sync=True, o=True)
    pitch = traitlets.Float(0).tag(sync=True, o=True)
    bounds = traitlets.List([0, 0, 0, 0]).tag(sync=True, o=True)
    width = traitlets.Unicode("100%").tag(sync=True, o=True)
    height = traitlets.Unicode("600px").tag(sync=True, o=True)
    clicked_latlng = traitlets.List([None, None]).tag(sync=True, o=True)
    calls = traitlets.List(traitlets.Dict(), default_value=[]).tag(sync=True, o=True)
    view_state = traitlets.Dict().tag(sync=True)
    root = traitlets.Dict().tag(sync=True)
    sources = traitlets.Dict().tag(sync=True)
    loaded = traitlets.Bool(False).tag(sync=True)
    controls = traitlets.List(traitlets.Dict(), default_value=[]).tag(sync=True, o=True)
    style = traitlets.Any().tag(sync=True)

    # Draw-related traitlets
    draw_features_selected = traitlets.List(traitlets.Dict(), default_value=[]).tag(
        sync=True
    )
    draw_feature_collection_all = traitlets.Dict(
        default_value={"type": "FeatureCollection", "features": []}
    ).tag(sync=True)
    draw_features_created = traitlets.List(traitlets.Dict(), default_value=[]).tag(
        sync=True
    )
    draw_features_updated = traitlets.List(traitlets.Dict(), default_value=[]).tag(
        sync=True
    )
    draw_features_deleted = traitlets.List(traitlets.Dict(), default_value=[]).tag(
        sync=True
    )
    draw_repeat_mode = traitlets.Bool(False).tag(sync=True)

    def __init__(
        self,
        center=[0, 20],
        zoom=2,
        bearing=0,
        pitch=0,
        style="https://tiles.openfreemap.org/styles/liberty",
        controls=None,
        **kwargs,
    ):
        """Initialize the Map widget.

        Args:
            center: Initial center [lng, lat]. Defaults to [0, 20]
            zoom: Initial zoom level. Defaults to 2
            controls: List of controls to add by default. Defaults to ["navigation", "fullscreen", "globe"]
            **kwargs: Additional widget parameters
        """
        self._draw_control_request = None

        super().__init__(
            center=center,
            zoom=zoom,
            bearing=bearing,
            pitch=pitch,
            style=style,
            **kwargs,
        )

        # Store default controls to add after initialization
        self._default_controls = (
            controls if controls is not None else ["navigation", "fullscreen", "globe"]
        )

        # Add default controls after widget is ready
        self.observe(self._add_default_controls, names="loaded")

    def _add_default_controls(self, change):
        """Add default controls when the map is loaded."""
        if change["new"] and self._default_controls:
            for control in self._default_controls:
                self.add_control(control, "top-right")
            self._default_controls = []  # Clear to avoid re-adding

        if self._draw_control_request:
            self.add_call("addDrawControl", self._draw_control_request)
            self._draw_control_request = None

        if hasattr(self, "_pending_draw_mode"):
            for mode in self._pending_draw_mode:
                self.add_call("setDrawMode", [mode])
            del self._pending_draw_mode

        if hasattr(self, "_pending_legend"):
            for targets, options, position in self._pending_legend:
                self.add_call("addLegendControl", [targets, options, position])
            del self._pending_legend

        if hasattr(self, "_pending_opacity"):
            for (
                baseLayers,
                overLayers,
                options,
                position,
                defaultVisibility,
            ) in self._pending_opacity:
                self.add_call(
                    "addOpacityControl",
                    [baseLayers, overLayers, options, position, defaultVisibility],
                )
            del self._pending_opacity

    @property
    def layers(self):
        """Get the current style of the map."""
        return self.root.get("layers", [])

    @property
    def layer_names(self):
        """Get the names of the layers in the map."""
        return [layer["id"] for layer in self.layers]

    def add_call(self, method: str, args: list = None, kwargs: dict = None):
        """Invoke a JS map method with arguments."""
        if args is None:
            args = []
        if kwargs is None:
            kwargs = {}
        self.calls = self.calls + [{"method": method, "args": args, "kwargs": kwargs}]

    def set_center(self, lng: float, lat: float):
        """Set the center of the map."""
        self.add_call("setCenter", [[lng, lat]])

    def set_zoom(self, zoom: float):
        """Set the zoom level."""
        self.add_call("setZoom", [zoom])

    def pan_to(self, lng: float, lat: float):
        """Pan the map to a given location."""
        self.add_call("panTo", [[lng, lat]])

    def fly_to(self, center=None, zoom=None, bearing=None, pitch=None):
        """Fly to a given location with optional zoom, bearing, and pitch."""
        options = {}
        if center:
            options["center"] = center
        if zoom is not None:
            options["zoom"] = zoom
        if bearing is not None:
            options["bearing"] = bearing
        if pitch is not None:
            options["pitch"] = pitch
        self.add_call("flyTo", [options])

    def fit_bounds(self, bounds: list, options: dict = None):
        """Fit the map to given bounds [[west, south], [east, north]]."""
        args = [bounds]
        if options:
            args.append(options)
        self.add_call("fitBounds", args)

    def set_pitch(self, pitch: float):
        """Set the pitch of the map."""
        self.add_call("setPitch", [pitch])

    def set_bearing(self, bearing: float):
        """Set the bearing of the map."""
        self.add_call("setBearing", [bearing])

    def resize(self):
        """Trigger map resize."""
        self.add_call("resize")

    def add_source(self, source_id: str, source: dict):
        """Add a new source to the map."""
        self.add_call("addSource", [source_id, source])

    def remove_source(self, source_id: str):
        """Remove a source from the map."""
        self.add_call("removeSource", [source_id])

    def add_layer(self, layer: dict, before_id: str = None):
        """Add a new layer to the map."""
        args = [layer]
        if before_id:
            args.append(before_id)
        self.add_call("addLayer", args)

    def remove_layer(self, layer_id: str):
        """Remove a layer from the map."""
        self.add_call("removeLayer", [layer_id])

    def set_paint_property(self, layer_id: str, prop: str, value):
        """Set a paint property on a layer."""
        self.add_call("setPaintProperty", [layer_id, prop, value])

    def set_layout_property(self, layer_id: str, prop: str, value):
        """Set a layout property on a layer."""
        self.add_call("setLayoutProperty", [layer_id, prop, value])

    def set_filter(self, layer_id: str, filter_expr):
        """Set a filter expression on a layer."""
        self.add_call("setFilter", [layer_id, filter_expr])

    def set_style(self, style_url: str):
        """Set the map style."""
        self.add_call("setStyle", [style_url])

    def set_layer_visibility(self, layer_id: str, visibility: str):
        """Set visibility of a layer ('visible' or 'none')."""
        self.set_layout_property(layer_id, "visibility", visibility)

    def add_control(
        self, control_type: str, position: str = "top-right", options: dict = None
    ):
        """Add a control to the map.

        Args:
            control_type: Type of control to add. Options include:
                - 'navigation' or 'NavigationControl'
                - 'geolocate' or 'GeolocateControl'
                - 'scale' or 'ScaleControl'
                - 'fullscreen' or 'FullscreenControl'
                - 'attribution' or 'AttributionControl'
                - 'globe' or 'GlobeControl'
                - 'logo' or 'LogoControl'
                - 'terrain' or 'TerrainControl'
            position: Position on the map. Options: 'top-left', 'top-right', 'bottom-left', 'bottom-right'
            options: Optional configuration for the control
        """
        if options is None:
            options = {}
        self.add_call("addControl", [control_type, position, options])
        self.controls.append(
            {"type": control_type, "position": position, "options": options}
        )

    def remove_control(self, control_type: str):
        """Remove a control from the map.

        Args:
            control_type: The type of control to remove (e.g., 'navigation', 'fullscreen')
        """
        self.add_call("removeControl", [control_type])
        self.controls = [
            control for control in self.controls if control["type"] != control_type
        ]

    def add_draw_control(
        self,
        options: Optional[Dict[str, Any]] = None,
        controls: Optional[Dict[str, Any]] = None,
        position: str = "top-right",
        geojson: Optional[Dict[str, Any]] = None,
        **kwargs: Any,
    ) -> None:
        """
        Adds a drawing control to the map.

        This method enables users to add interactive drawing controls to the map,
        allowing for the creation, editing, and deletion of geometric shapes on
        the map. The options, position, and initial GeoJSON can be customized.

        Args:
            options (Optional[Dict[str, Any]]): Configuration options for the
                drawing control. Defaults to None.
            controls (Optional[Dict[str, Any]]): The drawing controls to enable.
                Can be one or more of the following: 'polygon', 'line_string',
                'point', 'trash', 'combine_features', 'uncombine_features'.
                Defaults to None.
            position (str): The position of the control on the map. Defaults
                to "top-right".
            geojson (Optional[Dict[str, Any]]): Initial GeoJSON data to load
                into the drawing control. Defaults to None.
            **kwargs (Any): Additional keyword arguments to be passed to the
                drawing control.

        Returns:
            None
        """
        if options is None:
            options = {}
        if controls is None:
            controls = {}

        # Merge kwargs into options
        options.update(kwargs)

        if self.loaded:
            self.add_call("addDrawControl", [options, controls, position, geojson])
        else:
            self._draw_control_request = [options, controls, position, geojson]

    def remove_draw_control(self) -> None:
        """
        Removes the drawing control from the map.

        This method removes the drawing control and clears all associated
        draw features from the map and model.

        Returns:
            None
        """
        self.add_call("removeDrawControl")

    def draw_features_delete_all(self) -> None:
        """
        Deletes all features from the drawing control.

        This method removes all drawn features from the map and updates
        the model accordingly.

        Returns:
            None
        """
        self.add_call("drawFeaturesDeleteAll")

    def add_legend(
        self,
        targets: Dict[str, str],
        options: Optional[Dict[str, Any]] = None,
        position: str = "top-right",
    ) -> None:
        """
        Adds a legend control to the map using mapbox-gl-legend plugin.

        Args:
            targets (Dict[str, str]): A dictionary mapping layer IDs to display names
            options (Optional[Dict[str, Any]]): Configuration options for the legend control.
                Available options:
                - showDefault (bool): Whether to show default legend. Defaults to False.
                - showCheckbox (bool): Whether to show checkboxes. Defaults to False.
                - onlyRendered (bool): Whether to show only rendered layers. Defaults to True.
                - reverseOrder (bool): Whether to reverse the order. Defaults to True.
            position (str): The position of the control on the map. Defaults to "top-right".

        Returns:
            None
        """
        if options is None:
            options = {
                "showDefault": False,
                "showCheckbox": False,
                "onlyRendered": True,
                "reverseOrder": True,
            }

        if self.loaded:
            self.add_call("addLegendControl", [targets, options, position])
        else:
            if not hasattr(self, "_pending_legend"):
                self._pending_legend = []
            self._pending_legend.append((targets, options, position))

    def set_draw_mode(self, mode: str):
        """Set the drawing mode, even if the map is not yet loaded."""
        if self.loaded:
            self.add_call("setDrawMode", [mode])
        else:
            if not hasattr(self, "_pending_draw_mode"):
                self._pending_draw_mode = []
            self._pending_draw_mode.append(mode)

    def add_opacity_control(
        self,
        base_layers: Optional[Dict[str, str]] = None,
        over_layers: Optional[Dict[str, str]] = None,
        options: Optional[Dict[str, Any]] = None,
        position: str = "top-right",
        default_visibility: Optional[Dict[str, bool]] = None,
        collapsible: bool = False,
    ) -> None:
        """
        Adds an opacity control to the map using maplibre-gl-opacity plugin.

        This control allows users to adjust the opacity of multiple tile layers
        and switch between base layers and overlays.

        Args:
            base_layers (Optional[Dict[str, str]]): A dictionary mapping base layer IDs
                to display names. Only one base layer can be visible at a time.
            over_layers (Optional[Dict[str, str]]): A dictionary mapping overlay layer IDs
                to display names. Multiple overlays can be visible simultaneously.
            options (Optional[Dict[str, Any]]): Configuration options for the opacity control.
                Available options:
                - opacityControl (bool): Whether to show opacity sliders. Defaults to True.
            position (str): The position of the control on the map. Defaults to "top-right".
            default_visibility (Optional[Dict[str, bool]]): A dictionary mapping layer IDs
                to their default visibility state. If not specified, overlay layers will
                be visible by default and base layers will follow the first-wins rule.
            collapsible (bool): Whether to add a toggle button to show/hide the control.
                Defaults to False.

        Returns:
            None

        Example:
            ```python
            # Define base layers (mutually exclusive)
            base_layers = {
                "osm": "OpenStreetMap",
                "satellite": "Satellite"
            }

            # Define overlay layers (can be combined)
            over_layers = {
                "roads": "Roads",
                "labels": "Labels"
            }

            # Control which layers are visible by default
            default_visibility = {
                "osm": True,        # Base layer visible
                "roads": True,      # Overlay visible
                "labels": False     # Overlay hidden
            }

            m.add_opacity_control(
                base_layers=base_layers,
                over_layers=over_layers,
                default_visibility=default_visibility,
                collapsible=True,  # Add toggle button
                position="top-left"
            )
            ```
        """
        if base_layers is None:
            base_layers = {}
        if over_layers is None:
            over_layers = {}
        if options is None:
            options = {"opacityControl": True}
        if default_visibility is None:
            default_visibility = {}

        # Add collapsible option to the options dict
        if collapsible:
            options["collapsible"] = True

        if self.loaded:
            self.add_call(
                "addOpacityControl",
                [base_layers, over_layers, options, position, default_visibility],
            )
        else:
            if not hasattr(self, "_pending_opacity"):
                self._pending_opacity = []
            self._pending_opacity.append(
                (base_layers, over_layers, options, position, default_visibility)
            )

layer_names property

Get the names of the layers in the map.

layers property

Get the current style of the map.

__init__(center=[0, 20], zoom=2, bearing=0, pitch=0, style='https://tiles.openfreemap.org/styles/liberty', controls=None, **kwargs)

Initialize the Map widget.

Parameters:

Name Type Description Default
center

Initial center [lng, lat]. Defaults to [0, 20]

[0, 20]
zoom

Initial zoom level. Defaults to 2

2
controls

List of controls to add by default. Defaults to ["navigation", "fullscreen", "globe"]

None
**kwargs

Additional widget parameters

{}
Source code in mapwidget/maplibre.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def __init__(
    self,
    center=[0, 20],
    zoom=2,
    bearing=0,
    pitch=0,
    style="https://tiles.openfreemap.org/styles/liberty",
    controls=None,
    **kwargs,
):
    """Initialize the Map widget.

    Args:
        center: Initial center [lng, lat]. Defaults to [0, 20]
        zoom: Initial zoom level. Defaults to 2
        controls: List of controls to add by default. Defaults to ["navigation", "fullscreen", "globe"]
        **kwargs: Additional widget parameters
    """
    self._draw_control_request = None

    super().__init__(
        center=center,
        zoom=zoom,
        bearing=bearing,
        pitch=pitch,
        style=style,
        **kwargs,
    )

    # Store default controls to add after initialization
    self._default_controls = (
        controls if controls is not None else ["navigation", "fullscreen", "globe"]
    )

    # Add default controls after widget is ready
    self.observe(self._add_default_controls, names="loaded")

add_call(method, args=None, kwargs=None)

Invoke a JS map method with arguments.

Source code in mapwidget/maplibre.py
131
132
133
134
135
136
137
def add_call(self, method: str, args: list = None, kwargs: dict = None):
    """Invoke a JS map method with arguments."""
    if args is None:
        args = []
    if kwargs is None:
        kwargs = {}
    self.calls = self.calls + [{"method": method, "args": args, "kwargs": kwargs}]

add_control(control_type, position='top-right', options=None)

Add a control to the map.

Parameters:

Name Type Description Default
control_type str

Type of control to add. Options include: - 'navigation' or 'NavigationControl' - 'geolocate' or 'GeolocateControl' - 'scale' or 'ScaleControl' - 'fullscreen' or 'FullscreenControl' - 'attribution' or 'AttributionControl' - 'globe' or 'GlobeControl' - 'logo' or 'LogoControl' - 'terrain' or 'TerrainControl'

required
position str

Position on the map. Options: 'top-left', 'top-right', 'bottom-left', 'bottom-right'

'top-right'
options dict

Optional configuration for the control

None
Source code in mapwidget/maplibre.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
def add_control(
    self, control_type: str, position: str = "top-right", options: dict = None
):
    """Add a control to the map.

    Args:
        control_type: Type of control to add. Options include:
            - 'navigation' or 'NavigationControl'
            - 'geolocate' or 'GeolocateControl'
            - 'scale' or 'ScaleControl'
            - 'fullscreen' or 'FullscreenControl'
            - 'attribution' or 'AttributionControl'
            - 'globe' or 'GlobeControl'
            - 'logo' or 'LogoControl'
            - 'terrain' or 'TerrainControl'
        position: Position on the map. Options: 'top-left', 'top-right', 'bottom-left', 'bottom-right'
        options: Optional configuration for the control
    """
    if options is None:
        options = {}
    self.add_call("addControl", [control_type, position, options])
    self.controls.append(
        {"type": control_type, "position": position, "options": options}
    )

add_draw_control(options=None, controls=None, position='top-right', geojson=None, **kwargs)

Adds a drawing control to the map.

This method enables users to add interactive drawing controls to the map, allowing for the creation, editing, and deletion of geometric shapes on the map. The options, position, and initial GeoJSON can be customized.

Parameters:

Name Type Description Default
options Optional[Dict[str, Any]]

Configuration options for the drawing control. Defaults to None.

None
controls Optional[Dict[str, Any]]

The drawing controls to enable. Can be one or more of the following: 'polygon', 'line_string', 'point', 'trash', 'combine_features', 'uncombine_features'. Defaults to None.

None
position str

The position of the control on the map. Defaults to "top-right".

'top-right'
geojson Optional[Dict[str, Any]]

Initial GeoJSON data to load into the drawing control. Defaults to None.

None
**kwargs Any

Additional keyword arguments to be passed to the drawing control.

{}

Returns:

Type Description
None

None

Source code in mapwidget/maplibre.py
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def add_draw_control(
    self,
    options: Optional[Dict[str, Any]] = None,
    controls: Optional[Dict[str, Any]] = None,
    position: str = "top-right",
    geojson: Optional[Dict[str, Any]] = None,
    **kwargs: Any,
) -> None:
    """
    Adds a drawing control to the map.

    This method enables users to add interactive drawing controls to the map,
    allowing for the creation, editing, and deletion of geometric shapes on
    the map. The options, position, and initial GeoJSON can be customized.

    Args:
        options (Optional[Dict[str, Any]]): Configuration options for the
            drawing control. Defaults to None.
        controls (Optional[Dict[str, Any]]): The drawing controls to enable.
            Can be one or more of the following: 'polygon', 'line_string',
            'point', 'trash', 'combine_features', 'uncombine_features'.
            Defaults to None.
        position (str): The position of the control on the map. Defaults
            to "top-right".
        geojson (Optional[Dict[str, Any]]): Initial GeoJSON data to load
            into the drawing control. Defaults to None.
        **kwargs (Any): Additional keyword arguments to be passed to the
            drawing control.

    Returns:
        None
    """
    if options is None:
        options = {}
    if controls is None:
        controls = {}

    # Merge kwargs into options
    options.update(kwargs)

    if self.loaded:
        self.add_call("addDrawControl", [options, controls, position, geojson])
    else:
        self._draw_control_request = [options, controls, position, geojson]

add_layer(layer, before_id=None)

Add a new layer to the map.

Source code in mapwidget/maplibre.py
191
192
193
194
195
196
def add_layer(self, layer: dict, before_id: str = None):
    """Add a new layer to the map."""
    args = [layer]
    if before_id:
        args.append(before_id)
    self.add_call("addLayer", args)

add_legend(targets, options=None, position='top-right')

Adds a legend control to the map using mapbox-gl-legend plugin.

Parameters:

Name Type Description Default
targets Dict[str, str]

A dictionary mapping layer IDs to display names

required
options Optional[Dict[str, Any]]

Configuration options for the legend control. Available options: - showDefault (bool): Whether to show default legend. Defaults to False. - showCheckbox (bool): Whether to show checkboxes. Defaults to False. - onlyRendered (bool): Whether to show only rendered layers. Defaults to True. - reverseOrder (bool): Whether to reverse the order. Defaults to True.

None
position str

The position of the control on the map. Defaults to "top-right".

'top-right'

Returns:

Type Description
None

None

Source code in mapwidget/maplibre.py
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
def add_legend(
    self,
    targets: Dict[str, str],
    options: Optional[Dict[str, Any]] = None,
    position: str = "top-right",
) -> None:
    """
    Adds a legend control to the map using mapbox-gl-legend plugin.

    Args:
        targets (Dict[str, str]): A dictionary mapping layer IDs to display names
        options (Optional[Dict[str, Any]]): Configuration options for the legend control.
            Available options:
            - showDefault (bool): Whether to show default legend. Defaults to False.
            - showCheckbox (bool): Whether to show checkboxes. Defaults to False.
            - onlyRendered (bool): Whether to show only rendered layers. Defaults to True.
            - reverseOrder (bool): Whether to reverse the order. Defaults to True.
        position (str): The position of the control on the map. Defaults to "top-right".

    Returns:
        None
    """
    if options is None:
        options = {
            "showDefault": False,
            "showCheckbox": False,
            "onlyRendered": True,
            "reverseOrder": True,
        }

    if self.loaded:
        self.add_call("addLegendControl", [targets, options, position])
    else:
        if not hasattr(self, "_pending_legend"):
            self._pending_legend = []
        self._pending_legend.append((targets, options, position))

add_opacity_control(base_layers=None, over_layers=None, options=None, position='top-right', default_visibility=None, collapsible=False)

Adds an opacity control to the map using maplibre-gl-opacity plugin.

This control allows users to adjust the opacity of multiple tile layers and switch between base layers and overlays.

Parameters:

Name Type Description Default
base_layers Optional[Dict[str, str]]

A dictionary mapping base layer IDs to display names. Only one base layer can be visible at a time.

None
over_layers Optional[Dict[str, str]]

A dictionary mapping overlay layer IDs to display names. Multiple overlays can be visible simultaneously.

None
options Optional[Dict[str, Any]]

Configuration options for the opacity control. Available options: - opacityControl (bool): Whether to show opacity sliders. Defaults to True.

None
position str

The position of the control on the map. Defaults to "top-right".

'top-right'
default_visibility Optional[Dict[str, bool]]

A dictionary mapping layer IDs to their default visibility state. If not specified, overlay layers will be visible by default and base layers will follow the first-wins rule.

None
collapsible bool

Whether to add a toggle button to show/hide the control. Defaults to False.

False

Returns:

Type Description
None

None

Example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Define base layers (mutually exclusive)
base_layers = {
    "osm": "OpenStreetMap",
    "satellite": "Satellite"
}

# Define overlay layers (can be combined)
over_layers = {
    "roads": "Roads",
    "labels": "Labels"
}

# Control which layers are visible by default
default_visibility = {
    "osm": True,        # Base layer visible
    "roads": True,      # Overlay visible
    "labels": False     # Overlay hidden
}

m.add_opacity_control(
    base_layers=base_layers,
    over_layers=over_layers,
    default_visibility=default_visibility,
    collapsible=True,  # Add toggle button
    position="top-left"
)
Source code in mapwidget/maplibre.py
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
def add_opacity_control(
    self,
    base_layers: Optional[Dict[str, str]] = None,
    over_layers: Optional[Dict[str, str]] = None,
    options: Optional[Dict[str, Any]] = None,
    position: str = "top-right",
    default_visibility: Optional[Dict[str, bool]] = None,
    collapsible: bool = False,
) -> None:
    """
    Adds an opacity control to the map using maplibre-gl-opacity plugin.

    This control allows users to adjust the opacity of multiple tile layers
    and switch between base layers and overlays.

    Args:
        base_layers (Optional[Dict[str, str]]): A dictionary mapping base layer IDs
            to display names. Only one base layer can be visible at a time.
        over_layers (Optional[Dict[str, str]]): A dictionary mapping overlay layer IDs
            to display names. Multiple overlays can be visible simultaneously.
        options (Optional[Dict[str, Any]]): Configuration options for the opacity control.
            Available options:
            - opacityControl (bool): Whether to show opacity sliders. Defaults to True.
        position (str): The position of the control on the map. Defaults to "top-right".
        default_visibility (Optional[Dict[str, bool]]): A dictionary mapping layer IDs
            to their default visibility state. If not specified, overlay layers will
            be visible by default and base layers will follow the first-wins rule.
        collapsible (bool): Whether to add a toggle button to show/hide the control.
            Defaults to False.

    Returns:
        None

    Example:
        ```python
        # Define base layers (mutually exclusive)
        base_layers = {
            "osm": "OpenStreetMap",
            "satellite": "Satellite"
        }

        # Define overlay layers (can be combined)
        over_layers = {
            "roads": "Roads",
            "labels": "Labels"
        }

        # Control which layers are visible by default
        default_visibility = {
            "osm": True,        # Base layer visible
            "roads": True,      # Overlay visible
            "labels": False     # Overlay hidden
        }

        m.add_opacity_control(
            base_layers=base_layers,
            over_layers=over_layers,
            default_visibility=default_visibility,
            collapsible=True,  # Add toggle button
            position="top-left"
        )
        ```
    """
    if base_layers is None:
        base_layers = {}
    if over_layers is None:
        over_layers = {}
    if options is None:
        options = {"opacityControl": True}
    if default_visibility is None:
        default_visibility = {}

    # Add collapsible option to the options dict
    if collapsible:
        options["collapsible"] = True

    if self.loaded:
        self.add_call(
            "addOpacityControl",
            [base_layers, over_layers, options, position, default_visibility],
        )
    else:
        if not hasattr(self, "_pending_opacity"):
            self._pending_opacity = []
        self._pending_opacity.append(
            (base_layers, over_layers, options, position, default_visibility)
        )

add_source(source_id, source)

Add a new source to the map.

Source code in mapwidget/maplibre.py
183
184
185
def add_source(self, source_id: str, source: dict):
    """Add a new source to the map."""
    self.add_call("addSource", [source_id, source])

draw_features_delete_all()

Deletes all features from the drawing control.

This method removes all drawn features from the map and updates the model accordingly.

Returns:

Type Description
None

None

Source code in mapwidget/maplibre.py
315
316
317
318
319
320
321
322
323
324
325
def draw_features_delete_all(self) -> None:
    """
    Deletes all features from the drawing control.

    This method removes all drawn features from the map and updates
    the model accordingly.

    Returns:
        None
    """
    self.add_call("drawFeaturesDeleteAll")

fit_bounds(bounds, options=None)

Fit the map to given bounds [[west, south], [east, north]].

Source code in mapwidget/maplibre.py
164
165
166
167
168
169
def fit_bounds(self, bounds: list, options: dict = None):
    """Fit the map to given bounds [[west, south], [east, north]]."""
    args = [bounds]
    if options:
        args.append(options)
    self.add_call("fitBounds", args)

fly_to(center=None, zoom=None, bearing=None, pitch=None)

Fly to a given location with optional zoom, bearing, and pitch.

Source code in mapwidget/maplibre.py
151
152
153
154
155
156
157
158
159
160
161
162
def fly_to(self, center=None, zoom=None, bearing=None, pitch=None):
    """Fly to a given location with optional zoom, bearing, and pitch."""
    options = {}
    if center:
        options["center"] = center
    if zoom is not None:
        options["zoom"] = zoom
    if bearing is not None:
        options["bearing"] = bearing
    if pitch is not None:
        options["pitch"] = pitch
    self.add_call("flyTo", [options])

pan_to(lng, lat)

Pan the map to a given location.

Source code in mapwidget/maplibre.py
147
148
149
def pan_to(self, lng: float, lat: float):
    """Pan the map to a given location."""
    self.add_call("panTo", [[lng, lat]])

remove_control(control_type)

Remove a control from the map.

Parameters:

Name Type Description Default
control_type str

The type of control to remove (e.g., 'navigation', 'fullscreen')

required
Source code in mapwidget/maplibre.py
247
248
249
250
251
252
253
254
255
256
def remove_control(self, control_type: str):
    """Remove a control from the map.

    Args:
        control_type: The type of control to remove (e.g., 'navigation', 'fullscreen')
    """
    self.add_call("removeControl", [control_type])
    self.controls = [
        control for control in self.controls if control["type"] != control_type
    ]

remove_draw_control()

Removes the drawing control from the map.

This method removes the drawing control and clears all associated draw features from the map and model.

Returns:

Type Description
None

None

Source code in mapwidget/maplibre.py
303
304
305
306
307
308
309
310
311
312
313
def remove_draw_control(self) -> None:
    """
    Removes the drawing control from the map.

    This method removes the drawing control and clears all associated
    draw features from the map and model.

    Returns:
        None
    """
    self.add_call("removeDrawControl")

remove_layer(layer_id)

Remove a layer from the map.

Source code in mapwidget/maplibre.py
198
199
200
def remove_layer(self, layer_id: str):
    """Remove a layer from the map."""
    self.add_call("removeLayer", [layer_id])

remove_source(source_id)

Remove a source from the map.

Source code in mapwidget/maplibre.py
187
188
189
def remove_source(self, source_id: str):
    """Remove a source from the map."""
    self.add_call("removeSource", [source_id])

resize()

Trigger map resize.

Source code in mapwidget/maplibre.py
179
180
181
def resize(self):
    """Trigger map resize."""
    self.add_call("resize")

set_bearing(bearing)

Set the bearing of the map.

Source code in mapwidget/maplibre.py
175
176
177
def set_bearing(self, bearing: float):
    """Set the bearing of the map."""
    self.add_call("setBearing", [bearing])

set_center(lng, lat)

Set the center of the map.

Source code in mapwidget/maplibre.py
139
140
141
def set_center(self, lng: float, lat: float):
    """Set the center of the map."""
    self.add_call("setCenter", [[lng, lat]])

set_draw_mode(mode)

Set the drawing mode, even if the map is not yet loaded.

Source code in mapwidget/maplibre.py
364
365
366
367
368
369
370
371
def set_draw_mode(self, mode: str):
    """Set the drawing mode, even if the map is not yet loaded."""
    if self.loaded:
        self.add_call("setDrawMode", [mode])
    else:
        if not hasattr(self, "_pending_draw_mode"):
            self._pending_draw_mode = []
        self._pending_draw_mode.append(mode)

set_filter(layer_id, filter_expr)

Set a filter expression on a layer.

Source code in mapwidget/maplibre.py
210
211
212
def set_filter(self, layer_id: str, filter_expr):
    """Set a filter expression on a layer."""
    self.add_call("setFilter", [layer_id, filter_expr])

set_layer_visibility(layer_id, visibility)

Set visibility of a layer ('visible' or 'none').

Source code in mapwidget/maplibre.py
218
219
220
def set_layer_visibility(self, layer_id: str, visibility: str):
    """Set visibility of a layer ('visible' or 'none')."""
    self.set_layout_property(layer_id, "visibility", visibility)

set_layout_property(layer_id, prop, value)

Set a layout property on a layer.

Source code in mapwidget/maplibre.py
206
207
208
def set_layout_property(self, layer_id: str, prop: str, value):
    """Set a layout property on a layer."""
    self.add_call("setLayoutProperty", [layer_id, prop, value])

set_paint_property(layer_id, prop, value)

Set a paint property on a layer.

Source code in mapwidget/maplibre.py
202
203
204
def set_paint_property(self, layer_id: str, prop: str, value):
    """Set a paint property on a layer."""
    self.add_call("setPaintProperty", [layer_id, prop, value])

set_pitch(pitch)

Set the pitch of the map.

Source code in mapwidget/maplibre.py
171
172
173
def set_pitch(self, pitch: float):
    """Set the pitch of the map."""
    self.add_call("setPitch", [pitch])

set_style(style_url)

Set the map style.

Source code in mapwidget/maplibre.py
214
215
216
def set_style(self, style_url: str):
    """Set the map style."""
    self.add_call("setStyle", [style_url])

set_zoom(zoom)

Set the zoom level.

Source code in mapwidget/maplibre.py
143
144
145
def set_zoom(self, zoom: float):
    """Set the zoom level."""
    self.add_call("setZoom", [zoom])