typescript OSRM API:查找到最近应急站的距离

kx5bkwkv  于 2023-05-08  发布在  TypeScript
关注(0)|答案(1)|浏览(142)

我有一个打字项目,我试图得到距离最近的警察局(后来我也添加消防站)。我用的是 typescript
我在网上找到了这个URL:https://router.project-osrm.org/route/v1/driving/${lon},${lat};nearest?annotations=distance&exclude=motorway,toll
但似乎根本不管用。
我在文档中进一步查看,我不确定我应该使用哪个:路线/v1/驾驶或最近的/v1/驾驶。我没有找到一个解决方案,两者都有(?)的。
因此,总的目标是获得我的位置坐标,并获得到最近的警察局和最近的消防站的距离(以公里为单位)。
例如,我还尝试了以下函数:

import axios from "axios";
async function getNearestPoliceStation(
  lat: number,
  lon: number
): Promise<[number, number]> {
  try {
    console.log("input lat and lon", lat, lon);
    const url2 = `https://nominatim.openstreetmap.org/search?format=json&q=police+station&limit=1&lat=${lat}&lon=${lon}`;
    const response2 = await axios.get(url2);
    console.log(response2.data[0]);
    const nearestPoliceStation = response2.data[0];
    if (!nearestPoliceStation) {
      return [-1, -1];
    }

    const lati = parseFloat(nearestPoliceStation.lat);
    const longi = parseFloat(nearestPoliceStation.lon);

    return [lati, longi];
  } catch (error) {
    console.error(error);
    return [-1, -1];
  }
}

但是当我输入49.85349,8.65859(在德国)时,它会找到新泽西州最近的警察局:40.7007047,-75.1719147
一个Python代码也会有帮助。我在Python上尝试了一些测试,使用Google Maps API(而不是TS和OSMR),这也不是太简单。

qjp7pelc

qjp7pelc1#

这里的a jsFiddle demo将在Map上显示警察局和消防局作为标记,当您单击其中一个时,驾驶路线将被绘制为蓝线:

我的JavaScript代码发送以下Overpass API查询来获取具有特定标记的节点:

[out:json][bbox:{{bbox}}];
(
  node[amenity=fire_station];
  node[amenity=police];
);
out center;

然后将节点绘制为标记,当您单击其中一个时,将从OSRM服务器请求行驶路线:

'use strict';

function processOsrmReply(data) {

  if (data.code === 'Ok') {
    data.routes.forEach(function(route) {
      groups.routes.addData(route.geometry);
    });
  }
}

function sendOsrmRequest(lat, lng) {
  groups.routes.clearLayers();

  var url = 'https://router.project-osrm.org/route/v1/car/' +
    parseFloat(startMarker.getLatLng().lng).toFixed(6) + ',' +
    parseFloat(startMarker.getLatLng().lat).toFixed(6) + ';' +
    parseFloat(lng).toFixed(6) + ',' +
    parseFloat(lat).toFixed(6) +
    '?overview=simplified' +
    '&alternatives=3' +
    '&steps=false' +
    '&annotations=false' +
    '&geometries=geojson';

  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      var data = JSON.parse(this.response);
      processOsrmReply(data);
    }
  };
  request.send();
}

function processOverpassReply(data) {

  data.elements.forEach(function(element) {
    if (element.type === 'node') {
      var amenity = element.tags.amenity;
      var name = element.tags.name;
      var lat = element.lat;
      var lng = element.lon;

      L.marker([lat, lng])
        .bindPopup(amenity + '<br>' + name)
        .on('click', function(ev) { sendOsrmRequest(lat, lng); })
        .addTo(groups[amenity]);
    }
  });
}

function sendOverpassRequest() {
  groups.fire_station.clearLayers();
  groups.police.clearLayers();

  var mapBounds = myMap.getBounds();
  var bbox = [
    mapBounds.getWest(),
    mapBounds.getSouth(),
    mapBounds.getEast(),
    mapBounds.getNorth()
  ].join(',');

  var query = '[out:json];(node[amenity=fire_station](bbox);node[amenity=police](bbox););out+center;';

  var url = 'https://overpass-api.de/api/interpreter?bbox=' + bbox +
    '&data=' + query;

  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      var data = JSON.parse(this.response);
      processOverpassReply(data);
    }
  };
  request.send();
}

var startPosition = [49.85349, 8.65859];
var zoomOptions = {
  minZoom: 12,
  maxZoom: 16
};

var myMap = L.map('myMap', zoomOptions).setView(startPosition, 14);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(myMap);

var groups = {
  fire_station: L.featureGroup().addTo(myMap),
  police: L.featureGroup().addTo(myMap),
  routes: L.geoJSON().addTo(myMap)
};

var overlays = {
  'Show fire stations': groups.fire_station,
  'Show police stations': groups.police,
  'Show OSRM routes': groups.routes
};

L.control.layers(null, overlays, {
  collapsed: false
}).addTo(myMap);

var startMarker = L.marker(startPosition, { draggable: true })
  .on('dragend', function(ev) { groups.routes.clearLayers(); })
  .bindPopup('You are here')
  .addTo(myMap);

myMap.on('dragend zoomend', sendOverpassRequest);

sendOverpassRequest();
html,
body {
  margin: 0;
  padding: 0;
}

#myMap {
  position: absolute;
  width: 100%;
  height: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/leaflet@1/dist/leaflet.min.css" type="text/css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/leaflet@1/dist/leaflet-src.min.js"></script>

<div id="myMap"></div>

相关问题