Comecei a trabalhar com bancos de dados espaciais e quero escrever uma consulta SQL (PostGIS) para generalização automática de trilhas GPS brutas (com frequência de rastreamento fixa). A primeira coisa em que estou trabalhando é uma consulta que identifica pontos de parada na forma de consulta como "x pontos a uma distância de y metros" para substituir nuvens de pontos maciças por pontos representativos. Eu já percebi encaixar pontos a uma certa distância e contar os encaixados. Na figura abaixo, é possível ver uma trilha de exemplo bruto (pequenos pontos pretos) e o centro dos pontos quebrados como círculos coloridos (tamanho = número de pontos quebrados).
CREATE table simplified AS
SELECT count(raw.geom)::integer AS count, st_centroid(st_collect(raw.geom)) AS center
FROM raw
GROUP BY st_snaptogrid(raw.geom, 500, 0.5)
ORDER BY count(raw.geom) DESC;
Eu ficaria muito satisfeito com esta solução, mas existe o problema do tempo: imaginar a pista como uma pista de dia inteiro em uma cidade em que a pessoa pode retornar a lugares já visitados anteriormente. No meu exemplo, o círculo azul escuro representa a casa da pessoa que ele visitou duas vezes, mas é claro que minha pergunta ignora isso.
Nesse caso, a consulta sofisticada deve coletar apenas pontos com registros de data e hora contíguos (ou IDs), para que produza aqui dois pontos representativos. Minha primeira ideia foi uma modificação da minha consulta para uma versão 3d (tempo como terceira dimensão), mas parece não funcionar.
Alguém tem algum conselho para mim? Espero que minha pergunta seja clara.
Obrigado pela ideia da linha. Eu percebi fazer e simplificar uma cadeia de linhas, como você pode ver na captura de tela abaixo (pontos são pontos originais). O que eu ainda preciso é determinar os locais de descanso (> x pontos em <x metros de raio), idealmente como um ponto com um horário de chegada e um horário de saída ... outras idéias?
Respostas:
Se você realmente precisar de todos os pontos de visualização, poderá criar uma linha e o st_simplify (que é a implementação de Douglas Peucker) faria o trabalho muito bem.
Em alguns casos, você nem precisa armazenar todos os pontos; portanto, você pode filtrar antes de salvar os dados dos pontos; por exemplo, quando o assunto não se mover, não os armazene. Você pode aplicar o DouglasPeucker ou algum outro filtro básico antes de adicionar pontos ao DB. Além disso, alguns provedores de GPS (como a API do Android Location) podem fazer a filtragem inicial com base no tempo e na distância mínima automaticamente. Em alguns casos, você mantém dados duplicados: pré-filtrados para visualizações rápidas e log completo para arquivamento. Atualmente, o armazenamento simples é bastante barato.
fonte
Enquanto isso, encontrei uma solução para o meu problema:
Primeiro, eu determinei um "tipo de distância" para cada ponto. Se o ponto estiver mais próximo de x metros do próximo ponto, será determinado como "parar", caso contrário, como "mover". Então, iniciei uma função de janela como esta:
A tabela resultante tem a seguinte aparência:
A próxima etapa simples agrupa os pontos de "parada", identifica o centróide desses grupos de pontos e assume os carimbos de data e hora mínimos e máximos como hora de chegada e saída.
fonte