用Python跟踪国际空间站的实时位置,并绘制在地图上

一、介绍


本项目中使用一项 web 服务来查找国际空间站 (ISS) 的当前位置并在地图上绘制其位置。

最终的效果如图:


image

本项目来自于树莓派(raspberrypi)官网学习项目。


二、获取国际空间站中宇航员的信息


首先需要用到提供国际空间站实时信息的web服务。

http://api.open-notify.org/astros.json

该服务返回的是json格式

{
  "message": "success",
  "number": 3,
  "people": [
    {
      "craft": "ISS",
      "name": "Yuri Malenchenko"
    },
    {
      "craft": "ISS",
      "name": "Timothy Kopra"
    },
    {
      "craft": "ISS",
      "name": "Timothy Peake"
    }
  ]
}

接下来创建python文件,使用python分析打印出空间站宇航员的信息。

导入 urllib.request 和 json 模块。

import json
import urllib.request

获取web服务返回的结果

# 将请求地址放入变量中
url = "http://api.open-notify.org/astros.json"
# 调用web服务
response = urllib.request.urlopen(url)
# 保存返回的json结果
result = json.loads(response.read())
# 打印出结果
print(result)

在控制台打印出的结果为

{'people': [{'craft': 'ISS', 'name': 'Alexey Ovchinin'}, {'craft': 'ISS', 'name': 'Nick Hague'}, {'craft': 'ISS', 'name': 'Christina Koch'}], 'number': 3, 'message': 'success'}

可以看出这是一个有3个键的字典

将字典中people(宇航员)的信息单独取出来


# 打印空间站当前人数

number = result['number']
print("现在空间中有 %s 人:" % number)

# 将people放入字典中
people = result['people']

# 将people单独打印出来
for p in people:
    # 获取宇航员姓名
    name = p["name"] 
    # 获取宇航员所在飞行器
    craft = p['craft']

    print("宇航员 %s 在飞行器 %s 里" % (name,craft))

打印结果为

现在空间中有 3 人:
宇航员 Alexey Ovchinin 在飞行器 ISS 里
宇航员 Nick Hague 在飞行器 ISS 里
宇航员 Christina Koch 在飞行器 ISS 里

三、获取国际空间站的位置


国际空间站处于环绕地球的轨道内。它每隔大约一个半小时绕地球运行一周。ISS 以平均每秒 7.66 km 的速度运行。速度很快!

获取国际空间站实时位置的web服务地址为:

http://api.open-notify.org/iss-now.json

返回的json格式为

{
    "timestamp": 1561455890,
    "message": "success",
    "iss_position": {
        "longitude": "-136.1358",
        "latitude": "-37.3534"
    }
}

该结果包含ISS当前所处位置投影到地球上的点的坐标。

经度是东-西位置,范围是 -180 到 180。0 指贯穿英国伦敦格林威治的本初子午线。

纬度是南-北位置,范围是 90 到 -90。0 指赤道。

同样用python将国际空间站位置提取出来

# 获取国际空间站位置

# 将请求地址放入变量中
url = "http://api.open-notify.org/iss-now.json"
# 调用web服务
response = urllib.request.urlopen(url)
# 保存返回的json结果
result = json.loads(response.read())
# 获取位置信息
position = result['iss_position']
# 获取经度
longitude = position['longitude']
# 获取纬度
latitude = position['latitude']

#打印
print("当前空间站的位置为:")
print("经度:",longitude)
print("维度:",latitude)

打印结果为:

当前空间站的位置为:
经度: -121.3688
维度: 6.2800

四、将位置信息显示在地图上


首先要用到两张图片资源

一张是世界地图

image

一张是空间站

image

需要导入绘图库

import tuytle

加载一张世界地图作为背景图

# 将位置信息显示在地图上
# 加载一张世界地图作为背景图
screen = turtle.Screen()
#设置图片大小
screen.setup(720.360)
# 设置画面来匹配坐标
screen.setworldcoordinates(-180,-90,180,90)
screen.bgpic('map.gif')

创建空间站,并将空间站的实际位置显示在地图上

# 创建空间站的图
screen.register_shape('iss.gif')
iss = turtle.Turtle()
iss.shape('iss.gif')
iss.setheading(90)

