mirror of
https://github.com/esm7/obsidian-map-view.git
synced 2026-07-22 05:40:27 +00:00
CLI and skills improvements
This commit is contained in:
parent
39c0af0ea5
commit
d58d3aada5
4 changed files with 109 additions and 10 deletions
|
|
@ -10,6 +10,7 @@ All notable changes to Map View are documented here.
|
|||
|
||||
- A new `distancefrom` query operator.
|
||||
- New CLI commands for running queries and calculating routes, especially for usage in conjunction with an LLM.
|
||||
- Geosearch CLI can return Google Places field to give agents access to ratings, opening hours etc.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
|||
24
docs/cli.md
24
docs/cli.md
|
|
@ -30,6 +30,30 @@ Example output:
|
|||
|
||||
Use this to find and verify the right result before recording it.
|
||||
|
||||
Add `extra-data` to include all fields returned by the geocoding provider:
|
||||
|
||||
```bash
|
||||
obsidian mv-geosearch name="Eiffel Tower" --extra-data
|
||||
```
|
||||
|
||||
When using Google Places (New) API with data fields configured in Map View settings (e.g. `regularOpeningHours,rating,websiteUri`), the extra data is appended as JSON after each result:
|
||||
|
||||
```
|
||||
1. Eiffel Tower (Champ de Mars, 5 Av. Anatole France, 75007 Paris, France) [48.8584, 2.2945]
|
||||
{
|
||||
"regularOpeningHours": {
|
||||
"openNow": true,
|
||||
"weekdayDescriptions": [
|
||||
"Monday: 9:00 AM – 11:45 PM",
|
||||
...
|
||||
]
|
||||
},
|
||||
"rating": 4.6
|
||||
}
|
||||
```
|
||||
|
||||
The `extra-data` flag works on all three geosearch commands.
|
||||
|
||||
### `mv-geosearch-as-front-matter`
|
||||
|
||||
Search for a location and return the top result as a front matter property.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ TRIGGER when: user asks to add, list, or recommend places, venues, restaurants,
|
|||
|
||||
If the [obsidian-skills](https://github.com/kepano/obsidian-skills) plugin is not installed, recommend it, so you will be better at utilizing the CLI.
|
||||
|
||||
Geolocations: When the content to be added contains named real-world places (restaurants, venues, hotels, attractions, etc.), format each as a Map View inline geolink -- [Place Name](geo:lat,lng) -- rather than plain text.
|
||||
If coordinates are not already known, use this skill to look them up before appending.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
|
|
@ -76,6 +79,29 @@ obsidian mv-query "distancefrom:32.08,34.78<500m AND tag:#restaurant"
|
|||
|
||||
Radius can be in `km`, `m`, `mi`, or `ft`. This is the fastest way to find vault markers near a given point — no routing API key required. Use it to quickly narrow down candidates before calling `mv-calc-route` only on the ones that are geographically plausible, or to answer the users for queries like "what do I have in my vault that is around...".
|
||||
|
||||
## Getting rich place data (opening hours, ratings, etc.)
|
||||
|
||||
All three geosearch commands accept an optional `extra-data` flag. When set, the full data returned by the geocoding provider is appended to each result as JSON.
|
||||
|
||||
```bash
|
||||
obsidian mv-geosearch name="Central Park Cafe" --extra-data
|
||||
obsidian mv-geosearch-as-inline name="Louvre Museum" --extra-data
|
||||
obsidian mv-geosearch-as-front-matter name="Hotel du Nord, Paris" --extra-data
|
||||
```
|
||||
|
||||
This is intended to be used with the **Google Places API**, which can return fields like `regularOpeningHours`, `rating`, `priceLevel`, `websiteUri`, `nationalPhoneNumber`, and more.
|
||||
|
||||
**Setup required:** The user must configure two things in Map View settings:
|
||||
|
||||
1. Switch the search provider to **Google Places**.
|
||||
2. Add the desired field names to **"Google Places Data Fields"**, e.g.: `regularOpeningHours,rating,priceLevel,websiteUri`
|
||||
|
||||
If the user asks for opening hours, ratings, or other place details, and the output does not include them (either shows no extra data or just not the right fields), suggest they configure these settings. **Important:** if you think you can achieve what the user wants by adding fields, STOP WHAT YOU ARE DOING with other tools (like web fetching) and tell the user to add the fields to the Map View settings.
|
||||
|
||||
**Example use case:** User asks for coffee shops open on Sunday morning near a location. Use `mv-geosearch name="..." --extra-data` for each candidate, then filter based on the `regularOpeningHours.weekdayDescriptions` in the JSON output.
|
||||
|
||||
**Prefer geo searches with the correct fields using the Google Places API over web fetches, unless the user instructs otherwise or does not use Places API.**
|
||||
|
||||
## Checking distance and travel time for recommendations
|
||||
|
||||
Use `mv-calc-distance` or `mv-calc-route` to verify that places meet a proximity criterion before presenting them to the user.
|
||||
|
|
|
|||
68
src/cli.ts
68
src/cli.ts
|
|
@ -18,29 +18,40 @@ export function registerCliHandlers(
|
|||
app: App,
|
||||
settings: PluginSettings,
|
||||
) {
|
||||
const nameFlag = {
|
||||
const nameAndExtraDataFlags = {
|
||||
name: {
|
||||
value: '<query>',
|
||||
description: 'Location name or address to search for',
|
||||
required: true,
|
||||
},
|
||||
'extra-data': {
|
||||
description:
|
||||
'Include all extra data returned by the geocoding provider (e.g. opening hours, rating, website from Google Places). Requires Google Places API with data fields configured in Map View settings.',
|
||||
required: false,
|
||||
},
|
||||
};
|
||||
|
||||
plugin.registerCliHandler(
|
||||
'mv-geosearch',
|
||||
'Search for a location by name and return up to 10 results',
|
||||
nameFlag,
|
||||
nameAndExtraDataFlags,
|
||||
async (params: { name: string }) => {
|
||||
const results = await new GeoSearcher(app, settings).search(
|
||||
params.name,
|
||||
);
|
||||
if (!results.length) return 'No results found.';
|
||||
const wantExtra =
|
||||
(params as any)['--extra-data'] === 'true' ||
|
||||
(params as any)['--extra-data'] === 'true' ||
|
||||
(params as any)['extra-data'] === 'true';
|
||||
return results
|
||||
.slice(0, 10)
|
||||
.map(
|
||||
(r, i) =>
|
||||
`${i + 1}. ${r.name} [${r.location.lat}, ${r.location.lng}]`,
|
||||
)
|
||||
.map((r, i) => {
|
||||
const line = `${i + 1}. ${r.name} [${r.location.lat}, ${r.location.lng}]`;
|
||||
return wantExtra
|
||||
? line + '\n' + formatExtraData(r.extraLocationData)
|
||||
: line;
|
||||
})
|
||||
.join('\n');
|
||||
},
|
||||
);
|
||||
|
|
@ -48,28 +59,44 @@ export function registerCliHandlers(
|
|||
plugin.registerCliHandler(
|
||||
'mv-geosearch-as-front-matter',
|
||||
'Search for a location and return it as a front matter property',
|
||||
nameFlag,
|
||||
nameAndExtraDataFlags,
|
||||
async (params: { name: string }) => {
|
||||
const results = await new GeoSearcher(app, settings).search(
|
||||
params.name,
|
||||
);
|
||||
if (!results.length) return 'No results found.';
|
||||
const { lat, lng } = results[0].location;
|
||||
return `${settings.frontMatterKey}: "${lat},${lng}"`;
|
||||
const main = `${settings.frontMatterKey}: "${lat},${lng}"`;
|
||||
if (
|
||||
(params as any)['--extra-data'] === 'true' ||
|
||||
(params as any)['extra-data'] === 'true'
|
||||
)
|
||||
return (
|
||||
main + '\n' + formatExtraData(results[0].extraLocationData)
|
||||
);
|
||||
return main;
|
||||
},
|
||||
);
|
||||
|
||||
plugin.registerCliHandler(
|
||||
'mv-geosearch-as-inline',
|
||||
'Search for a location and return it as an inline geolink',
|
||||
nameFlag,
|
||||
nameAndExtraDataFlags,
|
||||
async (params: { name: string }) => {
|
||||
const results = await new GeoSearcher(app, settings).search(
|
||||
params.name,
|
||||
);
|
||||
if (!results.length) return 'No results found.';
|
||||
const { lat, lng } = results[0].location;
|
||||
return `[${params.name}](geo:${lat},${lng})`;
|
||||
const main = `[${params.name}](geo:${lat},${lng})`;
|
||||
if (
|
||||
(params as any)['--extra-data'] === 'true' ||
|
||||
(params as any)['extra-data'] === 'true'
|
||||
)
|
||||
return (
|
||||
main + '\n' + formatExtraData(results[0].extraLocationData)
|
||||
);
|
||||
return main;
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -195,6 +222,27 @@ export function registerCliHandlers(
|
|||
},
|
||||
);
|
||||
|
||||
function formatExtraData(extra: any): string {
|
||||
const place = extra?.googleMapsPlaceData;
|
||||
if (!place) {
|
||||
return (
|
||||
'[No extra data returned. Requires Google Places (New) API ' +
|
||||
'with data fields configured in Map View settings, e.g. ' +
|
||||
'regularOpeningHours,rating,websiteUri]'
|
||||
);
|
||||
}
|
||||
// Strip fields already shown in the main output line
|
||||
const { location, displayName, formattedAddress, ...rest } = place;
|
||||
if (Object.keys(rest).length === 0) {
|
||||
return (
|
||||
'[No additional fields. Add field names such as ' +
|
||||
'regularOpeningHours,rating,websiteUri to "Google Places Data Fields" ' +
|
||||
'in Map View settings.]'
|
||||
);
|
||||
}
|
||||
return JSON.stringify(rest, null, 2);
|
||||
}
|
||||
|
||||
function parseLatLng(str: string): leaflet.LatLng | null {
|
||||
const cleaned = str.replace(/[\[\]\s]/g, '');
|
||||
const m = cleaned.match(/^(-?\d+\.?\d*),(-?\d+\.?\d*)$/);
|
||||
|
|
|
|||
Loading…
Reference in a new issue