使用 OpenLayers 从 GraphHpper 绘制路线

问题描述

我是使用地图 GraphHopper、OpenStreetMap 和其他库的新手。我想绘制由GraphHopper Routing Engine(实际上是Java语言)生成的路线。是否可以使用 OpenLayer 从 GH 绘制路线?
我已阅读此 GWT-OpenLayer,但我找不到如何在真实道路中编写路线 GraphHopper Routing Example
我希望 openlayers API 可以满足我的需求

  1. GH 路由引擎生成从 A(长,纬度)到 B(长,纬度)的路由
  2. OpenLayers GWT 从 GH 绘制每条路线

任何帮助将不胜感激:)

解决方法

GraphHopper 路由 API 与许多其他路由 API 非常相似,它可以直接从 OpenLayers 等 JavaScript 应用程序中获取,结果包含本示例中使用的折线 https://openlayers.org/en/main/examples/feature-move-animation.html(但折线可以包含高程并具有标准的 ie5 比例因子)。更改 OpenLayers 示例以使用 GraphHopper 示例中的路由(我复制了 API 密钥,但对于生产,您应该获得自己的密钥)结果是:

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css">
    <style>
      html,body,.map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
      #map {
        position: relative;
      }
      #controls {
        z-index: 1;
        position: absolute;
        bottom: 0;
        left: 0;
     }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
  </head>
  <body>
    <div id="map" class="map">
      <div id="controls">
        <label for="speed">
          speed:&nbsp;
          <input id="speed" type="range" min="10" max="999" step="10" value="60">
        </label>
        <button id="start-animation">Start Animation</button>
      </div>
    </div>
    <script type="text/javascript">

const center = [-5639523.95,-3501274.52];
const map = new ol.Map({
  target: document.getElementById('map'),view: new ol.View({
    center: center,zoom: 10,minZoom: 2,maxZoom: 19,}),layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM(),],});

// The polyline string is read from a JSON similiar to those returned
// by directions APIs such as Openrouteservice and Mapbox.

const api_key = 'ab642f98-3b45-4643-981d-9b80f58239a3';
const startLonLat = [111.352111,0.136299];
const endLonLat = [111.299744,-0.255431];

fetch('https://graphhopper.com/api/1/route' +
  '?point=' + startLonLat.slice().reverse().join(',') +
  '&point=' + endLonLat.slice().reverse().join(',') +
  '&type=json&locale=en-US&key=' + api_key +
  '&elevation=true&profile=car'
).then(function (response) {
  response.json().then(function (result) {

    const polyline = result.paths[0].points;

    const route = new ol.format.Polyline({
      factor: 1e5,geometryLayout: 'XYZ'
    }).readGeometry(polyline,{
      dataProjection: 'EPSG:4326',featureProjection: 'EPSG:3857',});

    map.getView().fit(route);

    const routeFeature = new ol.Feature({
      type: 'route',geometry: route,});
    const geoMarker = new ol.Feature({
      type: 'geoMarker',geometry: new ol.geom.Point(route.getCoordinateAt(0)),});
    const startMarker = new ol.Feature({
      type: 'icon',});
    const endMarker = new ol.Feature({
      type: 'icon',geometry: new ol.geom.Point(route.getCoordinateAt(1)),});

    const styles = {
      'route': new ol.style.Style({
        stroke: new ol.style.Stroke({
          width: 6,color: [237,212,0.8],'icon': new ol.style.Style({
        image: new ol.style.Icon({
          anchor: [0.5,1],src: 'https://openlayers.org/en/main/examples/data/icon.png','geoMarker': new ol.style.Style({
        image: new ol.style.Circle({
          radius: 7,fill: new ol.style.Fill({color: 'black'}),stroke: new ol.style.Stroke({
            color: 'white',width: 2,};

    let animating = false;

    const vectorLayer = new ol.layer.Vector({
      source: new ol.source.Vector({
        features: [routeFeature,geoMarker,startMarker,endMarker],style: function (feature) {
        // hide geoMarker if animation is active
        if (animating && feature.get('type') === 'geoMarker') {
          return null;
        }
        return styles[feature.get('type')];
      },});

    map.addLayer(vectorLayer);

    let speed,startTime;
    const speedInput = document.getElementById('speed');
    const startButton = document.getElementById('start-animation');

    function moveFeature(event) {
      const vectorContext = ol.render.getVectorContext(event);
      const frameState = event.frameState;

      if (animating) {
        const elapsedTime = frameState.time - startTime;
        const distance = (speed * elapsedTime) / 1e6;

        if (distance >= 1) {
          stopAnimation(true);
          return;
        }

        const currentPoint = new ol.geom.Point(route.getCoordinateAt(distance));
        const feature = new ol.Feature(currentPoint);
        vectorContext.drawFeature(feature,styles.geoMarker);
      }
      // tell OpenLayers to continue the postrender animation
      map.render();
    }

    function startAnimation() {
      if (animating) {
        stopAnimation(false);
      } else {
        animating = true;
        startTime = new Date().getTime();
        speed = speedInput.value;
        startButton.textContent = 'Cancel Animation';
        // hide geoMarker
        geoMarker.changed();
        // just in case you pan somewhere else
        map.getView().fit(route);
        vectorLayer.on('postrender',moveFeature);
        map.render();
      }
    }

    function stopAnimation(ended) {
      animating = false;
      startButton.textContent = 'Start Animation';

      // if animation cancelled set the marker at the beginning
      const coord = route.getCoordinateAt(ended ? 1 : 0);
      geoMarker.getGeometry().setCoordinates(coord);
      // remove listener
      vectorLayer.un('postrender',moveFeature);
    }

    startButton.addEventListener('click',startAnimation,false);
  });
});

    </script>
  </body>
</html>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...