看看过去跑过哪些地方,用Python和高德API绘制跑步轨迹

最近几个月跑了不少步,试用了很多不同的APP,导致轨迹、跑量什么的各自为政,因此萌生了写个程序把所有跑步的轨迹都画在一张地图上的想法。

第一步,先把各个地方能导出轨迹的都导出来。看了一下.FIT .TPX .GPX中,以GPX文件结构最简单,下面就是一段.gpx文件的记录点格式,于是把轨迹都导成.gpx文件。

GPX文件数据点

第二步,读取GPX文件数据

人生苦短,我用Python——用Python读入这些GPX轨迹信息,处理后再画在地图上,应该是最容易的做法了。Python本身接近自然语言,丰富的第三方库让写程序就像用英文和计算机对话一样。

直接使用Python自带的xml库完成读取,注意要剔除lat和lon为0的数据点,因为GPX是用这种方法来标记暂停的。

    import xml.dom.minidom as xdom

    gpxPath = 'test.gpx'
    dom_tree = xdom.parse(gpxPath)
    collection = dom_tree.documentElement
    trkpts = collection.getElementsByTagName("trkpt")
    lats, lons = [], []

    for trkpt in trkpts:
        lat = trkpt.getAttribute("lat")
        lon = trkpt.getAttribute("lon")
        if lat=='0' or lon=='0':
            continue
        lats.append(float(lat))
        lons.append(float(lon))

    datas = {'lat': lats, 'lon': lons}

第三步,将数据画在地图上

前面进行的一切顺利,没想到在画地图的时候卡住了。

建筑师出身,对图面的要求不能太低。而Python的地图库里面几乎没有好看的地图,而且使用起来都颇为麻烦。在尝试了Basemap、Plotly、Folium之后,最终选择使用高德地图,方便好用。

高德地图JavaScrip API快速入门
在正式开始开发地图应用之前,您需要做如下几步:

<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.3&key=您申请的key值"></script> 
  • 创建地图容器
    在页面body里你想展示地图的地方创建一个div 容器,并指定id标识:
<div id="container"></div>  
  • 指定容器大小
    按照需要设定地图容器的大小,确保大小合适,比如用CSS这样设置它:
#container {width:300px; height: 180px; }  

接下来要写个网页用来读取本地的数据文件。因为之前已经使用Python完成了GPX数据读取,所以先改写一下,输出JS可以方便读取的JSON文件。

    import os

    fileDir, fileName = os.path.split(gpxPath)
    jsonDir = os.path.join(fileDir, 'jsons')
    if not os.path.exists(jsonDir):
        os.mkdir(jsonDir)

    jsonPath = os.path.join(jsonDir, fileName) + '.json'
    with open(jsonPath, 'w') as f:
        f.write(json.dumps(datas))

同时为了方便的处理多条数据,把上面Python的部分写成一个procXml函数,然后在命令行中将要转换的文件作为参数传入。

import sys

def main():
    if len(sys.argv) < 2:
        print 'Specify the gpx file path'
        return

    fileList = sys.argv[1:]
    for p in fileList:
        if os.path.isfile(p):
            gpxPath = os.path.abspath(p)
            print 'Processing'+str(gpxPath)
            try:
                procXml(p)
                print 'Coresponding JSON file was generated.'
            except:
                print '=====Somthing was wrong!====='

if __name__ == '__main__':
    main()

保存为gpx2json.py,将从跑步软件中导出的GPX文件都放在同目录下的gpxs文件夹中,然后在命令行中输入以下命令进行批量转换:

python gpx2json.py gpxs/*

轨迹处理完毕后的json文件会放到gpxs/json/下,马上就要读取本地的json文件并调用高德地图的API画轨迹了,已经接近完成了呢。

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <script type="text/javascript" src="http://webapi.amap.com/maps?v=1.3&key=cgbvip@gmail.com"></script>
    <title>-*- iRunMap -*-</title>
</head>

<body>
    <form action="" method="post" enctype="multipart/form-data">
        <input id="file-upload" type="file" multiple>
        <input id ="clear" type="button" value='clear'>
    </form>
    <div id="container" style="width:1200px;height:800px;">
    </div>
    <script src="drawPath.js"></script>
</body>

</html>

保存为index.html。框架已经搭好,就差最后的drawPath.js了。
看了一下高德的API,mapStyle选择dark,黑色的背景地图非常酷炫。为了更清楚的显示轨迹信息,直接隐掉路网、建筑等图层,features设置为bg(纯背景)。用HTML5提供的ObjectURL获得本地文件的地址。

'use strict';

var map = new AMap.Map('container', {
    zoom: 12,
    center: [121, 31],
    mapStyle: 'dark',
    features: ['bg'] 
});

$(document).ready(function(){
    $('#clear').on('click', (function(){
        map.clearMap();
    }));
    $('#file-upload').on('change', function(){
        for(var i=0,f;f=this.files[i];i++){
            var fPath = window.URL.createObjectURL(f);
            $.getJSON(fPath, function(data){
                var lineArr = new Array();
                for(var i=0;i<data.lat.length;i++){
                    lineArr.push(new AMap.LngLat(data.lon[i],data.lat[i]));
                }
                var polyline =new AMap.Polyline({
                    path: lineArr,
                    strokeColor: "#00ff00",
                    strokeOpacity: 0.5,
                    strokeWeight: 3, 
                    strokeStyle: "solid",
                });
                polyline.setMap(map);
            });
        }
    });
});

Duang的一下就完成了!打开文件上传所有GPX文件,一直在复旦大学和上海西南某高校附近徘徊呢,真是冤家。

7月-9月的跑步轨迹.png

查看源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,426评论 6 428
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,275评论 25 707
  • GitHub 上有一个 Awesome - XXX 系列的资源整理,资源非常丰富,涉及面非常广。awesome-p...
    若与阅读 18,605评论 4 418
  • 加入到现在为止就是你生命的全部,那么你满意自己的过往么?上天给了你同等的时间,你活出了自己的价值了么?如果此刻你正...
    木戏阅读 163评论 0 0