Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d42a256
Made it easier to run the development build
gentlegiantJGC Feb 7, 2022
48e960e
Moved images into an img folder to declutter the root
gentlegiantJGC Feb 7, 2022
e5932b1
Renamed getFrontMatterLocation to getFrontMatterCoordinate
gentlegiantJGC Feb 7, 2022
416aacf
Renamed another two methods and variables
gentlegiantJGC Feb 7, 2022
4406742
Simplified if else
gentlegiantJGC Feb 7, 2022
d176ce3
Renamed urlConverter to coordinateParser
gentlegiantJGC Feb 7, 2022
698c668
Added some comments to the main script
gentlegiantJGC Feb 7, 2022
7141029
Cleaned up the coordinate parser
gentlegiantJGC Feb 7, 2022
91b2e54
Renamed the globe icon
gentlegiantJGC Feb 7, 2022
332dffa
Split verifyOrAddFrontMatter in two
gentlegiantJGC Feb 8, 2022
d5d9df4
Renamed variable fileLocation to characterIndex
gentlegiantJGC Feb 8, 2022
ed795f4
Cleaned up the newNote util function
gentlegiantJGC Feb 11, 2022
bc6db93
Added docstrings and cleanup to mapView
gentlegiantJGC Feb 11, 2022
b6a2812
Added some docstrings to marker.ts
gentlegiantJGC Feb 11, 2022
d97a042
Added a base class for all geo data
gentlegiantJGC Feb 11, 2022
c4cbf93
Increased max zoom and stopped tiles disappearing when zoomed in too far
gentlegiantJGC Feb 11, 2022
3df927a
Moved marker construction into the marker class
gentlegiantJGC Feb 11, 2022
37ea66e
Move the get and set state methods out of the constructor
gentlegiantJGC Feb 12, 2022
a448a10
Removed input from isDarkMode
gentlegiantJGC Feb 12, 2022
e526d45
Added missing ViewStateResult import
gentlegiantJGC Feb 12, 2022
8b4c3dc
Reordered and documented the MapView attributes
gentlegiantJGC Feb 12, 2022
fe1289d
renamed updateMapToState to setMapState
gentlegiantJGC Feb 12, 2022
d5dc84f
Added more docstrings and comments to mapView
gentlegiantJGC Feb 12, 2022
8bb779e
Renamed updateMapMarkers to setMapMarkers
gentlegiantJGC Feb 12, 2022
3538a5f
Rewritten regular expressions to use named capture groups
gentlegiantJGC Feb 13, 2022
887be2c
Moved some FileMarker attributes into the base class
gentlegiantJGC Feb 13, 2022
1b91b89
Switched typing to the base geo layer class
gentlegiantJGC Feb 13, 2022
b149bd8
Fixed a compile error when accessing the location attribute
gentlegiantJGC Feb 14, 2022
4feae76
Added geoJSON viewing support
gentlegiantJGC Feb 14, 2022
9c86382
Removed incorrectly imported variable
gentlegiantJGC Feb 14, 2022
343c6e6
Added in the UI overlay for geoJSON object
gentlegiantJGC Feb 14, 2022
1147777
Compacted single line docstrings
gentlegiantJGC Feb 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ You can set different icons for different note types, filter the displayed notes

It also provides a wide range of tools to add geolocations to your notes, including address searches and parsing of URLs from external sources such as Google Maps.

![](sample.png)
![](img/sample.png)

![](intro.gif)
![](img/intro.gif)

The plugin's guiding philosophy and goal is to provide a **personal GIS system** as a complementary view for your notes.
I wrote it because I wanted my ever-growing Zettelkasten to be able to answer questions like...
Expand Down Expand Up @@ -93,7 +93,7 @@ Map View adds an Obsidian command named "New geolocation note", which you can ma

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).

![](new-note-popup.gif)
![](img/new-note-popup.gif)

### In an Existing Note

Expand All @@ -113,15 +113,15 @@ The map offers several tools to create 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 you clicked. You can create either an empty note with a front matter (single geolocation) or an empty note with an inline geolocation.

