前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【python】【Djang】GPS/北斗串口数据实时定位百度地图

【python】【Djang】GPS/北斗串口数据实时定位百度地图

作者头像
一点儿也不潇洒
发布2018-12-13 16:11:39
6.3K2
发布2018-12-13 16:11:39
举报
文章被收录于专栏:肖洒的博客肖洒的博客

一个小项目,做点总结。

俱乐部2.gif
俱乐部2.gif

项目需求

本项目为从串口读取GPS/北斗设备接收数据,进行处理后使用百度地图api实时显示定位。

解决办法

这里有几个关键的信息,需要一步一步进行实现。

串口

串口通信这里就不做介绍。本意是使用百度地图的api,但是这是一个静态的网页。如果要动态显示,且由前端直接读取PC端的串口数据其实不好实现,在网上查了很多资料,最通常的做法是在前端使用一个active控件读取串口的数据。这样有缺点,一是技术过于老套,只兼容IE,其他浏览器就不行;二是怎么做到动态实时定位呢?这个没有想明白。放弃了从前端直接读取PC串口的想法。还是需要去用后台采集数据,搭建后台和前端进行通信。

串口模拟

路是一步一步走的,胖子也是一口一口吃的,直接去读取GPSS/北斗设备的数据是不可行的。 先采用电脑端的串口助手进行数据的发送和接收。

  1. 首先采用VSPD(很著名)在PC端模拟出一怼串口,再使用某个串口助手实现数据的发送和接收显示。串口助手很多,随便选择一种即可。
  2. 这样就可以保证有可靠的数据发送和接收的通信是没有问题的。保证发送端数据的一直发送,接着用程序去读取串口的数据。 #语言版本:Python3 #依赖库:serial,pyserial #串口助手发送数据:108.111,34.111 import serial from time import sleep if __name__ == '__main__': serial = serial.Serial('COM2', 115200)#根据自己模拟的端口确定com if serial.isOpen() : print("open success") else : print("open failed") while True: n = serial.inWaiting() if n: data= str(serial.read(n))[2:-1].split(',')#对读取的数据进行简单的处理 j = data[0] w = data[1] print(data)

读取串口

保证程序可以正确的读取发送的数据后,再去处理真实的数据,开启GPS/北斗设备,将USB插在电脑上,开始读取原始数据。原始数据包含的信息比较多,而且发送频率也比较高,数据眼花缭乱,这里只匹配想要的数据进行处理。在百度地图上定位只需要“经度”、“纬度”。(这里牵扯到一个坐标系的转换,后面说),这是一个Ajax的程序:

代码语言:javascript
复制
def ajax_list(request):
    s = serial.Serial('COM5', 115200)
    #定义接收数据的次数
    l = 0
    data=[]
    while True:
        line = str(str(s.readline())[2:])
        # print(line)#原始数据
        if line.startswith('$GNGGA'):#只匹配以“$GNGGA”开头的数据
            line=str(line).split(',')
            # print("接收的数据:"+ str(line))
            # print("OK:"+str(line))
            # print("指令名称: ", line[0])
            # print("发送时间: ", line[1][:6])

            # 经纬度转换
            #经度数据处理
            j = float(line[4][:-7])+float(line[4][-7:])/60
            #纬度数据处理
            w = float(line[2][:-7])+float(line[2][-7:])/60

            #时间
            gpstime=time.strftime('%H:%M:%S',time.localtime(time.time()))

            # id
            global l 
            l= l + 1

            # 添加数据
            data.append(j)
            data.append(w)
            data.append(l)
            data.append(gpstime)
            print(data)
            return HttpResponse(json.dumps(data), content_type='application/json')

百度地图api

先去申请百度地图api 的 key。然后看这里:http://lbsyun.baidu.com/jsdemo.htm#i8_4 这里放出百度地图定位aip的源码:

代码语言:javascript
复制
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body, html{width: 100%;height: 100%;margin:0;font-family:"微软雅黑";}
        #allmap{height:500px;width:100%;}
        #r-result{width:100%; font-size:14px;}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥"></script>
    <title>城市名定位</title>
</head>
<body>
    <div id="allmap"></div>
    <div id="r-result">
        经度: <input id="longitude" type="text" style="width:100px; margin-right:10px;" />
        纬度: <input id="latitude" type="text" style="width:100px; margin-right:10px;" />
        <input type="button" value="查询" onclick="theLocation()" />
    </div>
</body>
</html>
<script type="text/javascript">
    // 百度地图API功能
    var map = new BMap.Map("allmap");
    map.centerAndZoom(new BMap.Point(116.331398,39.897445),11);
    map.enableScrollWheelZoom(true);
    
    // 用经纬度设置地图中心点
    function theLocation(){
        if(document.getElementById("longitude").value != "" && document.getElementById("latitude").value != ""){
            map.clearOverlays(); 
            var new_point = new BMap.Point(document.getElementById("longitude").value,document.getElementById("latitude").value);
            var marker = new BMap.Marker(new_point);  // 创建标注
            map.addOverlay(marker);              // 将标注添加到地图中
            map.panTo(new_point);      
        }
    }
</script>

上面的程序是静态的,项目需求把从串口源源不断读取的数据在百度地图上进行显示。这里想到使用了Ajax。

Ajax

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。 Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集)。 Ajax 是一种用于创建快速动态网页的技术。 Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。 传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

