refactor: centralize MapPoint

This commit is contained in:
ccmdi 2025-11-23 17:14:06 -05:00
parent 5998c99cbe
commit da11401e63
No known key found for this signature in database
5 changed files with 89 additions and 68 deletions

View file

@ -9,33 +9,15 @@ import { MapView as MapViewType } from '@deck.gl/core';
import { MapTagSettings } from './settings/map-tag-settings';
import type MapPlugin from './main';
import type { ThumbnailCacheManager } from './thumbnail-cache';
import { LatLng } from './types/latlng';
import { LatLng } from './types/LatLng';
import { MapPoint } from './types/MapPoint';
function easeCubic(t: number): number {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
type PropertyValue = string | number | boolean | string[] | null;
export let currentViewState: MapViewState | null = null;
interface MapProperty {
name: string;
value: PropertyValue;
}
export interface MapPoint {
location: LatLng.Verified;
title: string;
color?: string;
size?: number;
cover?: string;
file?: TFile;
tags?: string[];
properties?: MapProperty[];
polygon?: LatLng.Verified[];
}
interface TileIndex {
index: {
x: number;

View file

@ -1,43 +0,0 @@
import { MapPoint } from "./map-renderer";
import { LatLng } from "./types/latlng";
export function haveLocationsChanged(points1: MapPoint[], points2: MapPoint[]): boolean {
return !arePointsEqual(points1, points2);
}
export function arePointsEqual(points1: MapPoint[], points2: MapPoint[]): boolean {
if (points1.length !== points2.length) return false;
for (let i = 0; i < points1.length; i++) {
const p1 = points1[i];
const p2 = points2[i];
if (!LatLng.equals(p1.location, p2.location) ||
p1.title !== p2.title ||
p1.color !== p2.color ||
p1.size !== p2.size ||
p1.cover !== p2.cover ||
p1.file?.path !== p2.file?.path) {
return false;
}
const tags1 = p1.tags || [];
const tags2 = p2.tags || [];
if (tags1.length !== tags2.length || !tags1.every((tag, idx) => tag === tags2[idx])) {
return false;
}
const props1 = p1.properties || [];
const props2 = p2.properties || [];
if (props1.length !== props2.length) {
return false;
}
for (let j = 0; j < props1.length; j++) {
if (props1[j].name !== props2[j].name || props1[j].value !== props2[j].value) {
return false;
}
}
}
return true;
}

82
src/types/MapPoint.ts Normal file
View file

@ -0,0 +1,82 @@
import { TFile } from "obsidian";
import { LatLng } from "./LatLng";
type PropertyValue = string | number | boolean | string[] | null;
interface MapProperty {
name: string;
value: PropertyValue;
}
export interface MapPoint {
location: LatLng.Verified;
title: string;
color?: string;
size?: number;
cover?: string;
file?: TFile;
tags?: string[];
properties?: MapProperty[];
polygon?: LatLng.Verified[];
}
export namespace MapPoint {
export function areSamePlace(point1: MapPoint, point2: MapPoint): boolean {
return point1.location.lat === point2.location.lat && point1.location.lng === point2.location.lng;
}
export function areEqual(point1: MapPoint[], point2: MapPoint[]): boolean;
export function areEqual(point1: MapPoint, point2: MapPoint): boolean;
export function areEqual(
point1: MapPoint | MapPoint[],
point2: MapPoint | MapPoint[]
): boolean {
// Handle array case
if (Array.isArray(point1) && Array.isArray(point2)) {
if (point1.length !== point2.length) return false;
for (let i = 0; i < point1.length; i++) {
if (!areEqual(point1[i], point2[i])) return false;
}
return true;
}
// Handle single MapPoint case
if (!Array.isArray(point1) && !Array.isArray(point2)) {
if (!LatLng.equals(point1.location, point2.location) ||
point1.title !== point2.title ||
point1.color !== point2.color ||
point1.size !== point2.size ||
point1.cover !== point2.cover ||
point1.file?.path !== point2.file?.path) {
return false;
}
const tags1 = point1.tags || [];
const tags2 = point2.tags || [];
if (tags1.length !== tags2.length || !tags1.every((tag, idx) => tag === tags2[idx])) {
return false;
}
const props1 = point1.properties || [];
const props2 = point2.properties || [];
if (props1.length !== props2.length) {
return false;
}
for (let j = 0; j < props1.length; j++) {
if (props1[j].name !== props2[j].name || props1[j].value !== props2[j].value) {
return false;
}
}
return true;
}
return false;
}
export function haveLocationsChanged(points1: MapPoint[], points2: MapPoint[]): boolean {
return !areEqual(points1, points2);
}
}

View file

@ -11,12 +11,12 @@ import {
} from 'obsidian';
import { Deck, FlyToInterpolator, MapViewState } from '@deck.gl/core';
import { MapView as MapViewType } from '@deck.gl/core';
import { createMapRenderer, MapPoint, updateMapPoints } from '../map-renderer';
import { createMapRenderer, updateMapPoints } from '../map-renderer';
import MapPlugin from '../main';
import { haveLocationsChanged } from '../pointutils';
import { currentViewState } from '../map-renderer';
import { LatLng } from '../types/latlng';
import { LatLng } from '../types/LatLng';
import { extractFromFrontmatter } from '../utils';
import { MapPoint } from '../types/MapPoint';
export const MapBasesViewType = 'map';
export const SEARCH_DEBOUNCE_TIME = 300;
@ -339,7 +339,7 @@ export class MapBasesView extends BasesView {
const center = this.getCenter();
const hasConfiguredCenter = center.lat !== 0 || center.lng !== 0;
const locationsChanged = haveLocationsChanged(points, this.lastPoints);
const locationsChanged = MapPoint.haveLocationsChanged(points, this.lastPoints);
const configChanged = this.hasConfigMeaningfullyChanged();
this.lastConfigState = { ...this.config.data };

View file

@ -5,7 +5,7 @@ import {
ViewOption,
setIcon,
} from 'obsidian';
import { MapPoint } from '../map-renderer';
import { MapPoint } from '../types/MapPoint';
import MapPlugin from '../main';
import { MapBasesView } from './map-bases-view';