美文网首页GIS加油站
一种基于高德Web API实现沿路画面的实现

一种基于高德Web API实现沿路画面的实现

作者: 牛老师讲webgis | 来源:发表于2024-05-28 21:41 被阅读0次

    概述

    本文在mapboxGL框架下,分享一种基于高德Web API实现沿路画面的实现。

    实现效果

    image.png

    实现

    1. 实现思路

    1. 通过点击获取路径的起点和终点;
    2. 将多次规划路径的结果连成一条线;
    3. 当鼠标点击回到第一个点的时候结束绘制;
    4. 绘制结束后将路径闭合,形成多边形,并对形成的多边形进行处理;

    实现代码

    <template>
      <div class="map">
        <lzugismap-map
          :onLoad="mapLoaded"
          :maxPitch="0"
          :minPitch="0"
          :pitch="0"
          :style="style"
          :center="[113.91505797606129, 22.536719264512044]"
          :zoom="zoom"
          :interactive="true"
        >
        </lzugismap-map>
        <div class="map-tools">
          <button :disabled="isDraw" @click="startDraw">绘制</button>
        </div>
      </div>
    </template>
    
    <script>
    import { LzugismapMap } from "@lzugismap/vue-lzugismap";
    import * as turf from "@turf/turf";
    
    class Geojson {
      constructor(features = []) {
        this.features = features;
        this.type = "FeatureCollection";
      }
    }
    
    let points = [],
      routes = [];
    
    export default {
      components: {
        LzugismapMap ,
      },
      data() {
        return {
          map: null,
          zoom: 16,
          isDraw: false,
        };
      },
      methods: {
        mapLoaded(map) {
          this.map = map;
          map.addSource("route-source", {
            type: "geojson",
            data: new Geojson(),
          });
          map.addSource("fill-source", {
            type: "geojson",
            data: new Geojson(),
          });
          map.addSource("point-source", {
            type: "geojson",
            data: new Geojson(),
          });
          map.addLayer({
            id: "route-source-fill",
            source: "fill-source",
            type: "fill",
            paint: {
              "fill-color": "red",
              "fill-opacity": 0.15,
            },
          });
          map.addLayer({
            id: "route-source-line",
            source: "route-source",
            type: "line",
            paint: {
              "line-color": "red",
              "line-width": 3.5,
            },
          });
          map.addLayer({
            id: "route-point",
            source: "point-source",
            type: "circle",
            paint: {
              "circle-color": "blue",
              "circle-opacity": 0.8,
              "circle-radius": 5,
            },
          });
          // this.showRoute();
        },
        startDraw() {
          this.isDraw = true;
          points = [];
          routes = [];
          const that = this;
          that.map.getSource("point-source").setData(new Geojson());
          that.map.getSource("route-source").setData(new Geojson());
          that.map.getSource("fill-source").setData(new Geojson());
          that.map.getCanvas().style.cursor = "crosshair";
          const mapClickEvt = (e) => {
            const point = e.lngLat.toArray();
            points.push(point);
            that.map
              .getSource("point-source")
              .setData(new Geojson(points.map((p) => turf.point(p))));
            if (points.length > 1) {
              const p0 = points[0];
              const start = points[points.length - 2];
              let end = points[points.length - 1];
              const dis = turf.distance(turf.point(p0), turf.point(end)) * 1000;
              const isEnd = dis < 10;
              if (isEnd) {
                end = p0;
              }
              // driving walking
              const url = `https://restapi.amap.com/v3/direction/walking?origin=${start.join(
                ","
              )}&destination=${end.join(
                ","
              )}&output=JSON&key={你申请的key}`;
              fetch(url)
                .then((res) => res.json())
                .then((res) => {
                  const paths = res?.route?.paths || [];
                  paths.forEach(({ steps }) => {
                    steps.forEach(({ polyline }) => {
                      const _points = polyline
                        .split(";")
                        .map((item) => item.split(",").map(Number));
                      routes = [...routes, ..._points];
                    });
                  });
                  if (isEnd) {
                    const polygon = turf.lineToPolygon(turf.lineString(routes));
                    const geojson = turf.polygonSmooth(polygon, { iterations: 10 });
                    that.map.getSource("route-source").setData(geojson);
                    that.map.getSource("fill-source").setData(geojson);
                    that.isDraw = false;
                    this.map.off("click", mapClickEvt);
                    that.map.getCanvas().style.cursor = "";
                  } else {
                    const line = turf.lineString(routes);
                    that.map.getSource("route-source").setData(line);
                  }
                });
            }
          };
          this.map.on("click", mapClickEvt);
        },
      },
    };
    </script>
    
    <style scoped lang="scss">
    .map {
      width: 100%;
      height: 100%;
    }
    .map-tools {
      position: absolute;
      right: 2rem;
      top: 2rem;
      z-index: 99;
    }
    </style>
    

    相关文章

      网友评论

        本文标题:一种基于高德Web API实现沿路画面的实现

        本文链接:https://www.haomeiwen.com/subject/aghkqjtx.html