简体   繁体   中英

How To Draw Path Between Two Location Coordinates Using OSRM Routing Machine in OpenLayers?

如何在 OpenLayers 中使用 OSRM 路由机在两个位置坐标之间绘制路径?

That is very similar to how the route is added in this example https://openlayers.org/en/latest/examples/feature-move-animation.html

For the route in the OSRM example http://project-osrm.org/docs/v5.7.0/api/#route-service the code would be

const coordinates = [
  [13.38886, 52.517037],
  [13.397634, 52.529407],
  [13.428555, 52.523219],
];

fetch(
  'https://router.project-osrm.org/route/v1/driving/' +
    coordinates.join(';') +
    '?overview=full&geometries=polyline6'
).then(function (response) {
  response.json().then(function (result) {
    const polyline = result.routes[0].geometry;

    const route = new Polyline({
      factor: 1e6,
    }).readGeometry(polyline, {
      dataProjection: 'EPSG:4326',
      featureProjection: map.getView().getProjection(),
    });
    const routeFeature = new Feature({
      type: 'route',
      geometry: route,
    });

    const vectorLayer = new VectorLayer({
      source: new VectorSource({
        features: [routeFeature],
      }),
      style: new Style({
        stroke: new Stroke({
          width: 4,
          color: 'red',
        }),
      }),
    });

    map.addLayer(vectorLayer);
    map.getView().fit(routeFeature.getGeometry());
  });
});

Working example https://codesandbox.io/s/osrm-route-xci7vf

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>OpenLayers 3 - OSRM Polyline Route</title>
    <meta name="robots" content="noindex, nofollow">
    <meta name="googlebot" content="noindex, nofollow">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.10.1/ol.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.10.1/ol.min.css">
    <script id="insert"></script>
  </head>
  <body>
    <div id="map"></div>
    <div id="msg">Click to add a point.</div>
    <script type="text/javascript">
      var points = [],
        msg_el = document.getElementById('msg'),
        url_osrm_nearest = 'https://router.project-osrm.org/nearest/v1/driving/',
        url_osrm_route = 'https://router.project-osrm.org/route/v1/driving/',
        icon_url = 'https://cdn.rawgit.com/openlayers/ol3/master/examples/data/icon.png',
        vectorSource = new ol.source.Vector(),
        vectorLayer = new ol.layer.Vector({
          source: vectorSource
        }),
        styles = {
          route: new ol.style.Style({
            stroke: new ol.style.Stroke({
              width: 6, color: [40, 40, 40, 0.8]
            })
          }),
          icon: new ol.style.Style({
            image: new ol.style.Icon({
              anchor: [0.5, 1],
              src: icon_url
            })
          })
        };
      var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          }),
          vectorLayer
        ],
        view: new ol.View({
          center: [-5685003, -3504484],
          zoom: 11
        })
      });
      map.on('click', function (evt) {
        utils.getNearest(evt.coordinate).then(function (coord_street) {
          var last_point = points[points.length - 1];
          var points_length = points.push(coord_street);

          utils.createFeature(coord_street);

          if (points_length < 2) {
            msg_el.innerHTML = 'Click to add another point';
            return;
          }
          //get the route
          var point1 = last_point.join();
          var point2 = coord_street.join();

          fetch(url_osrm_route + point1 + ';' + point2).then(function (r) {
            return r.json();
          }).then(function (json) {
            if (json.code !== 'Ok') {
              msg_el.innerHTML = 'No route found.';
              return;
            }
            msg_el.innerHTML = 'Route added';
            utils.createRoute(json.routes[0].geometry);
          });
        });
      });
      var utils = {
        getNearest: function (coord) {
          var coord4326 = utils.to4326(coord);
          return new Promise(function (resolve, reject) {
            //make sure the coord is on street
            fetch(url_osrm_nearest + coord4326.join()).then(function (response) {
              // Convert to JSON
              return response.json();
            }).then(function (json) {
              if (json.code === 'Ok') resolve(json.waypoints[0].location);
              else reject();
            });
          });
        },
        createFeature: function (coord) {
          var feature = new ol.Feature({
            type: 'place',
            geometry: new ol.geom.Point(ol.proj.fromLonLat(coord))
          });
          feature.setStyle(styles.icon);
          vectorSource.addFeature(feature);
        },
        createRoute: function (polyline) {
          // route is ol.geom.LineString
          var route = new ol.format.Polyline({
            factor: 1e5
          }).readGeometry(polyline, {
            dataProjection: 'EPSG:4326',
            featureProjection: 'EPSG:3857'
          });
          var feature = new ol.Feature({
            type: 'route',
            geometry: route
          });
          feature.setStyle(styles.route);
          vectorSource.addFeature(feature);
        },
        to4326: function (coord) {
          return ol.proj.transform([
            parseFloat(coord[0]), parseFloat(coord[1])
          ], 'EPSG:3857', 'EPSG:4326');
        }
      };
    </script>
  </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM