Add Draw Data Example¶
This notebook demonstrates the new add_draw_data()
method in AnyMap, which allows you to append features to existing draw control data without clearing what's already there.
In [1]:
Copied!
from anymap import MapLibreMap
import json
print("AnyMap loaded successfully!")
from anymap import MapLibreMap
import json
print("AnyMap loaded successfully!")
AnyMap loaded successfully!
Difference between load_draw_data
and add_draw_data
¶
load_draw_data()
: Replaces ALL existing features with new dataadd_draw_data()
: Appends new features to existing data (NEW!)
This makes add_draw_data()
perfect for:
- Building up features programmatically
- Adding data from multiple sources
- Incrementally adding features without losing existing ones
In [2]:
Copied!
# Create a map with draw control
m = MapLibreMap(center=[-122.4194, 37.7749], zoom=13, height="600px", style="liberty")
m.add_draw_control()
# Start with initial data (this replaces any existing data)
initial_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "Initial Point", "color": "red"},
}
],
}
m.load_draw_data(initial_data)
print(f"✓ Loaded initial data: {len(m.get_draw_data()['features'])} features")
m
# Create a map with draw control
m = MapLibreMap(center=[-122.4194, 37.7749], zoom=13, height="600px", style="liberty")
m.add_draw_control()
# Start with initial data (this replaces any existing data)
initial_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "Initial Point", "color": "red"},
}
],
}
m.load_draw_data(initial_data)
print(f"✓ Loaded initial data: {len(m.get_draw_data()['features'])} features")
m
✓ Loaded initial data: 1 features
Out[2]:
In [3]:
Copied!
# Add a single point feature (appends to existing data)
new_point = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4150, 37.7700]},
"properties": {"name": "Added Point", "color": "blue"},
}
m.add_draw_data(new_point)
# Add a single point feature (appends to existing data)
new_point = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4150, 37.7700]},
"properties": {"name": "Added Point", "color": "blue"},
}
m.add_draw_data(new_point)
In [4]:
Copied!
m.get_draw_data()
m.get_draw_data()
Out[4]:
{'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [-122.4194, 37.7749]}, 'properties': {'name': 'Initial Point', 'color': 'red'}}]}
In [5]:
Copied!
# Add multiple features at once using a FeatureCollection
multiple_features = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4100, 37.7750]},
"properties": {"name": "Point 3", "color": "green"},
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.4200, 37.7700],
[-122.4180, 37.7700],
[-122.4180, 37.7720],
[-122.4200, 37.7720],
[-122.4200, 37.7700],
]
],
},
"properties": {"name": "Sample Polygon", "color": "yellow"},
},
],
}
m.add_draw_data(multiple_features)
print(
f"✓ Added multiple features. Total features: {len(m.get_draw_data()['features'])}"
)
# Add multiple features at once using a FeatureCollection
multiple_features = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4100, 37.7750]},
"properties": {"name": "Point 3", "color": "green"},
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.4200, 37.7700],
[-122.4180, 37.7700],
[-122.4180, 37.7720],
[-122.4200, 37.7720],
[-122.4200, 37.7700],
]
],
},
"properties": {"name": "Sample Polygon", "color": "yellow"},
},
],
}
m.add_draw_data(multiple_features)
print(
f"✓ Added multiple features. Total features: {len(m.get_draw_data()['features'])}"
)
✓ Added multiple features. Total features: 1
In [6]:
Copied!
# Add a line feature programmatically
line_feature = {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.4180, 37.7720],
[-122.4160, 37.7740],
[-122.4140, 37.7730],
],
},
"properties": {"name": "Route Line", "color": "purple"},
}
m.add_draw_data(line_feature)
final_count = len(m.get_draw_data()["features"])
print(f"✓ Added line feature. Final total: {final_count} features")
# Display all features
all_features = m.get_draw_data()["features"]
print("\nAll features on the map:")
for i, feature in enumerate(all_features, 1):
geom_type = feature["geometry"]["type"]
name = feature["properties"].get("name", f"Feature {i}")
print(f" {i}. {name} ({geom_type})")
# Add a line feature programmatically
line_feature = {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.4180, 37.7720],
[-122.4160, 37.7740],
[-122.4140, 37.7730],
],
},
"properties": {"name": "Route Line", "color": "purple"},
}
m.add_draw_data(line_feature)
final_count = len(m.get_draw_data()["features"])
print(f"✓ Added line feature. Final total: {final_count} features")
# Display all features
all_features = m.get_draw_data()["features"]
print("\nAll features on the map:")
for i, feature in enumerate(all_features, 1):
geom_type = feature["geometry"]["type"]
name = feature["properties"].get("name", f"Feature {i}")
print(f" {i}. {name} ({geom_type})")
✓ Added line feature. Final total: 1 features All features on the map: 1. Initial Point (Point)
Comparison: load_draw_data
vs add_draw_data
¶
Let's demonstrate the difference between the two methods:
In [7]:
Copied!
# Create a new map to demonstrate the difference
m2 = MapLibreMap(center=[-122.4194, 37.7749], zoom=13, height="400px", style="light")
m2.add_draw_control()
# Add some initial features
points = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.41, 37.77]},
"properties": {"name": "A"},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.42, 37.77]},
"properties": {"name": "B"},
},
],
}
m2.add_draw_data(points)
print(f"After add_draw_data: {len(m2.get_draw_data()['features'])} features")
# Now use load_draw_data - this will REPLACE all existing features
replacement_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.43, 37.78]},
"properties": {"name": "C"},
}
],
}
m2.load_draw_data(replacement_data)
print(
f"After load_draw_data: {len(m2.get_draw_data()['features'])} features (replaced all!)"
)
m2
# Create a new map to demonstrate the difference
m2 = MapLibreMap(center=[-122.4194, 37.7749], zoom=13, height="400px", style="light")
m2.add_draw_control()
# Add some initial features
points = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.41, 37.77]},
"properties": {"name": "A"},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.42, 37.77]},
"properties": {"name": "B"},
},
],
}
m2.add_draw_data(points)
print(f"After add_draw_data: {len(m2.get_draw_data()['features'])} features")
# Now use load_draw_data - this will REPLACE all existing features
replacement_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.43, 37.78]},
"properties": {"name": "C"},
}
],
}
m2.load_draw_data(replacement_data)
print(
f"After load_draw_data: {len(m2.get_draw_data()['features'])} features (replaced all!)"
)
m2
After add_draw_data: 0 features After load_draw_data: 1 features (replaced all!)
Out[7]:
Use Cases for add_draw_data
¶
The add_draw_data
method is particularly useful for:
- Progressive Data Loading: Load data from multiple sources incrementally
- User Interaction: Add features based on user input or calculations
- Data Integration: Combine manual drawing with programmatic feature addition
- Incremental Visualization: Build up complex visualizations step by step
Method Signature:¶
map.add_draw_data(geojson_data: Union[Dict[str, Any], str]) -> None
Parameters:
geojson_data
: Can be a single Feature, FeatureCollection, or JSON string
Key Features:
- ✅ Appends features without clearing existing ones
- ✅ Accepts both single Features and FeatureCollections
- ✅ Handles JSON strings automatically
- ✅ Immediately syncs with JavaScript draw control
- ✅ Maintains existing features on the map