Skip to content

Commit

Permalink
added max drawn objects argument
Browse files Browse the repository at this point in the history
  • Loading branch information
big-yellow-duck committed Jul 9, 2024
1 parent 771679b commit 935effa
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 8 deletions.
9 changes: 7 additions & 2 deletions examples/pages/draw_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@
from streamlit_folium import st_folium

m = folium.Map(location=[39.949610, -75.150282], zoom_start=5)
Draw(export=True).add_to(m)
Draw(export=False).add_to(m)

c1, c2 = st.columns(2)
with c1:
output = st_folium(m, width=700, height=500)
output = st_folium(
m,
width=700,
height=500,
max_drawn_objects=2,
)

with c2:
st.write(output)
127 changes: 127 additions & 0 deletions leaflet-draw-rectangles.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leaflet Draw Rectangle from Coordinates</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" />
<style>
#map {
height: 400px;
margin-bottom: 20px;
}

#coordinateForm {
margin-bottom: 20px;
}

input {
margin-right: 10px;
}
</style>
</head>

<body>
<div id="map"></div>
<form id="coordinateForm">
<label>Southwest Corner:</label>
<input type="number" id="swLat" step="any" placeholder="Latitude" required>
<input type="number" id="swLng" step="any" placeholder="Longitude" required>
<label>Northeast Corner:</label>
<input type="number" id="neLat" step="any" placeholder="Latitude" required>
<input type="number" id="neLng" step="any" placeholder="Longitude" required>
<button type="submit">Draw Rectangle</button>
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<script>
// Initialize the map
var map = L.map('map').setView([0, 0], 2);

// Add the base tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);

// Initialize the FeatureGroup to store the editable layers
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);

// Variable to store the current rectangle
var currentRectangle = null;

// Initialize the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
},
draw: {
polygon: false,
polyline: false,
circle: false,
marker: false,
circlemarker: false,
rectangle: true
}
});
map.addControl(drawControl);

// Function to add a rectangle to the map
function addRectangle(bounds) {
// Remove the current rectangle if it exists
if (currentRectangle) {
drawnItems.removeLayer(currentRectangle);
}

// Create and add the new rectangle
currentRectangle = L.rectangle(bounds, { color: "#ff7800", weight: 1 });
drawnItems.addLayer(currentRectangle);

// Fit the map to the rectangle bounds
map.fitBounds(bounds);

console.log("New rectangle created:", bounds);
}

// Event handler for when a rectangle is created using the draw tool
map.on(L.Draw.Event.CREATED, function (event) {
addRectangle(event.layer.getBounds());
});

// Event handler for when a rectangle is edited
map.on(L.Draw.Event.EDITED, function (event) {
var layers = event.layers;
layers.eachLayer(function (layer) {
console.log("Rectangle edited:", layer.getBounds());
});
});

// Event handler for when a rectangle is deleted
map.on(L.Draw.Event.DELETED, function (event) {
currentRectangle = null;
console.log("Rectangle deleted");
});

// Handle form submission
document.getElementById('coordinateForm').addEventListener('submit', function (e) {
e.preventDefault();
var swLat = parseFloat(document.getElementById('swLat').value);
var swLng = parseFloat(document.getElementById('swLng').value);
var neLat = parseFloat(document.getElementById('neLat').value);
var neLng = parseFloat(document.getElementById('neLng').value);

if (isNaN(swLat) || isNaN(swLng) || isNaN(neLat) || isNaN(neLng)) {
alert('Please enter valid coordinates');
return;
}

var bounds = L.latLngBounds([swLat, swLng], [neLat, neLng]);
addRectangle(bounds);
});
</script>
</body>

