User:DressyPear4/Centroide
From OpenStreetMap Wiki
Jump to navigation
Jump to search
Criar centroide
Criar um ponto central em cada geometria pode ser útil quando quiser separar poi ou endereço de edificações
Como funciona?
- Selecione um ou mais polígonos
- Será criado um ponto no centro de cada geometria
Demonstração

Código
Python
Última atualização: 2026-03-11
from org.openstreetmap.josm.gui import MainApplication, Notification
from org.openstreetmap.josm.data.osm import Node, Way
from org.openstreetmap.josm.data.coor import LatLon, EastNorth
from org.openstreetmap.josm.data.projection import ProjectionRegistry
from org.openstreetmap.josm.command import AddCommand, SequenceCommand
from org.openstreetmap.josm.data.UndoRedoHandler import getInstance
from javax.swing import UIManager
def centroide_area(way, proj):
coords = [proj.latlon2eastNorth(n.getCoor()) for n in way.getNodes()]
if coords[0] != coords[-1]:
coords.append(coords[0])
sum_east = sum(coord.east() for coord in coords[:-1])
sum_north = sum(coord.north() for coord in coords[:-1])
avg_east = sum_east / len(coords[:-1])
avg_north = sum_north / len(coords[:-1])
return proj.eastNorth2latlon(EastNorth(avg_east, avg_north))
def main():
dataset = MainApplication.getLayerManager().getEditDataSet()
if not dataset:
Notification(u"Nenhuma camada de edição ativa!")\
.setIcon(UIManager.getIcon("OptionPane.errorIcon"))\
.show()
return
ways = list(dataset.getSelectedWays())
if not ways:
Notification(u"Selecione pelo menos um polígono fechado.")\
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))\
.show()
return
proj = ProjectionRegistry.getProjection()
comandos = []
for way in ways:
nodes = way.getNodes()
if len(nodes) < 3 or nodes[0] != nodes[-1]:
continue
centro = centroide_area(way, proj)
novo_node = Node(centro)
# Copiar tags do polígono para o ponto
for key in way.getKeys().keySet():
novo_node.put(key, way.get(key))
comandos.append(AddCommand(dataset, novo_node))
if comandos:
getInstance().add(SequenceCommand("Criar centroides com tags", comandos))
Notification("Centroides foram criados com sucesso.")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()
else:
Notification(u"Nenhum polígono válido selecionado.")\
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))\
.show()
main()
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 Node = Java.type("org.openstreetmap.josm.data.osm.Node");
const Way = Java.type("org.openstreetmap.josm.data.osm.Way");
const AddCommand = Java.type("org.openstreetmap.josm.command.AddCommand");
const SequenceCommand = Java.type("org.openstreetmap.josm.command.SequenceCommand");
const ProjectionRegistry = Java.type("org.openstreetmap.josm.data.projection.ProjectionRegistry");
const EastNorth = Java.type("org.openstreetmap.josm.data.coor.EastNorth");
const UndoRedoHandler = Java.type("org.openstreetmap.josm.data.UndoRedoHandler");
const UIManager = Java.type("javax.swing.UIManager");
const ArrayList = Java.type("java.util.ArrayList");
function calcularCentroide(way, proj) {
let nodes = way.getNodes();
let numNodes = nodes.size();
// Ignora o último nó se for igual ao primeiro (fechamento)
let count = way.isClosed() ? numNodes - 1 : numNodes;
let sumEast = 0;
let sumNorth = 0;
for (let i = 0; i < count; i++) {
let en = proj.latlon2eastNorth(nodes.get(i).getCoor());
sumEast += en.east();
sumNorth += en.north();
}
let avgEast = sumEast / count;
let avgNorth = sumNorth / count;
return proj.eastNorth2latlon(new EastNorth(avgEast, avgNorth));
}
function criarCentroidesComTags() {
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 dataset = layer.data;
const selecionados = dataset.getSelectedWays();
if (selecionados.isEmpty()) {
new Notification("Selecione pelo menos um polígono fechado.")
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))
.show();
return;
}
const proj = ProjectionRegistry.getProjection();
const comandos = new ArrayList();
let countCriadors = 0;
let it = selecionados.iterator();
while (it.hasNext()) {
let way = it.next();
// Validação: precisa ter pelo menos 3 nós e ser fechado
if (way.getNodesCount() < 3 || !way.isClosed()) {
continue;
}
let centroLatLon = calcularCentroide(way, proj);
let novoNode = new Node(centroLatLon);
// Copiar tags do polígono para o ponto
novoNode.setKeys(way.getKeys());
comandos.add(new AddCommand(dataset, novoNode));
countCriadors++;
}
if (!comandos.isEmpty()) {
UndoRedoHandler.getInstance().add(new SequenceCommand("Criar centroides com tags", comandos));
new Notification("Centroides foram criados com sucesso.")
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))
.show();
} else {
new Notification("Nenhum polígono válido selecionado.")
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))
.show();
}
}
criarCentroidesComTags();