User:DressyPear4/SelecaoNos

From OpenStreetMap Wiki
Jump to navigation Jump to search

Seleção de nós

Em muitas geometrias grudadas/mescladas com outras, selecionar os nós de ambas pode ser um processo trabalhoso, esse script facilita a seleção de nós.

Como funciona?

  • Selecione uma linha ou polígono
  • Escolha o modo "Apenas selecionado"
  • Escolha o tipo

- - -

  • Selecione duas linhas ou polígonos
  • Escolha o modo "Entre selecionados"
  • Escolha o tipo

Se as escolhas não forem compatíveis com a seleção, uma notificação aparecerá.

Demonstração

Imagem.gif, clique para visualizar.

Código

from org.openstreetmap.josm.gui import MainApplication, Notification
from org.openstreetmap.josm.data.osm import Node, Way
from javax.swing import (
    JPanel, JRadioButton, ButtonGroup, BoxLayout, Box, UIManager,
    JOptionPane, BorderFactory
)
from java.awt import Font, Component
from javax.swing.border import TitledBorder

# ----------------------------
# Utilitários
# ----------------------------

def show_message(text, tipo="info"):
    icons = {
        "erro": "OptionPane.errorIcon",
        "aviso": "OptionPane.warningIcon",
        "info": "OptionPane.informationIcon"
    }
    Notification(text).setIcon(UIManager.getIcon(icons.get(tipo, "info"))).show()

def get_selected_ways():
    ds = MainApplication.getLayerManager().getEditDataSet()
    if not ds:
        show_message(u"Nenhuma camada de edição ativa.", "erro")
        return None, []
    selected_ways = [o for o in ds.getSelected() if isinstance(o, Way)]
    if not selected_ways:
        show_message(u"Nenhuma linha selecionada.", "aviso")
        return ds, []
    return ds, selected_ways

def count_nodes_by_way(selected_ways):
    node_count = {}
    for way in selected_ways:
        for node in way.getNodes():
            node_count.setdefault(node, set()).add(way)
    return node_count

# ----------------------------
# Seleção de nós
# ----------------------------

def select_nodes_not_shared(entresel):
    ds, selected_ways = get_selected_ways()
    if not selected_ways:
        return

    node_count = count_nodes_by_way(selected_ways)

    if entresel and len(selected_ways) < 2:
        show_message(u"Selecione ao menos dois objetos.", "aviso")
        return

    if entresel:
        nodes = [n for n, ways in node_count.items() if len(ways) == 1]
    else:
        nodes = [n for w in selected_ways for n in w.getNodes() if len(n.getReferrers()) == 1]

    if not nodes:
        show_message(u"Nenhum nó não compartilhado encontrado.", "aviso")
        return

    ds.setSelected(nodes)
    show_message(u"%d nós não compartilhados selecionados!" % len(nodes))

def find_shared_nodes(entresel):
    ds, selected_ways = get_selected_ways()
    if not selected_ways:
        return

    node_count = count_nodes_by_way(selected_ways)

    if entresel:
        nodes = [n for n, ways in node_count.items() if len(ways) > 1]
    else:
        nodes = [n for w in selected_ways for n in w.getNodes() if len(n.getReferrers()) > 1]

    if not nodes:
        show_message(u"Nenhum nó compartilhado encontrado.", "aviso")
        return

    ds.setSelected(nodes)
    show_message(u"%d nós compartilhados selecionados!" % len(nodes))

# ----------------------------
# Interface principal
# ----------------------------

def main():
    ds, selected_ways = get_selected_ways() 
    if not selected_ways:
        return

    main_panel = JPanel()
    main_panel.setLayout(BoxLayout(main_panel, BoxLayout.Y_AXIS))
    main_panel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 5))

    # --- Tipo ---
    panel_tipo = JPanel()
    panel_tipo.setLayout(BoxLayout(panel_tipo, BoxLayout.Y_AXIS))
    panel_tipo.setBorder(BorderFactory.createTitledBorder(
        BorderFactory.createEtchedBorder(),
        u"Tipo",
        TitledBorder.LEFT,
        TitledBorder.TOP,
        Font("Dialog", Font.BOLD, 12)
    ))

    rb_shared = JRadioButton(u"Nós compartilhados", True)
    rb_shared.setAlignmentX(Component.LEFT_ALIGNMENT)

    rb_not_shared = JRadioButton(u"Nós não compartilhados")
    rb_not_shared.setAlignmentX(Component.LEFT_ALIGNMENT)

    group_tipo = ButtonGroup()
    group_tipo.add(rb_shared)
    group_tipo.add(rb_not_shared)

    panel_tipo.add(rb_shared)
    panel_tipo.add(rb_not_shared)
    main_panel.add(panel_tipo)
    main_panel.add(Box.createVerticalStrut(15))

    # --- Modo ---
    panel_modo = JPanel()
    panel_modo.setLayout(BoxLayout(panel_modo, BoxLayout.Y_AXIS))
    panel_modo.setBorder(BorderFactory.createTitledBorder(
        BorderFactory.createEtchedBorder(),
        u"Modo",
        TitledBorder.LEFT,
        TitledBorder.TOP,
        Font("Dialog", Font.BOLD, 12)
    ))

    opt_entre = JRadioButton(u"Entre selecionados", True)
    opt_entre.setAlignmentX(Component.LEFT_ALIGNMENT)

    opt_apenas = JRadioButton(u"Apenas selecionado")
    opt_apenas.setAlignmentX(Component.LEFT_ALIGNMENT)

    group_modo = ButtonGroup()
    group_modo.add(opt_entre)
    group_modo.add(opt_apenas)

    panel_modo.add(opt_entre)
    panel_modo.add(opt_apenas)
    main_panel.add(panel_modo)

    # --- Diálogo ---
    result = JOptionPane.showConfirmDialog(
        None,
        main_panel,
        u"Selecionar nós",
        JOptionPane.OK_CANCEL_OPTION,
        JOptionPane.PLAIN_MESSAGE
    )
    if result != JOptionPane.OK_OPTION:
        return

    entre = opt_entre.isSelected()
    if rb_shared.isSelected():
        find_shared_nodes(entre)
    else:
        select_nodes_not_shared(entre)

main()