Custom Draw Control Styling¶
This notebook demonstrates how to customize the appearance of draw control features using custom paint parameters and styling.
Features Covered¶
- Custom Colors: Set different colors for points, lines, and polygons
- Style Parameters: Customize stroke width, fill opacity, and point radius
- Multiple Draw Controls: Use different styles for different purposes
- Easy Styling: Use the built-in
create_draw_styles()
helper method
In [1]:
Copied!
# Import required modules
from anymap import MapLibreMap
from anymap.draw_styles import create_draw_styles
import json
print("AnyMap with custom draw control styling!")
# Import required modules
from anymap import MapLibreMap
from anymap.draw_styles import create_draw_styles
import json
print("AnyMap with custom draw control styling!")
AnyMap with custom draw control styling!
Example 1: Default vs Custom Styles Comparison¶
Let's start by comparing the default styles with custom ones.
In [2]:
Copied!
# Create a map with default draw control styles
m1 = MapLibreMap(
center=[37.7749, -122.4194], # San Francisco
zoom=13,
height="600px",
style="streets",
)
# Add draw control with default styling (left side)
m1.add_draw_control(
position="top-left",
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
m1
# Create a map with default draw control styles
m1 = MapLibreMap(
center=[37.7749, -122.4194], # San Francisco
zoom=13,
height="600px",
style="streets",
)
# Add draw control with default styling (left side)
m1.add_draw_control(
position="top-left",
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
m1
Out[2]:
Example 2: Themed Styles for Different Use Cases¶
Different color schemes for different purposes.
In [3]:
Copied!
# Create multiple maps with different themed styles
# Map 1: Transportation theme (roads, stops, areas)
m2 = MapLibreMap(
center=[37.7749, -122.4194], zoom=13, height="500px", style="dark-matter"
)
transportation_styles = create_draw_styles(
point_color="#FFD700", # Golden yellow for stops/stations
line_color="#32CD32", # Lime green for routes
polygon_fill_color="#FF6347", # Tomato red for service areas
polygon_stroke_color="#FF6347",
active_color="#00FFFF", # Cyan for selection
point_radius=4,
line_width=3,
)
m2.add_draw_control(
position="top-left",
styles=transportation_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print("🚌 Transportation Theme: Golden stops, green routes, red service areas")
m2
# Create multiple maps with different themed styles
# Map 1: Transportation theme (roads, stops, areas)
m2 = MapLibreMap(
center=[37.7749, -122.4194], zoom=13, height="500px", style="dark-matter"
)
transportation_styles = create_draw_styles(
point_color="#FFD700", # Golden yellow for stops/stations
line_color="#32CD32", # Lime green for routes
polygon_fill_color="#FF6347", # Tomato red for service areas
polygon_stroke_color="#FF6347",
active_color="#00FFFF", # Cyan for selection
point_radius=4,
line_width=3,
)
m2.add_draw_control(
position="top-left",
styles=transportation_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print("🚌 Transportation Theme: Golden stops, green routes, red service areas")
m2
🚌 Transportation Theme: Golden stops, green routes, red service areas
Out[3]:
In [4]:
Copied!
# Map 2: Environmental theme (sampling points, streams, protected areas)
m3 = MapLibreMap(
center=[37.7749, -122.4194], zoom=13, height="500px", style="satellite"
)
environmental_styles = create_draw_styles(
point_color="#8B4513", # Brown for sampling points
line_color="#4169E1", # Royal blue for water features
polygon_fill_color="#228B22", # Forest green for protected areas
polygon_stroke_color="#006400", # Dark green border
active_color="#FF1493", # Deep pink for selection
point_radius=3,
line_width=2,
polygon_opacity=0.3,
)
m3.add_draw_control(
position="top-right",
styles=environmental_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print(
"🌲 Environmental Theme: Brown sampling points, blue streams, green protected areas"
)
m3
# Map 2: Environmental theme (sampling points, streams, protected areas)
m3 = MapLibreMap(
center=[37.7749, -122.4194], zoom=13, height="500px", style="satellite"
)
environmental_styles = create_draw_styles(
point_color="#8B4513", # Brown for sampling points
line_color="#4169E1", # Royal blue for water features
polygon_fill_color="#228B22", # Forest green for protected areas
polygon_stroke_color="#006400", # Dark green border
active_color="#FF1493", # Deep pink for selection
point_radius=3,
line_width=2,
polygon_opacity=0.3,
)
m3.add_draw_control(
position="top-right",
styles=environmental_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print(
"🌲 Environmental Theme: Brown sampling points, blue streams, green protected areas"
)
m3
🌲 Environmental Theme: Brown sampling points, blue streams, green protected areas
Out[4]:
Example 3: High Contrast Styles for Accessibility¶
Bold, high-contrast styles for better visibility.
In [5]:
Copied!
# Create high contrast styles
m4 = MapLibreMap(
center=[37.7749, -122.4194],
zoom=13,
height="500px",
style="positron", # Light background for contrast
)
high_contrast_styles = create_draw_styles(
point_color="#000000", # Black points
line_color="#000000", # Black lines
polygon_fill_color="#000000", # Black polygon fill
polygon_stroke_color="#000000", # Black polygon stroke
active_color="#FF0000", # Bright red for selection
point_radius=6, # Larger for visibility
line_width=4, # Thicker for visibility
polygon_opacity=0.4, # More visible
)
m4.add_draw_control(
position="top-left",
styles=high_contrast_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print("♿ High Contrast Theme: Bold black features with bright red selection")
m4
# Create high contrast styles
m4 = MapLibreMap(
center=[37.7749, -122.4194],
zoom=13,
height="500px",
style="positron", # Light background for contrast
)
high_contrast_styles = create_draw_styles(
point_color="#000000", # Black points
line_color="#000000", # Black lines
polygon_fill_color="#000000", # Black polygon fill
polygon_stroke_color="#000000", # Black polygon stroke
active_color="#FF0000", # Bright red for selection
point_radius=6, # Larger for visibility
line_width=4, # Thicker for visibility
polygon_opacity=0.4, # More visible
)
m4.add_draw_control(
position="top-left",
styles=high_contrast_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print("♿ High Contrast Theme: Bold black features with bright red selection")
m4
♿ High Contrast Theme: Bold black features with bright red selection
Out[5]:
Example 4: Loading Data with Different Styled Controls¶
Show how features loaded via add_draw_data
appear with custom styling.
In [6]:
Copied!
# Create sample data for demonstration
sample_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "City Hall", "type": "landmark"},
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-122.42, 37.77], [-122.41, 37.78], [-122.40, 37.77]],
},
"properties": {"name": "Sample Route", "type": "route"},
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.415, 37.775],
[-122.405, 37.775],
[-122.405, 37.765],
[-122.415, 37.765],
[-122.415, 37.775],
]
],
},
"properties": {"name": "Sample Area", "type": "zone"},
},
],
}
# Create map with custom styles
m5 = MapLibreMap(center=[37.7749, -122.4194], zoom=14, height="600px", style="voyager")
# Create purple theme for loaded data
purple_styles = create_draw_styles(
point_color="#8A2BE2", # Blue violet
line_color="#9370DB", # Medium purple
polygon_fill_color="#DA70D6", # Orchid
polygon_stroke_color="#8A2BE2", # Blue violet
active_color="#FFD700", # Gold for selection
point_radius=4,
line_width=3,
polygon_opacity=0.25,
)
m5.add_draw_control(
position="top-left",
styles=purple_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
# Load the sample data - it will appear with purple styling
m5.load_draw_data(sample_data)
print("💜 Purple Theme with Pre-loaded Data")
print("• Point: City Hall location")
print("• Line: Sample route")
print("• Polygon: Sample area")
print("Try selecting and editing the features to see the gold selection color!")
m5
# Create sample data for demonstration
sample_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "City Hall", "type": "landmark"},
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-122.42, 37.77], [-122.41, 37.78], [-122.40, 37.77]],
},
"properties": {"name": "Sample Route", "type": "route"},
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.415, 37.775],
[-122.405, 37.775],
[-122.405, 37.765],
[-122.415, 37.765],
[-122.415, 37.775],
]
],
},
"properties": {"name": "Sample Area", "type": "zone"},
},
],
}
# Create map with custom styles
m5 = MapLibreMap(center=[37.7749, -122.4194], zoom=14, height="600px", style="voyager")
# Create purple theme for loaded data
purple_styles = create_draw_styles(
point_color="#8A2BE2", # Blue violet
line_color="#9370DB", # Medium purple
polygon_fill_color="#DA70D6", # Orchid
polygon_stroke_color="#8A2BE2", # Blue violet
active_color="#FFD700", # Gold for selection
point_radius=4,
line_width=3,
polygon_opacity=0.25,
)
m5.add_draw_control(
position="top-left",
styles=purple_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
# Load the sample data - it will appear with purple styling
m5.load_draw_data(sample_data)
print("💜 Purple Theme with Pre-loaded Data")
print("• Point: City Hall location")
print("• Line: Sample route")
print("• Polygon: Sample area")
print("Try selecting and editing the features to see the gold selection color!")
m5
💜 Purple Theme with Pre-loaded Data • Point: City Hall location • Line: Sample route • Polygon: Sample area Try selecting and editing the features to see the gold selection color!
Out[6]:
Example 5: Advanced Custom Styles with Raw Style Objects¶
For advanced users who want complete control over styling.
In [7]:
Copied!
# Define completely custom style objects
advanced_custom_styles = [
# Custom point style with gradient effect (using multiple circles)
{
"id": "custom-point-outer",
"type": "circle",
"filter": [
"all",
["==", "active", "false"],
["==", "$type", "Point"],
["==", "meta", "feature"],
],
"paint": {"circle-radius": 8, "circle-color": "#FF6B6B", "circle-opacity": 0.6},
},
{
"id": "custom-point-inner",
"type": "circle",
"filter": [
"all",
["==", "active", "false"],
["==", "$type", "Point"],
["==", "meta", "feature"],
],
"paint": {"circle-radius": 4, "circle-color": "#FF1744", "circle-opacity": 1.0},
},
# Active point style
{
"id": "custom-point-active",
"type": "circle",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "Point"]],
"paint": {
"circle-radius": 10,
"circle-color": "#FFEB3B",
"circle-stroke-color": "#F57F17",
"circle-stroke-width": 2,
},
},
# Custom line style with pattern
{
"id": "custom-line-inactive",
"type": "line",
"filter": ["all", ["==", "active", "false"], ["==", "$type", "LineString"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {
"line-color": "#4CAF50",
"line-width": 5,
"line-dasharray": [2, 1], # Dashed pattern
},
},
# Active line style
{
"id": "custom-line-active",
"type": "line",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "LineString"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {"line-color": "#FFEB3B", "line-width": 6, "line-dasharray": [1, 1]},
},
# Custom polygon fill
{
"id": "custom-polygon-fill",
"type": "fill",
"filter": ["all", ["==", "active", "false"], ["==", "$type", "Polygon"]],
"paint": {"fill-color": "#2196F3", "fill-opacity": 0.3},
},
# Custom polygon stroke
{
"id": "custom-polygon-stroke",
"type": "line",
"filter": ["all", ["==", "active", "false"], ["==", "$type", "Polygon"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {"line-color": "#1976D2", "line-width": 3},
},
# Active polygon styles
{
"id": "custom-polygon-fill-active",
"type": "fill",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "Polygon"]],
"paint": {"fill-color": "#FFEB3B", "fill-opacity": 0.4},
},
{
"id": "custom-polygon-stroke-active",
"type": "line",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "Polygon"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {"line-color": "#F57F17", "line-width": 4, "line-dasharray": [0.5, 1]},
},
# Vertex styles for editing
{
"id": "custom-vertex-stroke",
"type": "circle",
"filter": ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"]],
"paint": {
"circle-radius": 6,
"circle-color": "#FFFFFF",
"circle-stroke-color": "#333333",
"circle-stroke-width": 2,
},
},
{
"id": "custom-vertex",
"type": "circle",
"filter": ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"]],
"paint": {"circle-radius": 3, "circle-color": "#FFEB3B"},
},
]
# Create map with advanced custom styles
m6 = MapLibreMap(
center=[37.7749, -122.4194], zoom=13, height="600px", style="dark-matter"
)
m6.add_draw_control(
position="top-left",
styles=advanced_custom_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print("🔥 Advanced Custom Styles")
print("• Points: Gradient red circles with yellow selection")
print("• Lines: Dashed green with yellow selection")
print("• Polygons: Blue fill with custom stroke patterns")
print("• Vertices: White circles with yellow centers")
m6
# Define completely custom style objects
advanced_custom_styles = [
# Custom point style with gradient effect (using multiple circles)
{
"id": "custom-point-outer",
"type": "circle",
"filter": [
"all",
["==", "active", "false"],
["==", "$type", "Point"],
["==", "meta", "feature"],
],
"paint": {"circle-radius": 8, "circle-color": "#FF6B6B", "circle-opacity": 0.6},
},
{
"id": "custom-point-inner",
"type": "circle",
"filter": [
"all",
["==", "active", "false"],
["==", "$type", "Point"],
["==", "meta", "feature"],
],
"paint": {"circle-radius": 4, "circle-color": "#FF1744", "circle-opacity": 1.0},
},
# Active point style
{
"id": "custom-point-active",
"type": "circle",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "Point"]],
"paint": {
"circle-radius": 10,
"circle-color": "#FFEB3B",
"circle-stroke-color": "#F57F17",
"circle-stroke-width": 2,
},
},
# Custom line style with pattern
{
"id": "custom-line-inactive",
"type": "line",
"filter": ["all", ["==", "active", "false"], ["==", "$type", "LineString"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {
"line-color": "#4CAF50",
"line-width": 5,
"line-dasharray": [2, 1], # Dashed pattern
},
},
# Active line style
{
"id": "custom-line-active",
"type": "line",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "LineString"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {"line-color": "#FFEB3B", "line-width": 6, "line-dasharray": [1, 1]},
},
# Custom polygon fill
{
"id": "custom-polygon-fill",
"type": "fill",
"filter": ["all", ["==", "active", "false"], ["==", "$type", "Polygon"]],
"paint": {"fill-color": "#2196F3", "fill-opacity": 0.3},
},
# Custom polygon stroke
{
"id": "custom-polygon-stroke",
"type": "line",
"filter": ["all", ["==", "active", "false"], ["==", "$type", "Polygon"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {"line-color": "#1976D2", "line-width": 3},
},
# Active polygon styles
{
"id": "custom-polygon-fill-active",
"type": "fill",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "Polygon"]],
"paint": {"fill-color": "#FFEB3B", "fill-opacity": 0.4},
},
{
"id": "custom-polygon-stroke-active",
"type": "line",
"filter": ["all", ["==", "active", "true"], ["==", "$type", "Polygon"]],
"layout": {"line-cap": "round", "line-join": "round"},
"paint": {"line-color": "#F57F17", "line-width": 4, "line-dasharray": [0.5, 1]},
},
# Vertex styles for editing
{
"id": "custom-vertex-stroke",
"type": "circle",
"filter": ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"]],
"paint": {
"circle-radius": 6,
"circle-color": "#FFFFFF",
"circle-stroke-color": "#333333",
"circle-stroke-width": 2,
},
},
{
"id": "custom-vertex",
"type": "circle",
"filter": ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"]],
"paint": {"circle-radius": 3, "circle-color": "#FFEB3B"},
},
]
# Create map with advanced custom styles
m6 = MapLibreMap(
center=[37.7749, -122.4194], zoom=13, height="600px", style="dark-matter"
)
m6.add_draw_control(
position="top-left",
styles=advanced_custom_styles,
controls={"point": True, "line_string": True, "polygon": True, "trash": True},
)
print("🔥 Advanced Custom Styles")
print("• Points: Gradient red circles with yellow selection")
print("• Lines: Dashed green with yellow selection")
print("• Polygons: Blue fill with custom stroke patterns")
print("• Vertices: White circles with yellow centers")
m6
🔥 Advanced Custom Styles • Points: Gradient red circles with yellow selection • Lines: Dashed green with yellow selection • Polygons: Blue fill with custom stroke patterns • Vertices: White circles with yellow centers
Out[7]:
Example 6: Testing Custom Styles with Different Data¶
Let's test how the custom styling works with different types of loaded data.
In [8]:
Copied!
# Test with the transportation themed map from earlier
# Add different types of transportation data
transport_data = {
"type": "FeatureCollection",
"features": [
# Bus stops (points)
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.42, 37.775]},
"properties": {"type": "bus_stop", "name": "Market St & 5th St"},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.415, 37.78]},
"properties": {"type": "bus_stop", "name": "Union Square"},
},
# Bus route (line)
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.42, 37.775],
[-122.415, 37.78],
[-122.41, 37.782],
[-122.405, 37.78],
],
},
"properties": {"type": "bus_route", "name": "Route 38"},
},
# Service area (polygon)
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.425, 37.785],
[-122.405, 37.785],
[-122.405, 37.770],
[-122.425, 37.770],
[-122.425, 37.785],
]
],
},
"properties": {"type": "service_area", "name": "Downtown Coverage Zone"},
},
],
}
# Load the transportation data into our transportation-themed map
m2.load_draw_data(transport_data)
print("🚌 Transportation data loaded with custom styling:")
print("• Golden bus stops")
print("• Green bus route")
print("• Red service coverage area")
print("Try selecting and editing the features!")
m2
# Test with the transportation themed map from earlier
# Add different types of transportation data
transport_data = {
"type": "FeatureCollection",
"features": [
# Bus stops (points)
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.42, 37.775]},
"properties": {"type": "bus_stop", "name": "Market St & 5th St"},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.415, 37.78]},
"properties": {"type": "bus_stop", "name": "Union Square"},
},
# Bus route (line)
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.42, 37.775],
[-122.415, 37.78],
[-122.41, 37.782],
[-122.405, 37.78],
],
},
"properties": {"type": "bus_route", "name": "Route 38"},
},
# Service area (polygon)
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.425, 37.785],
[-122.405, 37.785],
[-122.405, 37.770],
[-122.425, 37.770],
[-122.425, 37.785],
]
],
},
"properties": {"type": "service_area", "name": "Downtown Coverage Zone"},
},
],
}
# Load the transportation data into our transportation-themed map
m2.load_draw_data(transport_data)
print("🚌 Transportation data loaded with custom styling:")
print("• Golden bus stops")
print("• Green bus route")
print("• Red service coverage area")
print("Try selecting and editing the features!")
m2
🚌 Transportation data loaded with custom styling: • Golden bus stops • Green bus route • Red service coverage area Try selecting and editing the features!
Out[8]:
In [9]:
Copied!
# Display current draw data
current_data = m2.get_draw_data()
print(f"\nLoaded {len(m2._draw_data.get('features', []))} features with custom styling")
# Display current draw data
current_data = m2.get_draw_data()
print(f"\nLoaded {len(m2._draw_data.get('features', []))} features with custom styling")
Loaded 4 features with custom styling