# 将空间站移动到当前实际位置
iss.penup()
iss.goto(lon,lat)

完整代码示例

#!/bin/python3

import json
import turtle
import urllib.request

# 将请求地址放入变量中
url = "http://api.open-notify.org/astros.json"
# 调用web服务
response = urllib.request.urlopen(url)
# 保存返回的json结果
result = json.loads(response.read())
# 打印出结果
print(result)

# 对json数据进行分析

# 打印空间站当前人数

number = result['number']
print("现在空间中有 %s 人:" % number)

# 将people放入字典中
people = result['people']

# 将people单独打印出来
for p in people:
    # 获取宇航员姓名
    name = p["name"] 
    # 获取宇航员所在飞行器
    craft = p['craft']

    print("宇航员 %s 在飞行器 %s 里" % (name,craft))

# 获取国际空间站位置

# 将请求地址放入变量中
url = "http://api.open-notify.org/iss-now.json"
# 调用web服务
response = urllib.request.urlopen(url)
# 保存返回的json结果
result = json.loads(response.read())
# 获取位置信息
position = result['iss_position']
# 获取经度
longitude = position['longitude']
# 获取纬度
latitude = position['latitude']

lon = float(longitude)
lat = float(latitude)
#打印
print("当前空间站的位置为:")
print("经度:",lon)
print("维度:",lat)

# 将位置信息显示在地图上
# 加载一张世界地图作为背景图
screen = turtle.Screen()
#设置图片大小
screen.setup(720.360)
# 设置画面来匹配坐标
screen.setworldcoordinates(-180,-90,180,90)
screen.bgpic('map.gif')

# 创建空间站的图
screen.register_shape('iss.gif')
iss = turtle.Turtle()
iss.shape('iss.gif')
iss.setheading(90)

# 将空间站移动到当前实际位置
iss.penup()
iss.goto(lon,lat)

五 持续获取空间站位置


运行一遍上面代码,只能获取一次当前的国际空间站信息。

想要持续的获取空间站位置,并显示在地图上,需做一下改进。使用while循环,每10秒获取一次。

#!/bin/python3

import json
import turtle
import urllib.request
import time

# 将请求地址放入变量中
url = "http://api.open-notify.org/astros.json"
# 调用web服务
response = urllib.request.urlopen(url)
# 保存返回的json结果
result = json.loads(response.read())
# 打印出结果
print(result)

# 对json数据进行分析

# 打印空间站当前人数

number = result['number']
print("现在空间中有 %s 人:" % number)

# 将people放入字典中
people = result['people']

# 将people单独打印出来
for p in people:
    # 获取宇航员姓名
    name = p["name"] 
    # 获取宇航员所在飞行器
    craft = p['craft']

    print("宇航员 %s 在飞行器 %s 里" % (name,craft))


# 将位置信息显示在地图上
# 加载一张世界地图作为背景图
screen = turtle.Screen()
#设置图片大小
screen.setup(720.360)
# 设置画面来匹配坐标
screen.setworldcoordinates(-180,-90,180,90)
screen.bgpic('map.gif')

# 创建空间站的图
screen.register_shape('iss.gif')
iss = turtle.Turtle()
iss.shape('iss.gif')
iss.setheading(90)

# 将空间站移动到当前实际位置


i = 1

while i > 0:
    # 获取国际空间站位置
    # 将请求地址放入变量中
    url = "http://api.open-notify.org/iss-now.json"
    # 调用web服务
    response = urllib.request.urlopen(url)
    # 保存返回的json结果
    result = json.loads(response.read())
    # 获取位置信息
    position = result['iss_position']
    # 获取经度
    longitude = position['longitude']
    # 获取纬度
    latitude = position['latitude']

    lon = float(longitude)
    lat = float(latitude)
    #打印
    print("当前空间站的位置为:")
    print("经度:",lon)
    print("维度:",lat)

    # 将空间站移动到当前实际位置
    iss.penup()
    iss.goto(lon,lat)
    # 每10秒执行一次
    time.sleep(10)

六、效果演示


以下是跟踪国际空间站20多分钟的运行轨迹,放快100倍的效果。

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

推荐阅读更多精彩内容