MapLibreLayer Control¶
This notebook demonstrates the fixed layer control implementation that:
- Shows immediately after map initialization
- Groups background layers as "Background Map"
- Dynamically updates when new layers are added
- Properly syncs with programmatic changes
In [1]:
Copied!
from anymap.maplibre import MapLibreMap
from anymap.maplibre import MapLibreMap
1. Create Map with Immediate Layer Control¶
The layer control now shows up immediately after map initialization, displaying the "Background Map" control even when no user layers are present.
In [2]:
Copied!
# Create map with default style
m = MapLibreMap(center=[-122.4307025, 37.780538], zoom=12, style="dark-matter")
# Add layer control - should show immediately with Background
m.add_layer_control(position="top-right", collapsed=True)
m
# Create map with default style
m = MapLibreMap(center=[-122.4307025, 37.780538], zoom=12, style="dark-matter")
# Add layer control - should show immediately with Background
m.add_layer_control(position="top-right", collapsed=True)
m
Out[2]:
2. Dynamic Layer Addition¶
New layers are now automatically detected and added to the layer control panel.
In [3]:
Copied!
# Add a test point layer - should appear in layer control automatically
point_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "San Francisco"},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4294, 37.7849]},
"properties": {"name": "Point 2"},
},
],
}
layer_config = {
"id": "test-points",
"type": "circle",
"source": {"type": "geojson", "data": point_data},
"paint": {
"circle-radius": 8,
"circle-color": "#FF0000",
"circle-stroke-color": "#FFFFFF",
"circle-stroke-width": 2,
},
}
m.add_layer("test-points", layer_config)
print(
"Added test-points layer. Check the layer control - it should now show both 'Background' and 'test-points'."
)
# Add a test point layer - should appear in layer control automatically
point_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "San Francisco"},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4294, 37.7849]},
"properties": {"name": "Point 2"},
},
],
}
layer_config = {
"id": "test-points",
"type": "circle",
"source": {"type": "geojson", "data": point_data},
"paint": {
"circle-radius": 8,
"circle-color": "#FF0000",
"circle-stroke-color": "#FFFFFF",
"circle-stroke-width": 2,
},
}
m.add_layer("test-points", layer_config)
print(
"Added test-points layer. Check the layer control - it should now show both 'Background' and 'test-points'."
)
Added test-points layer. Check the layer control - it should now show both 'Background' and 'test-points'.
3. Add Multiple Layers¶
All new layers are automatically added to the control panel.
In [4]:
Copied!
# Add a polygon layer
polygon_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.43, 37.77],
[-122.43, 37.78],
[-122.42, 37.78],
[-122.42, 37.77],
[-122.43, 37.77],
]
],
},
"properties": {"name": "Test Area"},
}
],
}
polygon_layer_config = {
"id": "test-polygon",
"type": "fill",
"source": {"type": "geojson", "data": polygon_data},
"paint": {"fill-color": "#00FF00", "fill-opacity": 0.5},
}
m.add_layer("test-polygon", polygon_layer_config)
# Add a line layer
line_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-122.45, 37.77], [-122.44, 37.78], [-122.43, 37.79]],
},
"properties": {"name": "Test Route"},
}
],
}
line_layer_config = {
"id": "test-line",
"type": "line",
"source": {"type": "geojson", "data": line_data},
"paint": {"line-color": "#0000FF", "line-width": 3},
}
m.add_layer("test-line", line_layer_config)
print(
"Added test-polygon and test-line layers. Layer control should now show all 4 items:"
)
print("- Background")
print("- test-points")
print("- test-polygon")
print("- test-line")
# Add a polygon layer
polygon_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.43, 37.77],
[-122.43, 37.78],
[-122.42, 37.78],
[-122.42, 37.77],
[-122.43, 37.77],
]
],
},
"properties": {"name": "Test Area"},
}
],
}
polygon_layer_config = {
"id": "test-polygon",
"type": "fill",
"source": {"type": "geojson", "data": polygon_data},
"paint": {"fill-color": "#00FF00", "fill-opacity": 0.5},
}
m.add_layer("test-polygon", polygon_layer_config)
# Add a line layer
line_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-122.45, 37.77], [-122.44, 37.78], [-122.43, 37.79]],
},
"properties": {"name": "Test Route"},
}
],
}
line_layer_config = {
"id": "test-line",
"type": "line",
"source": {"type": "geojson", "data": line_data},
"paint": {"line-color": "#0000FF", "line-width": 3},
}
m.add_layer("test-line", line_layer_config)
print(
"Added test-polygon and test-line layers. Layer control should now show all 4 items:"
)
print("- Background")
print("- test-points")
print("- test-polygon")
print("- test-line")
Added test-polygon and test-line layers. Layer control should now show all 4 items: - Background - test-points - test-polygon - test-line
In [5]:
Copied!
html = m.to_html("layer_control.html", title="MapLibre Layer Control", height="800px")
html = m.to_html("layer_control.html", title="MapLibre Layer Control", height="800px")
4. Test Programmatic Changes¶
The layer control now properly syncs with programmatic visibility and opacity changes.
In [6]:
Copied!
# Test visibility changes - the checkboxes should update automatically
print("Testing visibility changes...")
m.set_visibility("test-points", False)
print("- Set test-points visibility to False (checkbox should be unchecked)")
m.set_visibility("test-polygon", False)
print("- Set test-polygon visibility to False (checkbox should be unchecked)")
# Test opacity changes - the sliders should update automatically
print("\nTesting opacity changes...")
m.set_opacity("test-line", 0.3)
print("- Set test-line opacity to 0.3 (slider should move to 30%)")
m.set_opacity("test-polygon", 0.8)
print("- Set test-polygon opacity to 0.8 (slider should move to 80%)")
print("\nCheck the layer control - all changes should be reflected in the UI!")
# Test visibility changes - the checkboxes should update automatically
print("Testing visibility changes...")
m.set_visibility("test-points", False)
print("- Set test-points visibility to False (checkbox should be unchecked)")
m.set_visibility("test-polygon", False)
print("- Set test-polygon visibility to False (checkbox should be unchecked)")
# Test opacity changes - the sliders should update automatically
print("\nTesting opacity changes...")
m.set_opacity("test-line", 0.3)
print("- Set test-line opacity to 0.3 (slider should move to 30%)")
m.set_opacity("test-polygon", 0.8)
print("- Set test-polygon opacity to 0.8 (slider should move to 80%)")
print("\nCheck the layer control - all changes should be reflected in the UI!")
Testing visibility changes... - Set test-points visibility to False (checkbox should be unchecked) - Set test-polygon visibility to False (checkbox should be unchecked) Testing opacity changes... - Set test-line opacity to 0.3 (slider should move to 30%) - Set test-polygon opacity to 0.8 (slider should move to 80%) Check the layer control - all changes should be reflected in the UI!
5. Restore Visibility and Test Background Control¶
Test that the background control properly affects all map style layers.
In [7]:
Copied!
# Restore visibility
m.set_visibility("test-points", True)
m.set_visibility("test-polygon", True)
m.set_opacity("test-line", 1.0)
m.set_opacity("test-polygon", 0.5)
print("Restored all layer visibility and opacity.")
print("\nTry using the layer control UI:")
print("- Toggle the 'Background' checkbox to hide/show all background layers")
print("- Adjust the 'Background' opacity slider to change map transparency")
print("- Toggle individual layer checkboxes to show/hide specific layers")
print("- Adjust individual layer opacity sliders for fine control")
print("\nAll changes should work in both directions (UI → Python and Python → UI)!")
# Restore visibility
m.set_visibility("test-points", True)
m.set_visibility("test-polygon", True)
m.set_opacity("test-line", 1.0)
m.set_opacity("test-polygon", 0.5)
print("Restored all layer visibility and opacity.")
print("\nTry using the layer control UI:")
print("- Toggle the 'Background' checkbox to hide/show all background layers")
print("- Adjust the 'Background' opacity slider to change map transparency")
print("- Toggle individual layer checkboxes to show/hide specific layers")
print("- Adjust individual layer opacity sliders for fine control")
print("\nAll changes should work in both directions (UI → Python and Python → UI)!")
Restored all layer visibility and opacity. Try using the layer control UI: - Toggle the 'Background' checkbox to hide/show all background layers - Adjust the 'Background' opacity slider to change map transparency - Toggle individual layer checkboxes to show/hide specific layers - Adjust individual layer opacity sliders for fine control All changes should work in both directions (UI → Python and Python → UI)!
6. Test Multiple Layer Controls¶
You can add multiple layer controls in different positions with different layer filters.
In [8]:
Copied!
# Add a second layer control with only specific layers
m.add_layer_control(
position="top-left",
collapsed=True,
layers=["test-points", "test-line"], # Only show these layers
)
print("Added second layer control on top-left with filtered layers.")
print("The left control should only show test-points and test-line.")
print("The right control should show all layers including Background.")
# Add a second layer control with only specific layers
m.add_layer_control(
position="top-left",
collapsed=True,
layers=["test-points", "test-line"], # Only show these layers
)
print("Added second layer control on top-left with filtered layers.")
print("The left control should only show test-points and test-line.")
print("The right control should show all layers including Background.")
Added second layer control on top-left with filtered layers. The left control should only show test-points and test-line. The right control should show all layers including Background.
In [9]:
Copied!
# Export to HTML with improved styling that matches the notebook appearance
html = m.to_html("layer_control.html", title="Layer Control Test")
print("✓ Map exported to HTML with enhanced layer control styling!")
print("\\nThe exported HTML now features:")
print("- Professional SVG layers icon (3 stacked rectangles)")
print("- Gray gradient opacity sliders matching notebook appearance")
print("- Consistent typography and spacing")
print("- Proper hover effects and visual feedback")
print("- Clean scrollbar styling")
print("- All interactive functionality preserved")
print("\\nThe layer control appearance now matches the Jupyter notebook exactly!")
print("\\nOpen layer_control.html in a browser to see the improved styling!")
# Export to HTML with improved styling that matches the notebook appearance
html = m.to_html("layer_control.html", title="Layer Control Test")
print("✓ Map exported to HTML with enhanced layer control styling!")
print("\\nThe exported HTML now features:")
print("- Professional SVG layers icon (3 stacked rectangles)")
print("- Gray gradient opacity sliders matching notebook appearance")
print("- Consistent typography and spacing")
print("- Proper hover effects and visual feedback")
print("- Clean scrollbar styling")
print("- All interactive functionality preserved")
print("\\nThe layer control appearance now matches the Jupyter notebook exactly!")
print("\\nOpen layer_control.html in a browser to see the improved styling!")
✓ Map exported to HTML with enhanced layer control styling! \nThe exported HTML now features: - Professional SVG layers icon (3 stacked rectangles) - Gray gradient opacity sliders matching notebook appearance - Consistent typography and spacing - Proper hover effects and visual feedback - Clean scrollbar styling - All interactive functionality preserved \nThe layer control appearance now matches the Jupyter notebook exactly! \nOpen layer_control.html in a browser to see the improved styling!
Summary¶
The layer control implementation now provides:
Features:¶
- Collapsible Panel: Click the icon to expand/collapse the layer list
- Visibility Control: Checkboxes to toggle layer visibility
- Opacity Control: Sliders to adjust layer transparency
- Layer Filtering: Optional parameter to show only specific layers
- Multiple Controls: Add controls in different positions with different layer sets
- Bidirectional Sync: Changes work both ways (UI ↔ Python)
Background Layer Handling:¶
- All map style layers (landcover, parks, roads, etc.) are grouped under "Background Map"
- User-added layers appear as individual controls
- Background control affects all style layers simultaneously
- Individual layer controls only affect their specific layer