Autres langues:
- English
- français
- Nederlands
Greffon -> Scripting -> Python
Objectif
D'autres exemples en Python :
Table des Matières
- Objectif
- Convertir un chemin qui se raccorde à un carrefour giratoire non …
- Convertir un chemin qui se raccorde à un carrefour giratoire …
- Exporter une collection d'itinéraires vers un fichier GPX Garmin
- Télécharger les éléments parents manquants pour l'élément sélectionné
- Télécharger les membres absents de la relation
- Valider une relation de route rcn
- Suppression des chemins supplémentaires résultant d'opérations Potlatch
- Voir également
Convertir un chemin qui se raccorde à un carrefour giratoire non fractionné en une bifurcation.
Convertir un chemin qui se connecte à un carrefour giratoire en une fourche composée de 2 chemins à sens unique. En divisant le chemin sur son dernier nœud et en l'attachant aux 2 nœuds adjacents au nœud commun du chemin du carrefour giratoire. Cette version ne fonctionne que sur les carrefours giratoires non fractionnés. Voir l'exemple suivant pour une version mise à jour.
from javax.swing import JOptionPane from org.openstreetmap.josm.gui import MainApplication import org.openstreetmap.josm.command as Command import org.openstreetmap.josm.data.osm.Way as Way editLayer = MainApplication.getLayerManager().getEditLayer() if editLayer and editLayer.data: selected_ways = editLayer.data.getSelectedWays() print selected_ways if not(selected_ways) or len(selected_ways)>1: JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Veuillez sélectionner un chemin unique qui se raccorde à un carrefour giratoire") else: for way in selected_ways: if way.get('oneway') in ['yes', '-1']: JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ce chemin a un attribut - sens unique") else: node_before = None node_after = None common_node = None common_node_becomes_node_before=None #print dir(way) for fln in [way.firstNode(), way.lastNode()]: print 'fln', fln for parentway in fln.getParentWays(): if parentway.get("junction")=='roundabout': for n in parentway.getNodes(): if common_node: # nous avons trouvé un nœud commun entre le chemin sélectionné et # le chemin du carrefour giratoire dans l'itération précédente node_after = n # nous avons terminé ici break if n.getId() == fln.getId(): # c'est le nœud que le carrefour giratoire a en commun avec le chemin sélectionné common_node = n if not(node_before): # normalement, nous avons rencontré un nœud du carrefour giratoire # bien avant celui-ci, mais si le nœud commun est le premier nœud # d'un carrefour giratoire non divisé, nous devrons prendre le dernier # nœud du carrefour giratoire à la place node_before = parentway.getNodes()[-2] node_after = parentway.getNodes()[1] break # si ce n'est pas le cas, nous passons par la boucle une fois de plus pour mettre le prochain # nœud dans node_after continue node_before = n if common_node: # si common_node est déjà défini à ce stade, cela signifie qu'il était # le premier nœud du chemin sélectionné, # il devra donc être remplacé par node_before dans le chemin sélectionné common_node_becomes_node_before = True adjacent_node_to_split_on = way.getNodes()[1] break else: common_node_becomes_node_before = False adjacent_node_to_split_on = way.getNodes()[-1] if not(common_node) or common_node_becomes_node_before==None: JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Veuillez sélectionner un chemin qui se raccorde à un carrefour giratoire") else: print common_node.get('name') print node_before.get('name') print node_after.get('name') commandsList = [] if len(way.getNodes())>2: # diviser le dernier segment avant le carrefour giratoire si nécessaire commandsList.append(Command.SplitWayCommand.split( way, [adjacent_node_to_split_on], [])) MainApplication.undoRedo.add(Command.SequenceCommand( "Séparation du chemin sélectionné", commandsList)) commandsList = [] # Après la séparation, trouvez le segment qui relie à nouveau le carrefour giratoire for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays(): if common_node in waypartconnectedtoroundabout.getNodes(): break if len(way.getNodes())==2: if common_node == waypartconnectedtoroundabout.firstNode(): adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode() else: adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode() # Il est temps de faire quelque chose # de faire une copie du chemin modified_way = Way(waypartconnectedtoroundabout) # remplacer ses nœuds, de sorte qu'il se transforme en une fourche modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after]) # ajouter un attribut "oneway" modified_way.put('oneway', 'yes') # appliquer les modifications commandsList.append(Command.ChangeCommand( waypartconnectedtoroundabout, modified_way)) MainApplication.undoRedo.add(Command.SequenceCommand( "Ajouter un attribut oneway et créer un chemin en forme de fourche", commandsList)) commandsList = [] # séparer ce chemin là où il se divise en fourche commandsList.append(Command.SplitWayCommand.split( waypartconnectedtoroundabout, [adjacent_node_to_split_on], [])) MainApplication.undoRedo.add(Command.SequenceCommand( "Divisez la fourche en deux chemins", commandsList)) commandsList = []
Convertir un chemin qui se raccorde à un carrefour giratoire fractionné en une bifurcation
Ce script fait la même chose que le précédent, mais il fonctionne aussi sur les carrefours giratoires dont les chemins sont séparés. Il ne s'occupe pas des relations.
from javax.swing import JOptionPane from org.openstreetmap.josm.gui import MainApplication import org.openstreetmap.josm.command as Command import org.openstreetmap.josm.data.osm.Way as Way editLayer = MainApplication.getLayerManager().getEditLayer() print '==== Fresh run ====' if editLayer and editLayer.data: selected_ways = editLayer.data.getSelectedWays() print selected_ways if not(selected_ways) or len(selected_ways)>1: JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Veuillez sélectionner un chemin unique qui se connecte à un carrefour giratoire") else: for way in selected_ways: if way.get('oneway') in ['yes', '-1']: JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ce chemin est balisé par un attribut oneway") elif way.get('junction') in ['roundabout']: JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ce chemin fait partie d'un carrefour giratoire") else: node_before = None node_after = None common_node = None common_node_becomes_node_before=None roundabout_way_before = None roundabout_way_after = None for fln in [way.firstNode(), way.lastNode()]: print 'fln', fln for parentway in fln.getParentWays(): if parentway.get("junction")=='roundabout': print parentway.get('name') if parentway.isClosed(): # carrefour giratoire non fractionné for n in parentway.getNodes(): if common_node: # noeud commun trouvé entre le chemin sélectionné # et le carrefour giratoire dans l'itération précédente node_after = n print node_before.get('name') print node_after.get('name') # nous avons terminé ici break if n.getId() == fln.getId(): # c'est le nœud que le carrefour giratoire a en commun avec le chemin sélectionné common_node = n print common_node.get('name') if not(node_before): # normalement, nous avons rencontré un nœud du carrefour giratoire bien # avant celui-ci, mais si le nœud commun est le premier nœud # d'un carrefour giratoire non divisé, nous devrons prendre le dernier # nœud du carrefour giratoire à la place node_before = parentway.getNodes()[-2] node_after = parentway.getNodes()[1] print node_before.get('name') print node_after.get('name') break # si ce n'est pas le cas, nous passons par la boucle une fois de plus pour mettre le prochain # noeud dans node_after continue node_before = n else: # il s'agit d'un carrefour giratoire fractionné if parentway.firstNode().getId() == fln.getId(): node_after = parentway.getNodes()[1] roundabout_way_after = parentway print 'node after', node_after.get('name') else: node_before = parentway.getNodes()[-2] roundabout_way_before = parentway if node_before and node_after: common_node = fln break if common_node: # si common_node est déjà défini à ce stade, cela signifie que c'était # le premier noeud du chemin sélectionné, # il devra donc être remplacé par node_before dans le chemin sélectionné common_node_becomes_node_before = True break else: common_node_becomes_node_before = False if common_node.getId() == way.firstNode().getId(): adjacent_node_to_split_on = way.getNodes()[1] else: adjacent_node_to_split_on = way.getNodes()[-1] if not(common_node) or ((parentway.isClosed() and common_node_becomes_node_before==None)): JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Please select a way that connects to a roundabout") else: commandsList = [] if len(way.getNodes())>2: # séparer le dernier segment avant le carrefour giratoire si nécessaire commandsList.append(Command.SplitWayCommand.split( way, [adjacent_node_to_split_on], [])) MainApplication.undoRedo.add(Command.SequenceCommand( "Partager le chemin sélectionné", commandsList)) commandsList = [] # Après la séparation, trouvez le segment qui rejoint à nouveau le carrefour giratoire for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays(): if waypartconnectedtoroundabout.get('junction') == 'roundabout': continue if common_node in waypartconnectedtoroundabout.getNodes(): break if len(way.getNodes())==2: if common_node == waypartconnectedtoroundabout.firstNode(): adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode() else: adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode() # Il est temps de faire quelque chose # faire une copie du chemin modified_way = Way(waypartconnectedtoroundabout) # replacer ses nœuds, il devient donc une fourche modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after]) # ajouter un attribut oneway modified_way.put('oneway', 'yes') # appliquer les modifications commandsList.append(Command.ChangeCommand( waypartconnectedtoroundabout, modified_way)) MainApplication.undoRedo.add(Command.SequenceCommand( "Ajouter l'attribut oneway et créer un chemin en forme de fourche", commandsList)) commandsList = [] # partager ce chemin où il y a une fourche commandsList.append(Command.SplitWayCommand.split( waypartconnectedtoroundabout, [adjacent_node_to_split_on], [])) MainApplication.undoRedo.add(Command.SequenceCommand( "Divisez la fourche en deux chemins", commandsList)) commandsList = [] if roundabout_way_before and roundabout_way_after: origway = roundabout_way_before roundabout_way_before.addNode(node_after) commandsList.append(Command.ChangeCommand( origway, roundabout_way_before)) origway = roundabout_way_after roundabout_way_after.removeNode(common_node) commandsList.append(Command.ChangeCommand( origway,roundabout_way_after)) # middleway = Way(roundabout_way_after).setNodes( # [node_before, common_node, node_after]) # commandsList.append(Command.AddCommand(editLayer.data, middleway)) # MainApplication.undoRedo.add(Command.SequenceCommand( # "Ajouter un chemin sur le carrefour giratoire où la fourche s'attache", commandsList)) commandsList.append(Command.SplitWayCommand.split( roundabout_way_before, [node_before], [])) MainApplication.undoRedo.add(Command.SequenceCommand( "decoupe le chemin du giratoire", commandsList)) commandsList = []
Exporter une collection d'itinéraires vers un fichier GPX Garmin
Exporter une collection d'itinéraires vers un fichier GPX Garmin (pas un super exemple, car je ne pense pas que nous fassions encore des relations de collection) :
#!/bin/jython ''' RWN2Garmin.py - Convertisseur de réseaux numérotés en fichiers GPX Garmin Ce code est publié sous la licence GNU General Public License v2 ou ultérieure. La GPL v3 est disponible ici : https://www.gnu.org/licenses/gpl.html Il est livré sans aucune garantie. ''' from javax.swing import JOptionPane, JDialog from java.awt.event import ActionListener, ActionEvent from org.openstreetmap.josm import Main import org.openstreetmap.josm.command as Command import org.openstreetmap.josm.data.osm.Node as Node import org.openstreetmap.josm.data.osm.Way as Way import org.openstreetmap.josm.data.osm.TagCollection as TagCollection import org.openstreetmap.josm.data.osm.DataSet as DataSet import time f = open('C:/export.gpx', 'w') f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n') f.write('<gpx xmlns="https://www.topografix.com/GPX/1/1" creator="OSM Route Manager" version="1.1" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://wwws.topografix.com/GPX/1/1 https://wwws.topografix.com/GPX/1/1/gpx.xsd">\n') f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (https://creativecommons.org/licenses/by-sa/2.0/). -->\n') editLayer = Main.getLayerManager().getEditLayer() if editLayer and editLayer.data: selectedRelations = mv.editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Veuillez sélectionner une relation de collection") else: print for collection in selectedRelations: print 'COLLECTION:', collection for member in collection.getMembers(): print 'MEMBER:',member if member.isNode(): node = member.getNode() coords = node.getCoor() lon = coords.getX() lat = coords.getY() rwn_ref = node.get('rwn_ref') f.write('\t<wpt lat="' + str(lat) + '" lon="' + str(lon) + '">\n') if rwn_ref: f.write('\t\t<name>' + rwn_ref + '</name>\n') f.write('\t</wpt>\n') for member in collection.getMembers(): if member.isRelation(): routerelation = member.getRelation() f.write('\t<trk>\n') networkname = routerelation.get('network:name') if not(networkname): networkname = '' else: networkname += ' ' note = routerelation.get('note') if not(note): note = '' f.write('\t\t<name>' + networkname + note + '</name>\n') f.write('\t\t<src>OpenStreetMap.org</src>\n') f.write('\t\t<type>foot</type>\n') for routerelmember in routerelation.getMembers(): if routerelmember.isWay(): f.write('\t\t<trkseg>\n') way=routerelmember.getWay() for waynode in way.getNodes(): coords = waynode.getCoor() lon = coords.getX() lat = coords.getY() f.write('\t\t\t<trkpt lat="' + str(lat) + '" lon="' + str(lon) + '"> </trkpt>\n') f.write('\t\t</trkseg>\n') f.write('\t</trk>\n') f.write('</gpx>\n') f.close()
Télécharger les éléments parents manquants pour l'élément sélectionné
#!/bin/jython ''' Ce code est publié sous la licence "GNU General Public" v2 ou ultérieure. La GPL v3 est disponible ici : https://www.gnu.org/licenses/gpl.html La GPL v2 est disponible ici : https://www.gnu.org/licenses/old-licenses/gpl-2.0.html Il est livré sans aucune garantie. Ce code illustre comment utiliser Jython pour : * Télécharger tous les référents d'un élément ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction editLayer = Main.getLayerManager().getEditLayer() if editLayer and editLayer.data: selectedElements = editLayer.data.getSelected() if not(selectedElements): JOptionPane.showMessageDialog(Main.parent, "Veuillez sélectionner un élément") else: DownloadReferrersAction.downloadReferrers(editLayer, selectedElements)
Télécharger les membres absents de la relation
#!/bin/jython ''' Ce code est publié sous la licence "GNU General Public" v2 ou ultérieure. La GPL v3 est disponible ici : https://www.gnu.org/licenses/gpl.html La GPL v2 est disponible ici : https://www.gnu.org/licenses/old-licenses/gpl-2.0.html Il est livré sans aucune garantie. Ce code illustre comment utiliser Jython pour : * Télécharger tous les membres absents de la relation ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main import org.openstreetmap.josm.data.osm.Node as Node import org.openstreetmap.josm.data.osm.Way as Way import org.openstreetmap.josm.data.osm.Relation as Relation import org.openstreetmap.josm.data.osm.TagCollection as TagCollection import org.openstreetmap.josm.data.osm.DataSet as DataSet import org.openstreetmap.josm.data.osm.RelationMember as RelationMember import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask editLayer = Main.getLayerManager().getEditLayer() if editLayer: selectedRelations = editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Please select a relation") else: for relation in selectedRelations: if relation.hasIncompleteMembers(): #print dir(relation) print dir(DownloadRelationMemberTask) DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), editLayer ))
Valider une relation de route rcn
#!/bin/jython ''' - Validation d'une relation de route rcn Ce code est publié sous la licence "GNU General Public" v2 ou ultérieure. La GPL v3 est disponible ici : https://www.gnu.org/licenses/gpl.html La GPL v2 est disponible ici : https://www.gnu.org/licenses/old-licenses/gpl-2.0.html Il est livré sans aucune garantie. Ce code illustre comment utiliser Jython pour : * passer en boucle tous les membres d'une relation de route * déterminer si le membre est un noeud, un chemin ou une relation * ajouter/changer les propriétés d'une relation * Supprimer les propriétés d'une relation * Ajouter des membres à une relation * Supprimer des membres d'une relation * trier tous les membres en arrière * Comment définir un élément sélectionné ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main import org.openstreetmap.josm.command as Command import org.openstreetmap.josm.data.osm.Node as Node import org.openstreetmap.josm.data.osm.Way as Way import org.openstreetmap.josm.data.osm.Relation as Relation import org.openstreetmap.josm.data.osm.TagCollection as TagCollection import org.openstreetmap.josm.data.osm.DataSet as DataSet import org.openstreetmap.josm.data.osm.RelationMember as RelationMember import re commandsList = [] reNumberDashNumber = re.compile(r'\d+-\d+') def getMapView(): if Main.main and Main.main.map: return Main.main.map.mapView else: return None mv = getMapView() if mv and mv.editLayer and mv.editLayer.data: dummy_relation = Relation() selectedRelations = mv.editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Veuillez sélectionner une relation d'itinéraire") else: print for route in selectedRelations: newRelation = Relation(route) relationChanged = False name = route.get('name') if name: if reNumberDashNumber.match(name): print 'en supprimant le nom lorsqu'il est de la forme ##-##' newRelation.remove('name') relationChanged = True else: name = '' ref = route.get('ref') if ref: if reNumberDashNumber.match(ref): print 'en supprimant ref lorsqu'elle est de la forme ##-##' newRelation.remove('ref') relationChanged = True else: ref = '' if relationChanged: commandsList.append(Command.ChangeCommand(route, newRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Removing name and/or ref " + name + '/' + ref, commandsList)) commandsList = [] rcn_refs = []; route_relation_names = []; memberslist = [] endnodes = []; prev_endnodes = [] continuous_forward = True; continuous_backward = True prev_role = None; prev_endnodes_before_forward = None; last_endnodes_before_backward = None for member in route.getMembers(): if member.isWay(): role = member.getRole() memberslist.append(member) way = member.getWay() #JOptionPane.showMessageDialog(Main.parent, 'way is selected') endnodes = [way.getNode(0), way.getNode(way.nodesCount-1)] notfoundyet = True for endnode in endnodes: # inventorizing of rcn_ref on end nodes rcn_ref = endnode.get('rcn_ref') if rcn_ref: rcn_refs.append(int(rcn_ref)) for referrer in endnode.getReferrers(): if referrer.getType() is dummy_relation.getType(): if referrer.get('type')=='network' and referrer.get('network')=='rcn': relname=referrer.get('name') if relname: route_relation_names.append(relname) elif referrer.get('type')=='collection': route_relation_names.append('Node not assigned to network yet') # checking for continuity on ways if notfoundyet: if role: if prev_role: if role=='forward' and prev_role=='forward' and endnode in prev_endnodes: notfoundyet = False elif role=='forward' and prev_role=='backward' and endnode in last_endnodes_before_backward: notfoundyet = False elif role=='backward' and prev_role=='forward' and endnode in prev_endnodes: notfoundyet = False elif role=='backward' and prev_role=='backward' and endnode in prev_endnodes: notfoundyet = False else: if role=='forward' and endnode in prev_endnodes: notfoundyet = False elif role=='backward' and endnode in prev_endnodes: notfoundyet = False else: if prev_role: if prev_role=='forward' and endnode in prev_endnodes: notfoundyet = False elif prev_role=='backward' and endnode in last_endnodes_before_backward: notfoundyet = False else: if endnode in prev_endnodes: notfoundyet = False # Analysis of continuity of ways if prev_endnodes and notfoundyet: if role: if role == 'forward': continuous_forward = False elif role == 'backward': continuous_backward = False else: continuous_forward = False continuous_backward = False if role=='forward': if not(prev_endnodes_before_forward): prev_endnodes_before_forward = prev_endnodes elif prev_role=='forward' and role=='backward': if not(last_endnodes_before_backward): last_endnodes_before_backward = prev_endnodes elif not(role) and prev_role=='backward': prev_endnodes_before_forward = None prev_role = role prev_endnodes = endnodes # Drawing conclusions about continuity of ways if continuous_forward: print 'Itinéraire continu dans la direction vers devant' else: print 'Itinéraire PAS CONTINU dans la direction vers devant' if continuous_backward: print 'Itinéraire continu dans la direction vers arrière' else: print 'Itinéraire PAS CONTINU dans la direction vers arrière' # Drawing conclusions about rcn_refs print rcn_refs if len(rcn_refs) > 1: newRelation = Relation(route) relationChanged = False if rcn_refs[0] > rcn_refs[1]: rcn_refs.sort() print 'Inversion de l'ordre des membres' for member in reversed(memberslist): newRelation.addMember( newRelation.getMembersCount(), member) newRelation.removeMember (0) commandsList.append(Command.ChangeCommand(route, newRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Flipping order of members", commandsList)) commandsList = [] note = route.get('note') newNote = str(rcn_refs[0]).zfill(2) + '-' + str(rcn_refs[1]).zfill(2) if not(note) or note != newNote: if not(note): note = 'nothing' newRelation.put('note', newNote) relationChanged = True commandsList.append(Command.ChangeCommand(route, newRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Changing note from " + note + ' to ' + newNote, commandsList)) commandsList = [] if len(route_relation_names) > 1 and route_relation_names[0] != route_relation_names[1]: print print 'Il s'agit probablement d'une CONNEXION à un autre réseau' print route_relation_names else: print 'moins de 2 noeuds terminaux avec rcn_ref trouvés'
Help/Plugin/Scripting/Python/RCN_Route_Validator
Suppression des chemins supplémentaires résultant d'opérations Potlatch
Suppression des chemins supplémentaires résultant des opérations de division des chemins de Potlatch dans le cadre des relations d'interdiction de tourner.
#!/bin/jython ''' RepairTurns.py - Suppression des chemins supplémentaires résultant des opérations de division des chemins de Potlatch dans le cadre des relations d'interdiction de tourner Ce code est publié sous la licence "GNU General Public" v2 ou ultérieure. La GPL v3 est disponible ici : https://www.gnu.org/licenses/gpl.html Il est livré sans aucune garantie. Ce code parcourt en boucle les relations d'interdiction de tourner sélectionnées, en essayant de supprimer les chemins divisés à l'origine de la même manière (avec des rôles to / from) sous les relations dinterdiction de tourner qui ne devraient plus rester membres de ces relations, à la suite d'un problème de Potlatch : https://trac.openstreetmap.org/ticket/3254. Ne fonctionne que pour les interdiction de tourner avec un noeud via e.g. Original : from: Way1, via: Node, to:Way2 Split : from: Way1a, from: Way1b, via: Node, to: Way2 After running : from: Way1b, via: Node, to: Way2 Ce code illustre comment utiliser Jython pour : * traiter les éléments sélectionnés * télécharger les primitives manquantes dans le même thread (blocage) * traiter, valider et supprimer des membres de relations ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main import org.openstreetmap.josm.data.osm.Node as Node import org.openstreetmap.josm.data.osm.Way as Way import org.openstreetmap.josm.data.osm.Relation as Relation import org.openstreetmap.josm.data.osm.TagCollection as TagCollection import org.openstreetmap.josm.data.osm.DataSet as DataSet import org.openstreetmap.josm.data.osm.RelationMember as RelationMember import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask import org.openstreetmap.josm.io.MultiFetchServerObjectReader as MultiFetchServerObjectReader import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor as PleaseWaitProgressMonitor import org.openstreetmap.josm.command as Command class RestrictionError(Exception): pass def getMembers (restriction): memberlist = dict() for member in restriction.getMembers(): memberRole = member.getRole() if memberRole == "via": if member.isNode() and not "via" in memberlist: memberlist[memberRole] = [member] else: raise RestrictionError, "Plus d'un avec rôle via ou avec via mais ce n'est pas un nœud" elif memberRole in ("from", "to"): if member.isWay(): try: memberlist[memberRole].append (member) except KeyError: memberlist[memberRole] = [member] else: raise RestrictionError, "avec le rôle From ou to mais n'est pas un chemin" else: raise RestrictionError, "Rôle inconnu " + memberRole if len(memberlist.keys())<3: raise RestrictionError, "Certains rôles manquent : Seulement " + ",".join (memberlist.keys()) + " found" return memberlist def downloadPrimitives (primitives, editlayer): """ Télécharger une liste de primitives depuis le serveur, et les fusionner dans editlayer. Blocking. """ monitor = PleaseWaitProgressMonitor() monitor.showForegroundDialog() print "Téléchargement" try: objectReader = MultiFetchServerObjectReader().append (primitives) dataSet = objectReader.parseOsm (monitor) editlayer.mergeFrom (dataSet) editlayer.onPostDownloadFromServer() if (not objectReader.getMissingPrimitives().isEmpty()) : raise RestrictionError, "Impossible de télécharger les primitives manquantes" print "Téléchargement terminé" finally: monitor.close() def checkIfConnected (node, way, reverse): """ Return (connecté, prochain nœud à comparer (c'est-à-dire l'autre extrémité du nœud) si vrai) """ if (way.isOneway() != 0 and reverse): return node == way.lastNode(True), way.firstNode(True) # True: auto process case whan isOneway == -1 if (way.isOneway() != 0): # pas d'inversion return node == way.firstNode(True), way.lastNode(True) if node == way.firstNode(): return True, way.lastNode() if node == way.lastNode(): return True, way.firstNode() return False, node def repairrestriction (relation, memberlist, editLayer): """ Télécharger les membres manquants si nécessaire, obtenir la liste des membres à supprimer, et les supprimer si aucune erreur n'a été soulevée pendant la vérification """ incompleteMembers = relation.getIncompleteMembers() if incompleteMembers: downloadPrimitives (incompleteMembers, editLayer); fromRemovalList = []; toRemovalList = [] if len (memberlist["from"]) >= 1: currnode = memberlist["via"][0].getNode() firstMember = True failed = False; # trace "from" des membres pour confirmer s'ils sont séparés d'un seul chemin for member in reversed(memberlist['from']): connected, currnode = checkIfConnected (currnode, member.getWay(), True) if not connected: if not firstMember: raise RestrictionError, "des chemins non continus du noeud via" failed = True break if not firstMember: fromRemovalList.append (member) else: firstMember = False if failed: # Deuxième tentative en cas d'inversion de la séquence lors du fractionnement currnode = memberlist["via"][0].getNode() for member in memberlist['from']: connected, currnode = checkIfConnected (currnode, member.getWay(), True) if not connected: raise RestrictionError, "des chemins non continus du noeud via" if not firstMember: fromRemovalList.append (member) else: firstMember = False if len (memberlist["to"]) >= 1: currnode = memberlist["via"][0].getNode() firstMember = True failed = False # trace les membres " to " pour confirmer s'ils ont été séparés d'un chemin for member in memberlist['to']: connected, currnode = checkIfConnected (currnode, member.getWay(), False) if not connected: if not firstMember: raise RestrictionError, "chemins to non continus avec le noeud via" failed = True break if not firstMember: toRemovalList.append (member) else: firstMember = False if failed: # Deuxième tentative en cas d'inversion de la séquence lors du fractionnement currnode = memberlist["via"][0].getNode() for member in reversed(memberlist['to']): connected, currnode = checkIfConnected (currnode, member.getWay(), False) if not connected: raise RestrictionError, "chemins to non continus avec le noeud via" if not firstMember: toRemovalList.append (member) else: firstMember = False # pour supprimer les chemins dans fromRemovalList, toRemovalList newRelation = Relation(relation) waysToRemove = set() for removalList in [fromRemovalList, toRemovalList]: waysToRemove |= set ([m.getWay() for m in removalList]) newRelation.removeMembersFor (waysToRemove) print "Supprimer le(s) chemin(s) identifiant : " + ",".join ([str(w.getId()) for w in waysToRemove]) return Command.ChangeCommand (relation, newRelation) validrestrictiontypes = ('only_straight_on', 'only_right_turn', 'only_left_turn', 'no_right_turn', 'no_left_turn', 'no_straight_on', 'no_u_turn') editLayer = Main.getLayerManager().getEditLayer() if editLayer and editLayer.data: selectedRelations = editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Veuillez sélectionner une ou plusieurs relations") else: commandsList = [] for relation in selectedRelations: if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes: try: memberlist = getMembers (relation) if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 : # Tentative de réparation print "Tentative de réparation", print "relation id: " + str(relation.getId()) command = repairrestriction (relation, memberlist, mv.editLayer) print "Succès" commandsList.append (command) except RestrictionError, e: print str(e), "; relation id: "+ str(relation.getId()) Main.main.undoRedo.add(Command.SequenceCommand("Réparation des interdictions de tourner", commandsList)) commandsList=[]
Voir également
- La version originale de cette page en anglais
Retour au Greffon Scripting
Retour à l'Aide des Greffons
Retour à l'Aide Principale