You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.5 KiB
78 lines
2.5 KiB
// Geocoding service using OpenStreetMap Nominatim
|
|
const NOMINATIM_BASE = 'https://nominatim.openstreetmap.org'
|
|
|
|
export async function geocode(placeName) {
|
|
const url = `${NOMINATIM_BASE}/search?q=${encodeURIComponent(placeName + ', China')}&format=json&limit=1`
|
|
try {
|
|
const response = await fetch(url, {
|
|
headers: { 'User-Agent': 'TripPlanner/1.0' }
|
|
})
|
|
const data = await response.json()
|
|
if (data.length > 0) {
|
|
return {
|
|
lat: parseFloat(data[0].lat),
|
|
lng: parseFloat(data[0].lon),
|
|
displayName: data[0].display_name
|
|
}
|
|
}
|
|
return null
|
|
} catch (e) {
|
|
console.warn('Geocoding failed:', e)
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function geocodeBatch(placeNames) {
|
|
const results = {}
|
|
for (const name of placeNames) {
|
|
const result = await geocode(name)
|
|
if (result) {
|
|
results[name] = result
|
|
}
|
|
// Small delay to respect Nominatim rate limiting (1 req/s)
|
|
await new Promise(r => setTimeout(r, 1100))
|
|
}
|
|
return results
|
|
}
|
|
|
|
// Known Chinese tourist destinations with coordinates (fallback cache)
|
|
const KNOWN_PLACES = {
|
|
'昆明': { lat: 25.04, lng: 102.71 },
|
|
'大理': { lat: 25.69, lng: 100.26 },
|
|
'丽江': { lat: 26.87, lng: 100.23 },
|
|
'香格里拉': { lat: 27.83, lng: 99.70 },
|
|
'普者黑': { lat: 24.12, lng: 104.12 },
|
|
'坝美': { lat: 24.08, lng: 104.65 },
|
|
'西双版纳': { lat: 22.00, lng: 100.80 },
|
|
'腾冲': { lat: 25.02, lng: 98.50 },
|
|
'建水': { lat: 23.62, lng: 102.82 },
|
|
'元阳': { lat: 23.22, lng: 102.83 },
|
|
'抚仙湖': { lat: 24.55, lng: 102.93 },
|
|
'弥勒': { lat: 24.41, lng: 103.41 },
|
|
'沙溪': { lat: 26.32, lng: 99.85 },
|
|
'泸沽湖': { lat: 27.72, lng: 100.82 },
|
|
'成都': { lat: 30.57, lng: 104.07 },
|
|
'重庆': { lat: 29.56, lng: 106.55 },
|
|
'贵阳': { lat: 26.65, lng: 106.63 },
|
|
'桂林': { lat: 25.27, lng: 110.29 },
|
|
'阳朔': { lat: 24.78, lng: 110.49 },
|
|
'杭州': { lat: 30.25, lng: 120.16 },
|
|
'乌镇': { lat: 30.75, lng: 120.48 },
|
|
'苏州': { lat: 31.30, lng: 120.58 },
|
|
'北京': { lat: 39.90, lng: 116.40 },
|
|
'上海': { lat: 31.23, lng: 121.47 },
|
|
'西安': { lat: 34.34, lng: 108.94 },
|
|
'拉萨': { lat: 29.65, lng: 91.14 },
|
|
'张家界': { lat: 29.12, lng: 110.48 },
|
|
'九寨沟': { lat: 33.26, lng: 103.92 },
|
|
'厦门': { lat: 24.48, lng: 118.09 },
|
|
'青岛': { lat: 36.07, lng: 120.38 },
|
|
'巍山': { lat: 25.23, lng: 100.30 },
|
|
'蒙自': { lat: 23.37, lng: 103.38 },
|
|
'丘北': { lat: 24.05, lng: 104.18 },
|
|
}
|
|
|
|
export function getKnownPlace(name) {
|
|
return KNOWN_PLACES[name] || null
|
|
}
|