Usando o ArcGIS 10, tenho uma varredura na qual gostaria de encontrar o pixel com o valor máximo na varredura e retornar sua localização (centro do pixel) em graus decimais. Gostaria de percorrer esse processo retornando a localização do segundo valor mais alto da varredura, depois do terceiro e assim por diante, para que, no final, eu tenha uma lista de N localizações que tenham os valores mais altos na varredura em ordem.
Imagino que isso possa ser feito com mais facilidade usando um script Python, mas estou aberto a outras idéias, se houver uma maneira melhor.
Respostas:
Se você gosta de usar o R , existe um pacote chamado raster . Você pode ler em uma varredura usando o seguinte comando:
Então, quando você olhar (digitando
test
), poderá ver as seguintes informações:Pode haver maneiras melhores de manipular a varredura, mas uma maneira de encontrar as informações desejadas pode ser encontrar o valor mais alto e obter a localização da matriz, e depois adicioná-lo às extensões mais baixas.
fonte
R
, você pode usarR
funções padrão ou ogetValues
método para acessar os valores das células. A partir daí, é fácil identificar os valores mais altos e suas localizações.A resposta pode ser obtido por combinação de uma grelha de indicador de topo de 1% de valores com grades de latitude e longitude. O truque está na criação dessa grade de indicadores, porque o ArcGIS (ainda! Após 40 anos!) Não possui um procedimento para classificar dados rasterizados.
Uma solução para rasters de ponto flutuante é iterativa, mas felizmente rápida . Seja n o número de células de dados. A distribuição cumulativa empírica dos valores consiste em todos os pares (z, n (z)) em que z é um valor na grade en (z) é o número de células na grade com valores menores ou iguais a z . Temos uma curva conectando (-in infinito, 0) a (+ infinito, n) a partir da sequência desses vértices ordenada por z . Assim, define uma função f , onde (z, f (z)) sempre fica na curva. Você deseja encontrar um ponto (z0, 0,99 * n) nesta curva.
Em outras palavras, a tarefa é encontrar um zero de f (z) - (1-0.01) * n . Faça isso com qualquer rotina de busca zero (que pode lidar com funções arbitrárias: essa não é diferenciável). O mais simples, que geralmente é eficiente, é adivinhar e verificar: inicialmente, você sabe que z0 fica entre o valor mínimo zMin e o máximo zMax. Adivinhe qualquer valor razoável estritamente entre esses dois. Se a estimativa for muito baixa, defina zMin = z0; caso contrário, defina zMax = z0. Agora repita. Você convergirá rapidamente para a solução; você está próximo o suficiente quando o zMax e o zMin estão suficientemente próximos. Para ser conservador, escolha o valor final de zMin como a solução: ele pode obter alguns pontos extras que você pode descartar mais tarde. Para abordagens mais sofisticadas, consulte o Capítulo 9 de Receitas Numéricas (o link vai para uma versão gratuita mais antiga).
Analisando esse algoritmo, você precisa executar apenas dois tipos de operações de varredura : (1) selecione todas as células menores ou iguais a algum valor-alvo e (2) conte as células selecionadas. Essas estão entre as operações mais simples e rápidas. (2) pode ser obtido como uma contagem zonal ou lendo um registro da tabela de atributos da grade de seleção.
fonte
Eu fiz isso há algum tempo, embora minha solução esteja usando GDAL (então, isso não é apenas para ArcGIS). Eu acho que você pode obter uma matriz NumPy de uma varredura no ArcGIS 10, mas não tenho certeza. O NumPy fornece indexação de matriz simples e poderosa, como
argsort
outras. Este exemplo não lida com NODATA ou transforma coordenadas de projetadas em latas / longas (mas isso não é difícil de fazer com osgeo.osr, fornecido com GDAL)Mostra o seguinte para o meu arquivo raster de teste:
fonte
NODATA = rast_band.GetNoDataValue()
, em seguida, usando um valor NaN (rast[rast == NODATA] = np.nan
) ou usando uma matriz mascarada (rast = np.ma.array(rast, mask=(rast == NODATA))
). O truque mais complicado é conseguir,argsort
de alguma forma, remover os valores NODATA da análise ou simplesmente ignorá-los no loop for se estiverem NaN / mascarados.