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

本文介绍了如何在高德地图上展示车辆和轨迹点,从页面框架搭建到地图组件的实现,包括使用react-split-pane进行布局,通过websocket实现实时数据传输,以及在地图上添加Marker显示车辆位置。同时,文章提到了使用useState和useEffect进行状态管理和地图初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

下图为实例

使用的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])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值