Detectar divisão administrativa em função das coordenadas GPS

Alguém que saiba como detectar a freguesia, concelho e distrito em função das coordenadas GPS? Seria para a APP da MUBi para enviar para os municípios.

Encontrei isso, mas não me diz nada

1 Curtiu

Eu poria a hipótese de investigar a API do Open Street Maps. Não a conheço minimamente, mas como sei que tem uma API para obter e gravar dados, e costumam aparecer desenhadas no mapa as fronteiras administrativas, seria de tentar.

Mas, claro, há o problema de serem dados crowd-sourced e não oficiais, o que aumenta em muito a probabilidade de existirem informações erradas. Mesmo o Google Maps, que é baseado em dados oficiais, tem erros ao pontapé!

Olá @Sergio_Loureiro, é que o tenho usado :slight_smile: e até funciona bem, mas a divisão administrativa não é clara e tenho de a cruzar com uma lista de concelhos/distritos e freguesias para ter a certeza. Queria saber se existe algo oficial.

Algum arquitecto por aqui? Alguém sabe que ficheiros são estes que aparecem na base de dados com referência aos concelhos no ficheiro .zip?

@antoniopedro @brunobarao @david_vale @jjleiria

Talvez a @temospena… O ficheiro maior é o SHP, com os limites dos concelhos: deve haver uma fórmula para fazer corresponder uma dada coordenada a um determinado concelho.

1 Curtiu

O shp, shapefile é um formato proprietário da ESRi mas utilizado em muitos softwares, mas na verdade é um conjunto de ficheiros, uns com geometria outros com dados alfanuméricos e outros com a projecção etc.

O que precisas em concreto?

2 Curtiram

Querias uma API que te desse esta informação, ou querias ter a base de dados de concelhos do teu lado e verificar em que concelho está na app directamente?

