wiki:Fr:Help/Plugin/Scripting/Python

Autres langues:

Greffon -> Scripting -> Python

Objectif

D'autres exemples en Python :

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

Last modified 16 months ago Last modified on 2023-01-22T18:18:48+01:00
Note: See TracWiki for help on using the wiki.