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

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