Skip to content

Commit 8b264a9

Browse files
committed
Switch to formula option for map center configuration
Backwards support for string values is retained. New values going forward should be valid formulas. For example, instead of `lat, long`, the value should be a list (`[lat, long]`) or enclosed in quotes (`"lat, long"`).
1 parent c0fdf0e commit 8b264a9

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

src/map-view.ts

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ViewOption,
1313
setIcon,
1414
Value,
15+
NullValue,
1516
} from 'obsidian';
1617
import { LngLatBounds, LngLatLike, Map, Marker, Popup, StyleSpecification } from 'maplibre-gl';
1718
import { transformMapboxStyle } from './mapbox-transform';
@@ -282,20 +283,19 @@ export class MapView extends BasesView {
282283
}
283284

284285
private getCenterFromConfig(): [number, number] {
285-
const centerConfig = this.config.get('center');
286-
if (!centerConfig || !String.isString(centerConfig)) {
287-
return DEFAULT_MAP_CENTER;
288-
}
286+
let centerConfig = this.config.getEvaluatedFormula(this, 'center');
289287

290-
const parts = centerConfig.trim().split(',');
291-
if (parts.length >= 2) {
292-
const lat = parseFloat(parts[0].trim());
293-
const lng = parseFloat(parts[1].trim());
294-
if (!isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
295-
return [lat, lng];
288+
// Support for legacy string format.
289+
if (Value.equals(centerConfig, NullValue.value)) {
290+
const centerConfigStr = this.config.get('center');
291+
if (String.isString(centerConfigStr)) {
292+
centerConfig = new StringValue(centerConfigStr);
293+
}
294+
else {
295+
return DEFAULT_MAP_CENTER;
296296
}
297297
}
298-
return DEFAULT_MAP_CENTER;
298+
return this.coordinateFromValue(centerConfig) || DEFAULT_MAP_CENTER;
299299
}
300300

301301
private async applyConfigToMap(): Promise<void> {
@@ -385,7 +385,7 @@ export class MapView extends BasesView {
385385
const accessTokenMatch = styleUrl.match(/access_token=([^&]+)/);
386386
const accessToken = accessTokenMatch ? accessTokenMatch[1] : '';
387387
// Transform mapbox:// protocol URLs to HTTPS URLs if needed
388-
const transformedStyle = accessToken
388+
const transformedStyle = accessToken
389389
? transformMapboxStyle(styleJson, accessToken)
390390
: styleJson;
391391
return transformedStyle as StyleSpecification;
@@ -453,15 +453,15 @@ export class MapView extends BasesView {
453453
.setIcon('lucide-map-pin')
454454
.onClick(() => {
455455
// Set the current center as the default coordinates
456-
const coordString = `${currentLat}, ${currentLng}`;
456+
const coordListStr = `[${currentLat}, ${currentLng}]`;
457457

458458
// 1. Update the component's internal state immediately.
459459
// This ensures that if a re-render is triggered, its logic will use the
460460
// new coordinates and prevent the map from recentering on markers.
461461
this.center = [currentLat, currentLng];
462462

463463
// 2. Set the config value, which will be saved.
464-
this.config.set('center', coordString);
464+
this.config.set('center', coordListStr);
465465

466466
// 3. Immediately move the map for instant user feedback.
467467
this.map?.setCenter([currentLng, currentLat]); // MapLibre uses [lng, lat]
@@ -491,7 +491,17 @@ export class MapView extends BasesView {
491491
// Create markers for entries with valid coordinates
492492
const validMarkers: MapMarker[] = this.markers = [];
493493
for (const entry of this.data.data) {
494-
const coordinates = this.extractCoordinates(entry);
494+
if (!entry) continue;
495+
496+
let coordinates: [number, number] | null = null;
497+
try {
498+
const value = entry.getValue(this.coordinatesProp);
499+
coordinates = this.coordinateFromValue(value);
500+
}
501+
catch (error) {
502+
console.error(`Error extracting coordinates for ${entry.file.name}:`, error);
503+
}
504+
495505
if (coordinates) {
496506
const marker = this.createMarker(entry, coordinates);
497507
if (marker) {
@@ -524,46 +534,38 @@ export class MapView extends BasesView {
524534
}
525535
}
526536

527-
private extractCoordinates(entry: BasesEntry): [number, number] | null {
528-
if (!this.coordinatesProp) return null;
529-
530-
try {
531-
const value = entry.getValue(this.coordinatesProp);
532-
533-
if (!value) return null;
537+
private coordinateFromValue(value: Value | null): [number, number] | null {
538+
let lat: number | null = null;
539+
let lng: number | null = null;
534540

535-
// Handle list values (e.g., ["34.1395597", "-118.3870991"] or [34.1395597, -118.3870991])
536-
if (value instanceof ListValue) {
537-
if (value.length() >= 2) {
538-
const lat = this.parseCoordinate(value.get(0));
539-
const lng = this.parseCoordinate(value.get(1));
540-
if (lat !== null && lng !== null) {
541-
return [lat, lng];
542-
}
543-
}
541+
// Handle list values (e.g., ["34.1395597", "-118.3870991"] or [34.1395597, -118.3870991])
542+
if (value instanceof ListValue) {
543+
if (value.length() >= 2) {
544+
lat = this.parseCoordinate(value.get(0));
545+
lng = this.parseCoordinate(value.get(1));
544546
}
545-
// Handle string values (e.g., "34.1395597,-118.3870991" or "34.1395597, -118.3870991")
546-
else if (value instanceof StringValue) {
547-
const stringData = value.toString().trim();
548-
549-
// Split by comma and handle various spacing
550-
const parts = stringData.split(',');
551-
if (parts.length >= 2) {
552-
const lat = this.parseCoordinate(parts[0].trim());
553-
const lng = this.parseCoordinate(parts[1].trim());
554-
if (lat !== null && lng !== null) {
555-
return [lat, lng];
556-
}
557-
}
547+
}
548+
// Handle string values (e.g., "34.1395597,-118.3870991" or "34.1395597, -118.3870991")
549+
else if (value instanceof StringValue) {
550+
// Split by comma and handle various spacing
551+
const parts = value.toString().trim().split(',');
552+
if (parts.length >= 2) {
553+
lat = this.parseCoordinate(parts[0].trim());
554+
lng = this.parseCoordinate(parts[1].trim());
558555
}
559556
}
560-
catch (error) {
561-
console.error(`Error extracting coordinates for ${entry.file.name}:`, error);
557+
558+
if (lat && lng && this.verifyLatLng(lat, lng)) {
559+
return [lat, lng];
562560
}
563561

564562
return null;
565563
}
566564

565+
private verifyLatLng(lat: number, lng: number): boolean {
566+
return !isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180;
567+
}
568+
567569
private parseCoordinate(value: unknown): number | null {
568570
if (value instanceof NumberValue) {
569571
const numData = Number(value.toString());
@@ -930,9 +932,9 @@ export class MapView extends BasesView {
930932

931933
{
932934
displayName: 'Center coordinates',
933-
type: 'text',
935+
type: 'formula',
934936
key: 'center',
935-
placeholder: '37.75904, -119.02042',
937+
placeholder: '[latitude, longitude]',
936938
},
937939
{
938940
displayName: 'Default zoom',

0 commit comments

Comments
 (0)