Try   HackMD

查詢國際太空站目前的位置

由於原本手冊上查詢國際太空站掠過特定位置時間的 API 已經停止服務,所以本文改成使用查詢國際太空站目前位置的 API,並試圖透過另一個 API 找出離該位置最近的城市名稱。

國際太空站目前的位置

提供國際太空站目前位置的 API 網址如下:

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

呼叫後會得到以下(整理過格式)的結果:

{
  "timestamp": 1736325835,
  "message": "success",
  "iss_position": {
    "longitude": "-171.7784",
    "latitude": "43.4497"
  }
}

其中 longitude 與 latitude 分別是國際太空站目前位置的經度與緯度,你也可以透過以下網址:

https://spotthestation.nasa.gov/tracking_map.cfm

查看目前位置:

image

因此只要解析傳回的資料,即可取得目前位置。

透過經緯度查詢最接近的城市

有了經緯度,我們想知道的是這個地點在哪裡,這可以透過 GeoDataSource 提供的 API 查詢,使用前必須註冊帳戶申請金鑰,請依照以下步驟註冊申請:

  1. 連到 GeoDataSource 註冊頁面

    image

    按一下 SIGN UP NOW 開始註冊。

    image

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

    image

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

    image

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

    image

    CONFIRM ORDER 完成:

    image

    它會寄出一封認證信給你。

  2. 請收信完成認證步驟:

    image

    按下確認信中的 CONFIRM & ACTIVATE YOUR ACCOUNT 完成。

  3. 登入取得金鑰:

    image

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

    image

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

    image

    Products/Web Service/Location Search

    image

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

    image

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

    image

    再一路按 CONTINUE 完成:

    image

    最後按下 CONFIRM ORDER 完成:

  4. 查看金鑰:

    image

    請按右上角 My Account

    image

    按左側的 License 即可在頁面上看到你的金鑰。

取得金鑰後,就可以使用 API,在 Products/Web Service/Location Search 頁面可以看到使用方法,API 網址是:

http://api.geodatasource.com/v2/city?lat=經度&lng=緯度&key=金鑰

以台北火車站為例,只要在 Google 地圖上特定地點按滑鼠右鍵,就可以看到經緯度:

image

左邊是經度、右邊是緯度,代入剛剛的 API 網址會得到如下(經過整理格式)的回應(你可以在瀏覽器網址列輸入測試):

{
  "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 上的範例:

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 行為剛剛從註冊取得的金鑰。底下是我執行程式時的位置:

image

實際的輸出結果:

>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
連接 WiFi...
已連上
國際太空站現在位置:
經度:-126.0224
緯度:51.4396
最靠近城市:
國家:CA
城市:Kingcome

OLED 上顯示的結果為:

image

如果目前位置在海上,就會查詢不到對應的城市或國家名稱,看到的輸出就會是這樣:

>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
連接 WiFi...
已連上
國際太空站現在位置:
經度:-172.5079
緯度:50.3105
最靠近城市查詢失敗

OLED 仍然會顯示經緯度,但查詢城市結果是 fail:

image