分享

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

 昱雄藏书 2020-04-09

一、介绍


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

最终的效果如图:


image

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


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


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

http://api./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./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./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./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./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./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./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./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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多