一、介紹
本項目中使用一項 web 服務來查找國際空間站 (ISS) 的當前位置并在地圖上繪制其位置。
最終的效果如圖:

本項目來自于樹莓派(raspberrypi)官網(wǎng)學習項目。
二、獲取國際空間站中宇航員的信息
首先需要用到提供國際空間站實時信息的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"
}
]
}
接下來創(chuàng)建python文件,使用python分析打印出空間站宇航員的信息。
導入 urllib.request 和 json 模塊。
import json
import urllib.request
獲取web服務返回的結果
# 將請求地址放入變量中
url = "http://api.open-notify.org/astros.json"
# 調(diào)用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(宇航員)的信息單獨取出來
# 打印空間站當前人數(shù)
number = result['number']
print("現(xiàn)在空間中有 %s 人:" % number)
# 將people放入字典中
people = result['people']
# 將people單獨打印出來
for p in people:
# 獲取宇航員姓名
name = p["name"]
# 獲取宇航員所在飛行器
craft = p['craft']
print("宇航員 %s 在飛行器 %s 里" % (name,craft))
打印結果為
現(xiàn)在空間中有 3 人:
宇航員 Alexey Ovchinin 在飛行器 ISS 里
宇航員 Nick Hague 在飛行器 ISS 里
宇航員 Christina Koch 在飛行器 ISS 里
三、獲取國際空間站的位置
國際空間站處于環(huán)繞地球的軌道內(nèi)。它每隔大約一個半小時繞地球運行一周。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當前所處位置投影到地球上的點的坐標。
經(jīng)度是東-西位置,范圍是 -180 到 180。0 指貫穿英國倫敦格林威治的本初子午線。
緯度是南-北位置,范圍是 90 到 -90。0 指赤道。
同樣用python將國際空間站位置提取出來
# 獲取國際空間站位置
# 將請求地址放入變量中
url = "http://api.open-notify.org/iss-now.json"
# 調(diào)用web服務
response = urllib.request.urlopen(url)
# 保存返回的json結果
result = json.loads(response.read())
# 獲取位置信息
position = result['iss_position']
# 獲取經(jīng)度
longitude = position['longitude']
# 獲取緯度
latitude = position['latitude']
#打印
print("當前空間站的位置為:")
print("經(jīng)度:",longitude)
print("維度:",latitude)
打印結果為:
當前空間站的位置為:
經(jīng)度: -121.3688
維度: 6.2800
四、將位置信息顯示在地圖上
首先要用到兩張圖片資源
一張是世界地圖

一張是空間站

需要導入繪圖庫
import tuytle
加載一張世界地圖作為背景圖
# 將位置信息顯示在地圖上
# 加載一張世界地圖作為背景圖
screen = turtle.Screen()
#設置圖片大小
screen.setup(720.360)
# 設置畫面來匹配坐標
screen.setworldcoordinates(-180,-90,180,90)
screen.bgpic('map.gif')
創(chuàng)建空間站,并將空間站的實際位置顯示在地圖上
# 創(chuàng)建空間站的圖
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"
# 調(diào)用web服務
response = urllib.request.urlopen(url)
# 保存返回的json結果
result = json.loads(response.read())
# 打印出結果
print(result)
# 對json數(shù)據(jù)進行分析
# 打印空間站當前人數(shù)
number = result['number']
print("現(xiàn)在空間中有 %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"
# 調(diào)用web服務
response = urllib.request.urlopen(url)
# 保存返回的json結果
result = json.loads(response.read())
# 獲取位置信息
position = result['iss_position']
# 獲取經(jīng)度
longitude = position['longitude']
# 獲取緯度
latitude = position['latitude']
lon = float(longitude)
lat = float(latitude)
#打印
print("當前空間站的位置為:")
print("經(jīng)度:",lon)
print("維度:",lat)
# 將位置信息顯示在地圖上
# 加載一張世界地圖作為背景圖
screen = turtle.Screen()
#設置圖片大小
screen.setup(720.360)
# 設置畫面來匹配坐標
screen.setworldcoordinates(-180,-90,180,90)
screen.bgpic('map.gif')
# 創(chuàng)建空間站的圖
screen.register_shape('iss.gif')
iss = turtle.Turtle()
iss.shape('iss.gif')
iss.setheading(90)
# 將空間站移動到當前實際位置
iss.penup()
iss.goto(lon,lat)
五 持續(xù)獲取空間站位置
運行一遍上面代碼,只能獲取一次當前的國際空間站信息。
想要持續(xù)的獲取空間站位置,并顯示在地圖上,需做一下改進。使用while循環(huán),每10秒獲取一次。
#!/bin/python3
import json
import turtle
import urllib.request
import time
# 將請求地址放入變量中
url = "http://api.open-notify.org/astros.json"
# 調(diào)用web服務
response = urllib.request.urlopen(url)
# 保存返回的json結果
result = json.loads(response.read())
# 打印出結果
print(result)
# 對json數(shù)據(jù)進行分析
# 打印空間站當前人數(shù)
number = result['number']
print("現(xiàn)在空間中有 %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')
# 創(chuàng)建空間站的圖
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"
# 調(diào)用web服務
response = urllib.request.urlopen(url)
# 保存返回的json結果
result = json.loads(response.read())
# 獲取位置信息
position = result['iss_position']
# 獲取經(jīng)度
longitude = position['longitude']
# 獲取緯度
latitude = position['latitude']
lon = float(longitude)
lat = float(latitude)
#打印
print("當前空間站的位置為:")
print("經(jīng)度:",lon)
print("維度:",lat)
# 將空間站移動到當前實際位置
iss.penup()
iss.goto(lon,lat)
# 每10秒執(zhí)行一次
time.sleep(10)
六、效果演示
以下是跟蹤國際空間站20多分鐘的運行軌跡,放快100倍的效果。
