基于webSocket高德地图的轨迹点页面代码分析

从零开始学高德地图,踩了很多坑,这次来给大家从实际业务讲起怎么在高德地图上显示车辆和轨迹点

下图为实例

使用的mock数据,只关注左上角即可

 首先我们先搭建页面框架

    <div className={style.container}>
      <SplitPane split="horizontal" minSize={350} maxSize={400} pane2Style={{ width: '100%', height: '100%' }} style={{ position: 'relative', width: '100%', height: '100%' }}>
        <SplitPane split="vertical" minSize={350} maxSize={700} pane2Style={{ width: '100%', height: '100%' }} defaultSize={700} style={{ position: 'relative', width: '100%', height: '100%' }}>
          <Map></Map>
          <CarList></CarList>
        </SplitPane>
        <div className={style.ticketShow}>
          <TicketList></TicketList>
        </div>
      </SplitPane>
    </div>

这里使用了react-split-pane这个npm包,可以动态调整div和div之间的布局,详情可以查看react-split-pane - npm (当然也可以直接把布局给固定)大家只需要关注map组件即可

之后我们写目录结构

|—compoent                     存放组件的文件夹

|——carList.tsx                 车辆列表组件(业务相关)

|——map.tsx                    地图组件

|——TicketList.tsx            小票列表组件(业务相关)

|—index.ts                        入口文件

|—location.tsx                  框架文件

|—style.less                     样式文件

如果要实时获取车辆定位,我们需要写一个全局websocket服务

const socket = require('socket.io-client')('---websocket服务地址---');

//socket连接服务
socket.on('connect', () => {
  console.log('socket已连接');
});

//socket发送消息
export function socketEmit(params: any) {
  console.log("发送的信息<---", params);
  socket.emit('push_event', params);
}

//socket初始化并接收消息
//需要页面传递一个useModal的setState函数
export function socketInit(setState: (arg0: any) => void) {
  socket.on('receive_event', (data: string) => {
    console.log("接受的信息--->", data);
    if (!data || data?.length == 0) {
      //当data为空时,开始报错
      return
    }
    //通过useModal实现全局广播
    setState(data)
  });
}

1.这是一个基于java的websocket服务,首先在工程启动的时候,就创建一个socket实例,之后用socket.on监听方法

2.发送socket和接受socket需要抛出为方法可以被其他组件使用

3.接受socket服务需要接收一个函数来将接受的信息持久化,这里是接受某个setState函数,当我们接受到socket信息之后,就会调用这个setState函数

需要注意的是,在开发过程中,一般map组件会接受多个和它同级的组件的数据,为了避免子传父再传子这一大坑,统一用了useModal进行全局状态管理

首先在map中写容器(需要定义高宽)

    <div className={style.map}>
      <div id='container' className={style.containerMap} />
    </div>

 之后创建一个地图实例

 const [mapState, setMapState] = useState(null) 
 useEffect(() => {
    initAMap()
  }, [])

  const initAMap = () => {
    const geolocation = new AMap.Geolocation();
    const toolbar = new AMap.ToolBar();
    const map = new AMap.Map('container', { resizeEnable: true, center: [114.298572, 30.584355], zoom: 15 })
    setMapState(map)
    map.addControl(geolocation);
    map.addControl(toolbar);
  };

这里需要注意的是

1.使用useEffect在页面加载前执行高德地图的初始化函数,绑定在container这个dom下

2.将map实例使用useState保存在内存中,方便后期调用

之后,我们需要在接收到websocket服务后,在map上新增一个marker点标记

const [locationData, setLocationData] = useState([])

useEffect(() => {
    socketInit(setLocationData)
})

其中,socketInit即全局socket服务的函数,接受了setLocationData这个函数,这样的话每次接受socket消息的时候都会触发该函数

最后,既然通过socket拿到了数据,我们可以直接处理数据,通过map.add即可

    const [locationData, setLocationData] = useState([])

useEffect(() => {
    socketInit(setLocationData)
})

useEffect(()=>{
    const startContent = `<div class="section9 flex-col"><div class="box3 flex-row"><div class="box3 flex-row justify-between"><div class="arrows"></div><div class="wrap4 flex-col"></div><div class="TextGroup3 flex-col"><span class="txt13">${routerInfo?.stationName || '起点'}</span><span class="txt14">${deliverTime || ''}发车</span></div></div></div></div>`
    const endContent = `<div class="section9 flex-col"><div class="wrap1 flex-row"><div class="wrap1 flex-row justify-between"><div class="arrows"></div><div class="main4 flex-col"></div><div class="TextGroup1 flex-col"><span class="word25">收货地址</span></div></div></div></div>`

    const startMarker = new AMap.Marker({
      content: startContent,  // 自定义点标记覆盖物内容
      //  @ts-ignore 
      position: locationData[0], // 基点位置
      extData: {
        type: 'start',
      },
    });
    map.add(startMarker);
    //终点标记
    const endMarker = new AMap.Marker({
      content: endContent,  // 自定义点标记覆盖物内容
      //  @ts-ignore
      position:  locationData[1], // 基点位置
      extData: {
        type: 'end',
      },
    });
    map.add(endMarker);
    map.setFitView()
},[locationData])

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要根据websocket返回的数据实时展示轨迹,你需要使用高德地图提供的API来绘制轨迹。具体步骤如下: 1. 在Vue项目中引入高德地图API,可以使用高德地图JavaScript API或Vue-AMap插件。 2. 创建一个地图实例,并设置地图的中心和缩放级别。 3. 使用高德地图提供的Polyline类创建一个折线对象,并设置其样式和属性,如颜色、宽度和透明度等。 4. 在websocket的onmessage事件中,将接收到的数据解析成经纬度坐标,并将其添加到折线对象中。 5. 调用折线对象的setPath方法更新折线的路径,实现实时展示轨迹的效果。 示例代码如下: ```javascript <template> <div id="map-container"></div> </template> <script> import AMapLoader from '@amap/amap-jsapi-loader' export default { data() { return { map: null, polyline: null, ws: null, } }, mounted() { AMapLoader.load({ key: 'YOUR_AMAP_API_KEY', version: '2.0', plugins: ['AMap.PolyEditor'], AMapUI: { version: '1.1', plugins: ['overlay/SimpleInfoWindow', 'misc/PositionPicker'], }, Loca: { version: '1.3.2', }, }).then((AMap) => { this.map = new AMap.Map('map-container', { zoom: 13, center: [120.139998, 30.259244], }) this.polyline = new AMap.Polyline({ path: [], strokeColor: '#3366FF', strokeWeight: 5, strokeOpacity: 0.8, }) this.polyline.setMap(this.map) this.ws = new WebSocket('YOUR_WEBSOCKET_URL') this.ws.onmessage = (event) => { const data = JSON.parse(event.data) const path = data.path.map((item) => [item.lng, item.lat]) this.polyline.setPath(path) } }) }, } </script> <style> #map-container { height: 400px; width: 100%; } </style> ``` 以上示例代码中,使用了Vue-AMap插件和WebSocket API,实现了根据websocket返回的数据实时展示轨迹的功能。你需要将其中的YOUR_AMAP_API_KEY和YOUR_WEBSOCKET_URL替换为你自己的高德地图API Key和websocket地址。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值