IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> websocket实现GPS数据的实时推送与地图的展示(优化) -> 正文阅读

[网络协议]websocket实现GPS数据的实时推送与地图的展示(优化)

概述

前两天,发布了一片文章websocket实现GPS数据的实时推送与地图的展示,文章发出后引来了不少读者的关注,也有不少读者要求做进步一优化。本文应大家的要求,对上文的内容做一个优化,优化地方包括:

  1. 加入了GPS方向的展示;
  2. 加入了GPS精度的展示;
  3. 加入了GPS轨迹的展示;

效果

img1.gif

实现

node模拟数据

const io = require('nodejs-websocket')
let connection = null
let gps = {}

for (let i = 0; i < 20; i++) {
  gps['gps' + i] = {
    offsetX: randomNum(-0.0001, 0.0001),
    offsetY: randomNum(-0.0001, 0.0001),
    accuracy: randomNum(50, 200)
  }
}

// 执行websocket处理连接方法
io.createServer(con => {
  console.log('new connection...')
  connection = con
  sendData()
  //处理客户端发送过来的消息
  // connection.on("text",function(data){
  //     console.log("接收到的客户端消息:" + data);
  // })
  //监听关闭
  connection.on("close", function (code, reason) {
    console.log("Connection closed")
  })
  //监听异常
  connection.on("error",() => {
    console.log('服务异常关闭...')
  })
}).listen(3000)

function sendData() {
  connection.sendText(getGpsPositions())
  setTimeout(sendData, 1000)
}

function getGpsPositions() {
  const [xmin, ymin, xmax, ymax] = [113.9875, 22.51947, 114.1066, 22.5711]
  let data = []
  for (let k in gps) {
    const d = gps[k]
    let {lon, lat} = d
    if(!d.lon) {
      d.lon = randomNum(xmin, xmax)
      d.lat = randomNum(ymin, ymax)
      d.rotate = 0
    } else {
      d.lon = d.lon + d.offsetX
      d.lat = d.lat + d.offsetY
      const angle = Math.atan2((lat - d.lat), (d.lon - lon))
      d.rotate = angle * (180/Math.PI)
    }
    data.push({
      code: k,
      coords: [d.lon, d.lat],
      accuracy: d.accuracy + randomNum(-0.5, 0.5),
      rotate: d.rotate
    })
  }
  return JSON.stringify(data)
}

function randomNum(min, max){
  return Math.random() * (max - min) + min
}

mapboxgl实现

  map.on('load', () => {
    const icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD+SURBVFhH7ZahDsIwFEUbFB5PMJgJHEFg8GDxfAAeyT4EQ8CA5DNQkPA/4zQ8yMsCC13bIehNTpYtffe2b1s3k5SUVFZhTA5DOY2ulhy1enBmEhdYQvtxuSER2IeixB4mMiS+CDuocM0NVtCRoXFEwEACqzjCVErCC/OdCqvCdmUNXSkNIwxHEuCC7cpcLPyF2UaZu/DsSiZW9YTBUAx98OsKxVdl5oPtSi62L73biMoK+XAxBwcxeiaz96H+LaDwpIxc8H8IKa6z+nCvIUbfrj78RoTZWMyriLcVY/xp9Xa1cT9GmGcSpmnuc0zQVkJ/9kOygMZ+yZKS/l3G3AESgItFg3XtsAAAAABJRU5ErkJggg=='
    const arrow = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAnElEQVQ4T63TsQ0CMQyF4f/NgMQQ0CBR0FIx190cFIiWhhFoKdgEiRUeSoF0gO8cjkub+Evs2OLPpc9422dgBRwlNZn/BtjeApdOUJsh0QuuwKYWiYAFcAKWHaSR1EbpfAHlkO0ICdMJgV+QXmAAmUu6v9IZA8wkPVKgtg7TF7H25t4UbN+A9ahGmqqVD8AO2GdzUF45+I3ZJJb9JxbwRhEhB66xAAAAAElFTkSuQmCC'
    map.loadImage(icon, (error1, image1) => {
      if (error1) throw error1;
      map.addImage('red-arrow', image1);
      map.loadImage(arrow, (error, image) => {
        if (error) throw error;
        map.addImage('white-arrow', image);

        // 精度
        map.addSource('accuracy', {
          type: 'geojson',
          data: getGeojson([])
        });
        map.addLayer({
          id: "accuracy",
          type: "fill",
          source: "accuracy",
          paint: {
            "fill-color": 'red',
            'fill-opacity': 0.1
          }
        });

        // 轨迹
        map.addSource('route', {
          type: 'geojson',
          data: getGeojson([])
        });
        map.addLayer({
          id: "route",
          type: "line",
          source: "route",
          'layout': {
            'line-cap': 'round',
            'line-join': 'round'
          },
          'paint': {
            'line-color': '#09801a',
            'line-width': 8
          }
        });
        map.addLayer({
          'id':'route-arrow',
          'source': 'route',
          'type': 'symbol',
          'layout': {
            'symbol-placement': 'line',
            'symbol-spacing': 50,
            'icon-image': 'white-arrow',
            'icon-size': 0.5,
            'icon-allow-overlap': true
          }
        })

        // GPS 位置
        map.addSource('points', {
          type: 'geojson',
          data: getGeojson([])
        });
        map.addLayer({
          id: "circle",
          "type": "symbol",
          source: "points",
          layout: {
            'icon-image': 'red-arrow',
            'icon-size': 0.8,
            'icon-rotate': ['get', 'rotate'],
            'icon-allow-overlap': true
          }
        });


        ws = new WebSocket("ws://localhost:3000")
        ws.onopen = function() {
          console.log("当前客户端已经连接到websocket服务器")
        }

        let routeCoords = {}

        ws.onmessage = function (evt) {
          const data = JSON.parse(evt.data)
          let accuracyFeatures = []
          let routeFeatures = []
          let features = data.map(d => {
            const pt = {
              "type":"Feature",
              "properties": d,
              "geometry":{
                "type":"Point",
                "coordinates": d.coords
              }
            }
            if(!routeCoords[d.code]) routeCoords[d.code] = []
            routeCoords[d.code].push(d.coords)
            if(routeCoords[d.code].length > 1) routeFeatures.push(turf.lineString(routeCoords[d.code]))
            const circle = turf.buffer(pt, d.accuracy / 1000)
            accuracyFeatures.push(circle)
            return pt
          })
          map.getSource('accuracy').setData(getGeojson(accuracyFeatures))
          map.getSource('route').setData(getGeojson(routeFeatures))
          map.getSource('points').setData(getGeojson(features))
        };

        ws.onclose = function(){
          alert("连接已关闭...");
        };
      })
    });
  })

  function getGeojson(features) {
    return  {
      "type": "FeatureCollection",
      "features": features
    }
  }
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:30:35  更:2022-04-01 00:31:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:55:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码