Django

使用的是Python语言,用Django后台框架就很简单,这里推荐一个博客,学习到很多。自强学堂-Django教程 花了点时间学习了下,Django还是很容易上手的最后将接收到处理的数据存储为csv文件。 这里给出本项目的Django和前端的程序。

view.py
代码语言:javascript
复制
from django.http import HttpResponse
from django.shortcuts import render
import json
import serial
import time
import csv
from time import sleep

def ajax_list(request):
    data=[]
    while True:
        line = str(str(s.readline())[2:])
        # print(line)
        if line.startswith('$GNGGA'):
            line=str(line).split(',')
            # print("接收的数据:"+ str(line))
            # print("OK:"+str(line))
            # print("指令名称: ", line[0])
            # print("发送时间: ", line[1][:6])

            # 经纬度转换
            j = float(line[4][:-7])+float(line[4][-7:])/60
            w = float(line[2][:-7])+float(line[2][-7:])/60

            #时间
            gpstime=time.strftime('%H:%M:%S',time.localtime(time.time()))

            # id
            global l 
            l= l + 1

            # 添加数据
            data.append(j)
            data.append(w)
            data.append(l)
            data.append(gpstime)
            print(data)
            with open('./rec_gps.csv','a',newline='') as csvFile1:
                writer = csv.writer(csvFile1)
                writer.writerow((l,gpstime,j,w))
                csvFile.close()
            return HttpResponse(json.dumps(data), content_type='application/json')
s = serial.Serial('COM5', 115200)
global l 
l = 0
csvFile = open('./rec_gps.csv', 'a',encoding = 'utf-8',newline='')
writer = csv.writer(csvFile)
writer.writerow(('id','time','longitude','latitude'))
index.html
代码语言:javascript
复制
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body, html{width: 100%;height: 100%;margin:0;font-family:"微软雅黑";}
        /* #allmap{height:500px;width:100%;}
        #r-result{width:100%; font-size:14px;} */
        #allmap{float: right;height:100%;width:80%;}
        #r-result{float: left;height:80%;width:20%; overflow:auto;text-align: center}
        #list{position:fixed;top:-16px;}
        #title{position:fixed;top:5px;}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=这里写你申请的百度地图api的key"></script>
    <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- WGS84转BD09 start-->
    <script src="https://unpkg.com/gcoord/dist/gcoord.js"></script>
    <!-- end -->
    <title>经纬度定位</title>
</head>
<!-- 框架测试start -->

<!-- end -->
<body>
    <div id="allmap"></div>

    <div id="r-result">
         <div id="list">
             <p  style="background-color:rgb(0, 255, 221)">经纬度数据(WGS84坐标)</p>
            </div> 
         <div id = "title" >
              <p style="background-color:rgb(0, 255, 221)">ID  |  Time  |  Longitude  | Latitude</p>
            </div> 
         <p>&nbsp</p>
         <div id="list_result" style="font-size: 90%"></div>
    </div>
</body>
</html>
<script type="text/javascript">
    // 百度地图API功能
    var map = new BMap.Map("allmap");
    map.centerAndZoom(new BMap.Point(108.953445,34.265721),15);
    map.enableScrollWheelZoom(true);

    $(document).ready(function(){
      // 列表 list
      $('#list').click(function(){
          $.getJSON('/ajax_list/',function(ret){

            //
            $('#list_result').append(ret[2]+",  "+ret[3]+",  "+ret[0].toFixed(6)+",  "+ret[1].toFixed(6) +"<br />");
            // $('#list_result').append("纬度:" + ret[1]+"<br />" );


           // WGS84坐标
            var result = gcoord.transform(
                [ret[0], ret[1]],    // 经纬度坐标
                gcoord.WGS84,               // 当前坐标系
                gcoord.BD09                 // 目标坐标系
                );
            //BD09坐标
            var longitude = result[0];
            var latitude  = result[1];
            var id 

            map.clearOverlays(); 
            var new_point = new BMap.Point(longitude,latitude);
            var marker = new BMap.Marker(new_point);  // 创建标注
            map.addOverlay(marker);              // 将标注添加到地图中
            map.panTo(new_point);    
            document.getElementById("longitude").innerHTML=longitude;  
            document.getElementById("latitude").innerHTML=latitude; 

            // $('#list_result').append("经度:" + ret[0]+"<br />" );
            // $('#list_result').append("纬度:" + ret[1]+"<br />" );
          })
      })
    });
</script>
<!-- # 自动点击按钮js -->
<script type="text/javascript">
    function myrefresh(){ 
    document.getElementById('list').click();
    } 
    setInterval("myrefresh()","2000"); 
</script>
urls.py
代码语言:javascript
复制
from django.urls import path
from gps import views as gps_views
from django.contrib import admin

urlpatterns = [
    path('', gps_views.index),
    path('ajax_list/', gps_views.ajax_list)
]
Run_me.bat

批处理文件,方便不懂Django的人开启服务

代码语言:javascript
复制
@echo on
python3 .\manage.py runserver
cmd /k
使用
俱乐部2.gif
俱乐部2.gif
微信截图_20181115165343.png
微信截图_20181115165343.png
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目需求
  • 解决办法
    • 串口
      • 串口模拟
    • 读取串口
      • 百度地图api
        • Ajax
          • Django
      相关产品与服务
      数据保险箱
      数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档