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
-
Imagem.gif, clique para visualizar.
-
Imagem.gif, clique para visualizar.
Código
Python
Última atualização: 2026-03-11
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()
JavaScript
Última atualização: 2026-03-11
"use strict";
const MainApplication = Java.type("org.openstreetmap.josm.gui.MainApplication");
const Notification = Java.type("org.openstreetmap.josm.gui.Notification");
const Way = Java.type("org.openstreetmap.josm.data.osm.Way");
const AddCommand = Java.type("org.openstreetmap.josm.command.AddCommand");
const ChangeCommand = Java.type("org.openstreetmap.josm.command.ChangeCommand");
const SequenceCommand = Java.type("org.openstreetmap.josm.command.SequenceCommand");
const UndoRedoHandler = Java.type("org.openstreetmap.josm.data.UndoRedoHandler");
const UIManager = Java.type("javax.swing.UIManager");
const ArrayList = Java.type("java.util.ArrayList");
function dividirPoligonosPreservandoUmId() {
const layer = MainApplication.getLayerManager().getEditLayer();
if (!layer || !layer.data) {
new Notification("Nenhuma camada de edição ativa.")
.setIcon(UIManager.getIcon("OptionPane.errorIcon")).show();
return;
}
const ds = layer.data;
const selectedNodes = ds.getSelectedNodes();
const selectedWays = ds.getSelectedWays();
if (selectedNodes.isEmpty() || selectedWays.isEmpty()) {
new Notification("Necessário 4 nós selecionados em cada polígono.")
.setIcon(UIManager.getIcon("OptionPane.informationIcon")).show();
return;
}
const cmds = new ArrayList();
let count = 0;
let itWays = selectedWays.iterator();
while (itWays.hasNext()) {
let way = itWays.next();
if (!way.isClosed()) continue;
let nodes = way.getNodes();
let nodesList = [];
for (let i = 0; i < nodes.size() - 1; i++) {
nodesList.push(nodes.get(i));
}
let splitIndices = [];
for (let i = 0; i < nodesList.length; i++) {
if (selectedNodes.contains(nodesList[i])) {
splitIndices.push(i);
}
}
// Permite apenas 2 ou 4 nós selecionados
if (splitIndices.length !== 2 && splitIndices.length !== 4) {
continue;
}
let segmentos = [];
for (let i = 0; i < splitIndices.length; i++) {
let idxInicio = splitIndices[i];
let idxFim = splitIndices[(i + 1) % splitIndices.length];
let segmento = [];
if (idxFim <= idxInicio) {
segmento = nodesList.slice(idxInicio).concat(nodesList.slice(0, idxFim + 1));
} else {
segmento = nodesList.slice(idxInicio, idxFim + 1);
}
if (segmento.length >= 3) {
segmento.push(segmento[0]);
segmentos.push(segmento);
}
}
if (segmentos.length < 2) continue;
// Primeiro segmento herda o ID
let wayPrincipal = new Way(way);
let listPrincipal = new ArrayList();
segmentos[0].forEach(n => listPrincipal.add(n));
wayPrincipal.setNodes(listPrincipal);
cmds.add(new ChangeCommand(way, wayPrincipal));
// Demais segmentos viram novas ways
for (let i = 1; i < segmentos.length; i++) {
let wayNova2 = new Way();
let listNova = new ArrayList();
segmentos[i].forEach(n => listNova.add(n));
wayNova2.setNodes(listNova);
wayNova2.setKeys(way.getKeys());
cmds.add(new AddCommand(ds, wayNova2));
}
count++;
}
if (!cmds.isEmpty()) {
UndoRedoHandler.getInstance().add(new SequenceCommand("Dividir polígonos (ID original em segmento principal)", cmds));
new Notification("Divididos " + count + " polígono(s).")
.setIcon(UIManager.getIcon("OptionPane.informationIcon")).show();
} else {
new Notification("O polígono deve ter 2 nós intermediários selecionados.")
.setIcon(UIManager.getIcon("OptionPane.warningIcon")).show();
}
}
dividirPoligonosPreservandoUmId();