Se "mais rápido" inclui o montante de seu tempo que é gasto, a solução vai depender do que o software que você está confortável com e pode usar de forma expedita. As observações a seguir, conseqüentemente, se concentram em idéias para alcançar os tempos de computação mais rápidos possíveis .
Se você usar um programa fixo, quase certamente o melhor que poderá fazer é pré-processar os polígonos para configurar uma estrutura de dados point-in-polygon, como uma árvore KD ou quadtree, cujo desempenho normalmente será O (log (V ) * (N + V)) onde V é o número total de vértices nos polígonos e N é o número de pontos, porque a estrutura de dados exigirá pelo menos O (log (V) * V) esforço para criar e, em seguida, deve ser sondado para cada ponto a um custo por ponto O (log (V)).
Você pode obter um desempenho substancialmente melhor primeiro agrupando os polígonos, explorando a suposição de que não há sobreposições. Cada célula da grade está inteiramente no interior de um polígono (incluindo o interior do "polígono universal"); nesse caso, rotule a célula com o ID do polígono ou então contenha uma ou mais arestas de polígono. O custo dessa rasterização, igual ao número de células de grade referenciadas durante a rasterização de todas as arestas, é O (V / c), em que c é o tamanho de uma célula, mas a constante implícita na notação O-grande é pequena.
(Uma vantagem dessa abordagem é que você pode explorar rotinas gráficas padrão. Por exemplo, se você tiver um sistema que (a) desenhe os polígonos em uma tela virtual usando (b) uma cor distinta para cada polígono e (c) permita para ler a cor de qualquer pixel que você queira endereçar, você o criou.)
Com essa grade instalada, faça uma pré-seleção dos pontos computando a célula que contém cada ponto (uma operação O (1) exigindo apenas alguns relógios). A menos que os pontos estejam agrupados em torno dos limites do polígono, isso normalmente deixará apenas cerca de O (c) pontos com resultados ambíguos. O custo total de construção da grade e pré-triagem é, portanto, O (V / c + 1 / c ^ 2) + O (N). É necessário usar outro método (como qualquer um dos recomendados até agora) para processar os pontos restantes (ou seja, aqueles que estão próximos aos limites dos polígonos), a um custo de O (log (V) * N * c) .
À medida que c diminui, cada vez menos pontos estarão na mesma célula da grade com uma aresta e, portanto, cada vez menos exigirá o processamento subsequente de O (log (V)). Agindo contra isso é a necessidade de armazenar células da grade O (1 / c ^ 2) e gastar tempo O (V / c + 1 / c ^ 2) rasterizando os polígonos. Portanto, haverá um tamanho de grade ideal c. Utilizando-o, o custo computacional total é O (log (V) * N), mas a constante implícita é tipicamente muito menor do que o uso de procedimentos em lata, devido à velocidade O (N) da pré-triagem.
Há 20 anos, testei essa abordagem (usando pontos espaçados uniformemente em toda a Inglaterra e no exterior e explorando uma grade relativamente bruta de cerca de 400 mil células oferecidas pelos buffers de vídeo da época) e obtive duas ordens de aceleração de magnitude em comparação com o melhor algoritmo publicado que pude encontrar. Mesmo quando os polígonos são pequenos e simples (como triângulos), você tem praticamente a garantia de uma ordem de magnitude acelerada.
Na minha experiência, o cálculo foi tão rápido que toda a operação foi limitada pelas velocidades de E / S de dados, não pela CPU. Antecipando que a E / S pode ser o gargalo, você obteria os resultados mais rápidos armazenando os pontos no formato mais compactado possível para minimizar os tempos de leitura dos dados. Pense também em como os resultados devem ser armazenados, para que você possa limitar as gravações em disco.
Da minha parte, provavelmente carregaria dados CSV em um arquivo shp e, em seguida, escreveria um script python usando shapefile e shapely para obter o ID do polígono e atualizar o valor do campo.
Não sei se geotools e JTS são mais rápidos que shapefile / shapely ... Não tenho tempo para testá-lo!
edit : A propósito, a conversão de csv para o formato shapefile provavelmente não é necessária, pois os valores podem ser facilmente formatados para serem testados com objetos espaciais do shapefile do polígono.
fonte
Acabei convertendo os polígonos em uma varredura e amostrando-os nas posições dos pontos. Como meus polígonos não se sobrepunham e a alta precisão não era necessária (polígonos representavam classes de uso da terra e suas fronteiras eram consideradas bastante incertas de qualquer maneira), essa era a solução mais eficiente em termos de tempo que eu consegui encontrar.
fonte
Eu rapidamente escrever um pequeno programa Java baseado no leitor shapefile de GeoTools ea operação contém de JTS . Eu não sei o quão rápido pode ser ...
fonte
Use Spatialite .
Faça o download da GUI. Você pode abrir o Shapefile e o CSV como tabelas virtuais. Isso significa que na verdade você não os importa para o banco de dados, mas eles aparecem como tabelas e você pode ingressar rapidamente e consultá-los da maneira que desejar.
fonte
Você pode fazer isso rapidamente usando OGR em C / C ++ / Python (o Python deve ser o mais lento dos 3). Faça um loop em todos os polígonos e defina um filtro nos pontos, faça um loop nos pontos filtrados e você saberá que cada um dos pontos em que fará o loop pertencerá ao polígono atual. Aqui está um exemplo de código em python usando OGR que percorrerá os polígonos e os pontos de filtro de acordo. O código C / C ++ será muito parecido com isso, e eu imagino que você obterá um aumento significativo de velocidade em comparação com python. Você precisará adicionar algumas linhas de código para atualizar o CSV à medida que avança:
Arquivo VRT (busstops.vrt):
Arquivo CSV (busstops.csv):
Arquivo CSVT (busstops.csvt, o OGR precisa dele para identificar os tipos de coluna, caso contrário, ele não executará o filtro espacial):
fonte
pode tentar csv2shp csv2shp
curioso para saber em que setor está o bilhão de pontos CSV?
fonte