User:DressyPear4/DividePoligono2Partes

From OpenStreetMap Wiki
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

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()