- ilAdiNormalize harf katlayarak eşler: IZMIR / izmir / İzmir → İZMİR (program_ara,
il_ozeti, profil evIl). il_ozeti "Afyon"u da bulur.
- program_ara bölüm ve üniversite aramasını katlanmış adla yapar ("isletme",
"bogazici", "ODTÜ"); LIKE jokerleri (%/_) artık her şeyi eşlemez.
- Tek harf / boş girdi ilk kaydı (Abaza Dili, Abdullah Gül) döndürmez; "en az 3
harf" hatası döner.
- Kısaltma tablosunda bozuk satır: dtu → deu (Dokuz Eylül).
- Akış hata logu tam hata nesnesi yerine mesajı basar; cagri.ts kullanılmayan import.
- (8'in devamı) dil seçenekleri veride olan dillerle eşitlendi; doğrulama
"Almanca" süzgecini reddetmesin.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
// İl merkezleri arası kuş uçuşu mesafe (km). Profildeki "evden en fazla N km"
|
||
// filtresi il düzeyinde çalışır: adres/koordinat tutulmaz (KVKK, §8).
|
||
import { turkishSlugify } from "./slug";
|
||
import { IL_MERKEZ, type LatLng } from "./uni-koordinatlar";
|
||
|
||
const DUNYA_YARICAP_KM = 6371;
|
||
|
||
export function kmMesafe(a: LatLng, b: LatLng): number {
|
||
const rad = (d: number) => (d * Math.PI) / 180;
|
||
const dLat = rad(b[0] - a[0]);
|
||
const dLng = rad(b[1] - a[1]);
|
||
const h =
|
||
Math.sin(dLat / 2) ** 2 +
|
||
Math.cos(rad(a[0])) * Math.cos(rad(b[0])) * Math.sin(dLng / 2) ** 2;
|
||
return Math.round(2 * DUNYA_YARICAP_KM * Math.asin(Math.sqrt(h)));
|
||
}
|
||
|
||
/**
|
||
* DB il adı biçimine (büyük harf, Türkçe) çevirir; bilinmiyorsa null.
|
||
* Türkçe harfler katlanarak karşılaştırılır: "IZMIR", "izmir", "İzmir" → İZMİR.
|
||
*/
|
||
export function ilAdiNormalize(ham: string): string | null {
|
||
const aday = turkishSlugify(ham);
|
||
if (!aday) return null;
|
||
const iller = Object.keys(IL_MERKEZ).map((il) => ({ il, katli: turkishSlugify(il) }));
|
||
const tam = iller.find((x) => x.katli === aday);
|
||
if (tam) return tam.il;
|
||
// "Afyon" → AFYONKARAHİSAR gibi öneki eşleşen tek il varsa onu al
|
||
const adaylar = iller.filter((x) => x.katli.startsWith(aday));
|
||
return adaylar.length === 1 ? adaylar[0].il : null;
|
||
}
|
||
|
||
/** Ev iline en fazla `km` uzaktaki iller (evin kendisi dahil), yakından uzağa. */
|
||
export function yakinIller(evIl: string, km: number): string[] {
|
||
const ev = IL_MERKEZ[evIl];
|
||
if (!ev) return [];
|
||
return Object.entries(IL_MERKEZ)
|
||
.map(([il, k]) => ({ il, km: kmMesafe(ev, k) }))
|
||
.filter((x) => x.km <= km)
|
||
.sort((a, b) => a.km - b.km)
|
||
.map((x) => x.il);
|
||
}
|
||
|
||
/** İki il arası km; biri bilinmiyorsa null. */
|
||
export function illerArasiKm(a: string, b: string): number | null {
|
||
const ka = IL_MERKEZ[a];
|
||
const kb = IL_MERKEZ[b];
|
||
return ka && kb ? kmMesafe(ka, kb) : null;
|
||
}
|