/** * Approximate centroids for Vietnam's 63 provinces / centrally-administered * cities, used as a fallback when OSM `addr:state` / `addr:province` tags * are missing (which is the common case for industrial-park polygons in VN). * * The coords are public-domain capital-city centroids (good enough for a * "which province does this point land in?" nearest-neighbour lookup at * the +/- few-km level — the long shape of some provinces means the * nearest centroid will occasionally pick the wrong neighbour, but admin * can correct on promote. * * Province name canonical form = display name in Vietnamese (no diacritics * stripped) so it matches what the seed data + UI already uses. */ export interface ProvinceCentroid { name: string; lat: number; lng: number; } export const VN_PROVINCE_CENTROIDS: ProvinceCentroid[] = [ { name: 'Hà Nội', lat: 21.028511, lng: 105.804817 }, { name: 'Hồ Chí Minh', lat: 10.762622, lng: 106.660172 }, { name: 'Hải Phòng', lat: 20.844912, lng: 106.688084 }, { name: 'Đà Nẵng', lat: 16.054407, lng: 108.202167 }, { name: 'Cần Thơ', lat: 10.045162, lng: 105.746857 }, { name: 'An Giang', lat: 10.521583, lng: 105.125896 }, { name: 'Bà Rịa - Vũng Tàu', lat: 10.541136, lng: 107.242851 }, { name: 'Bạc Liêu', lat: 9.294085, lng: 105.721787 }, { name: 'Bắc Giang', lat: 21.281932, lng: 106.197658 }, { name: 'Bắc Kạn', lat: 22.147291, lng: 105.834160 }, { name: 'Bắc Ninh', lat: 21.186080, lng: 106.076371 }, { name: 'Bến Tre', lat: 10.243519, lng: 106.375140 }, { name: 'Bình Dương', lat: 11.325237, lng: 106.477017 }, { name: 'Bình Định', lat: 13.782250, lng: 109.219574 }, { name: 'Bình Phước', lat: 11.751888, lng: 106.723917 }, { name: 'Bình Thuận', lat: 11.090668, lng: 108.072094 }, { name: 'Cà Mau', lat: 9.176790, lng: 105.150253 }, { name: 'Cao Bằng', lat: 22.665684, lng: 106.257549 }, { name: 'Đắk Lắk', lat: 12.710017, lng: 108.237633 }, { name: 'Đắk Nông', lat: 12.264144, lng: 107.609794 }, { name: 'Điện Biên', lat: 21.386073, lng: 103.016510 }, { name: 'Đồng Nai', lat: 11.066000, lng: 107.166700 }, { name: 'Đồng Tháp', lat: 10.493333, lng: 105.688200 }, { name: 'Gia Lai', lat: 13.808078, lng: 108.109375 }, { name: 'Hà Giang', lat: 22.823453, lng: 104.978573 }, { name: 'Hà Nam', lat: 20.541127, lng: 105.913303 }, { name: 'Hà Tĩnh', lat: 18.342745, lng: 105.905499 }, { name: 'Hải Dương', lat: 20.940981, lng: 106.330156 }, { name: 'Hậu Giang', lat: 9.757897, lng: 105.641110 }, { name: 'Hòa Bình', lat: 20.817192, lng: 105.337720 }, { name: 'Hưng Yên', lat: 20.852241, lng: 106.015511 }, { name: 'Khánh Hòa', lat: 12.258515, lng: 109.052528 }, { name: 'Kiên Giang', lat: 10.012103, lng: 105.080921 }, { name: 'Kon Tum', lat: 14.349953, lng: 108.000534 }, { name: 'Lai Châu', lat: 22.396519, lng: 103.471370 }, { name: 'Lâm Đồng', lat: 11.940419, lng: 108.458313 }, { name: 'Lạng Sơn', lat: 21.853708, lng: 106.761525 }, { name: 'Lào Cai', lat: 22.485198, lng: 103.974845 }, { name: 'Long An', lat: 10.535359, lng: 106.405460 }, { name: 'Nam Định', lat: 20.438822, lng: 106.162106 }, { name: 'Nghệ An', lat: 18.679585, lng: 105.681753 }, { name: 'Ninh Bình', lat: 20.250716, lng: 105.974623 }, { name: 'Ninh Thuận', lat: 11.673911, lng: 108.864225 }, { name: 'Phú Thọ', lat: 21.398716, lng: 105.151787 }, { name: 'Phú Yên', lat: 13.088067, lng: 109.092876 }, { name: 'Quảng Bình', lat: 17.478366, lng: 106.621288 }, { name: 'Quảng Nam', lat: 15.539353, lng: 108.019047 }, { name: 'Quảng Ngãi', lat: 15.120137, lng: 108.804340 }, { name: 'Quảng Ninh', lat: 21.006382, lng: 107.292514 }, { name: 'Quảng Trị', lat: 16.745360, lng: 107.187462 }, { name: 'Sóc Trăng', lat: 9.602522, lng: 105.973797 }, { name: 'Sơn La', lat: 21.328228, lng: 103.914400 }, { name: 'Tây Ninh', lat: 11.310300, lng: 106.098046 }, { name: 'Thái Bình', lat: 20.446016, lng: 106.336445 }, { name: 'Thái Nguyên', lat: 21.594280, lng: 105.844866 }, { name: 'Thanh Hóa', lat: 19.806692, lng: 105.785182 }, { name: 'Thừa Thiên Huế', lat: 16.467397, lng: 107.590533 }, { name: 'Tiền Giang', lat: 10.449334, lng: 106.342120 }, { name: 'Trà Vinh', lat: 9.812741, lng: 106.299250 }, { name: 'Tuyên Quang', lat: 21.778812, lng: 105.218015 }, { name: 'Vĩnh Long', lat: 10.253938, lng: 105.972456 }, { name: 'Vĩnh Phúc', lat: 21.308690, lng: 105.604813 }, { name: 'Yên Bái', lat: 21.722733, lng: 104.911289 }, ]; /** * Find the nearest province centroid for a given lat/lng. Uses naive squared * distance — fine for VN's ~1500-km north-south extent. Always returns a * province (the dataset covers the country); callers can fall back to * "Chưa xác định" if they need to. */ export function nearestProvince(lat: number, lng: number): string { let best = VN_PROVINCE_CENTROIDS[0]; let bestD = Infinity; for (const p of VN_PROVINCE_CENTROIDS) { const dLat = lat - p.lat; const dLng = lng - p.lng; const d = dLat * dLat + dLng * dLng; if (d < bestD) { bestD = d; best = p; } } return best.name; }