User:DressyPear4/DividePoligono2Partes
Jump to navigation
Jump to search
Divisão de polígono esm duas partes
Pode ser útil para supressão de vegetação onde é cortado por uma estrada, ou um espaço entre placas solares como no segundo exemplo.
Como funciona?
- Adicione 4 nós em um polígono para determinar o espaço
- Selecione o polígono ou grupo de polígonos
- Selecione também os nós centrais que irão se tornar os novos vértices
Demonstração
-
Imagem.gif, clique para visualizar.
-
Imagem.gif, clique para visualizar.
Código
from org.openstreetmap.josm.gui import MainApplication, Notification
from org.openstreetmap.josm.data.osm import Way
from org.openstreetmap.josm.command import AddCommand, ChangeCommand, DeleteCommand, SequenceCommand
from org.openstreetmap.josm.data import UndoRedoHandler
from javax.swing import UIManager
from java.util import ArrayList
def dividir_poligonos_preservando_um_id():
layer = MainApplication.getLayerManager().getEditLayer()
if layer is None:
Notification(u"Nenhuma camada de edição ativa.")\
.setIcon(UIManager.getIcon("OptionPane.errorIcon"))\
.show()
return
ds = layer.getDataSet()
selected_nodes = list(ds.getSelectedNodes())
selected_ways = list(ds.getSelectedWays())
if not selected_nodes or not selected_ways:
Notification(u"Necessário 4 nós selecionados em cada polígono.")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()
return
cmds = ArrayList()
count = 0
for way in selected_ways:
if not way.isClosed():
continue
nodes = list(way.getNodes())
if nodes[-1] == nodes[0]:
nodes = nodes[:-1]
selecionados = [n for n in nodes if n in selected_nodes]
if len(selecionados) < 4:
continue
split_indices = [i for i, n in enumerate(nodes) if n in selected_nodes]
split_indices = sorted(set(split_indices))
segmentos = []
for i in range(len(split_indices)):
idx_inicio = split_indices[i]
idx_fim = split_indices[(i + 1) % len(split_indices)]
if idx_fim <= idx_inicio:
segmento = nodes[idx_inicio:] + nodes[:idx_fim + 1]
else:
segmento = nodes[idx_inicio:idx_fim + 1]
# só segmentos com pelo menos 3 nós fechados
if len(segmento) >= 3:
if segmento[0] != segmento[-1]:
segmento.append(segmento[0])
segmentos.append(segmento)
if not segmentos:
continue
# O primeiro segmento substitui a way original (preservando o ID)
principal_seg = segmentos[0]
nova_way = Way(way) # preserva ID
nova_way.setNodes(principal_seg)
nova_way.setKeys(dict(way.getKeys()))
cmds.add(ChangeCommand(way, nova_way))
# Os demais segmentos viram novas ways (IDs novos)
for seg in segmentos[1:]:
nova_way2 = Way()
for n in seg:
nova_way2.addNode(n)
nova_way2.setKeys(dict(way.getKeys()))
cmds.add(AddCommand(ds, nova_way2))
count += 1
if not cmds.isEmpty():
seq = SequenceCommand(u"Dividir polígonos (ID original em segmento principal)", cmds)
UndoRedoHandler.getInstance().add(seq)
Notification(u"Divididos %d polígono(s)." % count)\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()
else:
Notification(u"O polígono deve ter 2 nós intermediários selecionados.")\
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))\
.show()
dividir_poligonos_preservando_um_id()