User:DressyPear4/TextoCaixaAlta

From OpenStreetMap Wiki
Jump to navigation Jump to search

Correção de nomes em formato de título

Um script para correção de nomes em lote, funciona para linhas, nós e polígonos.

Tags alvo = name, alt_name, old_name, official_name, loc_name, reg_name.

Palavras podem ser ajustadas no código, Dr.=Doutor, Prof.=Professor, etc... Criado para uso especifico no Brasil, para outro país o código deve ser adaptado

Como funciona?

  • Selecione elementos do mapa
  • Execute o código
  • Confira as correções na lista

Demonstração

Imagem.gif, clique para visualizar.

Código

from org.openstreetmap.josm.data.osm import OsmPrimitive
from org.openstreetmap.josm.gui import MainApplication, Notification
from org.openstreetmap.josm.command import ChangePropertyCommand, SequenceCommand
from org.openstreetmap.josm.data.UndoRedoHandler import getInstance
from javax.swing import UIManager, JOptionPane
import re

def title_case(text):
    ignore_words = {"da", "das", "de", "do", "dos"}
    siglas_conhecidas = {
        "br", "sp", "rj", "mg", "rs", "es", "df", "go", "sc", "pr",
        "to", "pi", "pa", "ce", "pe", "ap", "am", "ro", "rr", "ac",
        "ma", "pb", "rn", "ba", "se", "al", "mt", "ms", "to",
        "onu", "ibge", "dnit", "der",
        "lt", "ld"
    }

    correcoes_conhecidas = {
        "av.": "Avenida",
        "r.": "Rua",
        "tv.": "Travessa",
        "rod.": "Rodovia",
        "est.": "Estrada",
        "prof.": "Professor",
        "dr.": "Doutor"
    }

    # Expansão de abreviações com números/letras depois do ponto
    def expandir_abreviacoes(txt):
        for abrev, expandido in correcoes_conhecidas.items():
            padrao = r"\b" + re.escape(abrev) + r"\s*([a-z0-9]+)"
            txt = re.sub(padrao, expandido + r" \1", txt, flags=re.IGNORECASE)
        return txt

    text = expandir_abreviacoes(text)

    def is_sigla(word):
        limpo = word.lower().replace("-", "").replace("_", "")
        return limpo in siglas_conhecidas or re.match(r"^[a-z]{2,}[-\d]+$", limpo)

    words = text.split()

    def tratar(word, is_first):
        original = word.strip()
        lower = original.lower()

        # Sigla conhecida ou padrão tipo BR-101 → manter em caixa alta
        if is_sigla(original):
            return original.upper()

        # Corrigir palavra individual isolada (sem número/letra depois)
        if lower in correcoes_conhecidas:
            return correcoes_conhecidas[lower]

        # Palavra ignorada (de, da, etc.) minúscula, exceto se for a primeira
        if lower in ignore_words and not is_first:
            return lower

        # Palavras com hífen (ex: joao-pedro)
        if "-" in original:
            return "-".join(tratar(p, False) for p in original.split("-"))

        # Capitalizar normalmente
        return lower.capitalize()

    return " ".join(tratar(w, i == 0) for i, w in enumerate(words))

def adjust_name_tags():
    layer = MainApplication.getLayerManager().getEditLayer()

    if layer is None or not hasattr(layer, "data"):
        Notification(u"Nenhuma camada de edição ativa encontrada.")\
            .setIcon(UIManager.getIcon("OptionPane.errorIcon"))\
            .show()
        return

    dataset = layer.data
    selection = list(dataset.getSelectedNodes()) + \
                list(dataset.getSelectedWays()) + \
                list(dataset.getSelectedRelations())

    if not selection:
        Notification("Nenhum objeto com nome selecionado.")\
            .setIcon(UIManager.getIcon("OptionPane.warningIcon"))\
            .show()
        return

    tags_alvo = {"name", "alt_name", "old_name", "official_name", "loc_name", "reg_name"}

    commands = []
    alteracoes_texto = []

    for obj in selection:
        keys = obj.getKeys()
        for key, value in keys.items():
            if (key in tags_alvo or key.startswith("name:")) and value:
                ajustado = title_case(value)
                if ajustado != value:
                    alteracoes_texto.append(u"%s%s" % (value, ajustado))
                    commands.append(ChangePropertyCommand(obj, key, ajustado))

    if commands:
        getInstance().add(SequenceCommand("Ajustar nomes em formato titulo", commands))
        resumo = "\n".join(alteracoes_texto)
        if len(resumo) > 250:
            resumo = resumo[:250] + "\n...\n(mais alterações ocultadas)"
        JOptionPane.showMessageDialog(
            None,
            u"Alterações realizadas:\n\n" + resumo,
            u"Nomes ajustados com sucesso",
            JOptionPane.PLAIN_MESSAGE
        )
    else:
        Notification(u"Nenhuma mudança necessária.")\
            .setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
            .show()

# Executar
adjust_name_tags()