diff --git a/README.md b/README.md index 2ebf916..c1d4a09 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **PathsViewer** é uma ferramenta para visualização de dados espaço-temporais **em tempo real** ou **pós-eventos**. Essa ferramenta busca suprir a demanda por ferramentas de visualização de trajetórias de objetos, em vista do grande interesse em pesquisas nesse tipo de dado. -É possível utilizar conjuntos de dados variados, com estruturas diversas, tais como _traces_ de 5G georeferenciados e trajetórias de veículos. +É possível utilizar conjuntos de dados variados, com estruturas diversas, tais como _traces_ de 5G georreferenciados e trajetórias de veículos. Esse repositório (e sua [Wiki](//github.com/intrig-unicamp/paths-viewer/wiki/)) contém todo o código da ferramenta, como também instruções para execução, _deploy_, contribuição e demais informações. @@ -28,7 +28,7 @@ Para uma breve demonstração, acesse o **PathsViewer** no endereço [paths-view - Modo de operação **em tempo real** - Também podemos realizar o envio de dados em tempo real através de dispositivos distribuídos. Na imagem abaixo, são exibidos os parâmetros de conexão para enviar dados para a API do **PathsViewer**, para que a interface no navegador exiba em tempo real as coletas realizadas + Também podemos realizar o envio de dados em tempo real através de dispositivos distribuídos. Na imagem abaixo, são exibidos os parâmetros de conexão para enviar dados para a API do **PathsViewer**, para que a interface no navegador exiba em tempo real as coletas realizadas > 💡 Utilize o _script_ [realtime-sim](examples/realtime-sim.py) para simular o envio dos dados em tempo real @@ -37,6 +37,24 @@ Para uma breve demonstração, acesse o **PathsViewer** no endereço [paths-view

+## Formato de arquivo +A ferramenta aceita o envio de arquivos no formato `.csv` sem cabeçalho. Exemplo: + +```txt +C13062,10-03-2014,07:00:54,-23.007013,-43.311646 +C13062,10-03-2014,07:01:54,-23.007328,-43.306889 +C13062,10-03-2014,07:02:54,-23.009064,-43.305984 +C13062,10-03-2014,07:03:54,-23.010941,-43.309719 +C13062,10-03-2014,07:04:53,-23.013695,-43.313404 +``` + +As colunas devem ser na ordem: +- Identificador +- Data, no formato `--` +- Hora, no formato `--` +- Latitude em graus decimais +- Longitude em graus decimais + ## 🚀 Configuração inicial Essas instruções vão permitir que você tenha uma cópia funcional do projeto na sua máquina local para desenvolvimento e testes. diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..290830d --- /dev/null +++ b/examples/README.md @@ -0,0 +1,36 @@ +# Exemplos + +Essa pasta contém conjuntos de dados de exemplo para facilitar os testes do PathsViewer. Os seguintes dados estão disponíveis: + +- [Ônibus / Belo Horizonte](./belo_horizonte) ([fonte](https://ckan.pbh.gov.br/dataset/9c051f97-122a-427e-8997-4f0adcf5f93c/resource/a33650ce-2dc3-43b9-90bc-be74964763df/download/velocidade_nos_corredores.csv)) + + Esse _dataset_ é sobre das coordenadas geográficas de ônibus da cidade de Belo Horizonte em corredores da cidade, coletados de agosto de 2019 a março de 2020. As informações disponíveis são: identificador do ônibus, código da linha do ônibus, via do corredor, sentido, latitude, longitude, data e hora. + +- [Ônibus / Rio de Janeiro](./rio_de_janeiro) ([fonte](https://ieee-dataport.org/open-access/crawdad-coppe-ufrjriobuses)) + + Similar ao anterior, nesse _dataset_ foram coletados dados de posição em tempo real enviados por mais de 12.000 ônibus, com granularidade de 1 minuto, da cidade do Rio de Janeiro. Contém as informações: data, hora, identificador do ônibus, linha do ônibus, latitude, longitude e velocidade. + +- [Táxis / Roma](./rome) ([fonte](https://ieee-dataport.org/open-access/crawdad-romataxi)) + + Esse _dataset_ contém 30 dias de dados das coordenadas geográficas de táxis da cidade de Roma, na Itália. As informações disponíveis são: data e hora, identificador do veículo, latitude e longitude. + +- [Táxis / São Francisco](./san_francisco) ([fonte](https://ieee-dataport.org/open-access/crawdad-epflmobility)) + + O _dataset_ de táxis em São Francisco, nos Estados Unidos, contém dados de coordenadas GPS de aproximadamente 500 veículos, coletados por 30 dias. O arquivo contém as informações de identificação do veículo, data, hora, latitude, longitude e se o táxi estava ocupado. + +- [YouTube em 5G / São Paulo](./sao_paulo) ([fonte](https://ieee-dataport.org/documents/youtube-goes-5g-benchmarking-youtube-4g-vs-5g)) + + Métricas de utilização do YouTube na rede 5G SA (StandAlone) e NSA (Non-StandAlone) na cidade de São Paulo foram coletadas pelo grupo de pesquisa e analisadas através do PathsViewer. O _dataset_ possui granularidade de 1 segundo e foi construído com o suporte da ferramenta [G-NetTrack](https://gyokovsolutions.com/g-nettrack/), que coleta métricas como data, hora, geolocalização, frequência do sinal, Indicador de Qualidade do Canal (Channel Quality Indicator - do inglês), tecnologia da rede (e.g. 5G, 4G, 3G), velocidade de download/upload, entre outras. + +## Simulador de envio em tempo real +O _script_ [`realtime-sim.py`](./realtime-sim.py) faz o envio de dados históricos para a API do PathsViewer de forma como se fosse um dispositivo físico enviando dados em tempo real. Assim, é possível realizar o teste desse modo de operação. + +Esse _script_ pode ser executado pelo terminal da seguinte forma: +```bash +python3 realtime-sim.py --endpoint https://paths-viewer.vercel.app/api/session/1773295143798 --city RIO_DE_JANEIRO +``` + +Para mais opções de utilização, consulte o comando de ajuda: +```bash +python3 realtime-sim.py --help +``` diff --git a/examples/realtime-sim.py b/examples/realtime-sim.py index 57ce89b..c8df7d7 100755 --- a/examples/realtime-sim.py +++ b/examples/realtime-sim.py @@ -42,18 +42,18 @@ def send_request(endpoint, payload: dict): def get_milliseconds_from_datetime(date: str , time: str) -> int: - data = f"{date}T{time}" - format_data = "%d-%m-%YT%H:%M:%S" + data = f'{date}T{time}' + format_data = '%d-%m-%YT%H:%M:%S' current = datetime.strptime(data, format_data) return current def get_milliseconds_from_datetimeSP(timestamp: str) -> int: print(timestamp) - format_data = "%Y.%m.%d_%H.%M.%S" + format_data = '%Y.%m.%d_%H.%M.%S' current = datetime.strptime(timestamp, format_data) return current -def mainSP(city, objects_quantity, simulation_velocity, endpoint): +def mainSP(city, objects_quantity, simulation_speed, endpoint): coordinates_list = [] for object_index in range(1, objects_quantity+1): @@ -76,17 +76,17 @@ def mainSP(city, objects_quantity, simulation_velocity, endpoint): for payload in coordinates_list: next_ms = get_milliseconds_from_datetimeSP(payload['timestamp']) delta = next_ms - current_ms - date = next_ms.strftime("%Y-%m-%d") - time = next_ms.strftime("%H:%M:%S") + date = next_ms.strftime('%Y-%m-%d') + time = next_ms.strftime('%H:%M:%S') del payload['timestamp'] response = send_request(endpoint, { **payload, 'date': date, 'time': time }) print(response) - - sleep((1.0/simulation_velocity) * (delta.total_seconds())) + + sleep((1.0/simulation_speed) * (delta.total_seconds())) current_ms = next_ms -def main(city, objects_quantity, simulation_velocity, endpoint): +def main(city, objects_quantity, simulation_speed, endpoint): coordinates_list = [] for object_index in range(1, objects_quantity+1): @@ -111,41 +111,22 @@ def main(city, objects_quantity, simulation_velocity, endpoint): response = send_request(endpoint, payload) print(response) - - sleep((1.0/simulation_velocity) * (delta.total_seconds())) + + sleep((1.0/simulation_speed) * (delta.total_seconds())) current_ms = next_ms if __name__ == '__main__': MAX_OBJECTS = 3 + city_choices = ['BELO_HORIZONTE', 'RIO_DE_JANEIRO', 'ROME', 'SAN_FRANCISCO', 'SAO_PAULO'] - #sys.path.append('.') parser = argparse.ArgumentParser() - parser.add_argument("--city", "-c", help="Select which city dataset to use. \ - Current options are BELO_HORIZONTE, RIO_DE_JANEIRO, ROME, SAN_FRANCISCO and SAO_PAULO.") - parser.add_argument("--objects-quantity", "-o", help="Select how many objects to use, up to 3.") - parser.add_argument("--endpoint", "-s", help="Specifies endpoint to send the requests.") - parser.add_argument("--simulation-velocity", "-v", help="Specifies simulation velocity.") + parser.add_argument('--city', '-c', choices=city_choices, default='RIO_DE_JANEIRO', help='Which city dataset to use') + parser.add_argument('--objects-quantity', '-q', type=int, choices=range(1, MAX_OBJECTS + 1), default=1, help='Amount of objects to use') + parser.add_argument('--endpoint', '-e', required=True, help='Endpoint to send the requests') + parser.add_argument('--simulation-speed', '-s', type=int, default=120, help='Simulation speed') args = parser.parse_args() - print(args) - - city = args.city \ - if args.city is not None and args.city in ['BELO_HORIZONTE', 'RIO_DE_JANEIRO', 'ROME','SAN_FRANCISCO', 'SAO_PAULO'] \ - else 'RIO_DE_JANEIRO' - objects_quantity = int(args.objects_quantity) \ - if args.objects_quantity is not None \ - and args.objects_quantity.isnumeric() \ - and int(args.objects_quantity) <= MAX_OBJECTS \ - else 1 - simulation_velocity = int(args.simulation_velocity) \ - if args.simulation_velocity is not None \ - and args.simulation_velocity.isnumeric() \ - else 120 - endpoint = args.endpoint - - if endpoint is None: - raise Exception('Endpoint not specified.') - - if city == 'SAO_PAULO': - mainSP(city, objects_quantity, simulation_velocity, endpoint) + + if args.city == 'SAO_PAULO': + mainSP(args.city, args.objects_quantity, args.simulation_speed, args.endpoint) else: - main(city, objects_quantity, simulation_velocity, endpoint) + main(args.city, args.objects_quantity, args.simulation_speed, args.endpoint)