- ilSayfaHref: üniversite sayfası il hapı, /universiteler listesi, bölüm / sonuç / listem / tadımlık satırlarındaki il metası şehir sayfasına gider. - Şehir kümeleri tüm (üniversite, il) çiftlerinden: DB'deki her il değerinin sayfası var (ODTÜ Ankara + KKTC); dev'de eski globalThis önbelleğine dayanıklı. - PikselZemin ton="acik", CtaBandi/CtaSiraForm ton="beyaz": /universiteler altı ve /meraklisina kapanışı beyaz, diğer bantlar mavi (dönüşümlü). - ilUlkeHaritasi: il değerinden ülke haritası + şehir konumu. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
220 lines
7.2 KiB
TypeScript
220 lines
7.2 KiB
TypeScript
// Türkiye dışındaki (KKTC ve yurtdışı) üniversitelerin ülke haritası çözümü.
|
||
// Kontür verisi harita-ulkeler-verisi.ts'te (scripts/ulke-harita-uret.ts üretir).
|
||
|
||
import {
|
||
ULKE_HARITALARI,
|
||
type UlkeKodu,
|
||
type UlkeHarita,
|
||
} from "./harita-ulkeler-verisi";
|
||
import type { LatLng } from "./uni-koordinatlar";
|
||
|
||
export {
|
||
ULKE_HARITALARI,
|
||
ULKE_HARITA_GENISLIK,
|
||
ULKE_HARITA_YUKSEKLIK,
|
||
} from "./harita-ulkeler-verisi";
|
||
export type { UlkeKodu, UlkeHarita } from "./harita-ulkeler-verisi";
|
||
|
||
/** Schema.org addressCountry için ISO 3166-1 alpha-2 kodları. */
|
||
export const ULKE_ISO: Record<UlkeKodu, string> = {
|
||
kktc: "CY",
|
||
azerbaycan: "AZ",
|
||
kirgizistan: "KG",
|
||
kazakistan: "KZ",
|
||
"bosna-hersek": "BA",
|
||
makedonya: "MK",
|
||
arnavutluk: "AL",
|
||
};
|
||
|
||
type Sehir = { ulke: UlkeKodu; ad: string; koord: LatLng };
|
||
|
||
/** DB'deki il değerlerinden ve düzeltme tablosundan şehir anahtarları. */
|
||
const SEHIRLER: Record<string, Sehir> = {
|
||
GİRNE: { ulke: "kktc", ad: "Girne", koord: [35.341, 33.319] },
|
||
LEFKOŞA: { ulke: "kktc", ad: "Lefkoşa", koord: [35.19, 33.365] },
|
||
GAZİMAĞUSA: { ulke: "kktc", ad: "Gazimağusa", koord: [35.125, 33.941] },
|
||
GÜZELYURT: { ulke: "kktc", ad: "Güzelyurt", koord: [35.198, 32.994] },
|
||
LEFKE: { ulke: "kktc", ad: "Lefke", koord: [35.111, 32.849] },
|
||
"BAKÜ-AZERBAYCAN": {
|
||
ulke: "azerbaycan",
|
||
ad: "Bakü",
|
||
koord: [40.409, 49.867],
|
||
},
|
||
"BİŞKEK-KIRGIZİSTAN": {
|
||
ulke: "kirgizistan",
|
||
ad: "Bişkek",
|
||
koord: [42.875, 74.603],
|
||
},
|
||
"TÜRKİSTAN-KAZAKİSTAN": {
|
||
ulke: "kazakistan",
|
||
ad: "Türkistan",
|
||
koord: [43.297, 68.252],
|
||
},
|
||
"SARAYBOSNA - BOSNA - HERSEK": {
|
||
ulke: "bosna-hersek",
|
||
ad: "Saraybosna",
|
||
koord: [43.856, 18.413],
|
||
},
|
||
ÜSKÜP: { ulke: "makedonya", ad: "Üsküp", koord: [41.997, 21.428] },
|
||
TİRAN: { ulke: "arnavutluk", ad: "Tiran", koord: [41.328, 19.818] },
|
||
};
|
||
|
||
type SehirAnahtari = keyof typeof SEHIRLER;
|
||
|
||
/**
|
||
* Kaynak verideki gürültü için üniversite adına göre düzeltme:
|
||
* - Uluslararası Balkan Üniversitesi Üsküp'tedir; YÖK Atlas satırlarının
|
||
* çoğu il'i yanlışlıkla "SARAYBOSNA - BOSNA - HERSEK" der.
|
||
* - Tiran New York Üniversitesi'nin il alanı boştur.
|
||
* - ODTÜ ve ASBÜ'nün KKTC kampüs satırları vardır ama ana kampüs Türkiye'de;
|
||
* null → Türkiye haritasında kalır.
|
||
* Anahtar: uniAdiNormalize edilmiş adın tr-TR büyük harf hali.
|
||
*/
|
||
const UNI_DUZELTME: Record<string, SehirAnahtari | null> = {
|
||
"ULUSLARARASI BALKAN ÜNİVERSİTESİ": "ÜSKÜP",
|
||
"TİRAN NEW YORK ÜNİVERSİTESİ": "TİRAN",
|
||
"KIBRIS AYDIN ÜNİVERSİTESİ": "GİRNE", // il alanı yalnızca "KIBRIS"
|
||
"ORTA DOĞU TEKNİK ÜNİVERSİTESİ": null,
|
||
"ANKARA SOSYAL BİLİMLER ÜNİVERSİTESİ": null,
|
||
};
|
||
|
||
/** il değeri Türkiye dışını mı gösteriyor? ("KIBRIS" genel değeri dahil) */
|
||
const YURTDISI_IL = new Set([...Object.keys(SEHIRLER), "KIBRIS"]);
|
||
|
||
/**
|
||
* Ad sonundaki "(KKTC-LEFKOŞA)" ekinden şehir anahtarı. YÖK Atlas'ta 100'den
|
||
* fazla KKTC satırının il alanı şehir değil genel "KIBRIS"tır (Doğu Akdeniz,
|
||
* Yakın Doğu, Lefke Avrupa, Uluslararası Final, Kıbrıs Sağlık ve Toplum
|
||
* Bilimleri); şehir yalnızca üniversite adının parantezinde durur. Bu ek
|
||
* okunmazsa o programlar hiçbir haritaya düşmez, "haritada gösterilemiyor"
|
||
* sayısına yazılır.
|
||
*/
|
||
function ektenSehir(universite: string): SehirAnahtari | null {
|
||
const ek = universite.match(/\(([^)]*)\)\s*$/)?.[1];
|
||
if (!ek) return null;
|
||
// "KKTC-GAZİMAĞUSA" → "GAZİMAĞUSA"; ülke öneki olmayan "(ANKARA)" gibi
|
||
// ekler SEHIRLER'de karşılık bulmadığından kendiliğinden elenir.
|
||
const sehir = ek.split("-").pop()!.trim().toLocaleUpperCase("tr-TR");
|
||
return sehir in SEHIRLER ? (sehir as SehirAnahtari) : null;
|
||
}
|
||
|
||
/** Üniversite adı + il'den şehir anahtarı; şehri bilinmeyen KKTC'de ülke. */
|
||
type Cozum = { anahtar: SehirAnahtari } | { ulke: UlkeKodu } | null;
|
||
|
||
function coz(universite: string, il: string | null): Cozum {
|
||
const ad = universite
|
||
.replace(/\s*\([^)]*\)\s*$/, "")
|
||
.trim()
|
||
.toLocaleUpperCase("tr-TR");
|
||
|
||
if (ad in UNI_DUZELTME) {
|
||
const anahtar = UNI_DUZELTME[ad];
|
||
return anahtar === null ? null : { anahtar };
|
||
}
|
||
if (!il || !YURTDISI_IL.has(il)) return null;
|
||
if (il in SEHIRLER) return { anahtar: il as SehirAnahtari };
|
||
// il "KIBRIS": ülke bilinir, şehir adın parantez ekinden okunur;
|
||
// o da yoksa ülke seviyesinde kalır (şehir pini çizilemez)
|
||
const ekSehir = ektenSehir(universite);
|
||
return ekSehir ? { anahtar: ekSehir } : { ulke: "kktc" };
|
||
}
|
||
|
||
export type UlkeKonum = {
|
||
ulke: UlkeKodu;
|
||
ulkeAd: string;
|
||
iso: string;
|
||
harita: UlkeHarita;
|
||
/** Şehir adı; genel "KIBRIS" gibi şehri bilinmeyen durumda null */
|
||
sehir: string | null;
|
||
};
|
||
|
||
/**
|
||
* Üniversite Türkiye dışındaysa ülke haritası + şehir adı döner;
|
||
* Türkiye'deyse (veya çözülemiyorsa) null — Türkiye haritası kullanılır.
|
||
*/
|
||
export function uniUlkeKonum(
|
||
universite: string,
|
||
il: string | null,
|
||
): UlkeKonum | null {
|
||
const cozum = coz(universite, il);
|
||
if (!cozum) return null;
|
||
const ulke = "anahtar" in cozum ? SEHIRLER[cozum.anahtar].ulke : cozum.ulke;
|
||
const harita = ULKE_HARITALARI[ulke];
|
||
return {
|
||
ulke,
|
||
ulkeAd: harita.ad,
|
||
iso: ULKE_ISO[ulke],
|
||
harita,
|
||
sehir: "anahtar" in cozum ? SEHIRLER[cozum.anahtar].ad : null,
|
||
};
|
||
}
|
||
|
||
/** Yurtdışı şehir merkezinin kendi ülke haritasındaki viewBox konumu. */
|
||
export type YurtdisiKonum = {
|
||
ulke: UlkeKodu;
|
||
ulkeAd: string;
|
||
sehir: string;
|
||
x: number;
|
||
y: number;
|
||
};
|
||
|
||
function sehirKonumu(anahtar: SehirAnahtari): YurtdisiKonum {
|
||
const sehir = SEHIRLER[anahtar];
|
||
const { ad, proje } = ULKE_HARITALARI[sehir.ulke];
|
||
const [lat, lng] = sehir.koord;
|
||
return {
|
||
ulke: sehir.ulke,
|
||
ulkeAd: ad,
|
||
sehir: sehir.ad,
|
||
x: proje.ax * lng + proje.bx,
|
||
y: proje.ay * lat + proje.by,
|
||
};
|
||
}
|
||
|
||
/** Yurtdışı üniversitenin şehir konumu; şehir çözülemiyorsa null. */
|
||
export function yurtdisiUniKonum(
|
||
universite: string,
|
||
il: string | null,
|
||
): YurtdisiKonum | null {
|
||
const cozum = coz(universite, il);
|
||
return cozum && "anahtar" in cozum ? sehirKonumu(cozum.anahtar) : null;
|
||
}
|
||
|
||
/**
|
||
* Yalnızca il değerinden ülke haritası (şehir sayfası). "KIBRIS" genel
|
||
* değeri ülke seviyesinde kalır; "ÜSKÜP-MAKEDONYA" gibi ülke ekli değerler
|
||
* ilk parçasıyla çözülür. Türkiye ili ya da bilinmeyen değer → null.
|
||
*/
|
||
export function ilUlkeHaritasi(il: string): {
|
||
ulke: UlkeKodu;
|
||
ulkeAd: string;
|
||
harita: UlkeHarita;
|
||
sehir: YurtdisiKonum | null;
|
||
} | null {
|
||
const anahtar =
|
||
il in SEHIRLER
|
||
? (il as SehirAnahtari)
|
||
: (() => {
|
||
const ilk = il.split("-")[0].trim();
|
||
return ilk in SEHIRLER ? (ilk as SehirAnahtari) : null;
|
||
})();
|
||
const ulke: UlkeKodu | null = anahtar
|
||
? SEHIRLER[anahtar].ulke
|
||
: il === "KIBRIS"
|
||
? "kktc"
|
||
: null;
|
||
if (!ulke) return null;
|
||
const harita = ULKE_HARITALARI[ulke];
|
||
return {
|
||
ulke,
|
||
ulkeAd: harita.ad,
|
||
harita,
|
||
sehir: anahtar ? sehirKonumu(anahtar) : null,
|
||
};
|
||
}
|
||
|
||
/** Yalnızca il değerinden (kilitli satırlar) yurtdışı şehir konumu. */
|
||
export function yurtdisiIlKonum(il: string | null): YurtdisiKonum | null {
|
||
return il && il in SEHIRLER ? sehirKonumu(il as SehirAnahtari) : null;
|
||
}
|