Explorando os dados públicos de Curitiba com Python 💻📍🏠
Uma divertida análise de dados sobre a linha de turismo da cidade de Curitiba usando API do Google Maps, folium, polyline e geopandas 🍃
Alô alô, meu povo! No post de hoje vamos aprender algumas coisas bem legais a respeito da linha curitibana de turismo (vulgo Jardineira) com o senhor Python. Até o final desse post você será capaz de responder duas perguntas:
- Quantos pontos de ônibus ela possui?
- Quantos quilômetros a jardineira percorre ao todo?
Além disso, você vai aprender também:
- Calcular distância entre duas coordenadas geográficas através da API do Google Maps;
- Deixar o seu mapa interativo e colocar marcadores.
Estão preparados?
Esse post é uma continuação do tema sobre o transporte público da cidade de Curitiba. — Caso você não tenha lido a parte 1 e parte 2, já dá uma lida para se inteirar no assunto.
Curitiba contém 11 linhas de ônibus: Alimentador, Convencional, Linha Direta (ou Ligeirinho para os íntimos), Madrugueiro, Troncal, Expresso, Interbairros, Ligeirão, Circular Centro, Evento Especial e Jardineira.
ALIMENTADOR 144
CONVENCIONAL 72
LINHA DIRETA 28
MADRUGUEIRO 19
TRONCAL 17
EXPRESSO 11
INTERBAIRROS 9
LIGEIRÃO 3
EVENTO ESPECIAL 2
CIRCULAR CENTRO 2
JARDINEIRA 1
Porém todavia entretanto no entanto, o foco de hoje é para a nossa belíssima Jardineira. Caso você não seja de Curitiba ou nunca tenha visitado a cidade, segue foto:
Eu já até sei que a primeira coisa que você pensou ao olhar essa foto foi em querer andar na parte de cima do ônibus. Eu, você e toda a população da cidade temos o mesmo desejo. Tamo junto 🤙
Análise de 🎲
Observação: os dados utilizados para esse estudo é da data 01/01/2021.
Observação2: meu código está uma bagunça — prometo melhorar 🤡.
Dados sobre a linha de ônibus
Temos duas perguntas para responder, porém, o mais importante são os dados. Como que a gente consegue eles? 🌚
- Primeiro passo: acessar esse site e baixar os json que constam abaixo;
# IMPORTANDO AS BASES DE DADOS - URBSdfShape = pd.read_json('2021_01_01_shapeLinha.json')
dfTrecho = pd.read_json('2021_01_01_trechosItinerarios.json')
dfPontos = pd.read_json('2021_01_01_pontosLinha.json')
dfLinhas = pd.read_json('2021_01_01_linhas.json')
Eu modifiquei e formatei os nomes de algumas colunas. Usei esses comandos:
# RENOMEANDO NOME DA COLUNAdfLinhas = dfLinhas.rename(columns={'NOME':'NOME_LINHA'})
dfPontos = dfPontos.rename(columns={'LAT':'LATITUDE'})
dfPontos = dfPontos.rename(columns={'LON':'LONGITUDE'})# FORMATANDO AS COORDENADAS GEOGRÁFICASdfPontos['LATITUDE'] = dfPontos['LATITUDE'].str.replace(',', '.')
dfPontos['LONGITUDE'] = dfPontos['LONGITUDE'].str.replace(',', '.')
dfPontos['LATITUDE'] = dfPontos['LATITUDE'].astype(float)
dfPontos['LONGITUDE'] = dfPontos['LONGITUDE'].astype(float)dfShape['LAT'] = dfShape['LAT'].str.replace(',', '.')
dfShape['LON'] = dfShape['LON'].str.replace(',', '.')
dfShape['LAT'] = dfShape['LAT'].astype(float)
dfShape['LON'] = dfShape['LON'].astype(float)
dfShape.head()
Aqui estão os pontos principais do código, ele está completo lá no meu GitHub. Caso fique alguma dúvida é só entrar em contato.
# LINHA TURISMO PELO DF PONTOSdf979 = dfPontos[dfPontos['COD']=='979']
df979.sort_values('SEQ',ascending=True, inplace=True)
Abaixo eu filtro um dos itinerários, pois ele tem a ida e volta (para calcular um circuito completo da Jardineira).
# FIltrando o itinerary_id pois nesse df tem a ida e a voltadf979 = df979[df979['ITINERARY_ID']==1065]
print('Quantidade de pontos da linha turismo 979:',df979['SEQ'].count())
df979.head()
Temos a resposta da nossa primeira pergunta! 👀🏄♀️
Ou seja, a Jardineira possui 28 pontos para você descer, dar um rolêzinho e voltar depois (ao fim do post tem um mapa top da balada para você conferir os locais dos pontos de ônibus).
Essa é a carinha do nosso DataFrame.
# CRIANDO AS COORDENADASdf979['COORDENADA'] = list(zip(df979.LATITUDE, df979.LONGITUDE))
Eu acabo nem usando a coluna ‘COORDENADA’, mas caso um dia você precise dessa informação você já sabe como fazer.
# Aqui eu crio colunas com a latitude e longitude da próxima parada, para depois através da API do Google Maps calcular a distânciadf979['LATITUDE_FINAL'] = df979['LATITUDE'].shift(-1)
df979['LONGITUDE_FINAL'] = df979['LONGITUDE'].shift(-1)
API Google Maps
- Você precisa criar uma chave de acesso no Google Cloud Platform;
- Agora só alegria:
google_key = 'VOCÊCOLOCA SUA CHAVE AQUI'lat_origem = df979['LATITUDE'].tolist()
long_origem = df979['LONGITUDE'].tolist()
lat_destino = df979['LATITUDE_FINAL'].tolist()
long_destino = df979['LONGITUDE_FINAL'].tolist()
distancia = []
for i in range(len(long_destino)):
url = f"https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins={lat_origem[i]},{long_origem[i]}&destinations={lat_destino[i]}%2C{long_destino[i]}&key={google_key}"
r=requests.get(url)
data = r.json()
try:
distancia.append(data['rows'][0]['elements'][0]['distance']['text'])
except:
pass
distancia
Caso você dê outro nome ao seu DataFrame, basta modificar no meu código o df979 (o destaque em verde)para dfnomequevcquiser.
Outro ponto importante aqui é o units=metric, ele retorna os valores em quilômetros. Caso você queira em milhas basta mudar para units=imperial.
Como nem tudo são flores, o output da imagem acima vem com 1 valor a menos, temos 28 pontos de ônibus mas ele devolve 27. Por quê?
Eu coloco a origem e destino na mesma linha, masssssss a última linha não tem nenhum destino. Ela está vazia. Caso você só acredite vendo, então veja:
E AGORA? A gente senta e chora? Se quiser pode, ninguém vai te julgar! Entretanto, temos uma solução!
distancia.append('0 km')
Eu coloquei um ‘0 km’ ao fim da lista e cheirinho de sucesso.
# ESSA PARTE EU SEPARO O VALOR DA DISTÂNCIA ENTRE OS PONTOS E ADICIONO EM UMA COLUNA NO DF979 COM OS OUTROS DADOSdistancia2 = []
for i in range(len(distancia)):
distancia2.append(float((distancia[i].replace(' km', ''))))
df979['DIST_KM'] = distancia2
df979.head()
Agora vou tirar a prova e ver se realmente bate com os resultados do Google Maps.
Vou pegar a LATITUDE e LONGITUDE como ponto de partida e LATITUDE_FINAL e LONGITUDE_FINAL como ponto de chegada.Tem que dar aproximadamente 1km essa distância. SERÁAAAAAAAAAA QUE VAI DAR? Façam suas apostas.
Para dar mais uma conferida, vamos tentar outros pontos.
Mágica? Não! Python.
Agora com todos os dados fica bem fácil saber o quanto que a nossa Jardineira roda em km num circuito.
df979[‘DIST_KM’].sum()
Resultado: 45,7km!
Agora se alguém te perguntar você já sabe duas curiosidades sobre a nossa cidade das terras das capivaras.
Final feliz 💕
Mapa
mapa979 = folium.Map(location=[-25.4416481,-49.3481283], zoom_start=12,
tiles='OpenStreetMap')for i, v in Shape979.iterrows():
folium.CircleMarker(location=[v['LAT'], v['LON']],
radius=3,
color='#fc081c',
fill_color='#fc081c',
fill_opacity=0.1,
fill=True).add_to(mapa979)
folium.PolyLine(locations=Shape979[{'LAT','LON'}], color="#fc081c", weight=7, opacity=10).add_to(mapa979)mapa979
mapa979 = folium.Map(location=[-25.4416481,-49.3481283], zoom_start=12,
tiles='OpenStreetMap')for i, v in Shape979.iterrows():
folium.CircleMarker(location=[v['LAT'], v['LON']],
radius=3,
color='#fc081c',
fill_color='#fc081c',
fill_opacity=0.1,
fill=True).add_to(mapa979)
folium.PolyLine(locations=Shape979[{'LAT','LON'}], color="#fc081c", weight=7, opacity=10).add_to(mapa979)for i in range(0,len(df979)):
folium.Marker(
location=[df979.iloc[i]['LATITUDE'], df979.iloc[i]['LONGITUDE']],
popup=df979.iloc[i]['NOME'],
icon = folium.Icon(color='red', icon='info-sign')
).add_to(mapa979)mapa979
mapa979 = folium.Map(location=[-25.4416481,-49.3481283], zoom_start=12,
tiles='OpenStreetMap')for i, v in Shape979.iterrows():
folium.CircleMarker(location=[v['LAT'], v['LON']],
radius=3,
color='#fc081c',
fill_color='#fc081c',
fill_opacity=0.1,
fill=True).add_to(mapa979)
folium.PolyLine(locations=Shape979[{'LAT','LON'}], color="#fc081c", weight=7, opacity=10).add_to(mapa979)for i in range(0,len(df979)):
folium.Marker(
location=[df979.iloc[i]['LATITUDE'], df979.iloc[i]['LONGITUDE']],
popup=df979.iloc[i]['NOME'],
icon = folium.Icon(color='red', icon='info-sign')
).add_to(mapa979)folium.Marker(
location = ['-25.4420753','-49.2387704'],
popup = 'Jardim Botânico',
icon = folium.Icon(color='green', icon='camera')
).add_to(mapa979)folium.Marker(
location = ['-25.3846139','-49.2784345'],
popup = 'Ópera de Arame',
icon = folium.Icon(color='green', icon='camera')
).add_to(mapa979)folium.Marker(
location = ['-25.4100978','-49.2693819'],
popup = 'Museu Oscar Niemeyer',
icon = folium.Icon(color='green', icon='camera')
).add_to(mapa979)#folium.LayerControl(collapsed=False).add_to(mapa979)
#mapa979.save('jardineira_turismo_curitiba.html')mapa979
É isso, pessoal! Espero que tenham gostado. Estou aprendendo sobre o mundo dos dados, então qualquer feedback e cometário ele é muito bem-vindo. Obrigada pelo seu tempo em ler, curta e compartilhe.
Gratiluz ✨💕