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

概述

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

实现效果

实现

1. 实现思路

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

实现代码

vue 复制代码
<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>
相关推荐
大G哥5 分钟前
java提高正则处理效率
java·开发语言
VBA633715 分钟前
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
开发语言
轩辰~17 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
小_太_阳26 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it27 分钟前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
轻口味1 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami1 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
古希腊掌管学习的神1 小时前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师1 小时前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程1 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法