Skip to content

Instantly share code, notes, and snippets.

@mcdlee
Last active June 18, 2025 04:04
Show Gist options
  • Select an option

  • Save mcdlee/ec1fdeb32ddc46cb9f38f9cd6fdaf689 to your computer and use it in GitHub Desktop.

Select an option

Save mcdlee/ec1fdeb32ddc46cb9f38f9cd6fdaf689 to your computer and use it in GitHub Desktop.
從 TDX 得到 YouBike 站點
import requests
import json
import pandas as pd
from matplotlib import pyplot as plt
import folium
client_id = "xxxx" # 佛曰不可說
client_key = "xxxx" # 佛曰不可說
auth_url = "https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token"
url = "https://tdx.transportdata.tw/api/basic/v2/Bike/Station/City/PingtungCounty" ##要切換其他縣市的語法請看官網
class Auth():
def __init__(self, client_id, client_key):
self.client_id = client_id
self.client_key = client_key
def get_auth_header(self):
content_type = 'application/x-www-form-urlencoded'
grant_type = 'client_credentials'
return{
'content-type' : content_type,
'grant_type' : grant_type,
'client_id' : self.client_id,
'client_secret' : self.client_key
}
class data():
def __init__(self, client_id, client_key, auth_response):
self.client_id = client_id
self.client_key = client_key
self.auth_response = auth_response
def get_data_header(self):
auth_JSON = json.loads(self.auth_response.text)
access_token = auth_JSON.get('access_token')
return{
'authorization': 'Bearer ' + access_token,
'Accept-Encoding': 'gzip'
}
if __name__ == '__main__':
try:
d = data(client_id, client_key, auth_response)
data_response = requests.get(url, headers=d.get_data_header())
except:
a = Auth(client_id, client_key)
auth_response = requests.post(auth_url, a.get_auth_header())
d = data(client_id, client_key, auth_response)
data_response = requests.get(url, headers=d.get_data_header())
dataframe = pd.DataFrame(data_response.json())
dataframe['Lon'] = dataframe['StationPosition'].apply(lambda x: x.get('PositionLon') if isinstance(x, dict) else None)
dataframe['Lat'] = dataframe['StationPosition'].apply(lambda x: x.get('PositionLat') if isinstance(x, dict) else None)
center = [22.66021, 120.47921]
m = folium.Map(location=center, zoom_start=15, tiles="CartoDB Positron")
circle_300_group = folium.FeatureGroup(name="300 公尺", show=True)
circle_500_group = folium.FeatureGroup(name="500 公尺", show=False)
for _, row in dataframe.iterrows():
lat, lon = row['Lat'], row['Lon']
name = row['StationName']['Zh_tw']
# marker(直接加到主地圖)
marker = folium.Marker(
location=[lat, lon],
popup=name,
icon=folium.Icon(color='orange', icon='bicycle', prefix='fa')
)
m.add_child(marker)
# 300 公尺圓加到圖層 group
circle_300 = folium.Circle(
location=[lat, lon],
radius=300,
color='yellow',
fill=True,
fill_opacity=0.1
)
circle_300_group.add_child(circle_300)
# 500 公尺圓加到圖層 group
circle_500 = folium.Circle(
location=[lat, lon],
radius=500,
color='red',
fill=True,
fill_opacity=0.1
)
circle_500_group.add_child(circle_500)
# 將圖層群組加入地圖
m.add_child(circle_300_group)
m.add_child(circle_500_group)
# 加入圖層切換控制器
m.add_child(folium.LayerControl())
m.save("youbike_map.html")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment