用Python跟踪国际空间站的实时位置,并绘制在地图上
2019-06-29 本文已影响0人
MX飞鱼
一、介绍
本项目中使用一项 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