Densificação
A densificação dos limites de polígonos ou segmentos de polilinhas é uma tarefa comum.
Em uma versão anterior, escrevi sobre densificar geometria com base em um "fator", ou seja, dobrar, triplicar... o número de pontos ao longo de um segmento.
A densificação planar pode ser realizada nas Ferramentas de Edição, com várias opções. É não disponível no nível de licença Basic por algum motivo.
Densificar (Edição)—ArcGIS Pro | Documentação
Esta mensagem concentra-se na densificação baseada em um passo de distância planar ao longo da linha/perímetro. É o uso mais comum.
Incluirei alguns dos meus conjuntos de ferramentas (listados abaixo).
O código ilustra o poder do numpy no geoprocessamento.
def _pnts_on_line_(a, spacing=1, is_percent=False): # densificar por distância
"""Adicionar pontos, em espaçamento fixo, a um array que representa uma linha.
Parâmetros
----------
a : array
Uma sequência de `pontos`, pares x,y, representando os limites de um polígono
ou objeto polilinha.
spacing : número
Espaçamento entre os pontos a serem adicionados à linha.
is_percent : booleano
Expressa a densificação como uma porcentagem do comprimento total.
"""
a = _get_base_(a)
N = len(a) - 1 # segmentos
dxdy = a[1:, :] - a[:-1, :] # diferenças nas coordenadas
leng = np.sqrt(np.einsum('ij,ij->i', dxdy, dxdy)) # comprimentos dos segmentos
if is_percent: # como porcentagem
spacing = abs(spacing)
spacing = min(spacing / 100, 1.)
steps = (sum(leng) * spacing) / leng # distância do passo
else:
steps = leng / spacing # distância do passo
deltas = dxdy / (steps.reshape(-1, 1)) # passos nas coordenadas
pnts = np.empty((N,), dtype='O') # construir um array `O`
for i in range(N): # percorrer os segmentos e criar
num = np.arange(steps[i]) # os novos pontos
pnts[i] = np.array((num, num)).T * deltas[i] + a[i]
a0 = a[-1].reshape(1, -1) # adicionar o ponto final e concatenar
return np.concatenate((*pnts, a0), axis=0)
Acho que minhas 2 linhas favoritas são ...
dxdy = a[1:, :] - a[:-1, :] # diferenças nas coordenadas
leng = np.sqrt(np.einsum('ij,ij->i', dxdy, dxdy)) # comprimentos dos segmentos
Einstein era um cara inteligente.
Sua sintaxe de notação é implementada em muitas linguagens e causa confusão até você se acostumar (material para outro blog).
Em resumo, dxdy representa as diferenças sequenciais nas coordenadas de um array (leia coordenadas de polígono/polilinha).
Nada de ler a geometria e subtrair cada coordenada x e y uma por uma. Uma linha e pronto.
Agora a[1:, :] significa do segundo par de coordenadas em diante e a[:-1, :] significa do primeiro par até mas não incluindo o último (indexação começa em zero).
Cabeça girando? Você tem usado Pandas ou shapely por tempo demais.
Aqui está como um polígono simples é representado como um array (até mesmo um arcpy.Array )
a # ---- um array de coordenadas x, y... o primeiro e o último são iguais
array([[ 0.00, 0.00],
[ 2.00, 8.00],
[ 8.00, 10.00],
[ 10.00, 10.00],
[ 10.00, 8.00],
[ 9.00, 1.00],
[ 0.00, 0.00]])
dxdy # ---- delta x e delta y sequenciais entre os pares
array([[ 2.00, 8.00],
[ 6.00, 2.00],
[ 2.00, 0.00],
[ 0.00, -2.00],
[ -1.00, -7.00],
[ -9.00, -1.00]])
leng # ---- distância entre pares de pontos consecutivos
array([ 8.25, 6.32, 2.00, 2.00, 7.07, 9.06])
Agora que a mágica foi feita, o resto é apenas para determinar se você quer densificar baseado em uma distância absoluta ou como porcentagem da distância total.
A seção 'for loop' pode ser simplificada; no entanto mantive assim pois mostra como cada segmento é densificado e os resultados coletados e depois montados no resultado final.
Então como fica? O polígono simples mostrado acima e sua versão densificada são os seguintes.
Gráficos feitos no Spyder usando Matplotlib.
Finally, I will add this capability to my Polyline/Polygon tools and Free Tools tools shortly.
Free_Tools in Tools_for_ArcGIS_Pro (github.com)
PolygonLine Tools in Tools_for_ArcGIS_Pro (github.com)
If you are interested in geometry, computational geometry and numpy and its interface with arcpy and arcgis pro, then my Numpy Geometry link may be of interest. It is the foundation for all the toolset in my site.
numpy_geometry: A numpy geometry class and functions that work with arcpy and ESRI featureclasses
That's all for now. Give me a buzz if you need something you would like added... especially if it requires and Advance license 😉.
--------------------------
Previous work
Densification.... sometimes being dense is a good ... - GeoNet, The Esri Community