Documentation site

This commit is contained in:
Erez Shermer 2026-03-22 10:35:46 +02:00
parent 3630cd67fe
commit b5589cd618
58 changed files with 3746 additions and 918 deletions

47
.github/workflows/docs.yml vendored Normal file
View file

@ -0,0 +1,47 @@
name: Deploy Docs
on:
push:
branches:
- master
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Build docs
run: npm run docs:build
- uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deployment

View file

@ -1,2 +1,4 @@
build
.claude/
docs/.vitepress/dist
docs/.vitepress/cache

143
CHANGELOG.md Normal file
View file

@ -0,0 +1,143 @@
# Changelog
All notable changes to Map View are documented here.
---
## 6.1.3
### Fixed
- GPX registration causing plugin crashes (critical fix).
- Issue [#385](https://github.com/esm7/obsidian-map-view/issues/385).
- Issue [#383](https://github.com/esm7/obsidian-map-view/issues/383).
### Internal
- Long-overdue addition of unit tests for many low-level plugin functions.
---
## 6.1.2
### Added
- Auto-add current GPS location to notes on mobile (e.g. daily notes). See [GPS Support](https://esm7.github.io/obsidian-map-view/gps-support/).
- Icons added to Map View's registered commands for better visibility in the mobile toolbar.
---
## 6.1.1
### Fixed
- Issues with embedded maps ([#372](https://github.com/esm7/obsidian-map-view/issues/372)).
---
## 6.1.0
### Added
- **Real-time GPS location support** using Obsidian Mobile 1.11's new location permissions:
- Map View now shows your current location.
- "Follow my location" toggle to pan the map as you move (available in View drop-down and Bases settings).
- All GPS commands revised to use the new location permissions.
- Moving indicator shown when Map View opens before fully loading.
### Deprecated
- The Geo-Helper app is now obsolete and unsupported (superseded by native GPS support on mobile).
### Notes
- Desktop GPS support (Linux, Windows, Mac) is not yet available. Vote for it [here](https://forum.obsidian.md/t/geolocation-ability-in-desktop-app/109686).
---
## 6.0.5
### Fixed
- Issue [#367](https://github.com/esm7/obsidian-map-view/issues/367).
---
## 6.0.4
### Fixed
- Emoji support in tag names ([#348](https://github.com/esm7/obsidian-map-view/issues/348)).
- Plugin removing blank lines in note embeds ([#368](https://github.com/esm7/obsidian-map-view/issues/368)).
- Some cases where marker rules could disappear on upgrade ([#359](https://github.com/esm7/obsidian-map-view/issues/359)).
---
## 6.0.3
### Fixed
- Display rules with empty queries no longer allowed for non-preset rules ([#359](https://github.com/esm7/obsidian-map-view/issues/359)).
- `location` property no longer set to type `multitext` ([#358](https://github.com/esm7/obsidian-map-view/issues/358)).
- Map View embeds through Bases now work correctly; added Embedded Height control.
---
## 6.0.2
### Fixed
- Issue [#354](https://github.com/esm7/obsidian-map-view/issues/354).
---
## 6.0.1
### Fixed
- Issue [#352](https://github.com/esm7/obsidian-map-view/issues/352).
---
## 6.0.0
This is a major release with significant new features, fixes, and **breaking changes**.
### Breaking Changes
::: warning Read before upgrading
- **Google Places API:** This version upgrades to Google's new Places API (introduced 2025). Existing credentials may need to be updated. See the [migration guide](https://esm7.github.io/obsidian-map-view/search/#migrating-to-google-places-api-new).
- **Google Places Templates:** Field names changed in the new Places API — re-add them in plugin settings.
- **OpenStreetMap geocoding:** An email address is now required in the plugin configuration due to OSM usage restrictions.
- **Configuration file is not backwards-compatible.** Back up `VAULT_DIR/.obsidian/plugins/obsidian-map-view/data.json` before upgrading if needed.
:::
### Added
- **[Paths](https://esm7.github.io/obsidian-map-view/paths/)** — support for stand-alone path files (GPX, KML, TCX, GeoJSON) and inline GeoJSON paths within notes.
- **[Display Rules](https://esm7.github.io/obsidian-map-view/display-rules/)** — complete redesign of "marker rules" into a more powerful query-based system for both markers and paths.
- **[Routing](https://esm7.github.io/obsidian-map-view/routing/)** — built-in route calculation using the GraphHopper API (driving, cycling, walking).
- **[Badges](https://esm7.github.io/obsidian-map-view/display-rules/#marker-badges)** — small corner indicators that can be added to markers via display rules.
- **Edit Mode** — complete new interface for adding and modifying markers and paths directly from the map.
- **[Obsidian Bases view](https://esm7.github.io/obsidian-map-view/bases-view/)** — experimental integration with Obsidian Bases.
- `opacity` as a marker icon property.
- "Only one controls section open at a time" setting (default: on).
- "Show native Obsidian popup on marker hover" option (returned by popular request).
- Modifying notes now properly updates markers according to the active filter.
- Query tag suggestions now only show tags present on the current map.
- "Focus current note in Map View" command.
### Improved
- Major performance improvements — Map View opens nearly instantly after initial load; filtering is much faster.
### Fixed
- Obsidian's new "always focus new tab" setting is now respected.
- Fix for [#308](https://github.com/esm7/obsidian-map-view/issues/308) (thanks @edzillion!).
- Inline location bug on iOS ([#301](https://github.com/esm7/obsidian-map-view/issues/301)).
- Context menu 'open in' fix for Reading View ([#326](https://github.com/esm7/obsidian-map-view/issues/326)).
- File-menu event not properly registered to the plugin ([#327](https://github.com/esm7/obsidian-map-view/issues/327)).
- `autoFit` state flag of embedded maps now works more consistently.
- Map View now sets the `location` property type to List, preventing Obsidian from corrupting it.

243
CLAUDE.md Normal file
View file

@ -0,0 +1,243 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Obsidian Map View is a sophisticated Obsidian plugin that transforms notes into an interactive geographic information system (GIS). It parses geolocation data from note frontmatter, inline links, and external files (GPX, KML, GeoJSON), renders them on interactive maps, and provides powerful querying, filtering, and display customization capabilities.
## Development Commands
```bash
# Development with watch mode
npm run dev-dist
# Production build
npm run build
# Code formatting
npm run prettier
# Check code formatting
npm run stylecheck
```
## Tech Stack
- **TypeScript** with Svelte 5 for UI components
- **Rollup** for bundling with plugins for TypeScript, Svelte, PostCSS, and images
- **Leaflet** ecosystem for mapping (leaflet, markercluster, geosearch, geoman, offline)
- **boon-js** for query language parsing
- **@tmcw/togeojson** for GPX/KML conversion
- **FontAwesome** for marker icons
- **Obsidian API** for plugin integration
## Core Architecture
### Data Flow: File → Layer → Map
1. **Parsing** (`src/geoHelpers.ts`, `src/geojsonParser.ts`):
- `matchInlineLocation()`: Extracts `[name](geo:lat,lng) tag:foo` patterns from file content
- `getFrontMatterLocation()`: Reads `location:` property from Obsidian metadata cache
- `getGeoJsonLayersFromFile()`: Parses GeoJSON/GPX/KML files and inline geojson code blocks
2. **Layer System** (abstract base: `src/baseGeoLayer.ts`):
- `FileMarker` (`src/fileMarker.ts`): Individual location markers from notes
- `GeoJsonLayer` (`src/geojsonLayer.ts`): Paths and shapes from GeoJSON data
- Each logical layer maintains multiple Leaflet layer instances (one per map container) via `geoLayers: Map<containerId, leaflet.Layer>`
3. **Layer Cache** (`src/layerCache.ts`):
- Plugin-global repository indexed by layer ID and file path
- Rebuilds affected layers when files change via `updateMarkersWithRelationToFile()`
- Initialization can be deferred until first map opens (`loadLayersAhead` setting)
4. **Display Rules** (`src/displayRulesCache.ts`):
- Query-based styling engine that applies icon properties, path options, and badges
- Rules applied in sequence; matching rules override previous properties
- Uses Query system (`src/query.ts`) to match layers via `tag:`, `path:`, `linkedfrom:`, etc.
5. **Map Rendering** (`src/mapContainer.ts`):
- `filterAndPrepareMarkers()`: Applies user query filters and builds link edges
- `updateMapLayers()`: Diffs old/new layers and updates Leaflet map (reuses unchanged layers)
- Manages marker clusters, tile layers, and all UI controls
### Key Components
**Main Plugin** (`src/main.ts`):
- Entry point that registers views, commands, protocol handlers, and event listeners
- Maintains `allMapContainers` registry for all active map instances
- Handles vault file events (create, modify, delete, rename) to trigger layer updates
- Provides global handlers for geolink interactions in editor
**Map Views**:
- `MainMapView` (`src/mainMapView.ts`): Standalone full-featured map view
- `EmbeddedMap` (`src/embeddedMap.ts`): Inline maps from `mapview` code blocks with state persistence
- `BasesMapView` (`src/basesMapView.ts`): Integration with Obsidian Bases
- `MapPreviewPopup` (`src/mapPreviewPopup.ts`): Transient previews on geolink hover
**Query System** (`src/query.ts`):
- Boolean query language: `tag:#foo AND path:"bar" OR linkedfrom:"Trip Plan"`
- Parsed into RPN (reverse Polish notation) for fast evaluation
- Used for both display rule matching and user filtering
**Display Rules** (`src/displayRulesCache.ts`, `src/markerIcons.ts`):
- Rules composed of: query + icon details + path options + badges
- `IconFactory.getIconFromRules()` creates Leaflet markers with FontAwesome icons
- Badges add corner indicators (up to 4 per marker)
**State Management** (`src/mapState.ts`):
- Immutable `MapState` object: position, zoom, query, display options
- `mergeStates()` for partial updates, `areStatesEqual()` for diffing
- Persisted in embedded maps and presets
**Editor Integration**:
- `src/codemirrorViewPlugin.ts`: Decorates inline geolinks with custom event handlers
- `src/geoLinkReplacers.ts`: Post-processes reading view to make geolinks clickable
- `src/locationSuggest.ts`: Autocomplete for location search in `[](geo:)` templates
- `src/tagSuggest.ts`: Tag autocomplete for queries
### Multi-Instance Pattern
The plugin supports multiple simultaneous map views (main views, embeds, previews). Each logical layer (FileMarker or GeoJsonLayer) can exist as different Leaflet objects in different containers:
```typescript
class BaseGeoLayer {
geoLayers: Map<string, leaflet.Layer> = new Map();
// Same geographic data, different visual representations per container
}
```
This enables:
- Independent filtering per view (same note shown differently in two maps)
- Efficient reuse of layer data without duplication
- Container-specific display state (hover, selection)
### Performance Considerations
- **Editor updates are frequent**: `updateMarkersWithRelationToFile()` must be extremely efficient as it runs on every file change
- **Cluster groups**: Nearby markers grouped to reduce DOM nodes (configurable "max cluster size")
- **Lazy layer initialization**: Cache built only when needed if `loadLayersAhead` is false
- **Efficient diffing**: `updateMapLayers()` uses "touched" flag to identify add/remove operations, reuses unchanged layers with `isSame()`
- **Viewport-limited processing**: Geolink decorations only applied to visible editor content
- **Query pre-compilation**: Queries compiled to RPN once, evaluated many times
## Important File Locations
- **Main entry**: `src/main.ts` (MapViewPlugin class)
- **Layer system**: `src/baseGeoLayer.ts`, `src/fileMarker.ts`, `src/geojsonLayer.ts`
- **Parsing**: `src/geoHelpers.ts`, `src/geojsonParser.ts`
- **Query engine**: `src/query.ts`, `src/displayRulesCache.ts`
- **Map rendering**: `src/mapContainer.ts`, `src/mapState.ts`
- **Views**: `src/mainMapView.ts`, `src/embeddedMap.ts`, `src/basesMapView.ts`
- **Icons**: `src/markerIcons.ts`
- **Settings**: `src/settings.ts`, `src/settingsTab.ts`
- **Svelte UI**: `src/components/*.svelte` (controls, dialogs)
- **Styles**: `src/css/*.css`, `src/less/*.less`
## Common Development Patterns
### Adding a New Display Rule Property
1. Add property to `iconDetails`, `pathOptions`, or `badgeDetails` in `src/markerIcons.ts`
2. Update `EditDisplayRuleDialog.svelte` to expose the property in UI
3. Modify `IconFactory.getIconFromRules()` or `DisplayRulesCache.runOn()` to apply the property
4. Update `src/displayRulesCache.ts` if composition logic changes
### Adding a New Query Operator
1. Add operator constant to `query.ts`: `OPERATOR_NAME`
2. Implement matching logic in `Query.testPredicate()` switch statement
3. Add autocomplete support in `TagSuggest.getSuggestions()` if needed
4. Document in README.md under "Queries" section
### Handling a New Geolocation Format
1. Add regex pattern to `src/consts.ts` or add URL parsing rule
2. Implement parser function in `src/geoHelpers.ts`
3. Call parser in `getMarkersFromFileContent()` or equivalent
4. Add tests if available (currently limited test coverage)
### Creating a New Map View Type
1. Extend `AbstractMapView` from `src/abstractMapView.ts`
2. Implement `getViewType()`, `getDisplayText()`, `getIcon()`
3. Create and manage `MapContainer` instance in `onOpen()`
4. Register view in `main.ts` via `this.registerView()`
5. Add command to open view if needed
## Build System
**Rollup Configuration** (`rollup.config.js`):
- Plugins: TypeScript, Svelte, CommonJS, Node Resolve, PostCSS, Image, Copy
- Environment: `BUILD=development` disables minification for faster dev builds
- Output: `main.js` (plugin code) + `styles.css` (compiled styles)
- Source maps generated for debugging
**TypeScript Config**:
- Extends `@tsconfig/svelte` for Svelte 5 compatibility
- Target: ES2022
- Strict mode disabled (legacy codebase)
- Module resolution: Node
## Plugin Lifecycle
**Initialization** (`onload()`):
1. Load settings from `data.json`
2. Initialize LayerCache (if `loadLayersAhead` enabled)
3. Register views, commands, protocol handlers
4. Setup vault event listeners (file create/modify/delete/rename)
5. Initialize global tile cache for offline maps
6. Register CodeMirror view plugin and markdown post-processors
7. Add settings tab
**File Change Handling**:
1. Obsidian fires metadata cache `changed` event
2. Plugin calls `updateMarkersWithRelationToFile(file)`
3. LayerCache rebuilds layers for affected file
4. All active MapContainers receive layer diff
5. Each container calls `updateMapLayers()` to reflect changes
**Shutdown** (`onunload()`):
1. Destroy all active map containers
2. Clear global registries and event handlers
## Debugging Tips
- Enable "Developer Tools" in Obsidian settings
- Use `console.log()` - output visible in DevTools console
- Source maps available in development builds
- Breakpoints work in TypeScript source files
- Test changes by reloading plugin: Ctrl+P → "Reload app without saving"
## Testing Approach
This project has limited automated test coverage. When making changes:
- Manually test with sample vault containing various geolocation formats
- Verify embedded maps update correctly when notes change
- Check performance with large vaults (hundreds of geolocations)
- Test on both desktop and mobile if possible
- Validate display rules apply correctly with complex queries
## Common Gotchas
- **Layer cache must be rebuilt when files change**: Always update via `updateMarkersWithRelationToFile()`
- **Multiple map containers share layer cache**: Changes affect all open views
- **Display rules apply in order**: Later matching rules override earlier ones
- **Inline tags vs note tags**: Inline tags (`tag:foo`) only apply to specific markers, not whole note
- **Leaflet coordinates are `[lat, lng]`**: Beware of order when parsing user input
- **Settings changes require plugin reload**: No hot-reload for plugin settings
- **Svelte 5 runes syntax**: Use `$state`, `$derived`, `$effect` for reactivity
- All new UI should use Svelte 5, and not the vanilla JS style on which I started the plugin with, and slowly replacing.

940
README.md
View file

@ -1,933 +1,43 @@
# Obsidian.md Map View
# Obsidian Map View
[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/esm7)
## Intro
An **interactive map plugin** for [Obsidian.md](https://obsidian.md/) that transforms your notes into a personal geographic information system (GIS).
This plugin introduces an **interactive map view** for [Obsidian.md](https://obsidian.md/).
It searches your notes for encoded geolocations and paths in various formats (see below), places them on a map and offers many tools to interact with them.
![](docs/img/sample.png)
It effectively turns your Obsidian vault into a **personal GIS system** that adds a geographical layer to your notes, journals, trip planning and pretty much anything you use Obsidian for.
## What It Does
You can...
Map View searches your notes for geolocations and paths, places them on an interactive map, and gives you powerful tools to interact with them:
- Follow your current location on mobile.
- Add locations using a built-in search (optionally utilizing Google Places).
- Save geolocations from a variety of sources.
- Add locations from a search, from the map, from external mapping services, or from your device's GPS.
- View paths in GeoJSON, GPX, KML and TCX formats.
- Draw locations and shapes on the map.
- Instantly calculate routes between points and get driving/cycling/walking estimations.
- Use Map View together with Obsidian Bases, as a fully customizable view of a Base.
Plus...
- Customize marker icons, badges, shapes, colors, path properties and more using sophisticated display rules.
- Use a powerful query system.
- Embed maps in notes with great level of control.
- Quickly switch between map layers and save presets.
- Draw locations and shapes on the map using Edit Mode.
- Calculate routes between points (driving, cycling, walking).
- Customize marker icons, badges, colors, and path styles using display rules.
- Query and filter markers with a powerful boolean query language.
- Embed live maps in notes.
- Save maps for offline usage.
- Integrate with Obsidian Bases.
And much, **much** more -- this is quite a powerful tool.
![](docs/img/edit-mode.gif)
![](img/sample.png)
## Documentation
![](img/edit-mode.gif)
**Full documentation:** [esm7.github.io/obsidian-map-view](https://esm7.github.io/obsidian-map-view/)
![](img/intro.gif)
- [Quick Start](https://esm7.github.io/obsidian-map-view/quick-start/)
- [Location Formats](https://esm7.github.io/obsidian-map-view/location-formats/)
- [Queries](https://esm7.github.io/obsidian-map-view/queries/)
- [Display Rules](https://esm7.github.io/obsidian-map-view/display-rules/)
- [Changelog](https://esm7.github.io/obsidian-map-view/changelog/)
![](img/quick-embed.gif)
## Installation
I wrote this plugin because I wanted my ever-growing Zettelkasten to be able to answer questions like...
Install Map View from the Obsidian Community Plugins store: search for **"Map View"** and click Install.
- When I get recommendations about cool places to visit, how do I save them in a way that I can recall later?
- When I'm visiting somewhere, what interesting places do I know in the area?
- When I'm conducting research for planning a trip, how do I lay out on a map options for places to eat, hike or sleep, combine them with prior knowledge, and save them for future reference?
## Support
Map View can integrate with your note-taking flow in order to answer all of these questions and much more.
If you find Map View useful, please consider [buying me a coffee](https://www.buymeacoffee.com/esm7).
Just like the Obsidian graph view lets you visualize associative relations between some of your notes, the map view lets you visualize geographic ones.
## Support the Development
If you want to support the development of this plugin, please consider to [buy me a coffee](https://www.buymeacoffee.com/esm7).
## Quick How To
Map View is a powerful tool with many ways to use it.
If you wanna learn it thoroughly, you may wanna start from [understanding how it works](#understanding-map-view-parsing-location-data).
But if you wanna dive right in and give it a try, or get a quick glimpse of what it can do, continue reading.
### Log a Geolocation
Here are a few examples for logging a favorite location you want to see in a map.
**Option 1: from a Note**
- Starting from a note, e.g. your daily note or a note referring to a trip plan, launch the Obsidian Command Palette and choose "Map View: add inline geolocation link".
- A link in the format of `[](geo:)` will be added where your cursor is.
- Start typing a location name inside the bracket, and some geolocation results will pop up. Choose one and your _inline location_ is complete.
![](img/quick1.gif)
(Note: the default geosearch provider requires you fill-in your email address, see [here](#location-search--auto-complete) for more details.)
**Option 2: from the Map**
- Open Map View (e.g. from the Obsidian ribbon icon).
- Search or locate a location, e.g. using the search tool.
- Right-click the map and choose "new note here (front matter)" to create a note logging the selection point.
**Option 3: from the Map using Edit Mode**
- Open Map View.
- Switch to Edit Mode using the pencil icon on the right.
- Click the red "Choose Note" button to select which note you want to add items to.
- Place markers or other shapes on the map using the tools that appeared below the pencil icon.
- When in Edit Mode you can move or edit other markers and paths as well.
**Option 4: from your current location**
When using Obsidian Mobile, try the various GPS-enabled commands, like "GPS: new geolocation note" that creates a new note for your current geolocation.
Alternatively, customize the mobile toolbar and add Map View commands to it, e.g. "Map View: GPS: add geolocation at current position".
**There are many other ways to log geolocations in Map View**, see [here](#adding-a-location-to-a-note) for more details.
### Create a Trip Plan Map
There are many flows you can use to create custom maps, interact with them and use them for research and planning -- here's one that I typically use for trip planning.
**Step 1: log some locations.**
For most trips, I like to use a single note with sections, for example:
```
## To Visit
- [Place 1](geo:...) tag:activity
- Some information about this place
- [Place 2](geo:...) tag:activity
- Information about this place
## To Eat
- [Restaurant1](geo:...) tag:food
- Opening hours, other data...
- [Restaurant2](geo:...) tag:food
- Opening hours, other data...
```
I add the places using one of the methods above (by searching with "add inline geolocation link") or by one of the many other methods described below.
Notice the [inline tags](#understanding-map-view-parsing-location-data), these can be used for custom filters and/or creating different icons for different types of places.
**Step 2: map them!**
In the case of a single note, just click the note's menu (3 dots) and choose "focus (note name) in Map View".
You should immediately see a map of all your locations, and if you spend some moments to configure [marker icons](#marker-icons), you can easily get different shapes and colors for your various tags.
**Step 3: save this map**
You have a few options here.
One thing you can do is to open the Presets section on the map and save the current view, then open it from Map View anytime.
Another option is to save an embed: in Presets click 'Copy block' (or "Copy Map View code block" from the note menu), then paste the resulting code into a note.
![](img/quick2.gif)
**There are many more options of how to build a trip plan, present it and use it.**
[This](https://www.reddit.com/r/ObsidianMD/comments/xi42pt/planning_a_vacation_with_map_view/) post gives a more detailed example, and diving into the details of how Map View works will help you find your own optimal flow.
### Build Your Personal Geographic Information System (GIS)
The most powerful way to use Map View is to build a complete personal GIS (Geographic Information System) from your notes vault.
I personally do this as follows.
**1. Collection**
This part isn't specific to Map View, but the main idea is that I [collect](https://en.wikipedia.org/wiki/Getting_Things_Done) pieces of information from various sources, that often contain some geographic information.
For example, I can save a Facebook post that recommends a new restaurant, clip a cool hike from a hiking group, or draft a quick note when a friend tells me about a place that I want to remember.
I later turn these into notes, but of course if that's not how you do things, you can skip to Processing.
**2. Processing**
When I turn my clipped pieces of information into notes, I add geolocations as follows.
- For pieces of information that are _mainly geographical_, e.g. a restaurant recommendation, a hike or somewhere I may want to visit, I create a Zettelkasten note, then use the Map View "add geolocation (front matter) to current note" to tag the relevant geolocation.
- If the location isn't easy to find using a text search, I usually open a more specific mapping tool like a hiking map, locate the place that I want, copy it in lat,lng format and paste it into the same search box above.
- Alternatively, I sometimes prefer to locate it on the map, then right-click and "copy geolocation as front matter" (or create the note from the map in the first place).
- I then tag the complete note with some useful metadata. Examples include: `#hike`, `#season/spring`, `#dogs`, `#camping`, `#food`, `#food/pizza`, `#activity`, `#activity/kids`, `#not` (for negative recommendations).
- For bulks of geographical information, like a list of recommended coffee shops in a city, I create a note and add all geolocations via inline geolocation links. I have the "add inline geolocation link" command mapped to `Alt+L` so I can easily start a location search while typing a note.
**3. Querying**
There are countless occasions that I query my Personal GIS.
- When planning a trip I often look at the area that I'm visiting, sometimes saving it as a preset without any filter applied, and get a general understanding of what I know about the area.
- I often query the system for a specific set of needs. For example, I obsessively collect information about dog-friendly activities around where I live, so when I want to go camping I query for `#dogs AND #sleep` (to search for dog-friendly camp sites) and to choose dining options I query for `#dogs AND #food`. See [here](#queries) to learn more about how queries work and what you can do with them.
- When visiting an unknown area I frequently launch Map View from Obsidian Mobile to account for change in plans or finding what to do without planning in advance.
See also [this](https://www.reddit.com/r/ObsidianMD/comments/xi42pt/planning_a_vacation_with_map_view/) Reddit post about planning a vacation with Map View.
## Understanding Map View: Parsing Location Data
Map View provides [several methods to log locations in notes](#adding-a-location-to-a-note) and can manage the technicalities for you.
You can skip to that section if you want to just get started, or continue reading the more technical explanation below.
**To clarify, the best way to use Map View is to never enter a geolocation manually.**
You will, however, need to understand the difference between the front matter and the inline formats, and decide when to use which.
So, the plugin works by scanning your notes and parsing two types of location data.
First is a location tag in a note's [front matter](https://help.obsidian.md/Advanced+topics/YAML+front+matter):
<!-- prettier-ignore-start -->
```yaml
---
location: 40.6892494,-74.0466891
---
```
<!-- prettier-ignore-end -->
This is useful for notes that represent a single specific location.
There is an alternative syntax used by Map View previously: `location: [40.6892494, -74.0466891]`. While this format is compatible with [obsidian-leaflet](https://github.com/valentine195/obsidian-leaflet-plugin), it doesn't play very well with Obsidian's property editor. Both format are supported by the new one is encouraged for Obsidian version 1.4 and above.
Another way that the plugin parses location data is through **inline location URLs** in the format of `[link-name](geo:40.68,-74.04)`, which allow multiple markers in the same note.
To prevent the need to scan the full content of all your notes, it requires an empty `locations:` tag in the note front matter ('locations' and not 'location').
(In most methods of entering geolocations Map View will do this automatically.)
Example:
```
---
locations:
---
# Trip Plan
Point 1: [Hudson River](geo:42.277578,-76.1598107)
... more note content ...
Point 2: [New Haven](geo:41.2982672,-72.9991356)
```
Notes with multiple markers will contain multiple markers on the map with the same note name, and clicking on the marker will jump to the correct location within the note.
Inline locations also support **inline tags** in the format of `tag:dogs` (without the `#` sign). For example:
```
Point 1: [Hudson River](geo:42.277578,-76.1598107) tag:dogs
```
This will add the tag `#dogs` specifically to that point, regardless of the note's own tags.
This is useful for notes that contain tags of different types (e.g. a trip log with various types of locations).
Note that the `tag:` format should be used **without** the `#` sign, because this sets the tag for the whole note.
Map View will internally add `#` for the purpose of queries and marker icons, as explained below.
Multiple inline tags can be separated with a whitespace: `[](geo:42.2,-76.15) tag:dogs tag:trip`.
Multiple inline locations can be added in the same line, and the tags that follow them will be associated to the location on the left, but the right-click editor context menu will not know to choose the location that was selected.
Instead of using a `locations:` YAML tag, you can use a custom note tag. See "tag name to denote inline geolocations" in the settings. (This also works with wildcards.)
It will not be automatically added when you need it like the `locations:` YAML tag, however if you add an inline geolocation to an existing note where your custom tag is found, Map View will not add a `locations:` YAML tag.
**IMPORTANT NOTE:** for the time being, using this feature (i.e. having a non-empty "tag name to denote inline geolocations") slows down Map View by an order of magnitude. I'm looking into speeding it up in future releases.
For interoperability with Obsidian's property editor and possibly other plugins, Map View will also parse the syntax of:
```yaml
location:
- '39.100105'
- '-94.5781416'
```
And also:
```yaml
location:
- 39.100105,-94.5781416
```
## Adding a Location to a Note
Map View offers many ways to add geolocations to notes.
### Anywhere in Obsidian
Map View adds an Obsidian command named "New geolocation note", which you can map to a hotkey and use anywhere in Obsidian.
This opens a dialog on which you can search (address or location based on your [configured geocoding provider](#changing-a-geocoding-provider)) or paste a URL using the built-in or custom [URL parsing rules](#url-parsing-rules).
### In an Existing Note
There are multiple ways to add a geolocation to an existing note.
1. Create an inline geolocation link in the format of `[](geo:)`, and if you start typing inside the link name (the brackets), Map View will initiate a location search. If you confirm one of the options, it will fill-in the location's coordinates. See more on this in the ["In-Note Location Search"](#location-search--auto-complete) section below.
To make this more streamlined, Map View adds to Obsidian a command named 'Add inline geolocation link' which you can map to a keyboard shortcut.
2. Add a front matter geolocation by using the Obsidian command 'Add geolocation (front matter) to current note'. This opens the same dialog as "new geolocation note" which allows you to search for a location name or paste a [URL parsing rules](#url-parsing-rules).
3. If you have a geolocation in some other mapping service that you wish to log, e.g. from Google Maps, you can copy the URL or "lat,lng" geolocation from that service, right-click in your note and select "Paste as Geolocation". The supported services are configurable, see [below](#url-parsing-rules) for more details.
### From the Map
The map offers several tools to create notes or add markers to existing notes.
1. Use "new note here" when right-clicking the map. This will create a new note (based on the template you can change in the settings) with the location that you clicked. You can create either an empty note with a front matter (single geolocation) or an empty note with an inline geolocation.
![](img/new-note.png)
The map can be searched using the tool on the upper-right side, so you can quickly jump to the place you want to mark.
[URL parsing rules](#url-parsing-rules) also work here, so you can [copy a geolocation from Google Maps](#tip-copying-from-google-maps) (or any other service) and jump to it.
![](img/search.gif)
2. Using Edit Mode: click the pencil icon on the right, choose a note to edit by clicking the red button on the left, then add markers (or other shapes) using the marker tool below the pencil icon. Alternatively, when in Edit Mode, you can right-click anywhere on the map and select "Add to Edit Mode note".
3. If you prefer to enter geolocations as text, use one of the "copy geolocation" options when you right-click the map and paste them in a note.
![](img/copy.png)
### Using Your Current Location
When in Obsidian Mobile, Map View supports getting the device's real-time location, which enables several easy ways to add your locations to notes:
- When editing a note, you can use the commands "GPS: add geolocation (inline) at current position" and "GPS: add geolocation (front matter) to current note" (it's very useful to map these to the mobile toolbar).
- You can also use "GPS: copy inline location" to just copy the geolocation without adding it to the current note.
- Create a new note using the "GPS: new geolocation note" from anywhere in Obsidian.
- ...or just right-click the marker showing your current location on the map and use the methods shown in "From the Map" above.
### Paste as Geolocation
Map View monitors the system clipboard, and when it is is detected to contain an encoded geolocation (e.g. a Google Maps "lat, lng" location), a "Paste as geolocation" entry is added to the editor context menu.
For example, if you right-click a location in Google Maps and click the first item in the menu (coordinates in lat,lng format, see [below](#tip-copying-from-google-maps)), you can then paste it as a geolocation inside a note.
Alternatively, you can right-click a URL or a supported formatted string that is already present in a note and choose "Convert to geolocation".
By default Map View can parse URLs from two services: the OpenStreetMap "show address" link and a generic "lat, lng" encoding used by many URLs.
### Tip: Copying from Google Maps
Google Maps on desktop web offers a very easy shortcut for copying universal `lat, lng` coordinates.
1. Right-click anywhere in the Google map.
2. The first menu item should be the universal coordinates. By clicking it, the coordinates are copied to the clipboard.
3. In any Obsidian note, right click and choose "paste as geolocation", or paste the coordinates into any Map View search box.
![](img/google-copy.png)
## GPS Location Support
Starting Obsidian Mobile 1.11, plugins can be granted precise location permission, allowing Map View to show and utilize an exact geolocation.
This is enabled by default, and if you prefer not to use it, turn off GPS support in the plugin settings.
When your location is available, you can focus on it using the icon on the right toolbar.
You can also:
- Set "follow my location" in a view settings to automatically pan the map when you move.
- Use the "GPS: find location and focus" command from anywhere in Obsidian to open Map View and focus on your current location.
- Use the "GPS: focus and follow me" command from anywhere in Obsidian to do the same as above, but turn on "follow my location" so the view will move when you move.
- Use "GPS: add geolocation (inline) at current position" or "GPS: add geolocation (front matter) to current note" to add your current location to a note you are editing.
- Use "GPS: copy inline location" to copy an inline location to the clipboard.
- Use "GPS: new geolocation note" to create a new note in your current location.
**Tip:** map commands you use often to the mobile toolbar for quickly adding the current location to notes.
Additionally, when a location is available, when you click an existing marker you can use "route to point" from your current location without choosing a routing source (see [Routing](#routing)).
### Auto-Adding Location to Notes
On Obsidian Mobile, if this setting is turned on, Map View can automatically add the current location to notes. A common use case would be adding the current location to your daily note, for example.
By default, Map View (on mobile) fills-in the current location if an empty `location` property is found in a note, except notes that include the word "template" (this is configurable).
To auto-add the current location to notes, add an empty `location` property to the template that creates them, e.g. your daily note template.
## Embedding Maps in Notes
Map View supports the Obsidian code block format for embedding maps in notes.
There are several ways to do this:
1. **Embedding an existing map.** To embed an existing map from Map View, including its query and any other settings, click 'Copy Block' from the map's Presets dropdown and paste the block into a note.
![](img/copy-block-embed.gif)
1. **Embedding directly from a note.** From the editor, right-click and choose "embed a Map View" from the context menu, then enter a search term that will be used for the center of the map. Alternatively, there's an Obsidian command named "Map View: add an embedded map" that you can assign to a keyboard shortcut.
![](img/quick-embed.gif)
Once a map is embedded in a note, it represents a live view that updates according to your notes.
Geolocations that are added or modified in the viewed area, and match the query that is saved in the embed, will be updated live.
You can make light adjustments to the view from within the embed (change its zoom, pan or height), and if you want these to be saved, click the 'Save' button that will appear.
To make bigger adjustments, such as updating the query or changing the view completely, use the Open button, make your changes, then click 'Update from open Map View' in the embed's View menu.
Note that if you have multiple full instances of Map View open, 'Update from open Map View' may not do what you intended, and you may need to close the unwanted views first.
Embeds also work really nicely in Canvas including live updates.
![](img/canvas.gif)
### Advanced Additional Options
- The query field in an embedded map supports a template parameter `$filename$`. If, for example, you wish to embed a map in a note template, you can edit the `query` field of the code block to be `"query":"linkedfrom:\"$filename$\" OR linkedto:\"$filename$\""`, and the map will always reference the host note.
**Known annoyance:** the `$filename$` replacement is currently performed when processing the code block and sent to Map View as a final result. Therefore, if you edit the embed interactively (e.g. by zoom or pan and clicking Save), the `query` field will be overwritten with the actual file name rather than the template.
- The JSON in the embedded map code block supports an `autoFit` boolean flag. When set to `true` (i.e. add `"autoFit":true` to the code block's JSON), the map will load with the given pan and zoom, but will then perform an auto-fit and override further zoom and pan changes. This has the annoyance of animating zoom/pan if the saved state is different than the auto-fitted one (click Save to freeze a new state in such a case). I eventually want to bake this nicely to the UI with some more reasonable behaviors.
- The embedded map code block also supports an optional `customViewSettings` object, which allows for some adjustments to the map's UI. Properties and their defaults are defined in [`embeddedMap.ts`](https://github.com/esm7/obsidian-map-view/blob/master/src/embeddedMap.ts#L31-L47).
## Paths
![](img/paths-basic.png)
Map View supports paths in a variety of formats and usage patterns.
Somewhat similarly to markers, there is a distinction between **stand-alone path files** and **inline paths**.
### Stand-Alone Path Files
Stand-alone path files can be any GPX, KML, TCX or GeoJSON files in your vault.
Somewhat similarly to front matter geolocations, Map View collects everything from your vault and displays paths based on [display rules](#marker--path-display-rules) and [filters](#queries).
Without any filters present, with the default settings, any supported path file in your vault will be displayed using the default path display style.
Stand-alone paths can be included or excluded using many of the query operators like `path`, `name` and `linkedfrom`.
There is no notion of tags for stand-alone paths, so in order to apply display rules to them, you have a couple of other options:
- Include a relevant string in the file name and use the `path` or `name` operators.
- Use the `linkedfrom` operator, e.g. have a note "my runs" that links to all your GPX tracks, and use `linkedfrom:"my runs"` to apply display rules to these paths.
Here are a few options for how to add stand-alone paths to your vault:
1. Use Obsidian's "insert attachment" command to insert a path file (e.g. a GPX) as an embed to a note you are working on. Although a path does not need to be referenced from a note to be shown in the map, it is often useful to put paths in contexts, and this command copies the file into the vault and adds it to a note in one step.
2. From Map View, enter Edit Mode by clicking the pencil icon on the right side, click the file icon, then click "import a path as vault attachment". The selected file will be added to the vault under your default attachments folder.
3. Just copy the file into your vault using your system's file explorer. It should be automatically recognized and appear.
### Inline Paths
Map View supports GeoJSON paths stored in notes using a code block of type `geojson`.
By default, a fenced code block with type `geojson` will be rendered by Map View inside the note.
Unlike stand-alone path files, inline paths support tags by adding a line of the form `tag:a tag:b` right below the code block.
Also, another advantage of inline paths is that they can be modified using the Edit Mode tools.
For example, the following code block defines a line with the tag `#hike`:
````
```geojson
{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[13.754839,42.030225],[14.033704,42.045011]]}}
```
tag:hike
````
The easiest way to add an inline path to a note is using Map View's Edit Mode.
To enter Edit Mode, click the pencil button on the right, or the "Edit" drop-down on the left. Then choose a note to edit.
From there you can either:
1. Draw a path on the map using the Edit Mode tools on the right. When done, the path will be added to the selected note.
2. From the edit mode tools on the right, click the file icon, then click "import a path and add to Edit Mode note". The path will be converted to GeoJSON and added as an inline path to your selected note.
(Note: You will not see the path appear when done if it is excluded from the current filter.)
### Styling Paths
Similarly to markers, the way paths are displayed on the map can be heavily customized using powerful [display rules](#marker--path-display-rules).
There are two main differences between markers and paths in this regard:
1. Paths have different properties available for styling.
2. Stand-alone path files do not support tags, so in order to reference them with display rules, you will need to use names or `linkedto` queries.
See [here](#path-properties) for more details.
## Queries
Map View supports powerful queries that are roughly similar to Obsidian's query format.
![](img/query.gif)
The query string can contain the following _search operators_:
- `tag:#...` to search for notes or markers tagged with a specific tag.
- This works on both whole notes (`#hiking`) and inline tags for specific markers (`tag:hiking`).
- You can also use wildcards like in [tag rules](#tag-rules), e.g. `tag:#sleep*` will match `#sleep` but also `#sleep/camping`.
- `name:...` to search for markers that their name contains the given string.
- For front-matter geolocations this matches the file name.
- For inline geolocations this matches the link name and **ignores** the file name (if you want to always match the file name, use `OR` with `path:`).
- `path:...` to search by the note path.
- This operator will include all the markers in the path that matches the query.
- `linkedto:...` includes notes that contain a specific link.
- This operator will include a note (with all the markers in it) if it has a link name that matches the query.
- For example, if you have a note named `Cave Hikes` and you have geolocated notes that **link to it** (e.g. include `[[Cave Hikes]]` as a link), include them by the filter `linkedto:"Cave Hikes"`.
- Anything that resolves into a legal Obsidian link will work, e.g. both a note name ('Cave Hikes') or a path will do, but a partial name will not.
- `linkedfrom:...` includes notes that are linked from a specific note, and also the origin note itself.
- This operator will include a note (with all the markers in it) if it is linked **from** the note mentioned in the query.
- For example, if you have a note named `Trip to Italy` with links to various geolocated notes (e.g. of places you want to visit or a trip log), the query `linkedfrom:"Trip to Italy"` will filter only for those markers.
- Anything that resolves into a legal Obsidian link will work, e.g. both a note name ('Cave Hikes') or a path will do, but a partial name will not.
- Obsidian heading and block links are supported: if a link in the 'from' file includes a heading or a block link, it will match only front-matter markers or inline markers _within that heading or block_.
- The Obsidian Plugin ["Copy Block Link"](https://github.com/mgmeyers/obsidian-copy-block-link) makes this extra useful.
- `["property":"value"]` includes notes with the property name `property` set to `value`.
- `lines:x-y` includes only inline markers that are defined in the given line range in their note.
- For example, `lines:20-30` includes only inline geolocations that are defined in lines 20 to 30 in the file that contains them.
All operators are case insensitive.
You can combine the above with _logical operators_: `AND`, `OR`, `NOT`, and grouping with parenthesis.
**This differs from Obsidian's own query language which uses `-` instead of `NOT` and treats spaces as 'AND'.**
For examples:
- `linkedfrom:"Trip to Italy" AND tag:#wine` can include places you linked from your trip to Italy, or are within that note itself, and are tagged with `#wine`.
- `tag:#hike AND tag:#dogs` can include hikes you marked as suitable for dogs.
- `tag:#hike AND (tag:#dogs OR tag:#amazing) AND NOT path:"bad places"`
There are many creative ways to organize your notes with geolocations that utilize these query abilities.
You may represent location types with tags (e.g. `#hike` or `#restaurant`), or use tags to represent traits of places (`#hike/summer`, `#hike/easy`).
You can use paths for indexes using Zettelkasten back links (e.g. link to "Hikes that I Want" from notes you want to denote as such), then use `linkedto:` to find places that link to it.
And/or you can have notes to plan a trip and link to places from it, then use `linkedfrom:` to focus on your plan.
In all cases you can [save presets](#Presets) that include the filter or sub-filters of it.
## Marker & Path Display Rules
![](img/display-rules.png)
Map View includes a powerful mechanism that allows you to customize map markers and path display properties based on a flexible rules system.
These are called Display Rules.
Display rules are made of a **query**, which is the same as discussed [here](#queries), and various properties to apply to a marker or a path that match the query.
When Map View tries to decide how to display a marker or a path, it starts from the Default display rule, which has a certain set of properties (e.g. a blue marker with a circle). It then tests the rest of the display rules by order, and for each rule with a matching query, overwrites whatever properties that rule sets.
For example, the default rule for markers may be a blue marker color with an `fa-circle` icon. If the marker also matches a rule below the default one (e.g. a rule like `tag:#food`), and that rule sets just the icon to `fa-utensils`, the resulting marker will be blue (because the 2nd rule did not override the color) with an `fa-utensils` icon.
(Note to Map View users prior to version 6.0.0: this is the same way Marker Icons worked before, except that rules use _queries_ rather than tags, allowing more flexibility.)
To edit display rules, open the plugin settings, and click the button under the "Marker & Path Display Rules" section.
You will see the list of the currently-active rules. You can add new rules, change the order of rules (except the default which must be first), and edit existing rules.
When editing a rule, you will be able to set various properties that the rule can apply. All these properties are optional, and will overwrite the default (or prior matching rules) for every marker or path that will match its query.
![](img/edit-display-rule.png)
### Marker Icon Properties
Icons are based on either [emojis](https://emojipedia.org) or [Font Awesome](https://fontawesome.com/), so to add a marker icon you'll need to copy the emoji or find the name in the Font Awesome catalog.
Additionally, there are various marker properties (shape, color and more) that are based on [Leaflet.ExtraMarkers](https://github.com/coryasilva/Leaflet.ExtraMarkers#properties).
An additional shape of `simple-circle`, that draws a circle at the given color without a pin shape, is supported on top of these.
For example, if you want markers with the `#travel` tag to have a bus icon, add a display rule with the query `tag:#travel`. Then click Edit, search the Font Awesome catalog for the appropriate icon (in this case `fa-bus`), and enter that in the 'icon' box.
Alternatively, just paste an emoji of a bus (e.g. from [Emojipedia](https://emojipedia.org)) into the icon name box.
### Marker Badge
You can add more information to markers using **badges**, which are little circles that are added in the corners of markers based on criteria that you choose.
Up to 4 badges are supported per marker.
**The natural use case for badges is when you can add additional information on top of a marker.** For example, if you have an icon for `#food` markers, you can add badges that would apply to restaurants with vegan options, gluten-free, dog-friendly, etc.
Display rules can mix icon properties with badges in any way you see fit.
To add a badge to a display rule, in the display rule edit dialog, paste an emoji or up to 2 characters into the Symbol box. Markers that match the rule will have that badge, and possibly other badges from other matching display rules, starting from the top-left corner clockwise.
Badges can have a symbol, a text color, a background color, and a border in the syntax of a CSS [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) property, e.g. `1px solid black`.
**Warning:** having hundreds or thousands of badges displayed at once on the map can be resource-intensive for the rendering engine, especially on mobile. In this case, consider increasing the "max cluster size in pixels" setting to display less markers at once.
### Path Properties
Paths work similarly to markers, in the way that their style starts from the default rule, and properties of matching rules overwrite each other.
Like markers, you can set a rule like `tag:#hike` to a path and set to rule to have `red` for color.
The most useful properties to set for paths are `color`, `weight` and `opacity`, and a full list for advanced users (editable via JSON, see below) can be found [here](https://leafletjs.com/reference.html#path).
One key difference from markers is that stand-alone path files do not have a way to attach a tag to them; if you want to style some paths differently than others, you can use other query types, like name or `linkedfrom`. For example, you can have a central note named "My Runs" that will link to all the GPX files you want styled differently, and use a `linkedfrom` query in a display rule that will set these to red. See more about how to write such queries [here](#queries).
Also, paths do not supported badges, and there is no preview available for them at the moment in the edit dialog.
### Advanced: Editing Rules as JSON
The Edit Rule dialog allows you to directly edit a display rule as JSON, opening a few more options and control than the GUI provides.
- More options for marker icons can be found in [Leaflet.ExtraMarkers](https://github.com/coryasilva/Leaflet.ExtraMarkers#properties) properties. Note that some of these properties are known to not work with Map View.
- Path options reference can be found [here](https://leafletjs.com/reference.html#path).
- Marker badges have one more advanced property that is not present in the UI, `cssFilters`. This accepts a valid CSS `filter` string as defined [here](https://developer.mozilla.org/en-US/docs/Web/CSS/filter). For example, `"cssFilters": "grayscale(100%) brightness(0.8)"` can make an emoji grayscale and slightly dimmer.
## Search & Auto-Complete
Map View adds an Obsidian command named 'Add inline geolocation link', that you can (and encouraged) to map to a keyboard shortcut, e.g. `Ctrl+L` or `Ctrl+Shift+L`.
This command inserts an empty inline location template: `[](geo:)`.
When editing an inline location in this format, whether if you added it manually or using the command, if you start entering a link name, Map View will start offering locations based on a geocoding service.
Selecting one of the suggestions will fill-in the coordinates of the chosen locations and _not_ change your link name (assuming you prefer your own name rather than the formal one offered by the geocoding service).
![](img/geosearch-suggest.gif)
If your note is not yet marked as one including locations (by a `locations:`) tag in the front matter, this is added automatically.
**Important:** in order to use the default search provider (OSM Nominatim), you need to specify an e-mail address in the plugin settings.
**This does not require any registration.**
It is only because this free provider has limited resources and they need to be able to make sure no single user taxes the system.
### Changing a Geocoding Provider
By default, Map View is configured to use OpenStreetMap as the search provider.
If you prefer to use the Google Maps search, you can configure this in the plugin settings.
The Google Geocoding API is practically free or very cheap for normal note-taking usage, but you'd need to setup a project and obtain an API key from Google.
See [here](https://developers.google.com/maps/documentation/javascript/get-api-key) for more details.
If you want, you can add to your API key the slightly more expensive [Places API](https://developers.google.com/maps/documentation/places/web-service/cloud-setup) (now called "Google Places (New)"), then turn on "Use Google Places for searches" in the Map View settings.
For most reasonable note-taking usage, you will not likely go beyond the Places API free tier.
**Note:** usage of any geocoding provider is at your own risk, and it's your own responsibility to verify you are not violating the service's terms of usage.
The free OpenStreetMap provider (Nominatim) has limited resources, therefore Map View limits the rate of queries you can send to it, and requires per-user identification by e-mail as stated above.
### Google Places Templates
When using Google Maps Places API, templates can extract additional result data.
This has two steps:
1. Under "Google Places data fields to query", you need to specify in the plugin configuration what fields you want to be received in the Google Places search results. See [here](https://developers.google.com/maps/documentation/places/web-service/place-details#fieldmask) the list of available fields. Enlist any fields you want returned in queries using a comma-delimited list, e.g. `id,types,businessStatus`.
2. You can refer to these fields in the Map View "new note template" using the syntax `{{googleMapsPlacesData.fieldName}}`. For example, the following template will populate a `place_id` YAML field in your note's front matter with the `id` field returned from Google places, and add a tag like `#gym` using the `types` field (this assumes you defined the query fields in step 1 by the given example):
```
---
place_id: "{{googleMapsPlaceData.id}}"
---
#{{googleMapsPlaceData.types.0}}
```
Currently only Google Maps Places API supports this advanced templating feature.
### Migrating to Google Places API (New)
Google introduced a new Places API in 2025 and Map View is required to migrate for it in order for the service to continue working for all users.
To migrate your existing API key to Google Places API (New):
1. Visit the Google Cloud Admin [here](https://console.cloud.google.com/google/maps-apis).
2. You may need to select on top the project you created for creating the Places API, if you have more than one project.
3. Go to APIs & Services on the left. Search for "Places API (New)" and click Enable.
4. Go back, then click Keys & Credentials. Find your existing Places API key, and in its Actions menu, choose "Edit API key".
5. If under "API restrictions" you selected "Don't restrict key" -- you should be good to go. If you have "Restrict key", add "Places API (New)" that should be available after enabling it in step 3. Save the edited key.
Additionally, if you are using Google Places Templates (see above), field names were changed from the old API, and you need to explicitly add them in the plugin settings.
## Map Sources
By default, Map View uses the [CartoDB Voyager Map](https://github.com/CartoDB/basemap-styles), which is free for up to 75K requests per month.
However, you can change or add map sources in the configuration with any service that has a tiles API using a standard URL syntax.
There are many services of localized, specialized or just beautifully-rendered maps that you can use, sometimes following a free registration.
See a pretty comprehensive list [here](https://wiki.openstreetmap.org/wiki/Raster_tile_providers).
For providers that use an API key (e.g. MapTiler or Mapbox), consult the provider documentation for how to add the key to the API URL.
For example, in MapTiler it would be `https://api.maptiler.com/maps/outdoor/{z}/{x}/{y}.png?key=ABCDEFGH`.
Some providers have an extra setting for HiDPI ("retina") tiles, which look sharper on high-resolution displays; to use them automatically when a suitable display is detected, add `{r}` as an optional resolution identifier in the URL.
Although that's the case with this plugin in general, it's worth noting explicitly that using 3rd party map data properly, and making sure you are not violating any terms of use, is your own responsibility.
Note that Google Maps is not in that list, because although it does provide the same standard form of static tiles in the same URL format, the Google Maps terms of service makes it difficult to legally bundle the maps in an application.
If you have multiple map sources, they can be switched from the View pane.
Additionally, you can set an optional different dark theme URL for each map source.
If a dark theme is detected, or if you specifically change the map source type to Dark (using the drop down in the View pane), you will get the Dark URL if one is configured.
## Presets
If there is a map state you would like to save and easily come back to, you can save it as a preset.
To do so, open the Presets pane in the main plugin's controls, and click 'Save as' to save the current view with a name you can easily go back to.
If you enter an already-existing name, that preset will be overwritten.
The saved preset includes the map state (zoom & pan), the filters used, and if you check the box in the "save as" dialog -- also the chosen map source.
If you do not include the map source as part of the preset, switching to the newly-saved preset will use the currently-selected map source.
Presets _do not_ store the map's theme (light/dark).
The Default preset is special; you can save it using the 'Save as Default' button, and come back to it by clicking the Reset button, by choosing the Default preset from the box, or by opening a fresh Map View that has no previously saved state.
## Open In
Many context menus of Map View display a customizable Open In list, which can open a given location in external sources.
These sources can be Google Maps, OpenStreetMap, specialized mapping tools or pretty much anything you use for viewing locations.
![](img/open-in.png)
The Open In list is shown:
- When right-clicking on the map.
- When right-clicking a marker on the map.
- When right-clicking a geolocation link in a note (if not turned off in the settings).
- When right-clicking a line in a note that has a location.
- In the context menu of a note that has a front matter location.
This list can be edited through the plugin's settings menu, with a name that will be displayed in the context menus and a URL pattern. The URL pattern has two parameters -- `{x}` and `{y}` -- that will be replaced by the latitude and longitude of the clicked location. There's also an optional `{name}` parameter that can be replaced with the name of the location (the note name or inline link name).
![](img/custom-open-in.png)
Popular choices may be:
- Google Maps: `https://maps.google.com/?q={x},{y}`
- OpenStreetMap: `https://www.openstreetmap.org/#map=16/{x}/{y}` (replace `16` with your preferred zoom level)
- Waze (online dropped pin): `https://ul.waze.com/ul?ll={x}%2C{y}&navigate=yes&zoom=17` (replace `17` with your preferred zoom level)
And you can figure out many other mapping services just by inspecting the URL.
## Routing
You can use Map View to calculate routes between points on the map, either directly (using the GraphHopper API) or by launching an external tool like Google maps.
1. **Choose a starting point** by right-clicking a marker or a map location and choose "mark as routing source". Alternatively, click the flag icon on the right side of the map and select a marker from the list.
2. **Choose a destination** by right-clicking a marker or a map location and choose "route to point". Alternatively, after selecting a routing source, you can also select a destination using the "select a routing destination" button on the right side of the map (below the flag from step 1).
3. In the menu that opens, choose between routing using an external service (by default Google Maps) or through the GraphHopper API.
4. If one of the GraphHopper options are selected, the route is displayed on the map with a time and distance estimation.
![](img/routing.gif)
### External Tool Configuration
By default Map View is configured to use Google Maps as the external routing service.
You can change this in the settings under Routing -> External routing service URL.
### GraphHopper Configuration
[GraphHopper](https://www.graphhopper.com/) is an open-source-based service that provides a routing API with a generous free tier (as of mid-2025, the [free tier](https://www.graphhopper.com/pricing/) provides 500 route requests per day).
You can sign up [here](https://graphhopper.com/dashboard/signup), obtain an API key, and fill it in the "GraphHopper API key" field under the Map View -> Routing settings.
The free plan offers 3 **routing profiles**: `foot`, `bike` and `car`.
The paid plans have more profiles (see [here](https://docs.graphhopper.com/openapi/map-data-and-routing-profiles/openstreetmap/geographical-coverage)) and allow further flexibility.
For advanced users who want fine-grained control over GraphHopper routing, you may specify "extra parameters" that will be added to GraphHopper requests. For example, the `snap_preventions` parameter may be added to fine-tune which points the routing engine uses as the start and end points.
See [here](https://docs.graphhopper.com/openapi/routing/postroute) for a full documentation of the API.
## URL Parsing Rules
As described above, Map View uses _URL parsing rules_ in several places to provide the ability to parse URLs (or other strings) from external sources and convert them to standard geolocations.
1. When right-clicking a line with a recognized link, a "Convert to Geolocation" entry will be shown in the editor context menu.
2. When a recognized link is detected in the system clipboard, a "Paste as Geolocation" entry will be added in the editor context menu.
3. In the "New geolocation note" dialog and map search, pasting a supported URL will parse the geolocation.
URL parsing rules can be configured in the plugin's configuration pane and requires familiarity with regular expressions.
The syntax expects two captures group and you can configure if they are parsed as `lat, lng` (most common) or `lng, lat`.
And if you think your added regular expressions are solid enough, please add them to the plugin using a PR so others can benefit!
![](img/url-parsing.png)
## View URLs
You can save the current map state as a URL, which will open from other apps or from within Obsidian.
Click "Copy Map View URL" from the view's "more options" context menu, or "Copy URL" from the map Presets control.
You can paste the resulting `obsidian://` URL in any local app on your computer or phone, and it will launch Obsidian with Map View in the same view you saved.
Alternatively, you can paste this link inside a note and make it clickable by making it a Markdown link: `[Link name](url...)`.
This is really useful for going to a specific view (with its query, map source, zoom, pan etc) that is related to a note, e.g. a trip plan.
## Follow Active Note
Map View has a mode on which the map refocuses according to the currently active file, so if you have Map View open in its own pane, it can follow whatever file you are currently focused on.
This is closely related to the setting of "map follows search results", and probably works most intuitively when it is on.
The specific behavior of how to "follow" the active note can be configured via the 'query format for "follow active note"' setting in the configuration.
By default, Map View uses the [query](#queries) `path:"$PATH$"`, which means that when you switch to a note, the view automatically updates the query to show only the markers within the path of this note. You can edit this setting to achieve more fine-grained behaviors, for example:
- Use `linkedfrom:"$PATH$"` for a more elaborate inclusion of markers from both the file you're on and files it links to.
- Use `linkedfrom:"$PATH$" OR linkedto:"$PATH$"` to include markers that the active note links to and also markers that _link to this file_.
## Offline Tiles
Map View can store map tiles locally, to be used for caching and offline usage.
Whenever a map tile is needed to display a Map View or an embedded map, it is first searched in the local storage, leading to considerably better performance and less data usage the more you use Map View.
By default every downloaded map tile is saved to the cache, and downloaded tiles are stored for 6 months or up to 2GB (when the max storage size is reached, tiles are purged by age). These values are configurable under the "Offline Maps" section of the plugin's settings.
Additionally, you can batch-download map tiles that you expect to use often or offline:
- Open the Downloaded Tiles dialog by clicking "offline maps..." from the Map View context menu or "offline storage..." from the plugin settings.
- Click "download tiles..." to open the new download job dialog.
- This dialog creates a new download job based on the currently-active Map View, i.e. it will save the area of the map currently displayed.
- You can decide on a range of zoom levels for which to download tiles in the currently-displayed area of the map, with the current zoom you are viewing displayed under "current zoom level".
- If you choose "skip existing tiles", the download job will include only tiles that don't yet exist in the offline cache, but if you have tiles from a long time ago and the area has changed, your map may be an inconsistent mix of new and old tiles.
- **WARNING:** it is up to you to make sure you do not flood the tiles provider, as well as to make sure that caching tiles locally does not violate any terms of use (most providers encourage that, as it saves bandwidth, but it's up to you to make sure with your own specific tile providers).
- To prevent an accidental flood of tile providers, a maximum of 1 million tiles per download job is hard-coded.
![](img/offline-download.png)
Once starting a download job it progresses in the background, and you can cancel it or track its progress via the Downloaded Tiles dialog. **There is no need to keep the dialog open**, but if it's a mobile device (i.e. iOS or Android), the OS might pause the download when the device screen turns off, or close Obsidian completely.
**General tips:**
- Keep in mind that any click on the map's '+' button increases the zoom level by one. You can use that to assess the level of detail you want to keep offline; The number of tiles to download and the size to store increase exponentially between zoom levels, so if you want to save a large area for offline usage, you probably don't want to go beyond 5-6 zoom levels.
- You can selectively store different areas in different levels of detail, e.g. 4 zoom levels for your whole country and then 4 more levels for your city or area. Just start a few consecutive downloads while potentially marking "skip existing tiles".
- If you want to keep a large offline storage, make sure to adjust the "max offline tiles storage" plugin setting.
In order to get a sense of what tiles are available offline, you can check "highlight offline tiles" from the Map View context menu. It will mark with a blue box the tiles that are available locally. The mark is updated only when the map is redrawn, so to visualize the automatic cache (if turned on), go to an area and zoom level that was not downloaded, zoom in, then zoom back out.
Technically, tiles are stored locally in IndexedDB blobs.
There is currently no support to sync them between devices.
## Links View
Map View can optionally draw edges between markers of linked notes.
To turn this on, open the "Links" drop-down on the map controls and choose "show links".
The way it works is that all the markers of a given file (sources) are shown as linked to the markers pointed by the links in that file (destinations).
A destination can be:
- A whole file -- then all the markers in the source file are linked to all the markers in the destination file.
- A heading/block -- then all the markers in the source file are linked to:
- The front-matter marker of the destination file, if any.
- Only inline locations in the referenced heading/block.
Finally, you can configure the color used for the edges on the map using any valid [HTML color name](https://www.w3schools.com/tags/ref_colornames.asp) or a hex value like `#faebd7`.
**Warning!** heavily-linked maps are resource-intensive, so it's advisable to turn on links display only when your markers are reasonably filtered. Due to the way they work, links may need to be recalculated every time notes with geolocations are changed. Open Map Views (even background ones) with thousands of visible links may cause hiccups when typing inside geolocation notes that are included in these views' filters.
![](img/links.png)
## Obsidian Bases View
On Obsidian 1.10 and above, Map View implements a view for Obsidian Bases, on which the map controls work as Bases controls, and all Map View functionality continues to work the same.
To use this, in the Bases view selector click Add View, then choose Map View as the view type.
Filtering will be based on your Base filter, and you can add an additional Map View query (e.g. `tag:#dogs`) in the view's "additional filters" field.
Note: Bases work only at the resolution of complete files and do not support inline tags, inline markers etc.
## Import from KML
Map View has a built-in tool to convert geolocations from a KML file, typically generated by a tool like Google My Maps.
(To generate a KML from Google My Maps, in the map's context menu click "download KML", and select "export as KML instead of KMZ".)
To use it, open a new or an existing note, and from the note context menu click "import geolocations from file..."
Select a KML file to import, optionally edit the template used to create geolocations, then click "import into note".
## Relation to Obsidian Leaflet
Users who are looking to add mapping capabilities to Obsidian may want to also look at the great [Obsidian Leaflet plugin](https://github.com/valentine195/obsidian-leaflet-plugin).
And while both plugins are about maps and use Leaflet.js as their visual engine, they represent different approaches.
**Whats similar?**
- Both plugins support creating maps from your notes, or a folder of notes, with extensive options for customization.
- Both support creating a map for a specific use (e.g. a trip plan), from a focused set of notes, embedding the map in a note etc.
**What's different?**
- Map View started as a view (similarly to Obsidians Graph View) rather than an embedded syntax. And while it now supports embedding maps in notes, the main interaction with it is with a GUI and not with a code block. Leaflet, in contrast, offers its customizations mostly via code in its code block.
- Map View parses geolocations from the front-matter of notes and also from an inline syntax within notes (allowing multiple geolocations in a note, also with different individual tags), while Leaflet focuses on a geolocation-per-note approach (and further locations can be added to the map code itself).
- Map View is meant to be a research tool based on your notes: it offers interactive queries through a UI, for example, in order to get insights from it or consult it when planning a trip or arriving to a location. In contrast, Leaflet seems to be more directed towards presenting the most fine-grained customizable map.
- Map View has powerful geolocation search tools that allow you to quickly add locations from within a note or from the map.
- Map View builds marker icons based on customizable rules, so you do stuff like “color all #food/\* items in red”, on top of that “give #food/pizza a pizza icon”, and all pizza-tagged places will have a red pizza icon. In Leaflet marker icons are given individually for each marker, or with a global setting that assigns a full icon to a tag.
- Leaflet supports GPX files, overlays and GeoJSON shapes to be added to the map.
- Given the stand-alone nature of its maps, Leaflet is probably more suitable for TTRPG maps. (These are also possible with Map View, but I believe it comes less naturally.)
## Changelog
### 6.1.3
- Most importantly: fix to GPX registration causing plugin crashes.
- Fix to https://github.com/esm7/obsidian-map-view/issues/385.
- Fix to https://github.com/esm7/obsidian-map-view/issues/383.
Behind the scenes: long-overdue, addition of unit tests for many low-level functionality of the plugin.
### 6.1.2
- By a very common request, Map View on mobile can now auto-add the current location to notes (e.g. your daily notes). See [here](#auto-adding-location-to-notes) for more details.
- Added icons to the commands that Map View registers, so they're more easily visible if added to the mobile toolbar.
### 6.1.1
Fixed issues with embedded maps (https://github.com/esm7/obsidian-map-view/issues/372).
### 6.1.0
- Finally, real-time location support using the new location permissions of Obsidian Mobile 1.11!
- When starting Map View for the first time, you will be asked to grant location permissions. If you do, Map View will show your current location, and you can zoom to it using the button on the right toolbar.
- A new "follow my location" toggle in the View drop-down (and the Bases settings) that will pan the map to follow your current location.
- All the relevant commands were revised to use the new location permissions, see [here](#gps-location-support).
- Location support is not yet possible in Obsidian Desktop (Linux, Windows, Mac) -- only mobile. If you want this, vote [here](https://forum.obsidian.md/t/geolocation-ability-in-desktop-app/109686).
- The Geo-Helper app is now obsolete and unsupported, in spite of desktop users not being covered by the new mechanism (yet?)
- Map View now shows a moving indicator if opened before it fully loads.
Apologies to users waiting for some other features and various bug fixes -- I thought this real-time location support will benefit the vast majority of users and therefore prioritized it way above anything else.
### 6.0.5
- Fix to https://github.com/esm7/obsidian-map-view/issues/367.
### 6.0.4
- Fix to support emojis in tag names (https://github.com/esm7/obsidian-map-view/issues/348).
- Fix for plugin removing blank lines in note embeds (https://github.com/esm7/obsidian-map-view/issues/368).
- An improvement to some cases that may still cause marker rules to disappear on upgrade (https://github.com/esm7/obsidian-map-view/issues/359).
### 6.0.3
- Fix to https://github.com/esm7/obsidian-map-view/issues/359, not allowing anymore non-preset display rules with an empty query.
- Fix to https://github.com/esm7/obsidian-map-view/issues/358, no more setting the `location` property to type `multitext`, which seems to do more harm than good.
- Map View embeds through Bases now works, and an added Embedded Height control was added.
### 6.0.2
Fix to https://github.com/esm7/obsidian-map-view/issues/354.
### 6.0.1
- Fix to https://github.com/esm7/obsidian-map-view/issues/352.
### 6.0.0
This is a very big release with a long list of new features, fixes and **breaking changes**.
**Important Breaking Changes - DO NOT SKIP:**
- If you are using Google Places API for geosearches, this version upgrades to the new API introduced in 2025. This API is not backwards-compatible with the previous one, and to use it, you may need to update your credentials in Google. See migration guide [here](#migrating-to-google-places-api-new).
- If you are using [Google Places templates](#google-places-templates), the names of fields were changed in the new Places API, and you need to explicitly add them in the plugin settings.
- If you are using the OpenStreetMap geocoding provider (which is the default), you now need to provide an email address in the plugin configuration -- due to enforcement of usage restrictions from the OSM side.
**IMPORTANT NOTE: the v6.0 configuration file is not backwards-compatible.** If you wanna be on the safe side, before upgrading you can backup your Map View config file by copying `VAULT_DIR/.obsidian/plugins/obsidian-map-view/data.json`.
**Big New Stuff:**
- Support for [paths](#paths), either in stand-alone files (GPX etc) or inline within notes.
- A complete redo of what used to be called "marker rules" into a more powerful "display rules" idea, see [here](#marker--path-display-rules).
- Routing -- built-in tools for calculating driving, cycling and walking paths using the GraphHopper API, see [here](#routing).
- Badges -- cute little icons that can be added to markers with display rules. See [here](#marker-badge).
- Edit Mode -- a complete new interface for adding and modifying markers and paths directly from the map.
- An experimental Obsidian Bases view mode, see [here](#obsidian-bases-view).
**Smaller New Stuff:**
- Major performance improvements, Map View should now open instantly after an initial load, and filtering works much faster.
- Added `opacity` as a marker icon property.
- A (default) new setting for only one controls section to be expanded at a time.
- Comeback of "Show native Obsidian popup on marker hover" due to user request (https://github.com/esm7/obsidian-map-view/issues/235).
- Modifying notes now properly update according to the active filter.
- Query tag suggestions now only show tags present on the map
- Added a "focus current note in Map View" command.
**Bug Fixes (some long overdue)**:
- Fixes to respect Obsidian's new "always focus new tab" setting.
- Fix for https://github.com/esm7/obsidian-map-view/issues/308 (thanks @edzillion!).
- Inline location bug on iOS (https://github.com/esm7/obsidian-map-view/issues/301).
- Context menu 'open in' fix for Reading View (https://github.com/esm7/obsidian-map-view/issues/326).
- Fixed file-menu event not properly registered to the plugin (https://github.com/esm7/obsidian-map-view/issues/327).
- Fix to the `autoFit` state flag of embedded maps to work more consistently.
- Map View now sets the type of the 'location' property to List, to prevent issues of Obsidian corrupting it.
For bugs and feature requests, open an issue [here](https://github.com/esm7/obsidian-map-view/issues).

109
docs/.vitepress/config.ts Normal file
View file

@ -0,0 +1,109 @@
import { defineConfig } from 'vitepress';
export default defineConfig({
title: 'Map View',
description:
'An interactive map plugin for Obsidian.md — turn your vault into a personal GIS.',
base: '/obsidian-map-view/',
themeConfig: {
logo: '/img/main.png',
nav: [
{ text: 'Guide', link: '/quick-start' },
{ text: 'Changelog', link: '/changelog' },
],
sidebar: [
{
text: 'Overview',
link: '/',
},
{
text: 'Getting Started',
items: [
{ text: 'Quick Start', link: '/quick-start' },
{
text: 'Location Formats',
link: '/location-formats',
},
{
text: 'Adding Locations',
link: '/adding-locations',
},
{ text: 'GPS Support', link: '/gps-support' },
],
},
{
text: 'Features',
items: [
{ text: 'Embedding Maps', link: '/embedding-maps' },
{
text: 'Paths (GPX, KML, GeoJSON)',
link: '/paths',
},
{ text: 'Queries', link: '/queries' },
{ text: 'Display Rules', link: '/display-rules' },
{
text: 'Search & Geocoding',
link: '/search',
},
{ text: 'Map Sources', link: '/map-sources' },
{ text: 'Presets', link: '/presets' },
{ text: 'Routing', link: '/routing' },
{ text: 'Open In', link: '/open-in' },
{
text: 'URL Parsing Rules',
link: '/url-parsing',
},
{ text: 'Offline Tiles', link: '/offline-tiles' },
{ text: 'Links View', link: '/links-view' },
{
text: 'Follow Active Note',
link: '/follow-active-note',
},
{
text: 'Obsidian Bases View',
link: '/bases-view',
},
{ text: 'Import from KML', link: '/import-kml' },
{ text: 'View URLs', link: '/view-urls' },
],
},
{
text: 'Reference',
items: [
{
text: 'vs. Obsidian Leaflet',
link: '/vs-leaflet',
},
{ text: 'Changelog', link: '/changelog' },
],
},
],
socialLinks: [
{
icon: 'github',
link: 'https://github.com/esm7/obsidian-map-view',
},
],
footer: {
message:
'Released under the <a href="https://github.com/esm7/obsidian-map-view/blob/master/LICENSE">MIT License</a>.',
copyright:
'If you find Map View useful, <a href="https://www.buymeacoffee.com/esm7">buy me a coffee</a> ☕',
},
editLink: {
pattern:
'https://github.com/esm7/obsidian-map-view/edit/master/docs/:path',
text: 'Edit this page on GitHub',
},
search: {
provider: 'local',
},
},
});

77
docs/adding-locations.md Normal file
View file

@ -0,0 +1,77 @@
# Adding Locations to Notes
Map View offers many ways to add geolocations to your notes.
## From Anywhere in Obsidian
Map View adds an Obsidian command named **"New geolocation note"** that you can map to a hotkey and use anywhere in Obsidian.
This opens a dialog where you can:
- Search by address or location name (using your [configured geocoding provider](search.md))
- Paste a URL using the built-in or custom [URL parsing rules](url-parsing.md)
## In an Existing Note
### Inline Geolocation Link
Create an inline geolocation link in the format `[](geo:)`. If you start typing inside the link name (the brackets), Map View initiates a location search. Confirming an option fills in the coordinates.
To streamline this, Map View adds the command **"Add inline geolocation link"** — map it to a keyboard shortcut (e.g. `Alt+L`).
### Front Matter Geolocation
Use the Obsidian command **"Add geolocation (front matter) to current note"**. This opens the same dialog as "new geolocation note".
### Paste as Geolocation
Map View monitors the system clipboard. When the clipboard contains an encoded geolocation (e.g. from Google Maps), a **"Paste as geolocation"** entry appears in the editor context menu.
Alternatively, right-click a URL or supported formatted string already in a note and choose **"Convert to geolocation"**.
By default Map View parses URLs from:
- OpenStreetMap "show address" links
- A generic "lat, lng" encoding used by many services
#### Tip: Copying from Google Maps
Google Maps on desktop offers an easy shortcut for copying universal `lat, lng` coordinates:
1. Right-click anywhere in Google Maps.
2. The first menu item is the universal coordinates — clicking it copies them to your clipboard.
3. In any Obsidian note, right-click and choose **"paste as geolocation"**, or paste the coordinates into any Map View search box.
![](/img/google-copy.png)
## From the Map
### Right-Click to Create a Note
Right-click the map and choose **"new note here"** to create a new note at that location. You can create a note with a front matter geolocation or with an inline geolocation.
![](/img/new-note.png)
The map can be searched using the tool in the upper-right, so you can jump to any place. [URL parsing rules](url-parsing.md) work here too.
![](/img/search.gif)
### Edit Mode
Click the **pencil icon** on the right to enter Edit Mode:
1. Click the red **"Choose Note"** button to select which note to edit.
2. Add markers or other shapes using the marker tools below the pencil icon.
3. You can also right-click anywhere on the map and select **"Add to Edit Mode note"**.
In Edit Mode you can also move or modify existing markers and paths.
### Copy Geolocation
Right-click the map to use one of the **"copy geolocation"** options and paste the result into a note.
![](/img/copy.png)
## Import from KML
Map View has a built-in tool to convert geolocations from a KML file (e.g. from Google My Maps). See [Import from KML](import-kml.md).

23
docs/bases-view.md Normal file
View file

@ -0,0 +1,23 @@
# Obsidian Bases View
On Obsidian 1.10 and above, Map View implements a **view for Obsidian Bases**, where the map controls work as Bases controls and all Map View functionality continues to work.
## Setting Up a Bases Map View
1. In the Bases view selector, click **Add View**.
2. Choose **Map View** as the view type.
## Filtering
- Filtering is based on your **Base filter**.
- Add an optional **additional Map View query** (e.g. `tag:#dogs`) in the view's "additional filters" field.
## Limitations
::: info
Bases work only at the resolution of complete files. They do **not** support:
- Inline tags
- Inline markers
- Other inline content
:::

1
docs/changelog.md Normal file
View file

@ -0,0 +1 @@
<!--@include: ../CHANGELOG.md-->

105
docs/display-rules.md Normal file
View file

@ -0,0 +1,105 @@
# Marker & Path Display Rules
![](/img/display-rules.png)
Map View includes a powerful rule-based system for customizing how markers and paths appear on the map. These are called **Display Rules**.
## How Display Rules Work
Each display rule consists of a **[query](queries.md)** and a set of **visual properties**. When Map View decides how to display a marker or path:
1. Start with the **Default** rule's properties (e.g. a blue marker with a circle icon).
2. Evaluate each subsequent rule in order.
3. For each rule whose query matches the marker/path, **overwrite** only the properties that rule defines.
**Example:** The default rule sets a blue marker with an `fa-circle` icon. A rule `tag:#food` sets only the icon to `fa-utensils`. The resulting marker is **blue** (from default, not overridden) with a **utensils icon** (from the food rule).
## Editing Display Rules
Open the plugin settings and click the button under **"Marker & Path Display Rules"**.
You'll see the list of active rules. You can:
- Add new rules
- Change the order of rules (the Default rule is always first)
- Edit existing rules
When editing a rule, all properties are **optional** — only set the ones you want this rule to override.
![](/img/edit-display-rule.png)
## Marker Icon Properties
Icons are based on **emojis** or **[Font Awesome](https://fontawesome.com/)** icons. Marker shapes, colors, and sizes are based on [Leaflet.ExtraMarkers](https://github.com/coryasilva/Leaflet.ExtraMarkers#properties).
An additional `simple-circle` shape draws a circle at the given color without a pin.
**Example:** To give `#travel`-tagged markers a bus icon:
1. Add a display rule with query `tag:#travel`.
2. Click Edit, search Font Awesome for `fa-bus`, enter it in the 'icon' box.
Or paste an emoji directly into the icon name box (e.g. from [Emojipedia](https://emojipedia.org)).
Additional marker properties:
- `opacity` — controls marker transparency
## Marker Badges
Badges are small circles added to marker corners based on matching display rules. Up to **4 badges** per marker are supported.
::: tip Natural Use Case
If you have an icon for `#food` markers, add badges for vegan options, gluten-free, dog-friendly, etc. — each from a separate display rule.
:::
### Adding a Badge
In the display rule edit dialog, paste an emoji or up to 2 characters into the **Symbol** box.
Badge properties:
- **Symbol** — emoji or 1-2 character text
- **Text color** — color of the symbol
- **Background color** — badge background
- **Border** — CSS [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) string, e.g. `1px solid black`
Matching badges appear starting from the top-left corner, clockwise.
::: warning Performance
Hundreds or thousands of badges rendered at once can be resource-intensive, especially on mobile. Consider increasing the "max cluster size in pixels" setting if performance degrades.
:::
## Path Properties
Paths work the same way: the default rule applies first, then matching rules overwrite properties.
Most useful path properties:
| Property | Description |
| --------- | ----------------------------- |
| `color` | Line color (CSS color string) |
| `weight` | Line width in pixels |
| `opacity` | Line opacity (0.01.0) |
A full list of path properties (for advanced JSON editing) is in [Leaflet's path documentation](https://leafletjs.com/reference.html#path).
::: info
Stand-alone path files don't support tags -- only inline paths do. Use `name` or `linkedfrom` queries to style stand-alone path files.
:::
**Example:** Have a central note "My Runs" that links to all your GPX files. Use the display rule query `linkedfrom:"My Runs"` to style these paths red.
Paths do not support badges.
## Advanced: Editing Rules as JSON
The Edit Rule dialog has a **"Edit as JSON"** option that exposes additional properties:
- Extra marker icon options from [Leaflet.ExtraMarkers](https://github.com/coryasilva/Leaflet.ExtraMarkers#properties)
- Full path options from [Leaflet path docs](https://leafletjs.com/reference.html#path)
- The `cssFilters` badge property: accepts a CSS `filter` string, e.g.:
```json
"cssFilters": "grayscale(100%) brightness(0.8)"
```
This makes an emoji badge grayscale and slightly dimmer.

71
docs/embedding-maps.md Normal file
View file

@ -0,0 +1,71 @@
# Embedding Maps in Notes
Map View supports embedding interactive maps in notes using Obsidian's code block format. Embedded maps are **live views** that update as your notes change.
## How to Embed a Map
### Method 1: Copy from an Existing Map View
1. Open Map View and configure it to your liking (query, zoom, pan, etc.).
2. Open the **Presets** pane and click **'Copy Block'**.
3. Paste the resulting code block into any note.
![](/img/copy-block-embed.gif)
### Method 2: Embed from a Note
Right-click in a note editor and choose **"embed a Map View"** from the context menu, then enter a search term for the map center.
Alternatively, use the Obsidian command **"Map View: add an embedded map"** (assignable to a keyboard shortcut).
![](/img/quick-embed.gif)
## Updating an Embedded Map
Embedded maps support light adjustments directly (zoom, pan, height). Click the **'Save'** button that appears to persist those changes.
For bigger adjustments (new query, different view):
1. Click the **Open** button on the embedded map to open it in a full Map View.
2. Make your changes.
3. Click **'Update from open Map View'** in the embed's View menu.
::: info
If you have multiple full Map View instances open, 'Update from open Map View' may pick the wrong one. Close unwanted instances first.
:::
## Embedded Maps in Canvas
Embedded maps work in Obsidian Canvas and update live.
![](/img/canvas.gif)
## Advanced Options
### The `$filename$` Template Parameter
The `query` field in an embedded map supports a `$filename$` template parameter. This is useful for note templates:
```json
"query":"linkedfrom:\"$filename$\" OR linkedto:\"$filename$\""
```
The map will always reference the host note it's embedded in.
::: warning Known Annoyance
The `$filename$` replacement happens when the code block is processed. If you edit the embed interactively (zoom, pan, Save), the `query` field gets overwritten with the actual file name rather than the template.
:::
### The `autoFit` Flag
Add `"autoFit":true` to the code block JSON to make the map auto-fit to its markers on load, overriding the saved zoom/pan.
```json
{"autoFit":true, ...}
```
This causes a visible zoom/pan animation if the saved state differs from the auto-fitted one. Click Save to freeze the new state.
### Custom View Settings
The embedded map code block supports an optional `customViewSettings` object for UI adjustments. See the properties and defaults in [`embeddedMap.ts`](https://github.com/esm7/obsidian-map-view/blob/master/src/embeddedMap.ts#L31-L47).

View file

@ -0,0 +1,33 @@
# Follow Active Note
Map View has a mode where the map **refocuses according to the currently active file**. With Map View open in its own pane, it follows whatever note you are currently focused on.
This works most intuitively with **"map follows search results"** turned on.
## Configuration
The behavior when following an active note is configured via the **"query format for 'follow active note'"** setting.
The default query is:
```
path:"$PATH$"
```
This shows only the markers within the path of the current note when you switch to it.
## Custom Follow Behaviors
You can edit the query format for more sophisticated behaviors:
```
linkedfrom:"$PATH$"
```
Include markers from the file you're on **and** files it links to.
```
linkedfrom:"$PATH$" OR linkedto:"$PATH$"
```
Include markers that the active note links to **and** markers that link back to this file.

58
docs/gps-support.md Normal file
View file

@ -0,0 +1,58 @@
# GPS Location Support
Starting with Obsidian Mobile 1.11, plugins can be granted precise location permission, allowing Map View to show and use your exact geolocation.
GPS support is enabled by default. To disable it, turn off **"GPS support"** in the plugin settings.
## Showing Your Location
When your location is available, focus on it using the dedicated icon on the right toolbar.
You can also set **"follow my location"** in the view settings to automatically pan the map as you move.
## GPS Commands
The following commands are available when GPS is active:
| Command | Description |
| ------------------------------------------------------- | ----------------------------------------------------------------------- |
| **GPS: find location and focus** | Open Map View and focus on your current location |
| **GPS: focus and follow me** | Same as above, but also enables "follow my location" |
| **GPS: add geolocation (inline) at current position** | Add your current location as an inline link to the note you are editing |
| **GPS: add geolocation (front matter) to current note** | Add your current location to the note's front matter |
| **GPS: copy inline location** | Copy your current location as an inline link to the clipboard |
| **GPS: new geolocation note** | Create a new note at your current location |
::: tip
Map commands you use often to the **mobile toolbar** for quickly adding the current location to notes.
:::
## Routing from Current Location
When a GPS location is available, clicking an existing marker gives you the option to **"route to point"** from your current location without needing to manually choose a routing source. See [Routing](routing.md).
## Auto-Adding Location to Notes (Mobile)
On Obsidian Mobile, you can configure Map View to **automatically add your current location to notes** when they are opened or created.
A common use case is adding the current location to your daily note.
### How It Works
By default, Map View fills in the current location when it finds an **empty `location` property** in a note, except for notes whose name contains the word "template" (configurable).
### Setup
Add an empty `location` property to the template that creates your target notes (e.g. your daily note template):
```yaml
---
location:
---
```
When a note created from this template is opened, Map View will automatically fill in the current GPS coordinates.
::: info
Location support is not available on Obsidian Desktop (Linux, Windows, Mac) — only mobile. Vote for this feature [here](https://forum.obsidian.md/t/geolocation-ability-in-desktop-app/109686).
:::

19
docs/import-kml.md Normal file
View file

@ -0,0 +1,19 @@
# Import from KML
Map View has a built-in tool to convert geolocations from a **KML file**, typically generated by a tool like Google My Maps.
## Generating a KML from Google My Maps
1. In Google My Maps, open the map's context menu.
2. Click **"Download KML"**.
3. Select **"Export as KML instead of KMZ"**.
## Importing into a Note
1. Open a new or existing note.
2. From the note context menu, click **"import geolocations from file..."**.
3. Select your KML file.
4. Optionally edit the template used to create geolocations.
5. Click **"import into note"**.
The imported geolocations are added as inline links to the note.

34
docs/index.md Normal file
View file

@ -0,0 +1,34 @@
---
layout: home
hero:
name: 'Map View'
text: 'Interactive maps for Obsidian'
tagline: Transform your notes vault into a personal geographic information system.
image:
src: /img/main.png
alt: Map View screenshot
actions:
- theme: brand
text: Get Started
link: /quick-start
- theme: alt
text: View on GitHub
link: https://github.com/esm7/obsidian-map-view
features:
- title: Geolocation in Notes
details: Store geolocations in note front matter or as inline links with multiple locations per note. Add them via search, from the map, or from your device GPS.
- title: Powerful Queries
details: Filter what's shown on the map with a boolean query language — combine tags, paths, linked notes, properties, and more.
- title: Display Rules
details: Customize marker icons, badges, colors, and path styles using query-based rules. The same system that powers filtering also drives your visual customization.
- title: Paths & Shapes
details: View and draw paths in GPX, KML, TCX and GeoJSON formats. Edit Mode lets you draw directly on the map and save to notes.
- title: Routing
details: Calculate driving, cycling, and walking routes between map points using the GraphHopper API, or open in an external service.
- title: Offline Maps
details: Tiles are cached automatically for performance. Batch-download areas for offline use.
- title: Obsidian Bases
details: Full integration with Obsidian Bases for even more powerful queries and displays.
---

30
docs/links-view.md Normal file
View file

@ -0,0 +1,30 @@
# Links View
Map View can optionally draw **edges between markers** of linked notes, creating a visual representation of your note connections on the map.
## Enabling Links
Open the **Links** drop-down in the map controls and choose **"show links"**.
You can also configure the edge color using any valid [HTML color name](https://www.w3schools.com/tags/ref_colornames.asp) or hex value (e.g. `#faebd7`).
![](/img/links.png)
## How Links Work
All markers in a **source** file are shown as linked to the markers in **destination** files.
A destination can be:
- **A whole file** — all markers in the source are linked to all markers in the destination file.
- **A heading or block** — all markers in the source are linked to:
- The front-matter marker of the destination file (if any)
- Only inline markers within the referenced heading or block
## Performance Warning
::: warning
Heavily-linked maps are resource-intensive. Enabling links is advisable only when your markers are **reasonably filtered**.
Links may need to be recalculated every time notes with geolocations change. Open Map Views with thousands of visible links may cause noticeable lag when typing in geolocation notes included in those views' filters.
:::

93
docs/location-formats.md Normal file
View file

@ -0,0 +1,93 @@
# Location Formats
Map View scans your notes and parses two types of location data: **front matter locations** and **inline locations**.
::: tip
The best way to use Map View is to never enter geolocations manually — let the plugin handle it. But you do need to understand the difference between front matter and inline formats to decide which to use.
:::
## Front Matter Location
A location in a note's [front matter](https://help.obsidian.md/Advanced+topics/YAML+front+matter):
```yaml
---
location: 40.6892494,-74.0466891
---
```
This is best for notes that represent a **single specific location** (e.g. a restaurant note, a hike note).
### Alternative Front Matter Syntax
The older array format (compatible with obsidian-leaflet) is also supported:
```yaml
---
location: [40.6892494, -74.0466891]
---
```
And the Obsidian property editor format:
```yaml
location:
- '39.100105'
- '-94.5781416'
```
Or:
```yaml
location:
- 39.100105,-94.5781416
```
The `lat,lng` format (first example) is encouraged for Obsidian 1.4 and above, if you happen to enter locations manually for some reason.
## Inline Location URLs
Inline locations use the format `[link-name](geo:lat,lng)` and allow **multiple markers in the same note**.
To use inline locations, the note must have a `locations:` tag in its front matter (note: `locations`, not `location`). Map View adds this automatically in most cases.
```yaml
---
locations:
---
# Trip Plan
Point 1: [Hudson River](geo:42.277578,-76.1598107)
... more note content ...
Point 2: [New Haven](geo:41.2982672,-72.9991356)
```
Notes with multiple markers will show multiple markers on the map, all with the same note name. Clicking a marker jumps to the correct location within the note.
## Inline Tags
Inline locations support **inline tags** in the format `tag:tagname` (without the `#` sign):
```
Point 1: [Hudson River](geo:42.277578,-76.1598107) tag:dogs
```
This adds the tag `#dogs` specifically to that point, regardless of the note's own tags. Multiple inline tags are separated with spaces:
```
[](geo:42.2,-76.15) tag:dogs tag:trip
```
::: info
You must use `tag:` **without** the `#` sign for inline tags. Map View adds `#` internally for queries and display rules.
:::
## Custom Tag for Inline Geolocations
Instead of a `locations:` YAML tag, you can use a custom note tag. See **"tag name to denote inline geolocations"** in the settings.
::: warning
Having a non-empty "tag name to denote inline geolocations" setting currently slows down Map View significantly. This might be addressed in future releases.
:::

43
docs/map-sources.md Normal file
View file

@ -0,0 +1,43 @@
# Map Sources
## Default Map Source
By default, Map View uses the [CartoDB Voyager Map](https://github.com/CartoDB/basemap-styles), which is free for up to 75K requests per month.
## Adding Map Sources
You can add any map source that provides tiles via a standard URL in the plugin configuration. Many services offer localized, specialized, or beautifully-rendered maps — see a comprehensive list [here](https://wiki.openstreetmap.org/wiki/Raster_tile_providers).
### URL Format
Standard tile URL format: `https://example.com/{z}/{x}/{y}.png`
For providers that use an API key (e.g. MapTiler or Mapbox):
```
https://api.maptiler.com/maps/outdoor/{z}/{x}/{y}.png?key=YOUR_KEY
```
### HiDPI / Retina Tiles
Add `{r}` as an optional resolution identifier to automatically use retina tiles on high-resolution displays:
```
https://example.com/{z}/{x}/{y}{r}.png
```
### Dark Theme
Each map source can have an optional **dark theme URL**. If Obsidian's dark theme is detected, or if you manually select "Dark" from the View pane, the dark URL is used.
::: info
Google Maps is not a viable option here — while it provides tiles in the same format, the Google Maps terms of service make it difficult to legally bundle them in an application.
:::
## Switching Map Sources
If you have multiple map sources, switch between them from the **View** pane in the map controls.
## Tile Attribution
Using third-party map data is your responsibility. Always ensure you are not violating a provider's terms of use.

49
docs/offline-tiles.md Normal file
View file

@ -0,0 +1,49 @@
# Offline Tiles
Map View can store map tiles locally for caching and offline usage.
## How It Works
Whenever a map tile is needed, it is first searched in local storage. This leads to better performance and less data usage the more you use Map View.
By default:
- Every downloaded tile is saved to the cache.
- Tiles are stored for **6 months** or up to **2GB** (whichever comes first; oldest tiles are purged when the limit is reached).
These values are configurable under **"Offline Maps"** in the plugin settings.
## Batch-Downloading Tiles
1. Open the **Downloaded Tiles** dialog via **"offline maps..."** in the Map View context menu or **"offline storage..."** in the plugin settings.
2. Click **"download tiles..."** to open the new download job dialog.
3. The dialog creates a download job based on the **currently-active Map View** — it saves the area currently displayed on the map.
4. Choose a range of **zoom levels** for the download area.
5. Optionally check **"skip existing tiles"** to only download missing tiles (note: old tiles may be inconsistent if the area has changed).
::: warning Terms of Use
Ensure that caching tiles locally does not violate your tile provider's terms of use. Most providers encourage caching to save bandwidth, but verify with your specific provider. To prevent accidental flooding of tile servers, each download job is hard-capped at **1 million tiles**.
:::
![](/img/offline-download.png)
## Managing Downloads
Once started, a download job runs in the background. Track its progress or cancel it via the Downloaded Tiles dialog.
::: info Mobile Note
On iOS or Android, the OS may pause downloads when the screen turns off or close Obsidian entirely. There is no need to keep the dialog open on desktop.
:::
## Tips for Efficient Offline Storage
- Each click of the map's '+' button increases the zoom level by one — use this to assess the level of detail you want offline.
- The number of tiles and storage size **increase exponentially** between zoom levels. For large areas, don't go beyond 5-6 zoom levels.
- Store different areas at different detail levels: e.g. 4 zoom levels for your whole country, then 4 more for your city. Run consecutive downloads and mark "skip existing tiles" for the second pass.
- Adjust the **"max offline tiles storage"** setting if you need a large offline cache.
## Checking Offline Coverage
To see which tiles are available offline, check **"highlight offline tiles"** from the Map View context menu. Available tiles are marked with a blue box. The mark updates when the map is redrawn — to visualize the automatic cache, navigate to an area that wasn't downloaded, zoom in, then zoom back out.
Tiles are stored in **IndexedDB blobs** locally. There is currently no support for syncing tiles between devices.

35
docs/open-in.md Normal file
View file

@ -0,0 +1,35 @@
# Open In
Many Map View context menus display a customizable **Open In** list for opening locations in external mapping services.
![](/img/open-in.png)
## Where the Open In List Appears
- When right-clicking the map
- When right-clicking a marker on the map
- When right-clicking a geolocation link in a note (configurable in settings)
- When right-clicking a line in a note that has a location
- In the context menu of a note that has a front matter location
## Configuring Open In Entries
Configure the list through the plugin's settings menu. Each entry has:
- **Name** — displayed in context menus
- **URL pattern** — a URL with optional parameters:
- `{x}` — replaced by the latitude
- `{y}` — replaced by the longitude
- `{name}` — replaced by the location name (note name or inline link name)
![](/img/custom-open-in.png)
## Common Examples
| Service | URL |
| ------------- | ---------------------------------------------------------- |
| Google Maps | `https://maps.google.com/?q={x},{y}` |
| OpenStreetMap | `https://www.openstreetmap.org/#map=16/{x}/{y}` |
| Waze | `https://ul.waze.com/ul?ll={x}%2C{y}&navigate=yes&zoom=17` |
You can figure out many other services just by inspecting their URLs.

74
docs/paths.md Normal file
View file

@ -0,0 +1,74 @@
# Paths
![](/img/paths-basic.png)
Map View supports paths in a variety of formats. Like markers, there is a distinction between **stand-alone path files** and **inline paths**.
## Stand-Alone Path Files
Stand-alone path files are any **GPX, KML, TCX or GeoJSON** files in your vault. Map View collects them and displays paths based on [display rules](display-rules.md) and [filters](queries.md).
Without any filters, all supported path files in your vault are displayed using the default path style.
### Adding Stand-Alone Path Files
1. Use Obsidian's **"insert attachment"** command to insert a path file as an embed to a note. This copies the file into the vault and adds it to the note in one step.
2. From Map View, enter **Edit Mode** (pencil icon on the right), click the file icon, then click **"import a path as vault attachment"**. The file is added to the vault's default attachments folder.
3. **Copy the file into your vault** using your system's file explorer — it is automatically recognized.
### Querying Stand-Alone Paths
Stand-alone paths support many query operators: `path`, `name`, and `linkedfrom`.
Stand-alone path files do not support tags. To apply display rules to specific paths, you can:
- Include a relevant string in the file name and use the `path` or `name` operator.
- Use the `linkedfrom` operator: have a note "my runs" that links to all your GPX tracks, then use `linkedfrom:"my runs"` to match those paths in a display rule.
## Inline Paths
Map View supports GeoJSON paths stored in notes using a fenced code block of type `geojson`:
````
```geojson
{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[13.754839,42.030225],[14.033704,42.045011]]}}
```
tag:hike
````
A `tag:a tag:b` line directly below the code block attaches inline tags to the path.
Advantages of inline paths over stand-alone files:
- They support tags.
- They can be modified using Edit Mode tools.
### Adding Inline Paths
The easiest way is via Edit Mode (pencil button on the right):
1. Enter Edit Mode and choose a note to edit.
2. Draw a path on the map using the Edit Mode drawing tools — the path is added to the selected note when you finish.
3. Or click the file icon in Edit Mode, then **"import a path and add to Edit Mode note"** — the path is converted to GeoJSON and added as an inline path.
::: info
You won't see the path appear if it is excluded from the current filter.
:::
## Styling Paths
Paths are styled using [display rules](display-rules.md), starting from the default rule and applying each matching rule in order.
The most useful path properties are:
| Property | Description |
| --------- | -------------------------------- |
| `color` | Path color (any valid CSS color) |
| `weight` | Line width in pixels |
| `opacity` | Line opacity (0.01.0) |
A full list of advanced path properties (editable via JSON) can be found in [Leaflet's path documentation](https://leafletjs.com/reference.html#path).
::: info
Paths do not support badges, and no preview is available for them in the edit dialog.
:::

48
docs/presets.md Normal file
View file

@ -0,0 +1,48 @@
# Presets
Presets let you save and quickly return to specific map states.
## Saving a Preset
1. Open the **Presets** pane in the map controls.
2. Click **'Save as'** and enter a name.
If you enter an existing preset's name, it is overwritten.
A saved preset includes:
- Map position (zoom & pan)
- Active query/filters
- Map source (optional — check the box in the "save as" dialog)
::: info
Presets do **not** store the map's theme (light/dark).
:::
## The Default Preset
The **Default** preset is special:
- Save it using the **'Save as Default'** button.
- Return to it by clicking **Reset**, choosing "Default" from the preset list, or opening a fresh Map View with no previously saved state.
## Using Presets with Queries
Presets are great for saving complex query states. For example:
- A preset filtered to `tag:#dogs AND tag:#food` for finding dog-friendly restaurants
- A preset for a specific trip with `linkedfrom:"Trip to Italy"`
- A preset for your local area at a specific zoom level
## View URLs
You can save the current map state as a URL to open from any app on your computer or phone.
Click **"Copy Map View URL"** from the view's "more options" context menu, or **"Copy URL"** from the map Presets control.
The resulting `obsidian://` URL:
- Opens Obsidian with Map View in the exact saved state
- Can be pasted inside a note as a Markdown link: `[Link name](obsidian://...)`
This is useful for creating direct links to specific map views from trip plans, project notes, etc.

View file

Before

Width:  |  Height:  |  Size: 255 KiB

After

Width:  |  Height:  |  Size: 255 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 578 KiB

View file

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View file

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View file

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

View file

Before

Width:  |  Height:  |  Size: 360 KiB

After

Width:  |  Height:  |  Size: 360 KiB

View file

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View file

Before

Width:  |  Height:  |  Size: 344 KiB

After

Width:  |  Height:  |  Size: 344 KiB

View file

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 234 KiB

BIN
docs/public/img/main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View file

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View file

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

View file

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View file

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 372 KiB

View file

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View file

Before

Width:  |  Height:  |  Size: 637 KiB

After

Width:  |  Height:  |  Size: 637 KiB

View file

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 2.8 MiB

View file

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View file

Before

Width:  |  Height:  |  Size: 1,016 KiB

After

Width:  |  Height:  |  Size: 1,016 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

67
docs/queries.md Normal file
View file

@ -0,0 +1,67 @@
# Queries
Map View supports powerful queries to filter what is shown on the map.
![](/img/query.gif)
## Search Operators
| Operator | Description |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tag:#...` | Notes or markers tagged with a specific tag. Works on both note tags (`#hiking`) and inline tags (`tag:hiking`). Supports wildcards: `tag:#sleep*` matches `#sleep` and `#sleep/camping`. |
| `name:...` | Markers whose name contains the given string. For front-matter geolocations this matches the file name. For inline geolocations this matches the link name and **ignores** the file name. |
| `path:...` | Notes whose path matches the query. Includes all markers in matching notes. |
| `linkedto:...` | Notes that contain a link to the specified note. E.g. `linkedto:"Cave Hikes"` includes all notes that link to `[[Cave Hikes]]`. |
| `linkedfrom:...` | Notes that are linked from the specified note (plus the origin note itself). E.g. `linkedfrom:"Trip to Italy"` includes all notes linked from `[[Trip to Italy]]`. |
| `["property":"value"]` | Notes with the property `property` set to `value`. |
| `lines:x-y` | Only inline markers defined in the given line range in their note. E.g. `lines:20-30`. |
All operators are **case insensitive**.
### Notes on `linkedfrom`
- Obsidian heading and block links are supported: `[[Trip to Italy#Hotels]]` matches only front-matter markers or inline markers within that heading or block.
- The [Copy Block Link](https://github.com/mgmeyers/obsidian-copy-block-link) plugin makes block-level `linkedfrom` queries especially useful.
- Anything that resolves to a legal Obsidian link works (note name or full path), but partial names do not.
## Logical Operators
Combine search operators with:
- `AND` — both conditions must match
- `OR` — either condition must match
- `NOT` — negates the condition
- `(` `)` — grouping
::: warning Difference from Obsidian's Query Language
Map View uses `AND`, `OR`, `NOT`**not** `-` for NOT, and spaces are not treated as `AND`.
:::
## Examples
```
linkedfrom:"Trip to Italy" AND tag:#wine
```
Places linked from your Italy trip that are tagged with `#wine`.
```
tag:#hike AND tag:#dogs
```
Hikes suitable for dogs.
```
tag:#hike AND (tag:#dogs OR tag:#amazing) AND NOT path:"bad places"
```
Great hikes (dogs-OK or amazing), excluding notes in the "bad places" path.
## Creative Uses
- Represent location types with tags: `#hike`, `#restaurant`, `#camping`
- Use tags for traits: `#hike/summer`, `#hike/easy`
- Use Zettelkasten backlinks: link to "Hikes that I Want" from relevant notes, then use `linkedto:"Hikes that I Want"` to find them on the map
- Create trip planning notes that link to places, then use `linkedfrom:"Trip to Italy"` to focus your plan
Save complex queries as [presets](presets.md) for easy reuse.

128
docs/quick-start.md Normal file
View file

@ -0,0 +1,128 @@
# Quick Start
Map View is a powerful tool with many ways to use it. This page covers the most common flows to get you started quickly.
## Minimal Setup
To get the most out of Map View, you'll probably want to configure a geosearch provider. Map View supports two options:
**Option 1: OpenStreetMap (free, simplest, no account required)**
1. Open Obsidian **Settings → Map View**.
2. Find **"Geosearch email address"** and enter your email (this is an OpenStreetMap Nominatim requirement which is used to distinguish API calls between different users, so they won't be pooled together and blocked.)
That's it. OpenStreetMap's Nominatim service is free - no registration needed.
**Option 2: Google Maps / Google Places (most powerful, worth the 2-minute setup!)**
1. Obtain an API key from [Google Cloud](https://developers.google.com/maps/documentation/javascript/get-api-key).
2. Open Obsidian **Settings → Map View** and paste the key into **"Google Maps API key"**.
3. Optionally enable **"Use Google Places for searches"** for richer results (recommended!)
For most note-taking usage, the Google Geocoding API is free or very cheap.
**See [Search & Geocoding](search.md) for full details on providers and advanced options.**
## Log a Geolocation
Here are a few ways to log a favorite location.
### Option 1: From a Note
- Starting from a note (e.g. your daily note or a trip plan note), open the Command Palette and choose **"Map View: add inline geolocation link"**.
- A link in the format `[](geo:)` will be added where your cursor is.
- Start typing a location name inside the brackets, and geolocation results will appear. Choose one and your _inline location_ is complete.
![](/img/quick1.gif)
### Option 2: From the Map
- Open Map View (e.g. from the Obsidian ribbon icon).
- Search or locate a place using the search tool.
- Right-click the map and choose **"new note here (front matter)"** to create a note logging that location.
### Option 3: From the Map using Edit Mode
- Open Map View.
- Switch to **Edit Mode** using the pencil icon on the right.
- Click the red **"Choose Note"** button to select which note to add items to.
- Place markers or other shapes on the map using the tools that appeared below the pencil icon.
- In Edit Mode you can also move or edit existing markers and paths.
### Option 4: From Your Current Location
When using Obsidian Mobile, use the GPS-enabled commands such as **"GPS: new geolocation note"** to create a new note at your current location.
Customize the mobile toolbar to add Map View commands, e.g. **"Map View: GPS: add geolocation at current position"**.
There are [many other ways to log geolocations](adding-locations.md).
---
## Create a Trip Plan Map
Here's one flow for trip planning.
### Step 1: Log Some Locations
For most trips, use a single note with sections:
```
## To Visit
- [Place 1](geo:...) tag:activity
- Some information about this place
- [Place 2](geo:...) tag:activity
- Information about this place
## To Eat
- [Restaurant1](geo:...) tag:food
- Opening hours, other data...
- [Restaurant2](geo:...) tag:food
- Opening hours, other data...
```
Add places using one of the methods above. Notice the [inline tags](location-formats.md#inline-tags) — these can be used for custom filters and creating different icons for different types of places.
### Step 2: Map Them!
For a single note, click the note's menu (3 dots) and choose **"focus (note name) in Map View"**.
You should immediately see a map of all your locations. Configure [display rules](display-rules.md) to get different shapes and colors for your various tags.
### Step 3: Save This Map
You have a few options:
- Open the Presets section on the map and **save the current view**, then open it from Map View anytime.
- Click **'Copy block'** (or "Copy Map View code block" from the note menu) and paste the resulting code into a note to create an embedded map.
![](/img/quick2.gif)
---
## Build Your Personal GIS
The most powerful way to use Map View is to build a complete personal Geographic Information System (GIS) from your notes vault.
### 1. Collection
Collect pieces of information from various sources that often contain geographic information — restaurant recommendations, hike articles, places a friend mentioned.
### 2. Processing
When turning clipped information into notes, add geolocations:
- For _mainly geographical_ notes (a restaurant, a hike, a place to visit): create a Zettelkasten note, then use **"add geolocation (front matter) to current note"** to tag the location.
- If the location isn't easy to find by name, open a mapping tool, locate the place, copy it in lat,lng format and paste it into the Map View search box.
- Tag your notes with useful metadata: `#hike`, `#season/spring`, `#dogs`, `#camping`, `#food`, `#food/pizza`, `#activity`, `#activity/kids`, `#not` (for negative recommendations).
- For _bulks of geographical information_ (a list of recommended coffee shops): create a note and add all geolocations via inline links. Map the **"add inline geolocation link"** command to a shortcut like `Alt+L`.
### 3. Querying
- When planning a trip, look at the area and get a general understanding of what you know.
- Query for specific needs: e.g. `#dogs AND #sleep` (dog-friendly camp sites) or `#dogs AND #food` (dog-friendly dining). See [Queries](queries.md) for the full syntax.
- When visiting an unknown area, launch Map View from Obsidian Mobile to discover what you know in the area.
See also [this Reddit post](https://www.reddit.com/r/ObsidianMD/comments/xi42pt/planning_a_vacation_with_map_view/) about planning a vacation with Map View.

38
docs/routing.md Normal file
View file

@ -0,0 +1,38 @@
# Routing
Map View can calculate routes between points either directly (via the GraphHopper API) or by launching an external tool.
![](/img/routing.gif)
## How to Route
1. **Choose a starting point** — right-click a marker or map location and choose **"mark as routing source"**. Alternatively, click the flag icon on the right toolbar and select a marker.
2. **Choose a destination** — right-click a marker or location and choose **"route to point"**. Alternatively, use the **"select a routing destination"** button on the right toolbar after selecting a source.
3. Choose between routing via an **external service** (e.g. Google Maps) or the **GraphHopper API**.
4. If a GraphHopper option is selected, the route is displayed on the map with a time and distance estimate.
When GPS is active, you can use **"route to point"** from your current location without manually choosing a routing source. See [GPS Support](gps-support.md).
## External Routing Service
By default, Map View is configured to open Google Maps as the external routing service. Change this in the settings under **Routing → External routing service URL**.
## GraphHopper Configuration
[GraphHopper](https://www.graphhopper.com/) is an open-source-based routing API with a generous free tier (as of mid-2025: 500 route requests per day).
1. Sign up at [graphhopper.com/dashboard/signup](https://graphhopper.com/dashboard/signup).
2. Obtain an API key.
3. Enter it in **Map View Settings → Routing → GraphHopper API key**.
### Routing Profiles
The free plan supports 3 profiles: `foot`, `bike`, and `car`.
Paid plans offer more profiles — see the [GraphHopper docs](https://docs.graphhopper.com/openapi/map-data-and-routing-profiles/openstreetmap/geographical-coverage).
### Extra Parameters (Advanced)
For fine-grained control, specify extra parameters to be added to GraphHopper requests. For example, `snap_preventions` fine-tunes which points are used as routing start/end.
See the full [GraphHopper API reference](https://docs.graphhopper.com/openapi/routing/postroute).

75
docs/search.md Normal file
View file

@ -0,0 +1,75 @@
# Search & Geocoding
## In-Note Location Search
Map View adds the command **"Add inline geolocation link"** — map it to a keyboard shortcut (e.g. `Ctrl+L` or `Alt+L`).
This command inserts an empty inline location template: `[](geo:)`.
When editing an inline location in this format, typing a name inside the brackets triggers a location search from the geocoding service. Selecting a suggestion fills in the coordinates **without** changing your link name.
![](/img/geosearch-suggest.gif)
If the note isn't yet marked as containing locations (`locations:` in front matter), this is added automatically.
## Default Provider: OpenStreetMap Nominatim
::: warning
To use the default search provider (OSM Nominatim), you must specify an **email address** in the plugin settings. No registration required — this is only to let the free service identify and contact you if your usage exceeds their limits.
:::
## Changing the Geocoding Provider
By default Map View uses OpenStreetMap. To switch to Google Maps:
1. Obtain a Google Maps API key from [Google Cloud](https://developers.google.com/maps/documentation/javascript/get-api-key).
2. Enter the key in the **Google Maps API key** field in Map View settings.
The Google Geocoding API is free or very cheap for normal note-taking usage.
::: info
Usage of any geocoding provider is at your own risk. Verify you are not violating the service's terms of use.
:::
### Google Places API
For richer search results, enable the [Google Places API (New)](https://developers.google.com/maps/documentation/places/web-service/cloud-setup) and turn on **"Use Google Places for searches"** in Map View settings.
For most note-taking usage, you will not exceed the Places API free tier.
## Google Places Templates
When using the Google Places API, templates can extract additional result data.
### Setup
**Step 1:** In the plugin settings under "Google Places data fields to query", specify the fields you want returned. See [available fields](https://developers.google.com/maps/documentation/places/web-service/place-details#fieldmask). Example: `id,types,businessStatus`.
<div v-pre>
**Step 2:** Reference these fields in the Map View "new note template" using `{{googleMapsPlacesData.fieldName}}`.
Example template that populates a `place_id` field and adds a tag from the `types` field:
```yaml
---
place_id: '{{googleMapsPlaceData.id}}'
---
#{{googleMapsPlaceData.types.0}}
```
</div>
## Migrating to Google Places API (New)
Google introduced a new Places API in 2025. If you used Map View with the older API, you need to migrate as follows:
1. Visit [Google Cloud Console](https://console.cloud.google.com/google/maps-apis).
2. Select your project if you have more than one.
3. Go to **APIs & Services** → search for "Places API (New)" → click **Enable**.
4. Go back → click **Keys & Credentials** → find your existing key → **Edit API key**.
5. If under "API restrictions" you have "Restrict key", add "Places API (New)". Save.
::: info
If you use [Google Places Templates](#google-places-templates), field names changed in the new API — you must explicitly add them in the plugin settings.
:::

38
docs/url-parsing.md Normal file
View file

@ -0,0 +1,38 @@
# URL Parsing Rules
Map View uses _URL parsing rules_ to parse URLs (or other strings) from external sources and convert them to geolocations.
## Where URL Parsing Is Used
1. **Editor context menu** — right-clicking a line with a recognized link shows a "Convert to Geolocation" entry.
2. **Clipboard monitoring** — when a recognized link is detected in the clipboard, a "Paste as Geolocation" entry appears in the editor context menu.
3. **New geolocation note dialog and map search** — pasting a supported URL parses the geolocation.
## Default Rules
By default, Map View can parse:
- OpenStreetMap "show address" links
- A generic `lat, lng` encoding used by many services
## Adding Custom Rules
Configure URL parsing rules in the plugin's settings. This requires familiarity with regular expressions.
The syntax expects **two capture groups** and you can configure whether they are parsed as `lat, lng` (most common) or `lng, lat`.
![](/img/url-parsing.png)
::: tip
If you write solid regular expressions that work for a new service, consider submitting them as a PR so other users can benefit!
:::
## Tip: Copying from Google Maps
Google Maps on desktop offers an easy shortcut for universal `lat, lng` coordinates:
1. Right-click anywhere in Google Maps.
2. The first menu item is the universal coordinates — clicking it copies them to your clipboard.
3. In any Obsidian note, right-click and choose **"paste as geolocation"**, or paste the coordinates into any Map View search box.
![](/img/google-copy.png)

17
docs/view-urls.md Normal file
View file

@ -0,0 +1,17 @@
# View URLs
You can save the current map state as a URL to open from any app.
## Creating a View URL
- Click **"Copy Map View URL"** from the view's "more options" context menu, or
- Click **"Copy URL"** from the map Presets control.
## Using View URLs
The resulting `obsidian://` URL:
- Opens from any local app on your computer or phone, launching Obsidian with Map View in the saved state (zoom, pan, query, map source, etc.)
- Can be pasted into a note as a Markdown link: `[My Italy Trip Map](obsidian://...)`
This is especially useful for linking directly to specific map views from trip plans, project notes, or any context-specific note.

28
docs/vs-leaflet.md Normal file
View file

@ -0,0 +1,28 @@
# Map View vs. Obsidian Leaflet
Users adding mapping capabilities to Obsidian may also want to look at the great [Obsidian Leaflet plugin](https://github.com/valentine195/obsidian-leaflet-plugin). Both plugins use Leaflet.js as their visual engine, but they represent different approaches.
## What's Similar
- Both support creating maps from your notes or a folder of notes, with extensive customization options.
- Both support creating maps for specific use cases (e.g. trip planning), from a focused set of notes, and embedding maps in notes.
## What's Different
| | Map View | Obsidian Leaflet |
| ------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| **Primary interface** | GUI-driven view (like Obsidian's Graph View) | Code block-driven |
| **Customization** | Through a rich GUI | Mainly via code block parameters |
| **Multiple locations per note** | Yes — inline syntax with individual tags | Focused on one geolocation per note (more locations can be added to the map code block itself) |
| **Purpose** | Research & query tool — interactive filtering, trip planning, geographic insights | Presenting fine-grained customizable maps |
| **Geolocation search** | Built-in powerful location search tools | Not a focus |
| **Display rules** | Query-based rules: "color all `#food/*` items red", "give `#food/pizza` a pizza icon" | Icons assigned individually or by global tag |
| **GPX / GeoJSON / overlays** | Yes, via stand-alone files or inline | Yes |
| **TTRPG / custom maps** | Possible but less natural | More suitable |
## Which Should I Use?
- **Map View** is the better choice if you want to use your notes as a **personal geographic database** — collecting places, querying them with complex filters, and navigating your knowledge geographically.
- **Obsidian Leaflet** may be the better choice if you want **maximum control over a specific map's visual presentation**, especially for non-geographic maps (TTRPG, custom worlds).
The two plugins are not mutually exclusive — some users run both.

1990
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,10 @@
"stylecheck": "npx prettier --check .",
"test": "vitest run",
"test:watch": "vitest",
"prepare": "lefthook install"
"prepare": "lefthook install",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
"overrides": {
"@codemirror/state": "^6.6.0"
@ -53,6 +56,7 @@
"tslib": "^2.8.1",
"typescript": "^5.8.3",
"vite": "^8.0.0",
"vitepress": "^1.6.4",
"vitest": "^4.0.18"
},
"dependencies": {