You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OSRM/TypeScript获取最近警局、消防站距离的技术求助

解决方案:获取当前位置到最近警局的驾驶距离

一、修复Nominatim API调用问题

你当前的Nominatim请求未限定搜索范围,导致返回热门地点而非指定坐标附近的警局。需添加radius(搜索半径,单位米)和bounded=1参数强制限定坐标周边搜索,同时优化查询词提升准确性。

修正后的TypeScript代码:

import axios from "axios";

async function getNearestPoliceStation(lat: number, lon: number): Promise<[number, number] | null> {
  try {
    // 限定10公里范围内搜索警局,使用精准查询词
    const url = `https://nominatim.openstreetmap.org/search?format=json&q=police station&limit=1&lat=${lat}&lon=${lon}&radius=10000&bounded=1&addressdetails=1`;
    const response = await axios.get(url);
    
    if (!response.data || response.data.length === 0) {
      return null;
    }

    const station = response.data[0];
    return [parseFloat(station.lat), parseFloat(station.lon)];
  } catch (error) {
    console.error("获取警局位置失败:", error);
    return null;
  }
}

二、正确使用OSRM API计算驾驶距离

OSRM的nearest/v1/driving仅用于查找最近道路节点,无法直接获取POI(警局);route/v1/driving用于计算两点间路线距离。完整流程:

  1. 用Nominatim获取最近警局坐标
  2. 将当前位置与警局坐标传入OSRM route接口,获取驾驶距离

TypeScript完整实现:

import axios from "axios";

async function getDrivingDistance(startLat: number, startLon: number, endLat: number, endLon: number): Promise<number | null> {
  try {
    // OSRM route接口格式:起点lon,lat;终点lon,lat
    const url = `https://router.project-osrm.org/route/v1/driving/${startLon},${startLat};${endLon},${endLat}?annotations=distance&exclude=motorway,toll`;
    const response = await axios.get(url);
    
    if (!response.data.routes || response.data.routes.length === 0) {
      return null;
    }

    // 返回总距离(单位公里)
    return response.data.routes[0].distance / 1000;
  } catch (error) {
    console.error("计算驾驶距离失败:", error);
    return null;
  }
}

// 整合调用
async function getNearestPoliceStationDistance(lat: number, lon: number): Promise<number | null> {
  const stationCoords = await getNearestPoliceStation(lat, lon);
  if (!stationCoords) {
    return null;
  }
  const distance = await getDrivingDistance(lat, lon, stationCoords[0], stationCoords[1]);
  return distance;
}

// 测试德国坐标
getNearestPoliceStationDistance(49.85349, 8.65859).then(dist => {
  console.log("到最近警局的驾驶距离(公里):", dist);
});

三、Python实现方案

使用requests调用Nominatim和OSRM API,逻辑与TypeScript一致:

import requests

def get_nearest_police_station(lat: float, lon: float):
    try:
        url = f"https://nominatim.openstreetmap.org/search?format=json&q=police station&limit=1&lat={lat}&lon={lon}&radius=10000&bounded=1&addressdetails=1"
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
        
        if not data:
            return None
        
        station = data[0]
        return (float(station["lat"]), float(station["lon"]))
    except Exception as e:
        print(f"获取警局位置失败: {e}")
        return None

def get_driving_distance(start_lat: float, start_lon: float, end_lat: float, end_lon: float):
    try:
        url = f"https://router.project-osrm.org/route/v1/driving/{start_lon},{start_lat};{end_lon},{end_lat}?annotations=distance&exclude=motorway,toll"
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
        
        if not data.get("routes"):
            return None
        
        # 返回公里数
        return data["routes"][0]["distance"] / 1000
    except Exception as e:
        print(f"计算驾驶距离失败: {e}")
        return None

def get_nearest_police_station_distance(lat: float, lon: float):
    station_coords = get_nearest_police_station(lat, lon)
    if not station_coords:
        return None
    distance = get_driving_distance(lat, lon, station_coords[0], station_coords[1])
    return distance

# 测试德国坐标
distance = get_nearest_police_station_distance(49.85349, 8.65859)
print("到最近警局的驾驶距离(公里):", distance)

关键说明

  • Nominatim添加radius和bounded=1是确保返回指定区域结果的核心,可按需调整radius值(单位米)
  • OSRM route接口参数顺序为经度在前,纬度在后,请勿混淆
  • 扩展到消防站时,只需将Nominatim的q=police station改为q=fire station即可

内容的提问来源于stack exchange,提问作者ArieAI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:07:47