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
Última atualização: 2026-01-31
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()