</html>
2 changes: 2 additions & 0 deletions streamlit_folium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def st_folium(
pixelated: bool = False,
debug: bool = False,
render: bool = True,
max_drawn_objects: int = 0,
):
"""Display a Folium object in Streamlit, returning data as user interacts
with app.
Expand Down Expand Up @@ -416,6 +417,7 @@ def walk(fig):
pixelated=pixelated,
css_links=css_links,
js_links=js_links,
max_drawn_objects=max_drawn_objects,
)

return component_value
Expand Down
6 changes: 3 additions & 3 deletions streamlit_folium/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
"@testing-library/user-event": "^7.1.2",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/jest": "^24.0.0",
"@types/leaflet": "^1.7.9",
"@types/node": "^12.0.0",
"bootstrap": "^4.4.1",
"event-target-shim": "^5.0.1",
"hoist-non-react-statics": "^3.3.2",
"leaflet": "^1.7.1",
"leaflet": "^1.9.4",
"leaflet-draw": "^1.0.2",
"leaflet.sync": "^0.2.4",
"react-scripts": "^5.0.1",
Expand Down Expand Up @@ -45,7 +44,8 @@
"homepage": ".",
"devDependencies": {
"@babel/plugin-transform-private-property-in-object": "^7.21.11",
"@types/leaflet-draw": "^1.0.5",
"@types/leaflet": "^1.9.12",
"@types/leaflet-draw": "^1.0.11",
"@types/underscore": "^1.11.4"
}
}
15 changes: 12 additions & 3 deletions streamlit_folium/frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type GlobalData = {
last_center: any
last_feature_group: any
last_layer_control: any
max_drawn_objects: number
}

declare global {
Expand Down Expand Up @@ -90,7 +91,6 @@ function extractContent(s: string) {

function onDraw(e: any) {
const global_data = window.__GLOBAL_DATA__

var type = e.layerType,
layer = e.layer

Expand All @@ -108,6 +108,13 @@ function onDraw(e: any) {
global_data.last_circle_radius = radius / 1000 // Convert to km to match what UI shows
global_data.last_circle_polygon = polygon
}
// Get the number of drawn objects
console.log('number of drawn items', window.drawnItems.getLayers().length)
// destroy the oldest drawn object if max drawn object is set to any positive value not 0
if (window.drawnItems.getLayers().length > window.__GLOBAL_DATA__.max_drawn_objects && window.__GLOBAL_DATA__.max_drawn_objects !== 0) {
window.drawnItems.removeLayer(window.drawnItems.getLayers()[0])
}

return onLayerClick(e)
}

Expand Down Expand Up @@ -207,6 +214,7 @@ async function onRender(event: Event) {
const return_on_hover: boolean = data.args["return_on_hover"]
const layer_control: string = data.args["layer_control"]
const pixelated: boolean = data.args["pixelated"]
const max_drawn_objects: number = data.args['max_drawn_objects']

// load scripts
const loadScripts = async () => {
Expand All @@ -233,7 +241,6 @@ async function onRender(event: Event) {
style.innerHTML = getPixelatedStyles(pixelated)
window.document.head.appendChild(style)
}

// finalize rendering
const finalizeOnRender = () => {
if (
Expand All @@ -254,6 +261,7 @@ async function onRender(event: Event) {
// update feature group and layer control cache
window.__GLOBAL_DATA__.last_feature_group = feature_group
window.__GLOBAL_DATA__.last_layer_control = layer_control
window.__GLOBAL_DATA__.max_drawn_objects = max_drawn_objects

if (feature_group) {
// eslint-disable-next-line
Expand Down Expand Up @@ -285,7 +293,7 @@ async function onRender(event: Event) {
if (
center &&
JSON.stringify(center) !==
JSON.stringify(window.__GLOBAL_DATA__.last_center)
JSON.stringify(window.__GLOBAL_DATA__.last_center)
) {
new_center = center
window.__GLOBAL_DATA__.last_center = center
Expand Down Expand Up @@ -339,6 +347,7 @@ async function onRender(event: Event) {
last_center: null,
last_feature_group: null,
last_layer_control: null,
max_drawn_objects: max_drawn_objects,
}
if (script.indexOf("map_div2") !== -1) {
parent_div?.classList.remove("single")
Expand Down
29 changes: 29 additions & 0 deletions testmap.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import folium\n",
"\n",
"m = folium.Map(location=(45.5236, -122.6750))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 935effa

Please sign in to comment.