# leaflet > Choose based on aesthetic needs: - Author: Stephen Zweibel - Repository: CUNY-AI-Lab/agent-studio - Version: 20260106204321 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-07 - Source: https://github.com/CUNY-AI-Lab/agent-studio - Web: https://mule.run/skillshub/@@CUNY-AI-Lab/agent-studio~leaflet:20260106204321 --- --- name: leaflet description: Create interactive maps in preview panels. Use for: location visualization, markers, popups, shapes, GeoJSON. Example queries: 'show these locations on a map', 'plot coordinates', 'create a map of NYC'. --- # Leaflet Maps ## Overview Create interactive maps in preview panels using Leaflet.js. Load from CDN - no build step needed. ## Tile Providers Choose based on aesthetic needs: | Provider | URL | Style | |----------|-----|-------| | OpenStreetMap | `https://tile.openstreetmap.org/{z}/{x}/{y}.png` | Classic, detailed | | CartoDB Light | `https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png` | Clean, minimal | | CartoDB Dark | `https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png` | Dark mode | | CartoDB Voyager | `https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}.png` | Modern, colorful | ## CDN Links ```html ``` ## Basic Map ```javascript await addPanel({ id: 'map', type: 'preview', title: 'Map', content: `
` }); ``` ## Adding Markers ```javascript // Single marker L.marker([40.7128, -74.0060]) .addTo(map) .bindPopup('New York City
Population: 8.3M'); // Multiple markers from data const locations = [ { lat: 40.7128, lng: -74.0060, name: 'NYC' }, { lat: 34.0522, lng: -118.2437, name: 'LA' } ]; locations.forEach(loc => { L.marker([loc.lat, loc.lng]) .addTo(map) .bindPopup(loc.name); }); ``` ## Marker Clusters (for many points) ```html ``` ```javascript const markers = L.markerClusterGroup(); locations.forEach(loc => { markers.addLayer(L.marker([loc.lat, loc.lng])); }); map.addLayer(markers); ``` ## Custom Marker Icons ```javascript const customIcon = L.icon({ iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34] }); L.marker([lat, lng], { icon: customIcon }).addTo(map); ``` ## Fit Bounds to Markers ```javascript const group = L.featureGroup(markers); map.fitBounds(group.getBounds().pad(0.1)); ``` ## Drawing Shapes ```javascript // Circle L.circle([lat, lng], { radius: 500, // meters color: 'blue', fillOpacity: 0.3 }).addTo(map); // Polygon L.polygon([ [lat1, lng1], [lat2, lng2], [lat3, lng3] ]).addTo(map); // Polyline (path) L.polyline([ [lat1, lng1], [lat2, lng2] ], { color: 'red' }).addTo(map); ``` ## GeoJSON ```javascript const geojsonData = { "type": "FeatureCollection", "features": [...] }; L.geoJSON(geojsonData, { onEachFeature: (feature, layer) => { layer.bindPopup(feature.properties.name); } }).addTo(map); ``` ## Common Coordinates | Location | Lat, Lng | |----------|----------| | New York | 40.7128, -74.0060 | | Los Angeles | 34.0522, -118.2437 | | London | 51.5074, -0.1278 | | Paris | 48.8566, 2.3522 | | Tokyo | 35.6762, 139.6503 | ## Troubleshooting **Tiles not loading?** - Check the tile URL pattern is correct - Verify the provider allows public access **Map not showing?** - Ensure the container has explicit height (`height: 100vh` or fixed pixels) - Call `map.invalidateSize()` if container size changes