@Aonio_Lourenco, você pode manter local uma cópia dos dados do OSM (filtrados pelas fronteiras das divisões administrativas, extraídos via OSM XAPI / Overpass API) e usar alguma API JS para verificar se uma dada coordenada está dentro de qual polígono (por exemplo: https://github.com/mikolalysenko/robust-point-in-polygon (não testei, talvez haja melhores))

Caso a base de polígonos extraídas seja demasiado grande, é possível tratá-la usando o JOSM (editor GUI do OSM) ou alguma ferramenta de linha de comando para simplificar os shapes, já que não seria preciso ter um nível demasiado grande de precisão.

[]s

1 Curtiu

do nosso lado seria preferível pois não estaríamos dependentes de API de terceiros

Acham que podem ajudar nessa parte? Que vos parece @arlindopereira e @brunobarao podemos criar uma API web chave-na-mão ou melhor ainda, um pacote npm (assim não temos de alojar a API em lado nenhum) em que teríamos uma função que como entrada daríamos as geo-coordenadas e como saída daríamos a freguesia, concelho e distrito (divisão administrativa oficial de Portugal).

Que vos parece este módulo?

var res = getAdministrativeDivisionsPT(lat, long);
console.log(res) // {distrito: 'Leiria', concelho: 'Alcobaça', freguesia: 'Cós'}

@Pedro_Nobrega_da_Cos queres ajudar? Este módulo não existe, seria open source e qualquer um poderia usar. Acho que seria mesmo muito útil para todo o tipo de aplicações.

Estive a investigar isso ontem o dia todo e deixo aqui as conclusões a que até agora cheguei. Temos que usar duas bibliotecas. Temos que usar esta biblioteca (https://www.npmjs.com/package/shpjs) para abrir o zip e convertê-lo para GeoJSON e depois temos de usar esta função desta biblioteca (https://www.npmjs.com/package/d3-geo#geoContains) para saber se está contido no município. Ainda temos que usar isto (https://www.npmjs.com/package/d3-quadtree) pois não é eficiente estar a iterar por todos os municípios para saber se o ponto está ou não está dentro do município.

Saber com exatidão, dando como entrada um ponto de coordenadas, qual o concelho, freguesia e distrito.

Parece-me uma excelente ideia; apenas haveria de investir algum tempo em buscar se realmente já não há alguma solução implementada para não ter retrabalho.

Não é preciso incluir a biblioteca shpjs e converter os SHP para GeoJSON no cliente, precisará fazer isso somente uma vez e nas consultas ir direto aos GeoJSON. Podes fazer isso com ferramentas em linha de comando, ou mesmo através de interfaces web, por ex: https://mygeodata.cloud/converter/shp-to-geojson

Quanto a eficiência, penso não ser uma questão tão complexa, uma vez que não precisas consultar as coordenadas de todas as freguesias, mas tão somente as das freguesias que estejam dentro do concelho que esteja dentro do distrito consultado. Ou seja, fazer match primeiro ao distrito, depois ao concelho (filtrado pelo distrito) e finalmente à freguesia (filtrado pelo concelho).

[]s

Estive a investigar e aparentemente não há nada! Mas pf favor tenta também procurar para termos a certeza

Percebo perfeitamente o que dizes, mas podemos ter um script associado ao pacote npm, em que vais buscar diretamente à fonte quando fizeres npm update e nessa altura convertes, e assim estamos sempre atualizados, perante mudanças de fronteiras nas freguesias e assim. Mas sim, tens razão, para produção não precisamos de estar sempre a converter para GeoJSON em tempo real.

Bem visto, mas estive a investigar e há algoritmos otimizados para isso, como o quadtree, que já existe para javascript.

1 Curtiu

Estive também a ver, e a “base de dados” geojson fica muito grande para incluir numa aplicação, 120MB em plaintext, 46MB em zip.

Parece-me que uma api seria melhor.

1 Curtiu

Este dataset só tem os concelhos.
Se queres distrito + freguesia + concelho, sugiro que descarregues do site dgterritorio a última versão CAOP (Carta Administrativa Oficial de Portugal).
Lá tens os polígonos em formato .gpkg (geopackage) que é um formato que abre em software GIS opensource, como o QGIS. (para Portugal Continental: http://mapas.dgterritorio.pt/ATOM-download/CAOP-Cont/Cont_AAD_CAOP2020-GPKG.zip)
Daí podes abrir em qualquer software (QGIS, R, py, …), transformar em coordendas WGS84 (que é o que o GPS usa), e converter para GeoJSON, se é o que pretendes.

Ainda assim ficas com um ficheiro com 130MB.
Em python talvez possas recorrer ao ST_intersects para te dar a informação de onde é que “cai” o ponto.

4 Curtiram

4 Curtiram

fixe @brunobarao, como é que fizeste? podes partilhar o código num github?

Tenho um servidor a funcionar, posso criar um domínio e criamos essa API. Isso está em quê? Python, Javascript?

Deixa-me limpar o código, adicionar as ilhas, e publico no github. Está em python, mas crio um container docker para ser mais simples de utilizar.

2 Curtiram

Muito obrigados @brunobarao e @temospena

Estou a sacar diretamente daqui que julgo ser a mesma coisa

Isto permite-me ter uma ligação direta imutável o que é mais fácil para atualizações

@brunobarao como te disse por PM, tenho o servidor todo otimizado para NojdeJS com pm2 e afins (faz a utilização perfeita dos vários cores da CPU), por isso espero que não me leves a mal, mas preferi implementar a API em NodeJS.

A minha questão prende-se agora com o sistema manhosa de coordenadas do ficheiro

    [ -13243.458300000057, -288011.9726 ]

@temospena e @brunobarao sabem que coordenadas são estas? Latitude e Longitude não são

@brunobarao podes apenas enviar-me o link para o ficheiro das ilhas?

Mais uma vez muito obrigados a todos

1 Curtiu

reparei que esse é de 2020, que é mais atual. Como é que converto geopackage para shapefile .shp e .dbf?