Para divisão de um polígono/linha em distâncias exatamente iguais (75%,50%,25%...)
Como funciona?
Selecione uma linha ou polígono
Escolha a quantidade desejada
Novos nós serão adicionados
Selecione uma geometria e dois nós para adicionar os novos nós apenas entre esse seguimento
Demonstração
Imagem.gif, clique para visualizar.
Código
fromorg.openstreetmap.josm.guiimportMainApplication,Notificationfromorg.openstreetmap.josm.data.osmimportNode,Wayfromorg.openstreetmap.josm.commandimportSequenceCommand,AddCommand,ChangeNodesCommandfromorg.openstreetmap.josm.data.projectionimportProjectionRegistryfromorg.openstreetmap.josm.data.coorimportEastNorthfromorg.openstreetmap.josm.dataimportUndoRedoHandlerfromjavax.swingimportJOptionPane,JPanel,UIManager,JLabel,JSpinner,SpinnerNumberModelfromjava.awtimportGridLayoutdefmain():layer=MainApplication.getLayerManager().getEditLayer()iflayerisNoneornothasattr(layer,"data"):Notification(u"Nenhuma camada de edição ativa")\
.setIcon(UIManager.getIcon("OptionPane.errorIcon"))\
.show()returnds=layer.dataselection=ds.getSelected()selected_ways=[itemforiteminselectionifisinstance(item,Way)]selected_nodes=[itemforiteminselectionifisinstance(item,Node)]iflen(selected_ways)!=1:Notification(u"Selecione exatamente uma linha (e opcionalmente dois nós dela)")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()returniflen(selected_nodes)notin(0,2):Notification(u"Selecione exatamente dois nós do caminho como referência")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()returnway=selected_ways[0]way_nodes=list(way.getNodes())is_closed=way.isClosed()ifis_closedandlen(way_nodes)>1andway_nodes[0]==way_nodes[-1]:way_nodes=way_nodes[:-1]modo_trecho=Falseiflen(selected_nodes)==2:ifall(ninway_nodesforninselected_nodes):modo_trecho=Trueelse:Notification(u"Os dois nós selecionados devem pertencer a linha")\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()returntotal_segmentos=len(way_nodes)ifis_closedelselen(way_nodes)-1panel=JPanel(GridLayout(0,1))panel.add(JLabel("<html>Total de segmentos da linha: {}<br>"u"Informe o número de nós a serem<br>adicionados entre cada par</html>".format(total_segmentos)))spinner=JSpinner(SpinnerNumberModel(1,1,100,1))panel.add(spinner)result=JOptionPane.showConfirmDialog(None,panel,u"Adicionar nós",JOptionPane.OK_CANCEL_OPTION)ifresult!=JOptionPane.OK_OPTION:returnnum_nodes=spinner.getValue()projection=ProjectionRegistry.getProjection()commands=[]updated_nodes=[]nos_adicionados=0ifmodo_trecho:n1,n2=selected_nodesi1=way_nodes.index(n1)i2=way_nodes.index(n2)ifi1==i2:Notification(u"Os nós selecionados não formam um trecho válido.")\
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))\
.show()returntotal=len(way_nodes)caminho1,caminho2=[],[]idx=i1whileidx!=i2:caminho1.append(idx)idx=(idx+1)%totalcaminho1_len=len(caminho1)idx=i2whileidx!=i1:caminho2.append(idx)idx=(idx+1)%totalcaminho2_len=len(caminho2)indices_validos=caminho1if(is_closedandcaminho1_len<=caminho2_len)elsecaminho2ifnotis_closed:ifi1>i2:i1,i2=i2,i1indices_validos=list(range(i1,i2))foriinrange(len(way_nodes)):updated_nodes.append(way_nodes[i])ifiinindices_validos:node_start=way_nodes[i]node_end=way_nodes[(i+1)%len(way_nodes)]en_start=node_start.getEastNorth()en_end=node_end.getEastNorth()dx=(en_end.east()-en_start.east())/(num_nodes+1)dy=(en_end.north()-en_start.north())/(num_nodes+1)forjinrange(1,num_nodes+1):x=en_start.east()+dx*jy=en_start.north()+dy*jlatlon=projection.eastNorth2latlon(EastNorth(x,y))new_node=Node(latlon)new_node.setModified(True)commands.append(AddCommand(ds,new_node))updated_nodes.append(new_node)nos_adicionados+=1else:foriinrange(len(way_nodes)-(0ifis_closedelse1)):node_start=way_nodes[i]updated_nodes.append(node_start)node_end=way_nodes[(i+1)%len(way_nodes)]ifis_closedelseway_nodes[i+1]en_start=node_start.getEastNorth()en_end=node_end.getEastNorth()dx=(en_end.east()-en_start.east())/(num_nodes+1)dy=(en_end.north()-en_start.north())/(num_nodes+1)forjinrange(1,num_nodes+1):x=en_start.east()+dx*jy=en_start.north()+dy*jlatlon=projection.eastNorth2latlon(EastNorth(x,y))new_node=Node(latlon)new_node.setModified(True)commands.append(AddCommand(ds,new_node))updated_nodes.append(new_node)nos_adicionados+=1ifnotis_closed:updated_nodes.append(way_nodes[-1])ifis_closedandupdated_nodes[0]!=updated_nodes[-1]:updated_nodes.append(updated_nodes[0])commands.append(ChangeNodesCommand(way,updated_nodes))UndoRedoHandler.getInstance().add(SequenceCommand("Inserir nos",commands))total_final=len(updated_nodes)-(1ifis_closedelse0)Notification(u"<html><span style='white-space:nowrap;'>Nós adicionados: {}\nTotal de nós agora: {}</span></html>".format(nos_adicionados,total_final)).setIcon(UIManager.getIcon("OptionPane.informationIcon")).show()main()