codybontecou297 downloadsRender Leaflet maps inline from iso.me exports. Supports JSON, CSV, Markdown, OwnTracks, Overland, and GPX formats with stats and duration-encoded markers.
Render interactive Leaflet maps inline in Obsidian notes from iso.me exports and compatible location-tracking formats.
The plugin registers an Obsidian Markdown code block named iso-me. Add a fenced block to any note, point it at one or more export files in your vault, and the plugin renders visits, routes, outliers, stats, and optional interactive filters.
exports/iso.me-2026-05-04.json.```iso-me
source: exports/iso.me-2026-05-04.json
title: Where I went
height: 500
show_visits: true
show_routes: true
```
source or sources is required. Every other block parameter is optional.
Supported formats:
If the plugin is available in Community Plugins:
Download these files from the latest release:
manifest.jsonmain.jsstyles.cssIn your vault, create this folder:
.obsidian/plugins/iso-me-maps/
Copy the three files into that folder.
Restart Obsidian or run Reload app without saving from the command palette.
Open Settings → Community plugins and enable iso.me Maps.
npm install
npm run build
ln -s "$PWD" "<your-vault>/.obsidian/plugins/iso-me-maps"
Then reload Obsidian and enable the plugin.
In the iso.me iOS app, export the data you want to map. Recommended options:
A common layout is:
Your vault/
Daily Notes/
exports/
iso.me - Monday 2026-05-04 - all.json
iso.me - Tuesday 2026-05-05 - all.json
Open Settings → iso.me Maps.
Recommended first-time settings:
| Setting | Suggested value | Why |
|---|---|---|
| Exports folder | exports |
Lets you write source: yesterday or source: filename.json instead of full paths. |
| Export filename pattern | *{date}* |
Matches any file containing the resolved date. |
| Export date format | YYYY-MM-DD |
Matches iso.me's default date format in filenames. |
| Tile provider | CartoDB Voyager | Works in desktop and mobile Obsidian. |
```iso-me
source: yesterday
title: Yesterday
height: 500
interactive: true
```
With exportsFolder = exports, source: yesterday searches the exports/ folder for a file matching yesterday's date.
By default, maps automatically center and zoom to the visible visits/routes/outliers in the loaded export. If you prefer a fixed initial viewport, add auto_fit: false plus your desired center and zoom.
Use parameters inside a fenced iso-me code block:
```iso-me
source: exports/day.json
height: 500
zoom: 12
center: [37.7749, -122.4194]
show_visits: true
show_routes: true
show_stats: false
interactive: false
auto_fit: true
title: April trip
```
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
source |
path, folder, glob, or date keyword | Yes, unless sources is set |
— | Loads one source. Can point to a supported file, a folder, a filename glob, or a date keyword such as today. |
sources |
list of paths/folders/globs/date keywords | Yes, unless source is set |
— | Loads multiple sources and merges them into one map. Useful for separate visits + points exports or one-file-per-day batches. |
title |
string | No | none | Heading displayed above the map. Quotes are optional. |
height |
number | No | plugin Default map height (400) |
Map height in pixels. |
zoom |
number | No | plugin Default zoom (11) |
Initial/fallback zoom. If auto_fit is enabled and the export has one mappable coordinate, this zoom is used; multiple coordinates auto-fit the visible bounds. |
center |
[latitude, longitude] |
No | plugin default center ([0, 0]) |
Initial/fallback center when no visible layer provides bounds, or when auto_fit: false. |
auto_fit |
boolean | No | true |
Automatically centers and zooms to the visible visits/routes/outliers. Set to false to use center and zoom instead. |
show_visits |
boolean | No | plugin Show visit markers by default (true) |
Shows visit/stay markers when the export contains visits. |
show_routes |
boolean | No | plugin Show routes by default (true) |
Shows GPS route polylines when the export contains points. Outliers are excluded. |
show_stats |
boolean | No | false |
Shows the stats bar above the map. This is per-block only; there is no settings-tab default for stats. |
interactive |
boolean | No | false |
Shows day and time-of-day filters above the map. Filters re-render visits, routes, and outliers. |
The code fence language must be exactly iso-me:
```iso-me
source: exports/day.json
```
Keys are case-insensitive, but the documented lowercase names are recommended.
Blank lines are ignored.
Lines beginning with # are comments.
Unknown keys are ignored.
Malformed values are ignored and the plugin falls back to defaults.
Strings may be unquoted, single-quoted, or double-quoted:
title: My trip
title: "My trip"
title: 'My trip'
Boolean values accept all of these forms:
| True | False |
|---|---|
true |
false |
yes |
no |
on |
off |
1 |
0 |
center must be bracketed latitude/longitude:
center: [37.7749, -122.4194]
sources syntaxMulti-line YAML-style list:
```iso-me
sources:
- exports/visits.md
- exports/points.md
```
Inline bracket list:
```iso-me
sources: [exports/visits.md, exports/points.md]
```
Inline comma list:
```iso-me
sources: exports/visits.md, exports/points.md
```
If both source and sources are present, all listed sources are loaded and merged.
A source can be any of the following:
| Source form | Example | What happens |
|---|---|---|
| File path | source: exports/day.json |
Loads that vault-relative file. |
| Bare filename | source: day.json |
If Exports folder is set, loads exports/day.json; otherwise loads from the vault root. |
| Folder | source: exports/may/ |
Loads every supported export file inside that folder. |
| Glob | source: exports/iso.me*.json |
Loads every supported file in the literal directory whose filename matches the glob. |
| Date keyword | source: yesterday |
Resolves to one or more date-based glob searches using the settings below. |
Supported file extensions are:
.json, .csv, .md, .markdown, .gpx
Date keywords are available in source and in each item under sources.
| Keyword | Meaning |
|---|---|
today |
Today's date. |
yesterday |
Yesterday's date. |
YYYY-MM-DD |
A specific date, for example 2026-05-04. |
last N days |
Today plus the previous N - 1 days. N is clamped to 1...366. Examples: last 7 days, last 30 days, last 365 days. |
last week |
Alias for last 7 days. |
Examples:
```iso-me
source: today
title: Today
```
```iso-me
source: yesterday
title: Yesterday
```
```iso-me
source: 2026-05-04
title: May 4, 2026
```
```iso-me
source: last 7 days
title: Last week
interactive: true
```
Date keywords use three settings:
| Setting | Default | Description |
|---|---|---|
| Exports folder | empty | Vault-relative folder to search, for example exports. |
| Export filename pattern | *{date}* |
Glob template used to find files for a resolved date. {date} is replaced with the formatted date. |
| Export date format | YYYY-MM-DD |
Format used when inserting dates into the filename pattern. Supported tokens: YYYY, MM, DD. |
With these settings:
Exports folder: exports
Export filename pattern: *{date}*
Export date format: YYYY-MM-DD
This block:
```iso-me
source: yesterday
```
resolves to a glob like:
exports/*2026-05-08*
That matches filenames such as:
exports/iso.me - Friday 2026-05-08 - all.json
exports/isome_complete_export_2026-05-08_121042.json
| Pattern | Matches |
|---|---|
*{date}* |
Any filename containing the date. |
iso.me*{date}*all* |
iso.me per-day combined files containing all. |
*{date}*visits* |
Visit-only per-day files. |
*{date}*points* |
Point-only per-day files. |
daily-{date}.json |
Exact-style filenames like daily-2026-05-04.json. |
If the pattern does not contain {date}, the plugin appends *<date>* to the pattern internally.
* matches any characters within a filename component.? matches one character within a filename component.Open Settings → iso.me Maps to configure defaults.
| Setting | Stored key | Default | Description |
|---|---|---|---|
| Tile provider | tileProvider |
carto-voyager |
Basemap preset. |
| Tile layer URL | tileUrl |
CartoDB Voyager URL | Leaflet tile URL template. Visible when provider is Custom. |
| Tile attribution | tileAttribution |
Carto/OpenStreetMap attribution | HTML attribution shown in the map corner. Visible when provider is Custom. |
Available tile provider IDs:
| ID | Label | Notes |
|---|---|---|
carto-voyager |
CartoDB Voyager | Default. Good general-purpose map. |
carto-positron |
CartoDB Positron | Light basemap. |
carto-dark-matter |
CartoDB Dark Matter | Dark basemap. |
opentopomap |
OpenTopoMap | Topographic map. |
esri-world-imagery |
Esri World Imagery | Satellite imagery. |
osm |
OpenStreetMap | Mobile only; desktop Obsidian/Electron is blocked by OSM tile server referer policy. |
custom |
Custom | Use your own Leaflet tile URL and attribution. |
Tile setting changes apply to newly rendered maps. Already-open notes may need to be reloaded.
| Setting | Stored key | Default | Description |
|---|---|---|---|
| Exports folder | exportsFolder |
empty | Vault-relative folder used for bare filenames and date keywords. Trailing slashes are removed. |
| Export filename pattern | exportFilenamePattern |
*{date}* |
Glob template for date keyword lookup. Supports {date}, *, and ?. |
| Export date format | exportDateFormat |
YYYY-MM-DD |
Date formatting tokens used by date keywords. Supports YYYY, MM, DD. |
| Setting | Stored key | Default | Description |
|---|---|---|---|
| Default map height | defaultHeight |
400 |
Used when a block omits height. |
| Default zoom | defaultZoom |
11 |
Used as fallback zoom and when a block omits zoom. |
| Default center | defaultCenter |
[0, 0] |
Used when no visible layer provides bounds. This setting exists in saved plugin data; it is not currently exposed in the settings UI. |
| Route color | routeColor |
#2563eb |
Polyline color for routes. |
| Visit marker color | markerColor |
#2dd4bf |
Circle marker color for visits. |
| GPS glitch color | outlierColor |
#f59e0b |
Marker color for outliers when shown. |
| Show visit markers by default | showVisitsByDefault |
true |
Default for show_visits. |
| Show routes by default | showRoutesByDefault |
true |
Default for show_routes. |
| Show GPS glitches by default | showOutliersByDefault |
false |
Controls whether points flagged as outliers / GPS glitches are shown. |
The parser is intentionally permissive: rows or objects missing required plotting fields are skipped instead of breaking the whole export. A file-level parse error is shown only when the overall file shape is unrecognized or invalid.
File extension: .json
Supported root shapes:
{ "exportDate": "2026-05-04T12:00:00Z", "visits": [] }
{ "exportDate": "2026-05-04T12:00:00Z", "points": [] }
{ "exportDate": "2026-05-04T12:00:00Z", "visits": [], "points": [] }
Visit objects:
| Field | Required | Type | Description |
|---|---|---|---|
latitude |
Yes | number | Visit latitude. |
longitude |
Yes | number | Visit longitude. |
arrivedAt |
Yes | string | Arrival timestamp. ISO 8601 is recommended. |
departedAt |
No | string or null | Departure timestamp. |
durationMinutes |
No | number or null | Duration used for marker sizing and popup text. |
locationName |
No | string or null | Place name shown in popup and top-place stats. |
address |
No | string or null | Address shown in popup. |
notes |
No | string or null | Notes shown in popup. |
Point objects:
| Field | Required | Type | Description |
|---|---|---|---|
latitude |
Yes | number | Point latitude. |
longitude |
Yes | number | Point longitude. |
timestamp |
Yes | string | Point timestamp. ISO 8601 is recommended. |
timestampUnix |
No | number | Unix timestamp in seconds. |
altitude |
No | number or null | Altitude in meters. |
speed |
No | number or null | Speed in meters/second. Stats display average speed in km/h. |
course |
No | number or null | Course/bearing in degrees. Stored but not currently visualized. |
horizontalAccuracy |
No | number or null | Horizontal accuracy in meters. |
verticalAccuracy |
No | number or null | Vertical accuracy in meters. |
isOutlier |
No | boolean | Marks a GPS glitch/outlier. Defaults to false. |
File extension: .csv
CSV type is detected by the header row.
A visits CSV is detected when the header includes:
arrived_at
Required columns for plotted rows:
| Column | Required | Description |
|---|---|---|
arrived_at |
Yes | Arrival timestamp. |
latitude |
Yes | Visit latitude. Enable coordinates in iso.me export options. |
longitude |
Yes | Visit longitude. Enable coordinates in iso.me export options. |
Optional columns:
| Column | Description |
|---|---|
departed_at |
Departure timestamp. |
duration_minutes |
Visit duration. |
location_name |
Place name. |
address |
Address. |
notes |
Notes. |
Rows without arrived_at, latitude, or longitude are skipped.
A points CSV is detected when the header includes all of:
timestamp, latitude, longitude
Required columns for plotted rows:
| Column | Required | Description |
|---|---|---|
timestamp |
Yes | Point timestamp. |
latitude |
Yes | Point latitude. |
longitude |
Yes | Point longitude. |
Optional columns:
| Column | Description |
|---|---|
timestamp_unix |
Unix timestamp in seconds. |
altitude |
Altitude in meters. |
speed |
Speed in meters/second. |
horizontal_accuracy |
Horizontal accuracy in meters. |
is_outlier |
Outlier flag. Accepted true values: true, yes, 1. |
File extensions: .md, .markdown
Markdown parsing assumes iso.me's default English date/time export format, for example:
Friday, March 14, 2025
3:24 PM
3:24:05 PM
15:24
15:24:05
Supported H1 sections:
| H1 | Parsed as |
|---|---|
# iso.me Export |
Visits. |
# Visits |
Visits. |
Any H1 containing iso.me |
Visits, unless it is a location-points or complete-export heading. |
# iso.me Location Points Export |
Location points. |
Expected structure:
# iso.me Export
## Friday, March 14, 2025
### Coffee Shop
- **Arrived:** 8:12 AM
- **Departed:** 8:45 AM
- **Duration:** 33m
- **Address:** 123 Market St
- **Coordinates:** 37.7749, -122.4194
> Optional notes
Supported bullet fields:
| Field | Required | Description |
|---|---|---|
Arrived |
Yes | Arrival time. |
Coordinates |
Yes | latitude, longitude. |
Departed |
No | Departure time. |
Duration |
No | Text containing hours/minutes, for example 1h 20m or 33m. |
Address |
No | Address. |
| blockquote notes | No | Lines beginning with > . |
The ### heading is used as locationName unless the heading itself is just a time.
The parser also accepts visit tables with at least these columns:
Arrived, Lat, Lon
Optional columns:
Departed, Duration, Location, Address, Notes
Expected H1:
# iso.me Location Points Export
The point table must include:
Time, Lat, Lon
Optional columns:
Altitude, Speed, Accuracy, Outlier
Outlier is true when the cell is yes or true.
File extension: .json
Detected when the JSON root is an array whose first object looks like an OwnTracks location:
[
{
"_type": "location",
"lat": 37.7749,
"lon": -122.4194,
"tst": 1777891200,
"acc": 10,
"alt": 12,
"vel": 18,
"cog": 270,
"vac": 5
}
]
Supported fields:
| Field | Required | Description |
|---|---|---|
_type |
Yes | Must be location. |
lat |
Yes | Latitude. |
lon |
Yes | Longitude. |
tst |
Yes | Unix timestamp in seconds. |
acc |
No | Horizontal accuracy in meters. |
alt |
No | Altitude in meters. |
vel |
No | Speed in km/h; converted internally to meters/second. |
cog |
No | Course over ground in degrees. |
vac |
No | Vertical accuracy in meters. |
tid |
No | Tracker ID. Accepted but not displayed. |
OwnTracks files contain points only, so visit markers are not rendered.
File extension: .json
Detected when the JSON root has a locations array of GeoJSON point features:
{
"locations": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.4194, 37.7749]
},
"properties": {
"timestamp": "2026-05-04T12:00:00Z",
"altitude": 12,
"speed": 4.2,
"horizontalAccuracy": 10,
"deviceId": "iphone"
}
}
]
}
Supported fields:
| Field | Required | Description |
|---|---|---|
locations[] |
Yes | Array of GeoJSON features. |
type |
Yes | Feature type must be Feature. |
geometry.type |
Yes | Geometry type must be Point. |
geometry.coordinates |
Yes | [longitude, latitude] order. |
properties.timestamp |
Yes | Timestamp string. |
properties.altitude |
No | Altitude in meters. |
properties.speed |
No | Speed in meters/second. |
properties.horizontalAccuracy |
No | Horizontal accuracy in meters. |
properties.deviceId |
No | Accepted but not displayed. |
Overland files contain points only, so visit markers are not rendered.
File extension: .gpx
The parser uses the browser's built-in DOMParser, available in desktop and mobile Obsidian.
Supported GPX content:
| Element | Parsed as | Required data |
|---|---|---|
<wpt lat="..." lon="..."> |
Visit | lat, lon, and child <time>. |
<trk><trkseg><trkpt lat="..." lon="..."> |
Location point | lat, lon, and child <time>. |
<metadata><time> |
Export date | Optional. |
Waypoint visit fields:
| GPX field | Maps to |
|---|---|
wpt@lat, wpt@lon |
latitude, longitude |
<time> |
arrivedAt |
<name> |
locationName; Visit is treated as empty |
<desc> |
Address before — |
<extensions><isome:departedAt> |
departedAt |
<extensions><isome:durationMinutes> |
durationMinutes |
Track point fields:
| GPX field | Maps to |
|---|---|
trkpt@lat, trkpt@lon |
latitude, longitude |
<time> |
timestamp |
<ele> |
altitude |
<extensions><isome:speed> |
speed |
<extensions><isome:horizontalAccuracy> |
horizontalAccuracy |
<extensions><isome:isOutlier> |
isOutlier; true only when text is true |
iso.me extension namespace:
xmlns:isome="https://isome.isolated.tech/gpx/1.0"
durationMinutes using a logarithmic scale.isOutlier is true.The stats bar is hidden by default. Add show_stats: true to a map block to display it. It is best-effort and never blocks map rendering. It summarizes the loaded export data:
When interactive: true, filters update map layers but the stats bar remains a summary of the loaded export.
interactive: true adds:
Filtering uses each timestamp's local day and local time in Obsidian.
Set Exports folder to exports, then put this in a daily note template:
```iso-me
source: yesterday
title: Yesterday's movement
height: 450
interactive: true
```
Auto-fit is enabled by default. To always open the map at a specific place and zoom level, opt out with auto_fit: false:
```iso-me
source: yesterday
title: Yesterday near home
height: 450
auto_fit: false
center: [37.7749, -122.4194]
zoom: 12
```
```iso-me
source: last 30 days
title: Last 30 days
height: 600
interactive: true
```
```iso-me
sources:
- exports/2026-05-04-visits.md
- exports/2026-05-04-points.md
title: May 4, 2026
show_visits: true
show_routes: true
```
```iso-me
source: exports/may-2026/
title: May 2026
interactive: true
```
```iso-me
source: exports/iso.me*all*.json
title: Combined daily exports
```
Set Tile provider to esri-world-imagery in settings, then use normal blocks:
```iso-me
source: exports/hike.gpx
title: Hike
show_routes: true
```
The examples/ directory contains sample export files for all supported formats, plus examples/usage-examples.md with ready-to-paste Obsidian code blocks.
| File | Format | Contains |
|---|---|---|
san-francisco-combined.json |
iso.me JSON | Visits + points |
san-francisco-visits.json |
iso.me JSON | Visits only |
san-francisco-points.json |
iso.me JSON | Points only |
commute-visits.csv |
CSV | Visits |
commute-points.csv |
CSV | Points |
san-francisco-visits.md |
Markdown | Visits |
commute-points.md |
Markdown | Points |
owntracks-commute.json |
OwnTracks | GPS points |
overland-commute.json |
Overland | GPS points |
san-francisco-day.gpx |
GPX | Waypoints + tracks |
iso.me: Missing required sourceAdd either source: or sources: to the block.
File not foundCheck:
Use a more specific or more permissive Export filename pattern.
For example, if files are named:
iso.me - Friday 2026-05-08 - all.json
use:
*{date}*all*
Make sure the export includes coordinates. Visit rows without latitude and longitude are skipped.
Make sure the export includes location points. Visit-only exports can show visit markers but cannot render routes.
This is intentional. Outliers are always excluded from routes, distance, and average speed.
Use CartoDB Voyager, CartoDB Positron, CartoDB Dark Matter, OpenTopoMap, Esri World Imagery, or a custom provider. OSM's standard tile servers reject desktop Obsidian/Electron requests due to referer policy.
Interactive day and time filters use the local timezone of Obsidian when parsing timestamps.
npm install
npm run dev # esbuild watch mode
npm run build # type-check and bundle for production
To test locally, symlink the plugin folder into a test vault:
ln -s "$PWD" "<test-vault>/.obsidian/plugins/iso-me-maps"
Reload Obsidian, disable Restricted mode if needed, and enable iso.me Maps.
MIT