owned this note
owned this note
Published
Linked with GitHub
# 查詢國際太空站目前的位置
由於原本手冊上查詢國際太空站掠過特定位置時間的 API 已經停止服務,所以本文改成使用查詢國際太空站目前位置的 API,並試圖透過另一個 API 找出離該位置最近的城市名稱。
## 國際太空站目前的位置
提供國際太空站目前位置的 API 網址如下:
http://api.open-notify.org/iss-now.json
呼叫後會得到以下(整理過格式)的結果:
```json
{
"timestamp": 1736325835,
"message": "success",
"iss_position": {
"longitude": "-171.7784",
"latitude": "43.4497"
}
}
```
其中 longitude 與 latitude 分別是國際太空站目前位置的經度與緯度,你也可以透過以下網址:
https://spotthestation.nasa.gov/tracking_map.cfm
查看目前位置:

因此只要解析傳回的資料,即可取得目前位置。
## 透過經緯度查詢最接近的城市
有了經緯度,我們想知道的是這個地點在哪裡,這可以透過 [GeoDataSource](https://www.geodatasource.com/web-service/location-search) 提供的 API 查詢,使用前必須註冊帳戶申請金鑰,請依照以下步驟註冊申請:
1. 連到 [GeoDataSource 註冊頁面](https://www.geodatasource.com/profile):

按一下 **SIGN UP NOW** 開始註冊。

填入你的電子郵件位址以及你想使用的密碼,最後按 **CONTINUE** 繼續:

輸入全名選取國家後再按 **CONTINUE** 繼續:

勾選同意授權條款後按 **CONTINUE** 繼續:

按 **CONFIRM ORDER** 完成:

它會寄出一封認證信給你。
2. 請收信完成認證步驟:

按下確認信中的 **CONFIRM & ACTIVATE YOUR ACCOUNT** 完成。
3. 登入取得金鑰:

回到剛剛註冊頁面按右上角的 **Log in**:

填入註冊的電子郵件位址以及密碼後按 **LOGIN** 登入:

選 **Products/Web Service/Location Search**:

在免費價格那一列按 **ADD TO CART** 加入購物車:

確認費用為 0 後按 **CHECKOUT** 結帳:

再一路按 **CONTINUE** 完成:

最後按下 **CONFIRM ORDER** 完成:
4. 查看金鑰:

請按右上角 **My Account**:

按左側的 **License** 即可在頁面上看到你的金鑰。
取得金鑰後,就可以使用 API,在 **Products/Web Service/Location Search** 頁面可以看到使用方法,API 網址是:
```
http://api.geodatasource.com/v2/city?lat=經度&lng=緯度&key=金鑰
```
以台北火車站為例,只要在 Google 地圖上特定地點按滑鼠右鍵,就可以看到經緯度:

左邊是經度、右邊是緯度,代入剛剛的 API 網址會得到如下(經過整理格式)的回應(你可以在瀏覽器網址列輸入測試):
```json
{
"country": "TW",
"region": "Taipei",
"city": "Jiancheng",
"latitude": 25.05,
"longitude": 121.517,
"currency_code": "TWD",
"currency_name": "Taiwan Dollar",
"currency_symbol": "NT$",
"sunrise": "06:39",
"sunset": "17:21",
"time_zone": "+08:00",
"distance_km": 0.2347
}
```
其中 city 項目就是離指定經緯度最近的城市內區域名稱,本例應該是建成(從第圖上看),而 region 項目是城市名稱,country 項目則是該城市所在的國家。
## 範例程式
以下就是串接上述兩個 API 並顯示在 OLED 上的範例:
```python=
import network, urequests, utime, sys
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
oled = SSD1306_I2C(128, 64, I2C(scl=Pin(5), sda=Pin(4)))
ssid = "無線網路名稱"
pw = "無線網路密碼"
iss_url = "http://api.open-notify.org/iss-now.json"
key = '你的 GeoDataSource 金鑰'
geo_url = 'http://api.geodatasource.com/v2/city'
print("連接 WiFi...")
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)
while not wifi.isconnected():
pass
print("已連上")
response = urequests.get(iss_url)
if response.status_code != 200:
oled.text("Location fail", 0, 0)
oled.show()
print('國際太空站現在位置查詢失敗')
sys.exit(0)
parsed = response.json()
response.close()
print("國際太空站現在位置:")
longitude = parsed['iss_position']['longitude']
latitude = parsed['iss_position']['latitude']
print('經度:' + longitude)
print('緯度:' + latitude)
oled.text("Lat: " + latitude, 0, 0)
oled.text("Lng: " + longitude, 0, 16)
oled.show()
response = urequests.get(geo_url +
'?lat=' + latitude +
'&lng=' + longitude +
'&key=' + key)
if response.status_code != 200:
oled.text("City fail", 0, 32)
oled.show()
print('最靠近城市查詢失敗')
sys.exit(0)
parsed = response.json()
response.close()
print('最靠近城市:')
country = parsed['country']
city = parsed['city']
print('國家:' + country)
print('城市:' + city)
oled.text(city, 0, 32)
oled.text(country, 0, 48)
oled.show()
```
請記得修改 7,8 行為你要連接的無線網路名稱與密碼,並修改第 10 行為剛剛從註冊取得的金鑰。底下是我執行程式時的位置:

實際的輸出結果:
```
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
連接 WiFi...
已連上
國際太空站現在位置:
經度:-126.0224
緯度:51.4396
最靠近城市:
國家:CA
城市:Kingcome
```
OLED 上顯示的結果為:

如果目前位置在海上,就會查詢不到對應的城市或國家名稱,看到的輸出就會是這樣:
```
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
連接 WiFi...
已連上
國際太空站現在位置:
經度:-172.5079
緯度:50.3105
最靠近城市查詢失敗
```
OLED 仍然會顯示經緯度,但查詢城市結果是 fail:
