* 调用 Geoapify Reverse Geocoding API 获取真实地址
(lat, lon)
| 103 | * 调用 Geoapify Reverse Geocoding API 获取真实地址 |
| 104 | */ |
| 105 | async function fetchRealAddressFromApi(lat, lon) { |
| 106 | if (!geoapifyApiKey) return null; |
| 107 | |
| 108 | // 在城市中心附近小范围偏移 (约 300-500m),避免落到其他城市 |
| 109 | const offsetLat = lat + (Math.random() - 0.5) * 0.005; |
| 110 | const offsetLon = lon + (Math.random() - 0.5) * 0.005; |
| 111 | |
| 112 | const url = `https://api.geoapify.com/v1/geocode/reverse?lat=${offsetLat}&lon=${offsetLon}&apiKey=${geoapifyApiKey}`; |
| 113 | |
| 114 | try { |
| 115 | const response = await fetch(url); |
| 116 | if (!response.ok) { |
| 117 | console.log('[GeoFill] Geoapify API 请求失败:', response.status); |
| 118 | return null; |
| 119 | } |
| 120 | |
| 121 | const data = await response.json(); |
| 122 | |
| 123 | if (data.features && data.features.length > 0) { |
| 124 | const props = data.features[0].properties; |
| 125 | return { |
| 126 | address: props.address_line1 || props.street || props.name, |
| 127 | city: props.city || props.town || props.municipality, |
| 128 | state: props.state || props.county, |
| 129 | zipCode: props.postcode, |
| 130 | country: props.country, |
| 131 | source: 'geoapify' |
| 132 | }; |
| 133 | } |
| 134 | } catch (e) { |
| 135 | console.log('[GeoFill] Geoapify API 调用失败:', e); |
| 136 | } |
| 137 | |
| 138 | return null; |
| 139 | } |
| 140 | |
| 141 | /** |
| 142 | * 调用 OpenStreetMap Nominatim API 获取真实地址(免费,无需 Key) |
no outgoing calls
no test coverage detected