gedcom-ts 2026.5.0 → 2026.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +20 -6
- package/dist/geocode/index.d.ts +3 -0
- package/dist/geocode/place-city-utils.d.ts +11 -0
- package/dist/geocode/place-clusters.d.ts +34 -0
- package/dist/geocode/place-geocode.d.ts +50 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +1 -1
- package/dist/services/CitySearch.d.ts +4 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ All notable changes of gedcom-ts
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`src/geocode/`** : géocodage Nominatim (`GET /search?q=…&format=jsonv2`), contexte arbre (`inferGeocodeContext`), ranking (`rankGeocodeCandidates`), harmonisation des lieux (`findHarmonizationClusters`, `applyGeocodeCandidateToActs`), utilitaires ville (`normalizeCityKey`, `findCanonicalCityLabel`). `fetch` et `User-Agent` configurables pour les tests.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **`getCityCoordinates`** : marqué `@deprecated` ; utilise la nouvelle API Nominatim (plus `search.php?city=` ni `XMLHttpRequest`).
|
|
14
|
+
|
|
7
15
|
## [2026.5.0] - 2026-05-15
|
|
8
16
|
|
|
9
17
|
### Versioning
|
package/README.md
CHANGED
|
@@ -492,18 +492,32 @@ import { remainingTypesAct, Acts } from "gedcom-ts";
|
|
|
492
492
|
const available = remainingTypesAct(new Acts());
|
|
493
493
|
```
|
|
494
494
|
|
|
495
|
-
####
|
|
495
|
+
#### Geocoding (Nominatim)
|
|
496
496
|
|
|
497
|
-
|
|
497
|
+
Place search uses the official Nominatim endpoint `GET https://nominatim.openstreetmap.org/search` with `q`, `format=jsonv2`, and `addressdetails=1` (not the legacy `search.php?city=` API). A `User-Agent` header is required (`gedcom-ts/<version> (genealogy library)` by default).
|
|
498
498
|
|
|
499
499
|
```ts
|
|
500
|
-
import {
|
|
500
|
+
import {
|
|
501
|
+
inferGeocodeContext,
|
|
502
|
+
searchPlacesWithContext,
|
|
503
|
+
rankGeocodeCandidates,
|
|
504
|
+
findHarmonizationClusters,
|
|
505
|
+
applyGeocodeCandidateToActs,
|
|
506
|
+
} from "gedcom-ts";
|
|
501
507
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
508
|
+
const context = inferGeocodeContext(ged);
|
|
509
|
+
const candidates = await searchPlacesWithContext("Valence", context);
|
|
510
|
+
// candidates are ranked (French tree → Valence FR before ES)
|
|
511
|
+
|
|
512
|
+
const clusters = findHarmonizationClusters(ged);
|
|
505
513
|
```
|
|
506
514
|
|
|
515
|
+
For tests or Node without a global `fetch`, pass `fetchFn` in options. Low-level API: `searchPlaces(query, { countryCodes, limit, userAgent, fetchFn })`.
|
|
516
|
+
|
|
517
|
+
#### `getCityCoordinates(cityName, callback)` (deprecated)
|
|
518
|
+
|
|
519
|
+
Legacy callback API; delegates to `searchPlaces` and maps results to `Place[]`. Prefer `searchPlaces` / `searchPlacesWithContext`.
|
|
520
|
+
|
|
507
521
|
#### `resolveDatasetVersion(headerLines)` / `GedcomDatasetVersion`
|
|
508
522
|
|
|
509
523
|
Inspects the lines of a `0 HEAD` block and returns `"7.0"`, `"5.5"` or `"unknown"`. Useful to branch UI behaviour for legacy datasets.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { normalizeCityKey, tidyCityDisplay, findCanonicalCityLabel, } from "./place-city-utils";
|
|
2
|
+
export { type GeocodeCandidate, type GeocodeContext, type GeocodeFetchFn, type GeocodeSearchOptions, NOMINATIM_SEARCH_URL, defaultGeocodeUserAgent, parseCityQuery, countryLabelToIso, isoToCountryLabel, inferGeocodeContext, buildGeocodeQuery, geocodeContextWithHint, rankGeocodeCandidates, searchPlaces, searchPlacesWithContext, } from "./place-geocode";
|
|
3
|
+
export { type CoordVariant, type CityHarmonizationCluster, levenshteinDistance, citiesAreSimilar, clusterKeyForCity, findHarmonizationClustersFromActs, findHarmonizationClusters, applyCoordinatesToActs, applyGeocodeCandidateToActs, } from "./place-clusters";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Act } from "../commons/Act";
|
|
2
|
+
import type { ReadGed } from "../import/ReadGed";
|
|
3
|
+
/** Clé de regroupement : casse, espaces, compatibilité Unicode (NFKC). */
|
|
4
|
+
export declare function normalizeCityKey(city: string): string;
|
|
5
|
+
/** Libellé affiché : trim + espaces internes unifiés (sans forcer la casse). */
|
|
6
|
+
export declare function tidyCityDisplay(city: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Harmonise l’écriture avec le reste de l’arbre : même clé normalisée → libellé le plus fréquent
|
|
9
|
+
* (exclut l’acte en cours d’édition pour le décompte).
|
|
10
|
+
*/
|
|
11
|
+
export declare function findCanonicalCityLabel(ged: ReadGed, cityInput: string, excludeAct: Act | null): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Act } from "../commons/Act";
|
|
2
|
+
import type { ReadGed } from "../import/ReadGed";
|
|
3
|
+
import { type GeocodeCandidate } from "./place-geocode";
|
|
4
|
+
export interface CoordVariant {
|
|
5
|
+
readonly lat: number;
|
|
6
|
+
readonly lng: number;
|
|
7
|
+
readonly actCount: number;
|
|
8
|
+
}
|
|
9
|
+
/** Groupe de lieux similaires à harmoniser (libellés ou coordonnées divergents). */
|
|
10
|
+
export interface CityHarmonizationCluster {
|
|
11
|
+
readonly clusterKey: string;
|
|
12
|
+
readonly labels: readonly string[];
|
|
13
|
+
readonly coordVariants: readonly CoordVariant[];
|
|
14
|
+
readonly acts: readonly Act[];
|
|
15
|
+
readonly actsWithoutCoord: number;
|
|
16
|
+
}
|
|
17
|
+
/** Distance de Levenshtein (petites chaînes de noms de villes). */
|
|
18
|
+
export declare function levenshteinDistance(a: string, b: string): number;
|
|
19
|
+
/** Ville proche : même clé, faute légère, ou inclusion évidente (Saint-X / St-X). */
|
|
20
|
+
export declare function citiesAreSimilar(a: string, b: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Regroupe les actes dont les villes se ressemblent (libellés uniques + clés normalisées).
|
|
23
|
+
* Complexité ~ O(m²) sur le nombre de villes distinctes, pas sur le nombre d’actes.
|
|
24
|
+
*/
|
|
25
|
+
export declare function findHarmonizationClustersFromActs(acts: readonly Act[]): CityHarmonizationCluster[];
|
|
26
|
+
/** Analyse toute l’arbre (préférer {@link findHarmonizationClustersFromActs} sur un sous-ensemble). */
|
|
27
|
+
export declare function findHarmonizationClusters(ged: ReadGed): CityHarmonizationCluster[];
|
|
28
|
+
export declare function applyCoordinatesToActs(acts: readonly Act[], lat: number, lng: number, patch?: {
|
|
29
|
+
city?: string;
|
|
30
|
+
country?: string | null;
|
|
31
|
+
}): void;
|
|
32
|
+
export declare function applyGeocodeCandidateToActs(acts: readonly Act[], candidate: GeocodeCandidate, preferredCityLabel?: string): void;
|
|
33
|
+
/** Clé de regroupement carte : villes similaires → un marqueur. */
|
|
34
|
+
export declare function clusterKeyForCity(city: string): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ReadGed } from "../import/ReadGed";
|
|
2
|
+
/** Résultat Nominatim présenté à l’utilisateur. */
|
|
3
|
+
export interface GeocodeCandidate {
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly shortLabel: string;
|
|
6
|
+
readonly lat: number;
|
|
7
|
+
readonly lng: number;
|
|
8
|
+
readonly country: string | null;
|
|
9
|
+
readonly countryCode: string | null;
|
|
10
|
+
readonly region: string | null;
|
|
11
|
+
readonly kind: string | null;
|
|
12
|
+
readonly importance: number;
|
|
13
|
+
}
|
|
14
|
+
export interface GeocodeContext {
|
|
15
|
+
/** Codes ISO 3166-1 alpha-2 (ex. `fr`), du plus au moins probable. */
|
|
16
|
+
readonly countryCodes: readonly string[];
|
|
17
|
+
readonly defaultCountryLabel: string | null;
|
|
18
|
+
readonly centroid: {
|
|
19
|
+
lat: number;
|
|
20
|
+
lng: number;
|
|
21
|
+
} | null;
|
|
22
|
+
}
|
|
23
|
+
export type GeocodeFetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
24
|
+
export interface GeocodeSearchOptions {
|
|
25
|
+
readonly countryCodes?: readonly string[];
|
|
26
|
+
readonly limit?: number;
|
|
27
|
+
/** Défaut : `gedcom-ts/<version> (genealogy library)` */
|
|
28
|
+
readonly userAgent?: string;
|
|
29
|
+
/** Client HTTP injectable (tests, Node sans fetch global). */
|
|
30
|
+
readonly fetchFn?: GeocodeFetchFn;
|
|
31
|
+
}
|
|
32
|
+
export declare const NOMINATIM_SEARCH_URL = "https://nominatim.openstreetmap.org/search";
|
|
33
|
+
export declare function defaultGeocodeUserAgent(): string;
|
|
34
|
+
/** Parse « Valence », « Valence, Drôme », « Valence, France ». */
|
|
35
|
+
export declare function parseCityQuery(raw: string): {
|
|
36
|
+
city: string;
|
|
37
|
+
countryHint: string | null;
|
|
38
|
+
};
|
|
39
|
+
export declare function countryLabelToIso(label: string): string | null;
|
|
40
|
+
export declare function isoToCountryLabel(code: string | null | undefined): string | null;
|
|
41
|
+
/** Contexte géographique déduit de l’arbre (pays et centroïde des lieux déjà géolocalisés). */
|
|
42
|
+
export declare function inferGeocodeContext(ged: ReadGed | null): GeocodeContext;
|
|
43
|
+
export declare function buildGeocodeQuery(cityInput: string, context: GeocodeContext, extraCountryHint?: string | null): string;
|
|
44
|
+
/** Priorise le pays saisi par l’utilisateur pour filtre Nominatim et classement. */
|
|
45
|
+
export declare function geocodeContextWithHint(context: GeocodeContext, extraCountryHint?: string | null): GeocodeContext;
|
|
46
|
+
/** Trie les candidats : pays de l’arbre, proximité du centroïde, correspondance du nom. */
|
|
47
|
+
export declare function rankGeocodeCandidates(candidates: GeocodeCandidate[], cityInput: string, context: GeocodeContext): GeocodeCandidate[];
|
|
48
|
+
export declare function searchPlaces(query: string, options?: GeocodeSearchOptions): Promise<GeocodeCandidate[]>;
|
|
49
|
+
/** Recherche avec repli sans filtre pays si trop peu de résultats. */
|
|
50
|
+
export declare function searchPlacesWithContext(cityInput: string, context: GeocodeContext, extraCountryHint?: string | null, options?: GeocodeSearchOptions): Promise<GeocodeCandidate[]>;
|