![](new-note.png)
![](img/new-note.png)

Note that the map can be searched using the tool on the upper-right side.

![](search.png)
![](img/search.png)

2. If you prefer to enter geolocations as text, use one of the "copy geolocation" options when you right-click the map. If you use "copy geolocation", just remember you need the note to start with a front matter that has an empty `locations:` line.

![](copy.png)
![](img/copy.png)


## Paste as Geolocation
Expand Down Expand Up @@ -155,7 +155,7 @@ A single marker is defined with a *tag pattern* and *icon details*.
The tag pattern is usually a tag name (e.g. `#dogs`), but it can also be with a wildcard (e.g. `#trips/*`).
Icon details are a few properties: icon name (taken from the Font Awesome catalog), color and shape.

![](marker-rules.png)
![](img/marker-rules.png)

A single marker is defined in the following JSON structure:
`{"prefix": "fas", "icon": "fa-bus", "shape": "circle", "color": "red"}`
Expand Down Expand Up @@ -195,7 +195,7 @@ 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, *not* change your link name (assuming you prefer your own name rather than the formal one offered by the geocoding service), and jump the cursor to beyond the link so you can continue typing.

![](geosearch-suggest.gif)
![](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.

Expand Down Expand Up @@ -230,7 +230,7 @@ If a dark theme is detected, or if you specifically change the map source type t
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.

![](open-in.png)
![](img/open-in.png)

The Open In list is shown:
- When right-clicking on the map.
Expand All @@ -240,7 +240,7 @@ The Open In list is shown:

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.

![](custom-open-in.png)
![](img/custom-open-in.png)

Popular choices may be:
- Google Maps: `https://maps.google.com/?q={x},{y}`
Expand All @@ -263,7 +263,7 @@ The syntax expects two captures group and you can configure if they are parsed a

And if you think your added regular expressions are solid enough, please add them to the plugin using a PR so others can benefit!

![](url-parsing.png)
![](img/url-parsing.png)

## Relation to Other Obsidian Plugins

Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "An interactive map view for Obsidian.md",
"main": "main.js",
"scripts": {
"dev": "rollup --config rollup.config.js -w",
"dev": "rollup --config rollup.config.js -w --environment BUILD:development",
"build": "rollup --config rollup.config.js --environment BUILD:production"
},
"keywords": [],
Expand Down
16 changes: 9 additions & 7 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if you want to view the source visit the plugins github repository
export default {
input: 'src/main.ts',
output: {
dir: './dist',
dir: process.env.BUILD === 'development' ? '.' : './dist',
sourcemap: isProd ? false : 'inline',
sourcemapExcludeSources: isProd,
format: 'cjs',
Expand All @@ -30,11 +30,13 @@ export default {
nodeResolve({browser: true}),
commonjs(),
postcss({ extensions: ['.css'], plugins: [postcss_url({url: 'inline'})] }),
copy({
targets: [
{ src: './manifest.json', dest: 'dist' },
{ src: './styles.css', dest: 'dist' }
]
})
...(process.env.BUILD !== 'development' ? [
copy({
targets: [
{ src: './manifest.json', dest: 'dist' },
{ src: './styles.css', dest: 'dist' }
]
})
] : []),
]
};
2 changes: 1 addition & 1 deletion src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as leaflet from 'leaflet';
export const MAP_VIEW_NAME = 'map';

// SVG editor used: https://svgedit.netlify.app/editor/index.html
export const RIBBON_ICON = '<path fill="currentColor" stroke="currentColor" d="m50.06001,1.76c-26.54347,0 -48.06001,21.74039 -48.06001,48.56c0,26.81961 21.51654,48.56 48.06001,48.56c26.54347,0 48.06001,-21.74039 48.06001,-48.56c0,-26.81961 -21.51654,-48.56 -48.06001,-48.56zm15.94701,70.02039c-0.75578,0.75973 -1.54838,1.55666 -2.19177,2.2087c-0.57943,0.58742 -0.98833,1.3119 -1.19569,2.09709c-0.29262,1.10826 -0.52905,2.22828 -0.92438,3.30325l-3.37001,9.17353c-2.66656,0.58742 -5.42613,0.91833 -8.26516,0.91833l0,-5.36118c0.32751,-2.47108 -1.48056,-7.09994 -4.38548,-10.03508c-1.16274,-1.17484 -1.81582,-2.7687 -1.81582,-4.4311l0,-6.26776c0,-2.27919 -1.21507,-4.37432 -3.18979,-5.47671c-2.78477,-1.55666 -6.74584,-3.73207 -9.45891,-5.11251c-2.22471,-1.13176 -4.28277,-2.5729 -6.13346,-4.25879l-0.15503,-0.14098c-1.32339,-1.20715 -2.49854,-2.57055 -3.49985,-4.06103c-1.81775,-2.69625 -4.77887,-7.13127 -6.70321,-10.01354c3.96689,-8.90919 11.11582,-16.06396 19.99917,-19.95072l4.65291,2.35164c2.06193,1.04169 4.48818,-0.47189 4.48818,-2.80199l0,-2.21261c1.54838,-0.25259 3.1239,-0.41315 4.72655,-0.47385l5.48427,5.54132c1.21119,1.22379 1.21119,3.20731 0,4.4311l-0.90888,0.91637l-2.00379,2.02464c-0.60463,0.61092 -0.60463,1.60365 0,2.21457l0.90888,0.91833c0.60463,0.61092 0.60463,1.60365 0,2.21457l-1.55032,1.56645c-0.29107,0.29351 -0.68563,0.45838 -1.09685,0.45819l-1.74218,0c-0.40308,0 -0.79066,0.1586 -1.08135,0.44448l-1.9224,1.88953c-0.48351,0.47581 -0.60734,1.21263 -0.30619,1.82296l3.02119,6.1072c0.51548,1.04169 -0.23449,2.26744 -1.3856,2.26744l-1.09298,0c-0.37402,0 -0.73447,-0.13706 -1.01546,-0.38378l-1.79837,-1.5782c-0.82787,-0.72566 -1.97337,-0.95651 -3.01344,-0.607l-6.04045,2.03443c-0.9457,0.31858 -1.58365,1.21302 -1.58327,2.22045c0,0.887 0.4961,1.69568 1.28095,2.09317l2.1472,1.08477c1.82357,0.92225 3.83511,1.40197 5.87379,1.40197c2.03867,0 4.37772,5.34356 6.20129,6.26581l12.93551,0c1.64528,0 3.2208,0.65987 4.38548,1.83471l2.65299,2.68059c1.10829,1.12021 1.73074,2.63947 1.73055,4.22355c-0.00078,2.42428 -0.95771,4.74811 -2.6588,6.4577zm16.80356,-17.88692c-1.12205,-0.28392 -2.10069,-0.97903 -2.74213,-1.95219l-3.48435,-5.2809c-1.04259,-1.57781 -1.04259,-3.63456 0,-5.21237l3.79635,-5.75279c0.44959,-0.67945 1.06585,-1.23162 1.79062,-1.59582l2.5154,-1.27078c2.62005,5.27111 4.13161,11.20013 4.13161,17.49139c0,1.69764 -0.1434,3.36004 -0.3527,5.0009l-5.6548,-1.42743z" fill="#000000" id="shape0" stroke="#000000" stroke-linecap="square" stroke-linejoin="bevel" stroke-opacity="0" stroke-width="0"/>';
export const GLOBE_ICON = '<path fill="currentColor" stroke="currentColor" d="m50.06001,1.76c-26.54347,0 -48.06001,21.74039 -48.06001,48.56c0,26.81961 21.51654,48.56 48.06001,48.56c26.54347,0 48.06001,-21.74039 48.06001,-48.56c0,-26.81961 -21.51654,-48.56 -48.06001,-48.56zm15.94701,70.02039c-0.75578,0.75973 -1.54838,1.55666 -2.19177,2.2087c-0.57943,0.58742 -0.98833,1.3119 -1.19569,2.09709c-0.29262,1.10826 -0.52905,2.22828 -0.92438,3.30325l-3.37001,9.17353c-2.66656,0.58742 -5.42613,0.91833 -8.26516,0.91833l0,-5.36118c0.32751,-2.47108 -1.48056,-7.09994 -4.38548,-10.03508c-1.16274,-1.17484 -1.81582,-2.7687 -1.81582,-4.4311l0,-6.26776c0,-2.27919 -1.21507,-4.37432 -3.18979,-5.47671c-2.78477,-1.55666 -6.74584,-3.73207 -9.45891,-5.11251c-2.22471,-1.13176 -4.28277,-2.5729 -6.13346,-4.25879l-0.15503,-0.14098c-1.32339,-1.20715 -2.49854,-2.57055 -3.49985,-4.06103c-1.81775,-2.69625 -4.77887,-7.13127 -6.70321,-10.01354c3.96689,-8.90919 11.11582,-16.06396 19.99917,-19.95072l4.65291,2.35164c2.06193,1.04169 4.48818,-0.47189 4.48818,-2.80199l0,-2.21261c1.54838,-0.25259 3.1239,-0.41315 4.72655,-0.47385l5.48427,5.54132c1.21119,1.22379 1.21119,3.20731 0,4.4311l-0.90888,0.91637l-2.00379,2.02464c-0.60463,0.61092 -0.60463,1.60365 0,2.21457l0.90888,0.91833c0.60463,0.61092 0.60463,1.60365 0,2.21457l-1.55032,1.56645c-0.29107,0.29351 -0.68563,0.45838 -1.09685,0.45819l-1.74218,0c-0.40308,0 -0.79066,0.1586 -1.08135,0.44448l-1.9224,1.88953c-0.48351,0.47581 -0.60734,1.21263 -0.30619,1.82296l3.02119,6.1072c0.51548,1.04169 -0.23449,2.26744 -1.3856,2.26744l-1.09298,0c-0.37402,0 -0.73447,-0.13706 -1.01546,-0.38378l-1.79837,-1.5782c-0.82787,-0.72566 -1.97337,-0.95651 -3.01344,-0.607l-6.04045,2.03443c-0.9457,0.31858 -1.58365,1.21302 -1.58327,2.22045c0,0.887 0.4961,1.69568 1.28095,2.09317l2.1472,1.08477c1.82357,0.92225 3.83511,1.40197 5.87379,1.40197c2.03867,0 4.37772,5.34356 6.20129,6.26581l12.93551,0c1.64528,0 3.2208,0.65987 4.38548,1.83471l2.65299,2.68059c1.10829,1.12021 1.73074,2.63947 1.73055,4.22355c-0.00078,2.42428 -0.95771,4.74811 -2.6588,6.4577zm16.80356,-17.88692c-1.12205,-0.28392 -2.10069,-0.97903 -2.74213,-1.95219l-3.48435,-5.2809c-1.04259,-1.57781 -1.04259,-3.63456 0,-5.21237l3.79635,-5.75279c0.44959,-0.67945 1.06585,-1.23162 1.79062,-1.59582l2.5154,-1.27078c2.62005,5.27111 4.13161,11.20013 4.13161,17.49139c0,1.69764 -0.1434,3.36004 -0.3527,5.0009l-5.6548,-1.42743z" fill="#000000" id="shape0" stroke="#000000" stroke-linecap="square" stroke-linejoin="bevel" stroke-opacity="0" stroke-width="0"/>';

export const TILES_URL_OPENSTREETMAP = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
export const SEARCH_RESULT_MARKER = {prefix: 'fas', icon: 'fa-search', markerColor: 'blue'};
Expand Down
109 changes: 109 additions & 0 deletions src/coordinateParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { App, Editor, EditorPosition } from 'obsidian';

import * as leaflet from 'leaflet';
import { PluginSettings } from 'src/settings';
import * as utils from 'src/utils';


interface FindResult {
location: leaflet.LatLng;
index: number,
matchLength: number,
ruleName: string
}

/** A class to convert a string (usually a URL) into coordinate format */
export class CoordinateParser {
private settings: PluginSettings;

/**
* construct an instance of CoordinateParser
* @param app The obsidian App instance
* @param settings The plugin settings
*/
constructor(app: App, settings: PluginSettings) {
this.settings = settings;
}

/**
* Get coordinate from an encoded string (usually a URL).
* Will try each url parsing rule until one succeeds.
* @param str The string to decode
*/
parseString(str: string): FindResult | null {
for (const rule of this.settings.urlParsingRules) {
const regexp = RegExp(rule.regExp, 'g');
const results = str.matchAll(regexp);
for (let result of results) {
try {
return {
location: new leaflet.LatLng(parseFloat(result[1]), parseFloat(result[2])),
index: result.index,
matchLength: result[0].length,
ruleName: rule.name
};
}
catch (e) { }
}
}
return null;
}

/**
* Parse the line where the cursor is in the editor
* @param editor The obsidian Editor instance to use
*/
parseEditorLine(editor: Editor): FindResult | null {
const cursor = editor.getCursor();
const line = editor.getLine(cursor.line);
return this.parseString(line);
}

/**
* Insert a geo link into the editor at the cursor position
* @param editor The obsidian Editor instance
* @param coordinate The coordinate to insert into the editor
* @param replaceStart The EditorPosition to start the replacement at. If null will replace any text selected
* @param replaceEnd The EditorPosition to stop the replacement at. If null will replace any text selected
*/
editorInsertGeolocation(editor: Editor, coordinate: leaflet.LatLng, replaceStart?: EditorPosition, replaceEnd?: EditorPosition) {
const locationString = `[](geo:${coordinate.lat},${coordinate.lng})`;
let newCursorPos: EditorPosition;
if (replaceStart && replaceEnd) {
editor.replaceRange(locationString, replaceStart, replaceEnd);
newCursorPos = {line: replaceStart.line, ch: replaceStart.ch + 1};
} else {
const cursor = editor.getCursor();
editor.replaceSelection(locationString);
newCursorPos = {line: cursor.line, ch: cursor.ch + 1};
}

// Put the cursor after the opening square bracket
editor.setCursor(newCursorPos);
// TODO: This will modify in a second operation.
// Is there a way to make it apply in one operation so that one undo undoes both changes
utils.frontMatterSetDefault(editor, 'locations');
}

/**
* Replace the text at the cursor location with a geo link
* @param editor The obsidian Editor instance
*/
editorLineToGeolocation(editor: Editor): void {
const result = this.parseEditorLine(editor)
if (result) {
this.editorInsertGeolocation(
editor,
result.location,
{
line: editor.getCursor().line,
ch: result.index
},
{
line: editor.getCursor().line,
ch: result.index + result.matchLength
}
);
}
}
}
4 changes: 2 additions & 2 deletions src/geosearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class LocationSuggest extends EditorSuggest<SuggestInfo> {
finalResult,
{line: currentCursor.line, ch: linkOfCursor.index},
{line: currentCursor.line, ch: linkOfCursor.linkEnd});
if (utils.verifyOrAddFrontMatter(value.context.editor, 'locations', ''))
if (utils.frontMatterSetDefault(value.context.editor, 'locations'))
new Notice("The note's front matter was updated to denote locations are present");
}

Expand Down Expand Up @@ -100,7 +100,7 @@ export class LocationSuggest extends EditorSuggest<SuggestInfo> {
const firstResult = results[0];
editor.replaceSelection(`[${selection}](geo:${firstResult.y},${firstResult.x})`);
new Notice(firstResult.label, 10 * 1000);
if (utils.verifyOrAddFrontMatter(editor, 'locations', ''))
if (utils.frontMatterSetDefault(editor, 'locations'))
new Notice("The note's front matter was updated to denote locations are present");
}
else {
Expand Down
Loading