Sempre uso este script em conjunto com o plugin Gridify.
A combinação permite remover blocos intermediários com apenas um clique, ideal para fazendas solares ou condomínios
onde as construções seguem padrões repetitivos.
Como funciona?
Necessário um grupo de polígonos selecionados
Para o caso em que os espaços têm a mesma largura dos polígonos, selecione;
Remover blocos alternados
Para o caso em que os espaços têm o dobro da largura dos polígonos, selecione;
Remover dois a cada três blocos
Demonstração
Imagem.gif, clique para visualizar
Código
fromorg.openstreetmap.josm.guiimportMainApplication,Notificationfromorg.openstreetmap.josm.data.osmimportDataSet,Way,Nodefromorg.openstreetmap.josm.commandimportDeleteCommand,SequenceCommandfromorg.openstreetmap.josm.data.UndoRedoHandlerimportgetInstancefromjavax.swingimportJOptionPane,JPanel,JLabel,JRadioButton,ButtonGroup,BoxLayout,Box,UIManagerdefdelete_blocks_and_disconnected_nodes():layer=MainApplication.getLayerManager().getActiveLayer()ifnotlayerornothasattr(layer,"data")ornotisinstance(layer.data,DataSet):Notification("Nenhuma camada de dados ativa encontrada!")\
.setIcon(UIManager.getIcon("OptionPane.errorIcon"))\
.show()returndataset=layer.dataselected=dataset.getSelectedWays()ways=[wforwinselectedifw.isClosed()andw.isUsable()]ifnotways:Notification(u"Selecione ao menos um polígono fechado.")\
.setIcon(UIManager.getIcon("OptionPane.warningIcon"))\
.show()returnways.sort(key=lambdaway:way.getNodes()[0].getCoor().xifway.getNodes()elsefloat('inf'))node_to_blocks={}forwayinways:fornodeinway.getNodes():node_to_blocks.setdefault(node,[]).append(way)processed_blocks=set()connected_sequences=[]forwayinways:ifwayinprocessed_blocks:continuesequence=[]to_process=[way]whileto_process:current=to_process.pop()ifcurrentinprocessed_blocks:continuesequence.append(current)processed_blocks.add(current)fornodeincurrent.getNodes():forconnected_wayinnode_to_blocks.get(node,[]):ifconnected_waynotinprocessed_blocks:to_process.append(connected_way)iflen(sequence)>2:connected_sequences.append(sequence)# Criar painel customizadopanel=JPanel()panel.setLayout(BoxLayout(panel,BoxLayout.Y_AXIS))info=JLabel(u"<html><b>Escolha o método de remoção:</b><br>""<span style=\"color:#FF0000\">"u"Bug quando 90°. Girar para resolver.</span></html>")info.setAlignmentX(0.0)panel.add(info)panel.add(Box.createVerticalStrut(12))# espaçorb1=JRadioButton(u"Remover dois a cada três blocos")rb1.setSelected(True)rb1.setAlignmentX(0.0)rb2=JRadioButton("Remover blocos alternados")rb2.setAlignmentX(0.0)group=ButtonGroup()group.add(rb1)group.add(rb2)panel.add(rb1)panel.add(rb2)result=JOptionPane.showConfirmDialog(None,panel,u"Seleção de método",JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE)ifresult==JOptionPane.OK_OPTION:ifrb1.isSelected():choice=0else:choice=1else:returnto_delete_blocks=[]ifchoice==0:# Opcao 1forsequenceinconnected_sequences:fori,wayinenumerate(sequence):if(i%3)in[1,2]:to_delete_blocks.append(way)elifchoice==1:# Opcao 2forsequenceinconnected_sequences:foriinrange(1,len(sequence)-1,2):to_delete_blocks.append(sequence[i])all_commands=[]forwayinto_delete_blocks:all_commands.append(DeleteCommand(dataset,way))ifall_commands:sequence_blocks_cmd=SequenceCommand("Remover blocos selecionados",all_commands)getInstance().add(sequence_blocks_cmd)else:sequence_blocks_cmd=Noneto_delete_nodes=[nodefornodeindataset.getNodes()ifnotnode.getReferrers()andnotnode.isDeleted()andnode.getId()<=0]node_commands=[]fornodeinto_delete_nodes:try:node_commands.append(DeleteCommand(dataset,node))except:passifnode_commands:sequence_nodes_cmd=SequenceCommand(u"Remover nós desconectados",node_commands)getInstance().add(sequence_nodes_cmd)total_blocks=len(to_delete_blocks)total_nodes=len(to_delete_nodes)Notification(u"Removidos {} blocos e {} nós desconectados.".format(total_blocks,total_nodes))\
.setIcon(UIManager.getIcon("OptionPane.informationIcon"))\
.show()# Executa a funcaodelete_blocks_and_disconnected_nodes()