| | |
| | | message.success('坐标已应用'); |
| | | } |
| | | |
| | | /** |
| | | * POI 搜索(按地点/公司名称检索) |
| | | * |
| | | * Geocoder.getPoint 只做「地址解析」,把字符串当省市区街道处理,不认公司名。 |
| | | * 例如搜「新疆中亿装配式建筑有限公司」,它只识别出「新疆」这个地名, |
| | | * 直接跳到哈尔滨市平房区「新疆街道」。所以这里先用 LocalSearch 走 POI 检索, |
| | | * 命中不了再回退地址解析。 |
| | | */ |
| | | function searchByPoi(keyword: string): Promise<any> { |
| | | return new Promise((resolve) => { |
| | | const LocalSearchCtor = window.BMapGL?.LocalSearch; |
| | | if (!map || !LocalSearchCtor) { |
| | | resolve(null); |
| | | return; |
| | | } |
| | | let settled = false; |
| | | const finish = (value: any) => { |
| | | if (settled) { |
| | | return; |
| | | } |
| | | settled = true; |
| | | resolve(value); |
| | | }; |
| | | // 兜底:POI 检索偶尔不回调,2.5 秒后按失败处理,避免一直转圈 |
| | | const timer = setTimeout(() => finish(null), 2500); |
| | | const search = new LocalSearchCtor(map, { |
| | | // 注意:GL 版结果是通过回调参数返回的,不是 search.getResults() |
| | | onSearchComplete: (results: any) => { |
| | | clearTimeout(timer); |
| | | try { |
| | | if (typeof search.getStatus === 'function' && search.getStatus() !== 0) { |
| | | finish(null); |
| | | return; |
| | | } |
| | | // 兼容两种取法:标准 getPoi(0) 与内部 _pois[0] |
| | | const poi = results?.getPoi?.(0) ?? results?._pois?.[0]; |
| | | if (!poi?.point) { |
| | | finish(null); |
| | | return; |
| | | } |
| | | finish({ point: poi.point, title: poi.title, address: poi.address }); |
| | | } catch { |
| | | finish(null); |
| | | } |
| | | }, |
| | | }); |
| | | try { |
| | | search.search(keyword); |
| | | } catch { |
| | | clearTimeout(timer); |
| | | finish(null); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | async function handleSearch() { |
| | | const keyword = searchKeyword.value.trim(); |
| | | if (!keyword || !geocoder) { |
| | | if (!keyword) { |
| | | return; |
| | | } |
| | | loading.value = true; |
| | | try { |
| | | // 1. 优先 POI 检索:能搜公司名、地点名,比地址解析准确得多 |
| | | const poi = await searchByPoi(keyword); |
| | | if (poi?.point) { |
| | | await selectBaiduLocation(poi.point.lng, poi.point.lat); |
| | | selectedAddress.value = poi.address ?? poi.title ?? selectedAddress.value; |
| | | message.success(`已定位到:${poi.title ?? keyword}`); |
| | | return; |
| | | } |
| | | // 2. 回退地址解析(适用于「XX市XX区XX路XX号」这类纯地址) |
| | | if (!geocoder) { |
| | | message.warning('地图尚未就绪,请稍后重试'); |
| | | return; |
| | | } |
| | | const point = await new Promise<any>((resolve, reject) => { |
| | | geocoder.getPoint(keyword, (result: any) => { |
| | | result |
| | | ? resolve(result) |
| | | : reject( |
| | | new Error('没有搜索到该地址,请输入更完整的省市区和地点名称'), |
| | | new Error( |
| | | '没有搜索到该地点,请尝试输入公司全称或更完整的省市区地址', |
| | | ), |
| | | ); |
| | | }); |
| | | }); |