|
|
|
|
@ -32,12 +32,15 @@ declare global {
|
|
|
|
|
export interface TiandituSearchPoi {
|
|
|
|
|
name: string
|
|
|
|
|
address?: string
|
|
|
|
|
lonlat: string
|
|
|
|
|
lonlat?: string
|
|
|
|
|
lon?: number | string
|
|
|
|
|
lng?: number | string
|
|
|
|
|
lat?: number | string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TiandituLocalSearchResult {
|
|
|
|
|
getResultType(): number
|
|
|
|
|
getPois(): TiandituSearchPoi[]
|
|
|
|
|
getResultType(): number | string
|
|
|
|
|
getPois(): TiandituSearchPoi[] | Record<string, TiandituSearchPoi> | false | null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TiandituLocalSearchConfig {
|
|
|
|
|
@ -276,16 +279,53 @@ export function shortenSchoolMapLabel(name: string, max = 12): string {
|
|
|
|
|
return t.length > max ? `${t.slice(0, max)}…` : t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 解析天地图 POI 的 lonlat 字段(格式:"经度 纬度") */
|
|
|
|
|
export function parseTiandituPoiLonlat(lonlat: string): { lng: number; lat: number } | null {
|
|
|
|
|
const parts = lonlat.trim().split(/\s+/)
|
|
|
|
|
if (parts.length < 2) return null
|
|
|
|
|
const lng = Number(parts[0])
|
|
|
|
|
const lat = Number(parts[1])
|
|
|
|
|
function parseLonlatPair(first: unknown, second: unknown): { lng: number; lat: number } | null {
|
|
|
|
|
let lng = Number(first)
|
|
|
|
|
let lat = Number(second)
|
|
|
|
|
if (!Number.isFinite(lng) || !Number.isFinite(lat)) return null
|
|
|
|
|
// 部分结果可能为 "纬度,经度",按中国范围自动纠正
|
|
|
|
|
if (lng <= 60 && lat >= 70) {
|
|
|
|
|
;[lng, lat] = [lat, lng]
|
|
|
|
|
}
|
|
|
|
|
return { lng, lat }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 解析天地图 POI 坐标(支持 "经度 纬度"、"经度,纬度" 及 lon/lat 字段) */
|
|
|
|
|
export function parseTiandituPoiLonlat(
|
|
|
|
|
poi: TiandituSearchPoi | string,
|
|
|
|
|
): { lng: number; lat: number } | null {
|
|
|
|
|
if (typeof poi === 'string') {
|
|
|
|
|
const text = poi.trim()
|
|
|
|
|
if (!text) return null
|
|
|
|
|
const parts = text.split(/[\s,;,]+/).filter(Boolean)
|
|
|
|
|
if (parts.length < 2) return null
|
|
|
|
|
return parseLonlatPair(parts[0], parts[1])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const extra = poi as unknown as Record<string, unknown>
|
|
|
|
|
const rawLonlat = poi.lonlat ?? extra.LonLat ?? extra.lonLat
|
|
|
|
|
if (typeof rawLonlat === 'string' && rawLonlat.trim()) {
|
|
|
|
|
const fromLonlat = parseTiandituPoiLonlat(rawLonlat)
|
|
|
|
|
if (fromLonlat) return fromLonlat
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const lng = poi.lng ?? poi.lon ?? extra.Lon
|
|
|
|
|
const lat = poi.lat ?? extra.Lat
|
|
|
|
|
if (lng != null && lat != null) {
|
|
|
|
|
return parseLonlatPair(lng, lat)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 规范化 LocalSearch 返回的 POI 列表 */
|
|
|
|
|
export function normalizeTiandituPois(pois: unknown): TiandituSearchPoi[] {
|
|
|
|
|
if (!pois) return []
|
|
|
|
|
if (Array.isArray(pois)) return pois
|
|
|
|
|
if (typeof pois === 'object') return Object.values(pois)
|
|
|
|
|
return []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 高校雷达网地图:固定以苏州市为中心展示 */
|
|
|
|
|
export function centerMapOnSuzhou(
|
|
|
|
|
map: TiandituMap,
|
|
|
|
|
|