obsidian-leaflet-mapping
Use when creating interactive maps in Obsidian using LeafletJS plugin - covers real-world maps, image maps, markers from notes, overlays, GeoJSON, GPX tracks, and common issues with bounds/zoom levels
$ Instalar
git clone https://github.com/zenobi-us/dotfiles /tmp/dotfiles && cp -r /tmp/dotfiles/ai/files/skills/obsidian-leaflet-mapping ~/.claude/skills/dotfiles// tip: Run this command in your terminal to install the skill
name: obsidian-leaflet-mapping description: Use when creating interactive maps in Obsidian using LeafletJS plugin - covers real-world maps, image maps, markers from notes, overlays, GeoJSON, GPX tracks, and common issues with bounds/zoom levels
Obsidian Leaflet Mapping
Overview
The Obsidian Leaflet plugin enables interactive maps using LeafletJS without writing JavaScript. Maps are defined in code blocks with YAML parameters and can display real-world locations (OpenStreetMap), custom images (fantasy maps, floor plans), or both layered together.
Core principle: Maps are defined declaratively in markdown code blocks. The plugin handles all JavaScript - you just configure parameters.
Plugin: https://github.com/javalent/obsidian-leaflet
Prerequisites
Required:
- Obsidian Leaflet plugin (Community Plugins → Search "Leaflet")
Optional (enables advanced features):
- Dataview plugin - REQUIRED for
markerTag,filterTag,linksTo,linksFromfeatures - Basic understanding of YAML syntax for code blocks
- For real-world maps: coordinates from Google Maps, OpenStreetMap, or GPS devices
- For image maps: image file in vault, known reference measurements for scale
Quick Start: Complete Working Example
Goal: Create a map showing all notes tagged #visited
Step 1: Install plugins
- Settings → Community Plugins → Browse
- Search "Leaflet" → Install → Enable
- Search "Dataview" → Install → Enable (REQUIRED for tag-based markers)
- Restart Obsidian (recommended after installing plugins)
Step 2: Create a test note
Create New York.md:
---
location: [40.7128, -74.0060]
tags: visited
---
# New York
My trip notes...
Step 3: Create the map
Create Travel Map.md:
```leaflet
id: my-travels
markerTag: #visited
height: 500px
```
Expected result: Map displays with one marker. Click marker → opens New York note.
If markers don't appear: See troubleshooting checklist below.
When to Use
Use this skill when:
- Creating location-based navigation in vaults (world maps, city maps, building layouts)
- Visualizing geographic data from notes (locations with frontmatter)
- Displaying custom image maps with markers (RPG campaigns, story locations)
- Tracking routes with GPX files or GeoJSON
- Building interactive dashboards with spatial data
Don't use for:
- Simple image display (use standard markdown)
- Complex GIS analysis (use dedicated GIS tools)
- Real-time map editing (markers are saved to plugin data)
Quick Reference
Basic Map Structure
\`\`\`leaflet
id: unique-map-id # REQUIRED - any unique string
image: [[ImageFile.jpg]] # Image map (omit for real-world map)
lat: 50 # Initial latitude (center point)
long: 50 # Initial longitude (center point)
height: 500px # Map container height
width: 100% # Map container width
minZoom: 1 # Minimum zoom level
maxZoom: 10 # Maximum zoom level
defaultZoom: 5 # Initial zoom level
\`\`\`
Map Types
| Type | Parameters | Use Case |
|---|---|---|
| Real-World Map | Omit image parameter | OpenStreetMap, city maps, GPS data |
| Image Map | image: [[File.jpg]] | Fantasy maps, floor plans, custom artwork |
| Multi-Layer Image | image: [[[Layer1]], [[Layer2]]] | Maps with toggleable overlays |
| Custom Tile Server | tileServer: <url>|<alias> | Alternative map styles (Dark, Satellite) |
Creating Markers
| Method | Syntax | Editable | Use Case |
|---|---|---|---|
| Right-click map | Interactive UI | Yes | Manual marker placement |
| Code block | marker: type,lat,long,link,desc | No | Fixed markers in documentation |
| From note frontmatter | markerFile: [[Note]] | No | Single note as marker |
| From folder | markerFolder: Path/To/Folder | No | All notes in folder |
| From tags | markerTag: #location | No | All notes with tag (Dataview required) |
| From links | linksTo: [[Note]] | No | Notes linking to/from (Dataview required) |
Real-World Maps
Default tile server is OpenStreetMap. Add custom tile servers for different styles:
\`\`\`leaflet
id: city-map
tileServer: https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png|Dark
tileServer: https://tiles.wmflabs.org/hillshading/{z}/{x}/{y}.png|Hills
osmLayer: false # Turn off default OpenStreetMap layer
\`\`\`
Tile overlays (instead of full layer replacement):
tileOverlay: https://tiles.example.com/{z}/{x}/{y}.png|Overlay Name|on
Append |on to enable overlay by default.
Image Maps
Critical First Step: Set Bounds
Before adding markers, define bounds to prevent coordinate confusion:
\`\`\`leaflet
id: fantasy-map
image: [[WorldMap.jpg]]
bounds:
- [0, 0] # Top-left corner
- [100, 100] # Bottom-right corner
\`\`\`
Without bounds, the image stretches to fit arbitrary coordinates. With bounds, latitude/longitude map predictably to image pixels.
Common bound strategies:
[0,0] to [100,100]- Percentage-based (lat/long are percentages)[0,0] to [width,height]- Pixel-based (match image dimensions)- Custom coordinate system matching your source material
Multi-Layer Image Maps
Stack multiple images with independent marker sets:
\`\`\`leaflet
id: layered-map
image:
- [[BaseMap.jpg|Base Layer]]
- [[Roads.png|Roads]]
- [[Buildings.png|Buildings]]
\`\`\`
Layer control box (top-right) toggles layers. Markers saved per-layer.
Zoom Levels on Image Maps
Counter-intuitive behavior: Higher maxZoom makes map START farther away.
Why: Image is placed at [0,0] and stretched to fit. Zoom levels control the underlying map, not the image scale.
Solution: Set bounds first, then adjust zoom to taste.
bounds: [[0,0], [100,100]]
minZoom: 1
maxZoom: 6
defaultZoom: 3
zoomDelta: 0.5 # Finer zoom control
Markers from Notes
Marker behavior: Clicking a linked marker opens the note (Ctrl/Cmd-click for new pane). Markers automatically link to their source note when created via frontmatter.
Finding Coordinates
Real-world maps:
- Google Maps: Right-click location → First line shows coordinates
- OpenStreetMap: Share button → "Geo URI" contains coordinates
- GPS device: Export waypoint coordinates
Image maps:
- Use
bounds: [[0,0], [100,100]]for percentage system - Right-click map after bounds set → coordinates shown on click
- Trial-and-error: Place marker, adjust coordinates in frontmatter
Note Frontmatter Format
---
location: [lat, long] # REQUIRED for automatic markers (array format only)
mapmarker: custom-icon # Optional: marker type from settings
mapzoom: [minZoom, maxZoom] # Optional: visibility breakpoints
mapmarkers: # Optional: additional markers
- [type, [lat, long], "Description", minZoom, maxZoom]
- [type, [lat, long], "Another marker"]
---
Coordinate format: Must be array [lat, long]. Strings like "40.7128, -74.0060" will NOT work.
Marker Methods
Single note:
markerFile: [[LocationNote]]
Folder (all notes):
markerFolder: Locations/Cities
markerFolder: Locations/Cities/ # Limit to top-level only (one slash)
By tags (⚠️ REQUIRES DATAVIEW PLUGIN):
markerTag: #location # Notes with this tag
markerTag: [#city, #visited] # Notes with BOTH tags
markerTag:
- #location # Notes with #location OR
- [#city, #capital] # Notes with both #city AND #capital
For OR logic: Use separate markerTag lines. For AND logic: Use array [#tag1, #tag2].
Filter results:
markerFolder: Locations
filterTag: #important # Only show important locations
From link relationships (⚠️ REQUIRES DATAVIEW PLUGIN):
linksTo: [[MainCity]] # All notes linking to MainCity
linksFrom: [[TravelLog]] # All notes linked from TravelLog
Multiple files: linksTo: [[[File1]], [[File2]]]
Custom Marker Types
Define in plugin settings or markers.json in same directory:
[
{
"type": "city",
"icon": "building",
"color": "#FF0000",
"layer": true
},
{
"type": "dungeon",
"icon": "dungeon",
"color": "#8B4513",
"layer": true
}
]
Then use in frontmatter: mapmarker: city
Overlays
Circular overlays for areas of effect, regions, etc.
Interactive Creation
Shift + Right-click → drag → click to set radius
Code Block Definition
overlay: [color, [lat, long], radius unit, "description"]
Examples:
overlay: [blue, [32, -89], 25 mi, 'Capital region']
overlay:
- ['rgb(255,0,0)', [50, 50], 10 km, 'Danger zone']
- ['#00FF00', [60, 60], 500 ft, 'Safe area']
Note: Overlays draw in order. Smaller overlays behind larger ones become non-interactive.
Overlays from Note Frontmatter
---
location: [50, 50]
mapoverlay: [blue, [50, 50], 25 km, "Influence zone"]
---
Or auto-generate from distance tag:
\`\`\`leaflet
overlayTag: influence
overlayColor: rgba(0,100,255,0.3)
\`\`\`
Note frontmatter: influence: 50 km
GeoJSON and GPX
GeoJSON
geojson: [[File.geojson]]|Optional Alias
geojson:
- [[Routes.geojson]]
- [[Regions.geojson]]|Regions|[[LinkedNote]]
geojsonColor: #FF0000 # Default color
GeoJSON features can include:
title,description, orname→ tooltip- MapBox SimpleStyle properties → styling
- Drawn in order specified (layer order matters)
GPX (GPS tracks)
gpx: [[Track.gpx]]
gpx:
- [[Hike1.gpx]]
- [[Hike2.gpx]]
gpxColor: #00FF00
gpxMarkers:
start: start-marker-type # From plugin settings
waypoint: waypoint-type
GPX files show:
- Route line (colored by speed/elevation/heartrate if data present)
- Optional start/end/waypoint markers
- Interactive datapoint display (click track)
Common Patterns
Campaign Map with Location Notes
\`\`\`leaflet
id: campaign-world
image: [[WorldMap.jpg]]
bounds: [[0,0], [100,100]]
markerFolder: Locations/Cities
markerFolder: Locations/Dungeons
markerTag: #location
filterTag: #visited
defaultZoom: 3
\`\`\`
Travel Dashboard with GPX
\`\`\`leaflet
id: travel-routes
lat: 40
long: -100
gpxFolder: Travel/2024
gpxColor: #FF6600
gpxMarkers:
start: trip-start
waypoint: stop
\`\`\`
Multi-Layer Fantasy Map
\`\`\`leaflet
id: kingdom-map
image:
- [[Base.jpg|Terrain]]
- [[Political.png|Borders]]
- [[Trade.png|Routes]]
bounds: [[0,0], [1000,1000]]
markerTag: #city
overlayTag: territory
overlayColor: rgba(100,100,255,0.2)
\`\`\`
Common Mistakes
Problem: Markers appear in wrong locations on image maps
Cause: No bounds defined. Without bounds, Leaflet uses arbitrary coordinate space and your image stretches unpredictably.
Why this happens: Image maps overlay images onto Leaflet's default coordinate system. Without explicit bounds, the plugin has no way to map your coordinates (e.g., [50, 50]) to specific pixels on your image.
Fix:
- Set bounds FIRST before placing any markers:
bounds: [[0,0], [100,100]]
- Delete existing markers (they're in wrong coordinate system)
- Place markers again - they'll now appear where you click
Finding correct coordinates on image: After setting bounds, Shift+click map to see coordinates, use those in frontmatter.
Problem: Can't zoom in enough / Map starts too far away
Cause: Image maps: zoom controls underlying map, not image scale
Fix:
- Set bounds to match coordinate system
- Adjust
maxZoom(lower number = closer default view) - Use
zoomDelta: 0.5for finer control
Problem: Markers from notes not appearing
Quick diagnostic:
- Open note with location → does frontmatter show
location: [40.7128, -74.0060]? (array format) - Using
markerTag/filterTag/linksTo/linksFrom? → Is Dataview plugin installed AND enabled? - Try restarting Obsidian (plugins sometimes need restart to activate)
Full checklist:
- Note has
location: [lat, long]in frontmatter (exact format - array only, not string) - Tags work for both YAML (
tags: visited) and inline (#visitedin note body) - Coordinates are within map bounds (check min/max lat/long)
- Using
markerTag,filterTag,linksTo, orlinksFrom? Dataview plugin must be installed and enabled (hard dependency) - Verify Dataview works: Create a note with
dataviewcode block to confirm plugin active - Using
filterTag? Check note has ALL required tags - Marker zoom breakpoints (
mapzoom) within map'sminZoom/maxZoom? - For real-world maps: valid lat/long (lat: -90 to 90, long: -180 to 180)
- For image maps: coordinates match your bounds system
- Map doesn't specify
lat/long/defaultZoom? Default centers on [50% world map]. AddshowAllMarkers: trueto auto-fit all markers.
Problem: GeoJSON/GPX files not loading
Causes:
- File path incorrect (use wikilink
[[file.geojson]]or relative path) - Large files slow rendering (check console for errors)
- JSON syntax errors in GeoJSON
Fix: Validate GeoJSON at https://geojsonlint.com/
Problem: Overlays not interactive / Markers hidden under overlay
Cause: Drawing order matters. Overlays and markers drawn later appear on top.
Fix:
- Overlays obscuring other overlays: Reorder in code block (larger overlays last)
- Overlays obscuring markers: Use semi-transparent colors
rgba(255,0,0,0.3)or reduce overlay radius - Markers below overlay: Markers from
markerTag/markerFolderdraw AFTER overlays in code block
Problem: Custom tile server not working
Checklist:
- URL contains
{z},{x},{y}placeholders - Server allows public access (no API key required)
- Using
tileOverlayinstead oftileServerif layering over base map - Check browser console for CORS or 404 errors
Distances and Measurements
Display distance between two points:
- Shift/Alt + click location 1
- Shift/Alt + click location 2
- Distance appears in bottom-left control box
Scale and units:
unit: miles # Display unit
scale: 1.5 # Scale factor for image maps
For image maps, measure a known distance on your image, calculate scale:
scale = real_distance / measured_pixel_distance
Advanced Features
Initial View from Note
coordinates: [[CityNote]] # Note with location frontmatter
zoomTag: viewDistance # Read zoom from note's frontmatter
CityNote frontmatter:
location: [40, -100]
viewDistance: 50 miles
Marker Zoom Breakpoints
Show/hide markers at zoom levels (prevent clutter):
mapzoom: [3, 7] # Only visible between zoom 3-7
Or per-marker in code block:
marker: city,40,-100,[[Note]],"Description",3,7
Draw Mode
draw: true # Enable drawing tools
drawColor: #FF0000 # Default shape color
Right-click drawn shapes to edit/delete. Shapes saved to map instance.
Dark Mode
darkMode: true # CSS filter inversion
Customize in CSS snippet targeting .leaflet-container .dark-mode
Real-World Impact
Use cases from community:
- TTRPG campaigns: World maps with 100+ location notes, auto-updating as players discover areas
- Research: GeoJSON datasets visualized with linked analysis notes
- Travel journals: GPX tracks from Apple Health + journal entries as markers
- Urban planning: Building layouts with image overlays for different floors
- Story writing: Character location tracking across plot timeline
Performance notes:
- 50+ markers: Minimal impact
- 200+ markers: Noticeable load time
- Large GeoJSON/GPX: Consider splitting files
- Multiple maps per note: Works fine, independent instances
Repository
