# Add AntPath, Street Labels, and Enhanced EditControl Features
## Overview
…
This PR introduces three major enhancements to dash-leaflet:
1. **AntPath Component** - Animated polylines with marching ant effect
2. **Street Labels** - Text labels that follow polylines and ant paths
3. **Enhanced EditControl** - Support for custom colors and emoji markers
I've been a long-time user of dash-leaflet and wanted to contribute features that expand its visualization capabilities while maintaining the library's ease of use.
## Features Added
### 1. AntPath Component 🐜
A new component that creates animated polylines with a "marching ants" effect, based on [leaflet-ant-path](https://www.npmjs.com/package/leaflet-ant-path).
**Features:**
- Animated dashed lines with customizable speed and direction
- All standard polyline options supported
- Pause/resume animation control
- Hardware acceleration support
**Example Usage:**
```python
import dash_leaflet as dl
app.layout = dl.Map([
dl.TileLayer(),
dl.AntPath(
positions=[[51.505, -0.09], [51.51, -0.1], [51.515, -0.08]],
options={
"delay": 400,
"dashArray": [10, 20],
"weight": 5,
"color": "#ff0000",
"pulseColor": "#ffffff"
}
)
])
```
### 2. Street Labels 🏷️
Curved text labels that follow the path of Polyline and AntPath components, rebuilt based on [Leaflet.streetlabels](https://3mapslab.github.io/Leaflet.streetlabels/).
<img width="1708" alt="Street Labels Demo" src="https://github.com/user-attachments/assets/3bbd73a6-8747-41f4-a9dc-2fc52027ce50" />
**Features:**
- Canvas-based rendering for performance
- Automatic text orientation (no upside-down labels)
- Collision detection to prevent overlapping labels
- Zoom-based visibility control
- Customizable styling (font, size, color, stroke)
- Works with both Polyline and AntPath components
**Example Usage:**
```python
import dash_leaflet as dl
app.layout = dl.Map([
dl.TileLayer(),
dl.StreetLabelProvider([
dl.Polyline(
positions=[[51.505, -0.09], [51.51, -0.1]],
label="Oxford Street",
labelStyle={
"fontSize": 14,
"textColor": "#333",
"strokeColor": "#fff",
"strokeWidth": 3,
"minZoom": 13
}
),
dl.AntPath(
positions=[[51.52, -0.09], [51.525, -0.1]],
label="Animated Route",
showLabel=True,
options={"delay": 400}
)
])
])
```
### 3. Enhanced EditControl 🎨
The EditControl now supports dynamic styling with custom colors for shapes and emoji icons for markers.
**Features:**
- Dynamic color selection for polygons, polylines, rectangles, and circles
- Custom emoji support for marker icons (including custom image URLs)
- Color and emoji persistence when editing features
- Real-time style updates via props
**Example Usage:**
```python
import dash_leaflet as dl
from dash import html, dcc, Input, Output
app.layout = html.Div([
dcc.Input(id="color-picker", type="color", value="#3388ff"),
dcc.Input(id="emoji-picker", value="🏠"),
dl.Map([
dl.TileLayer(),
dl.EditControl(
id="edit-control",
currentColor="#3388ff",
currentEmoji="🏠"
)
])
])
@app.callback(
[Output("edit-control", "currentColor"),
Output("edit-control", "currentEmoji")],
[Input("color-picker", "value"),
Input("emoji-picker", "value")]
)
def update_styles(color, emoji):
return color, emoji
```
# Implementation Details
### Street Labels Architecture
CanvasTextLayer: Custom Leaflet layer for rendering text on canvas
TextPathRenderer: Handles curved text rendering along paths
LabelCollisionManager: RBush-based spatial indexing for collision detection
StreetLabelContext: React context for managing label registration
### Performance Optimizations
Canvas-based rendering for street labels
Request animation frame batching for updates
Delta updates for label rendering (only redraw changed labels)
Efficient collision detection using spatial indexing
### Known Issues
Street Labels Dragging: Labels may temporarily follow the map drag before snapping back to position. This is a rendering synchronization issue that needs investigation.
Build Warning: Minor TypeScript warning in MousePosition component (included fix in PR)
### Testing
Added example usage files:
tests/components/ant_path.py - Basic AntPath demonstration
tests/components/ant_path_advanced.py - More advanced
tests/components/dynamic_street_labels.py - change line color and text dynamically
tests/components/edit_control_simple.py - Enhanced EditControl with color/emoji picker
tests/components/edit_control_styled.py - EditControl testing in a clean dmc style
tests/components/popup_advanced.py - Exploring the use of popups
tests/components/popup_line.py - Exploring the popup on line click
tests/components/street_labels_usage.py - Basic StreetLabels
### Breaking Changes
None. All changes are additive and maintain backward compatibility.
**Future Enhancements**
- Additional ant path patterns?
- Resolve Drag bug with labels
Checklist
Code follows project style guidelines
Tests added for new components
Documentation added for new features
No breaking changes to existing API
Changelog updated
Dependencies Added
leaflet-ant-path: For animated polyline functionality
rbush: For efficient collision detection
cheap-ruler: For geographic calculations