User:DressyPear4/Estrela
From OpenStreetMap Wiki
Jump to navigation
Jump to search
Criar uma estrela
Não é tão comum mas as vezes encontradas em praças como caminho de pedestres ou espelho de água de um chafariz
Como funciona?
- Partindo do centro até uma das pontas desenhe uma linha com apenas dois nós
- Escolha o número de pontas
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 Way, Node
from org.openstreetmap.josm.data.coor import LatLon
from org.openstreetmap.josm.command import AddCommand, DeleteCommand, SequenceCommand
from org.openstreetmap.josm.data.UndoRedoHandler import getInstance
from javax.swing import JOptionPane, JPanel, JLabel, JSpinner, SpinnerNumberModel, UIManager
from java.awt import GridBagLayout, GridBagConstraints, Insets, Dimension
from java.util import LinkedList
import math
def criar_estrela_nodes(cx, cy, raio_externo, num_pontas, angulo_rotacao):
angulo_base = 2 * math.pi / (num_pontas * 2)
coords = []
for i in range(num_pontas * 2):
angulo = i * angulo_base
raio = raio_externo if i % 2 == 0 else raio_externo / 2.5
dx = raio * math.cos(angulo)
dy = raio * math.sin(angulo)
# Aplica rotacao
dx_rot = dx * math.cos(angulo_rotacao) - dy * math.sin(angulo_rotacao)
dy_rot = dx * math.sin(angulo_rotacao) + dy * math.cos(angulo_rotacao)
dlat = dy_rot / 111320.0
dlon = dx_rot / (111320.0 * math.cos(math.radians(cx)))
lat = cx + dlat
lon = cy + dlon
coords.append((lat, lon))
return coords
def executar():
layer = MainApplication.getLayerManager().getEditLayer()
if layer is None:
Notification(u"Nenhuma camada de edição ativa.")\
.setIcon(UIManager.getIcon("OptionPane.errorIcon"))\
.show()
return
dataset = layer.data
selecionados = dataset.getSelected()
ways = [x for x in selecionados if isinstance(x, Way)]
if len(ways) != 1:
Notification(u"Selecione uma linha com dois nós.")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()
return
linha = ways[0]
if len(linha.getNodes()) != 2:
Notification(u"A linha deve conter exatamente dois nós.")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()
return
centro = linha.getNodes()[0]
ponta = linha.getNodes()[1]
cx = centro.getCoor().lat()
cy = centro.getCoor().lon()
px = ponta.getCoor().lat()
py = ponta.getCoor().lon()
dx = (py - cy) * 111320 * math.cos(math.radians((cx + px) / 2))
dy = (px - cx) * 111320
raio = math.hypot(dx, dy)
# Calcular angulo de orientacao da linha
delta_x = (py - cy) * math.cos(math.radians((cx + px) / 2))
delta_y = (px - cx)
angulo_rot = math.atan2(delta_y, delta_x)
# Caixa de dialogo
panel = JPanel()
panel.setLayout(GridBagLayout())
c = GridBagConstraints()
c.insets = Insets(5, 5, 5, 5)
c.gridx = 0
c.gridy = 0
c.anchor = GridBagConstraints.EAST
panel.add(JLabel(u"Número de pontas:"), c)
c.gridx = 1
spinner_model = SpinnerNumberModel(5, 3, 25, 1)
spinner = JSpinner(spinner_model)
spinner.setPreferredSize(Dimension(80, 25))
panel.add(spinner, c)
resultado = JOptionPane.showConfirmDialog(None, panel, "Criar Estrela", JOptionPane.OK_CANCEL_OPTION)
if resultado != JOptionPane.OK_OPTION:
return
num_pontas = spinner.getValue()
coords = criar_estrela_nodes(cx, cy, raio, num_pontas, angulo_rot)
comandos = []
novos_nos = []
for lat, lon in coords:
n = Node(LatLon(lat, lon))
comandos.append(AddCommand(dataset, n))
novos_nos.append(n)
# Fechar a estrela com o primeiro no
novos_nos.append(novos_nos[0])
estrela = Way()
estrela.setNodes(LinkedList(novos_nos))
comandos.append(AddCommand(dataset, estrela))
# Remover a linha original e seus dois nos
comandos.append(DeleteCommand(dataset, linha))
comandos.append(DeleteCommand(dataset, linha.getNodes()))
getInstance().add(SequenceCommand("Criar estrela", comandos))
Notification("Estrela criada com sucesso.")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()
executar()
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 DeleteCommand = Java.type("org.openstreetmap.josm.command.DeleteCommand");
const SequenceCommand = Java.type("org.openstreetmap.josm.command.SequenceCommand");
const LatLon = Java.type("org.openstreetmap.josm.data.coor.LatLon");
const UndoRedoHandler = Java.type("org.openstreetmap.josm.data.UndoRedoHandler");
const UIManager = Java.type("javax.swing.UIManager");
const JOptionPane = Java.type("javax.swing.JOptionPane");
const JPanel = Java.type("javax.swing.JPanel");
const JLabel = Java.type("javax.swing.JLabel");
const JSpinner = Java.type("javax.swing.JSpinner");
const SpinnerNumberModel = Java.type("javax.swing.SpinnerNumberModel");
const GridBagLayout = Java.type("java.awt.GridBagLayout");
const GridBagConstraints = Java.type("java.awt.GridBagConstraints");
const Insets = Java.type("java.awt.Insets");
const Dimension = Java.type("java.awt.Dimension");
const ArrayList = Java.type("java.util.ArrayList");
function criarEstrela() {
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.size() !== 1) {
new Notification("Selecione uma linha com dois nós.")
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))
.show();
return;
}
const linha = selecionados.iterator().next();
const linhaNos = linha.getNodes();
if (linhaNos.size() !== 2) {
new Notification("A linha deve conter exatamente dois nós.")
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))
.show();
return;
}
const centro = linhaNos.get(0);
const ponta = linhaNos.get(1);
const cx = centro.getCoor().lat();
const cy = centro.getCoor().lon();
const px = ponta.getCoor().lat();
const py = ponta.getCoor().lon();
// Cálculos Geodésicos (Métrica simples)
const latRad = (cx + px) / 2 * Math.PI / 180.0;
const dx = (py - cy) * 111320 * Math.cos(latRad);
const dy = (px - cx) * 111320;
const raio = Math.sqrt(dx * dx + dy * dy);
// Calcular ângulo de orientação da linha
const deltaX = (py - cy) * Math.cos(latRad);
const deltaY = (px - cx);
const anguloRot = Math.atan2(deltaY, deltaX);
// Interface Gráfica
const panel = new JPanel(new GridBagLayout());
const gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0; gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
panel.add(new JLabel("Número de pontas:"), gbc);
gbc.gridx = 1;
const spinnerModel = new SpinnerNumberModel(5, 3, 25, 1);
const spinner = new JSpinner(spinnerModel);
spinner.setPreferredSize(new Dimension(80, 25));
panel.add(spinner, gbc);
const resultado = JOptionPane.showConfirmDialog(
MainApplication.getMainFrame(),
panel,
"Criar Estrela",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE
);
if (resultado !== JOptionPane.OK_OPTION) return;
const numPontas = spinner.getValue();
const anguloBase = (2 * Math.PI) / (numPontas * 2);
const comandos = new ArrayList();
const novosNos = new ArrayList();
for (let i = 0; i < numPontas * 2; i++) {
let angulo = i * anguloBase;
let r = (i % 2 === 0) ? raio : raio / 2.5;
let dxLocal = r * Math.cos(angulo);
let dyLocal = r * Math.sin(angulo);
// Aplica rotação conforme a orientação da linha original
let dxRot = dxLocal * Math.cos(anguloRot) - dyLocal * Math.sin(anguloRot);
let dyRot = dxLocal * Math.sin(anguloRot) + dyLocal * Math.cos(anguloRot);
let dlat = dyRot / 111320.0;
let dlon = dxRot / (111320.0 * Math.cos(cx * Math.PI / 180.0));
let node = new Node(new LatLon(cx + dlat, cy + dlon));
comandos.add(new AddCommand(dataset, node));
novosNos.add(node);
}
// Fechar a estrela
novosNos.add(novosNos.get(0));
const estrela = new Way();
estrela.setNodes(novosNos);
comandos.add(new AddCommand(dataset, estrela));
// Remover a linha guia original e seus nós
comandos.add(new DeleteCommand(dataset, linha));
let itNos = linhaNos.iterator();
while (itNos.hasNext()) {
comandos.add(new DeleteCommand(dataset, itNos.next()));
}
UndoRedoHandler.getInstance().add(new SequenceCommand("Criar estrela", comandos));
new Notification("Estrela criada com sucesso.")
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))
.show();
}
criarEstrela();