Changes between Initial Version and Version 1 of Nl:Help/Plugin/Scripting/Python


Ignore:
Timestamp:
2016-02-22T13:22:06+01:00 (10 years ago)
Author:
DiGro
Comment:

translated into Dutch

Legend:

Unmodified
Added
Removed
Modified
  • Nl:Help/Plugin/Scripting/Python

    v1 v1  
     1{{{TranslatedPages(revision=10)}}}
     2Nog enkele voorbeelden in Python:
     3
     4Exporteer een verzameling routes naar een Garmin GPX-bestand:
     5
     6
     7{{{#!python
     8#!/bin/jython
     9'''
     10RWN2Garmin.py  - Numbered networks to Garmin GPX file converter
     11This code is released under the GNU General
     12Public License v2 or later.
     13
     14The GPL v3 is accessible here:
     15http://www.gnu.org/licenses/gpl.html
     16
     17The GPL v2 is accessible here:
     18http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     19
     20It comes with no warranty whatsoever.
     21
     22This code illustrates how to use Jython to:
     23* work with selected items or how to process all the primitives of a certain kind (node, way, relation)
     24
     25'''
     26from javax.swing import JOptionPane, JDialog
     27from java.awt.event import ActionListener, ActionEvent
     28from org.openstreetmap.josm import Main
     29import org.openstreetmap.josm.command as Command
     30import org.openstreetmap.josm.data.osm.Node as Node
     31import org.openstreetmap.josm.data.osm.Way as Way
     32import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     33import org.openstreetmap.josm.data.osm.DataSet as DataSet
     34import time
     35
     36def getMapView():
     37    if Main.main and Main.main.map:
     38        return Main.main.map.mapView
     39    else:
     40        return None
     41
     42mv = getMapView()
     43f = open('C:/export.gpx', 'w')
     44f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n')
     45f.write('<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="OSM Route Manager" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">\n')
     46f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (http://creativecommons.org/licenses/by-sa/2.0/). -->\n')
     47if mv and mv.editLayer and mv.editLayer.data:
     48    #selectedNodes = mv.editLayer.data.getSelectedNodes()
     49    #selectedWays = mv.editLayer.data.getSelectedWays()
     50    selectedRelations = mv.editLayer.data.getSelectedRelations()
     51
     52    if not(selectedRelations):
     53        JOptionPane.showMessageDialog(Main.parent, "Please select a collection relation")
     54    else:
     55        # nodetype = Node().getType()
     56        print
     57        for collection in selectedRelations:
     58            print 'COLLECTION:', collection
     59            for member in collection.getMembers():
     60                print 'MEMBER:',member
     61                if member.isNode():
     62                    node = member.getNode()
     63                    coords = node.getCoor()
     64                    lon = coords.getX()
     65                    lat = coords.getY()
     66                    rwn_ref = node.get('rwn_ref')
     67                    f.write('\t<wpt lat="' + str(lat) + '" lon="' + str(lon) + '">\n')
     68                    if rwn_ref:
     69                        f.write('\t\t<name>' + rwn_ref + '</name>\n')
     70                    f.write('\t</wpt>\n')
     71            for member in collection.getMembers():
     72                if member.isRelation():
     73                    routerelation = member.getRelation()
     74                    f.write('\t<trk>\n')
     75                    networkname =  routerelation.get('network:name')
     76                    if not(networkname):
     77                        networkname =  ''
     78                    else:
     79                        networkname += ' '
     80                    note = routerelation.get('note')
     81                    if not(note): note =  ''
     82                    f.write('\t\t<name>' + networkname + note + '</name>\n')
     83                    f.write('\t\t<src>OpenStreetMap.org</src>\n')
     84                    f.write('\t\t<type>foot</type>\n')
     85                    for routerelmember in routerelation.getMembers():
     86                        if routerelmember.isWay():
     87                            f.write('\t\t<trkseg>\n')
     88                            way=routerelmember.getWay()
     89                            for waynode in way.getNodes():
     90                                 coords = waynode.getCoor()
     91                                 lon = coords.getX()
     92                                 lat = coords.getY()
     93                                 f.write('\t\t\t<trkpt lat="' + str(lat) + '" lon="' + str(lon) + '"> </trkpt>\n')
     94
     95                            f.write('\t\t</trkseg>\n')
     96                    f.write('\t</trk>\n')
     97f.write('</gpx>\n')
     98f.close()
     99}}}
     100
     101
     102Download ontbrekende ouder-elementen voor het geselecteerde element:
     103
     104
     105{{{#!python
     106#!/bin/jython
     107'''
     108
     109This code is released under the GNU General
     110Public License v2 or later.
     111
     112The GPL v3 is accessible here:
     113http://www.gnu.org/licenses/gpl.html
     114
     115The GPL v2 is accessible here:
     116http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     117
     118It comes with no warranty whatsoever.
     119
     120This code illustrates how to use Jython to:
     121* Download all referrer for an element
     122
     123'''
     124from javax.swing import JOptionPane
     125from org.openstreetmap.josm import Main
     126import org.openstreetmap.josm.data.osm.Node as Node
     127import org.openstreetmap.josm.data.osm.Way as Way
     128import org.openstreetmap.josm.data.osm.Relation as Relation
     129import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     130import org.openstreetmap.josm.data.osm.DataSet as DataSet
     131import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
     132import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction
     133#import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask as DownloadReferrersTask;
     134
     135def getMapView():
     136    if Main.main and Main.main.map:
     137        return Main.main.map.mapView
     138    else:
     139        return None
     140
     141mv = getMapView()
     142if mv and mv.editLayer and mv.editLayer.data:
     143    selectedElements = mv.editLayer.data.getSelected()
     144   
     145    if not(selectedElements):
     146        JOptionPane.showMessageDialog(Main.parent, "Please select an element")
     147    else:
     148        DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedElements)
     149}}}
     150
     151
     152Download ontbrekende leden van de relatie:
     153
     154
     155{{{#!python
     156#!/bin/jython
     157'''
     158
     159This code is released under the GNU General
     160Public License v2 or later.
     161
     162The GPL v3 is accessible here:
     163http://www.gnu.org/licenses/gpl.html
     164
     165The GPL v2 is accessible here:
     166http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     167
     168It comes with no warranty whatsoever.
     169
     170This code illustrates how to use Jython to:
     171* Download all missing members of a relation
     172
     173'''
     174from javax.swing import JOptionPane
     175from org.openstreetmap.josm import Main
     176import org.openstreetmap.josm.data.osm.Node as Node
     177import org.openstreetmap.josm.data.osm.Way as Way
     178import org.openstreetmap.josm.data.osm.Relation as Relation
     179import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     180import org.openstreetmap.josm.data.osm.DataSet as DataSet
     181import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
     182import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask
     183
     184def getMapView():
     185    if Main.main and Main.main.map:
     186        return Main.main.map.mapView
     187    else:
     188        return None
     189
     190mv = getMapView()
     191if mv and mv.editLayer and mv.editLayer.data:
     192    selectedRelations = mv.editLayer.data.getSelectedRelations()
     193   
     194    if not(selectedRelations):
     195        JOptionPane.showMessageDialog(Main.parent, "Please select a node")
     196    else:
     197        for relation in selectedRelations:
     198            if relation.hasIncompleteMembers():
     199                #print dir(relation)
     200                print dir(DownloadRelationMemberTask)
     201                DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer ))
     202
     203}}}
     204
     205
     206Valideer een RCN-routerelatie:
     207
     208
     209{{{#!python
     210#!/bin/jython
     211'''
     212- Validation of a rcn route relation
     213
     214This code is released under the GNU General
     215Public License v2 or later.
     216
     217The GPL v3 is accessible here:
     218http://www.gnu.org/licenses/gpl.html
     219
     220The GPL v2 is accessible here:
     221http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     222
     223It comes with no warranty whatsoever.
     224
     225This code illustrates how to use Jython to:
     226* loop over all members of a route relation
     227* find out whether the member is a node, a way or a relation
     228* add/change properties of a relation
     229* remove properties of a relation
     230* add members to a relation
     231* remove members from a relation
     232* sort all members backwards
     233
     234* How to set an element selected
     235
     236'''
     237from javax.swing import JOptionPane
     238from org.openstreetmap.josm import Main
     239import org.openstreetmap.josm.command as Command
     240import org.openstreetmap.josm.data.osm.Node as Node
     241import org.openstreetmap.josm.data.osm.Way as Way
     242import org.openstreetmap.josm.data.osm.Relation as Relation
     243import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     244import org.openstreetmap.josm.data.osm.DataSet as DataSet
     245import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
     246import re
     247
     248commandsList = []
     249reNumberDashNumber = re.compile(r'\d+-\d+')
     250def getMapView():
     251    if Main.main and Main.main.map:
     252        return Main.main.map.mapView
     253    else:
     254        return None
     255
     256mv = getMapView()
     257if mv and mv.editLayer and mv.editLayer.data:
     258    dummy_relation = Relation()
     259    selectedRelations = mv.editLayer.data.getSelectedRelations()
     260
     261    if not(selectedRelations):
     262        JOptionPane.showMessageDialog(Main.parent, "Please select a route relation")
     263    else:
     264        print
     265        for route in selectedRelations:
     266            newRelation = Relation(route)
     267            relationChanged = False
     268            name = route.get('name')
     269            if name:
     270                if reNumberDashNumber.match(name):
     271                    print 'removing name when it is of the form ##-##'
     272                    newRelation.remove('name')
     273                    relationChanged = True
     274            else:
     275                name = ''
     276            ref = route.get('ref')
     277            if ref:
     278                if reNumberDashNumber.match(ref):
     279                    print 'removing ref when it is of the form ##-##'
     280                    newRelation.remove('ref')
     281                    relationChanged = True
     282            else:
     283                ref = ''
     284            if relationChanged:
     285                commandsList.append(Command.ChangeCommand(route, newRelation))
     286               
     287                Main.main.undoRedo.add(Command.SequenceCommand("Removing name and/or ref " + name + '/' + ref, commandsList))
     288                commandsList = []
     289
     290            rcn_refs = []; route_relation_names = []; memberslist = []
     291            endnodes = []; prev_endnodes = []
     292            continuous_forward = True; continuous_backward = True
     293            prev_role = None; prev_endnodes_before_forward = None; last_endnodes_before_backward = None
     294            for member in route.getMembers():
     295                if member.isWay():
     296                    role = member.getRole()
     297                    memberslist.append(member)
     298                    way = member.getWay()
     299                    #JOptionPane.showMessageDialog(Main.parent, 'way is selected')
     300                    endnodes = [way.getNode(0), way.getNode(way.nodesCount-1)]
     301                    notfoundyet = True
     302                    for endnode in endnodes:
     303                        # inventorizing of rcn_ref on end nodes
     304                        rcn_ref = endnode.get('rcn_ref')
     305                        if rcn_ref:
     306                            rcn_refs.append(int(rcn_ref))
     307                            for referrer in endnode.getReferrers():
     308                                if referrer.getType() is dummy_relation.getType():
     309                                    if referrer.get('type')=='network' and referrer.get('network')=='rcn':
     310                                        relname=referrer.get('name')
     311                                        if relname:
     312                                            route_relation_names.append(relname)
     313                                       
     314                                    elif referrer.get('type')=='collection':
     315                                        route_relation_names.append('Node not assigned to network yet')
     316                        # checking for continuity on ways
     317                        if notfoundyet:
     318                            if role:
     319                                if prev_role:
     320                                    if role=='forward' and prev_role=='forward' and endnode in prev_endnodes:
     321                                        notfoundyet = False
     322                                    elif role=='forward' and prev_role=='backward' and endnode in last_endnodes_before_backward:
     323                                        notfoundyet = False
     324                                    elif role=='backward' and prev_role=='forward' and endnode in prev_endnodes:
     325                                        notfoundyet = False
     326                                    elif role=='backward' and prev_role=='backward' and endnode in prev_endnodes:
     327                                        notfoundyet = False
     328                                else:
     329                                    if role=='forward' and endnode in prev_endnodes:
     330                                        notfoundyet = False
     331                                    elif role=='backward' and endnode in prev_endnodes:
     332                                        notfoundyet = False
     333                            else:
     334                                if prev_role:
     335                                    if prev_role=='forward' and endnode in prev_endnodes:
     336                                        notfoundyet = False
     337                                    elif prev_role=='backward' and endnode in last_endnodes_before_backward:
     338                                        notfoundyet = False
     339                                else:
     340                                    if endnode in prev_endnodes:
     341                                        notfoundyet = False
     342                    # Analysis of continuity of ways
     343                    if prev_endnodes and notfoundyet:
     344                        if role:
     345                            if role == 'forward':
     346                                continuous_forward = False
     347                            elif role == 'backward':
     348                                continuous_backward = False
     349                        else:
     350                            continuous_forward = False
     351                            continuous_backward = False
     352                    if role=='forward':
     353                        if not(prev_endnodes_before_forward):
     354                            prev_endnodes_before_forward  = prev_endnodes
     355                    elif prev_role=='forward' and role=='backward':
     356                        if not(last_endnodes_before_backward):
     357                            last_endnodes_before_backward = prev_endnodes
     358                    elif not(role) and prev_role=='backward':
     359                        prev_endnodes_before_forward = None
     360                    prev_role = role
     361                    prev_endnodes = endnodes
     362            # Drawing conclusions about continuity of ways
     363            if continuous_forward:
     364                print 'route is continous in the forward direction'
     365            else:
     366                print 'route is NOT CONTINUOUS in the forward direction'
     367            if continuous_backward:
     368                print 'route is continous in the backward direction'
     369            else:
     370                print 'route is NOT CONTINUOUS in the backward direction'
     371
     372            # Drawing conclusions about rcn_refs
     373            print rcn_refs
     374            if len(rcn_refs) > 1:
     375                newRelation = Relation(route)
     376                relationChanged = False
     377
     378                if rcn_refs[0] > rcn_refs[1]:
     379                    rcn_refs.sort()
     380                    print 'Flipping members order'
     381                    for member in reversed(memberslist):
     382                        newRelation.addMember( newRelation.getMembersCount(), member)
     383                        newRelation.removeMember (0)
     384                    commandsList.append(Command.ChangeCommand(route, newRelation))
     385                    Main.main.undoRedo.add(Command.SequenceCommand("Flipping order of members", commandsList))
     386                    commandsList = []
     387                note = route.get('note')
     388                newNote = str(rcn_refs[0]).zfill(2) + '-' + str(rcn_refs[1]).zfill(2)
     389                if not(note) or note != newNote:
     390                    if not(note): note = 'nothing'
     391                    newRelation.put('note', newNote)
     392                    relationChanged = True
     393                    commandsList.append(Command.ChangeCommand(route, newRelation))
     394               
     395                    Main.main.undoRedo.add(Command.SequenceCommand("Changing note from " + note + ' to ' + newNote, commandsList))
     396                    commandsList = []
     397
     398                if len(route_relation_names) > 1 and route_relation_names[0] != route_relation_names[1]:
     399                    print
     400                    print 'This is probably a CONNECTION to another network'
     401                    print route_relation_names
     402            else:
     403                print 'less than 2 end nodes with rcn_ref found'
     404}}}
     405
     406[wiki:Python/RCN_Route_Validator]
     407
     408Extra wegen die resultaat zijn van de bewerkingen Weg splitsen van Potlatch onder relaties van Beperkingen Afslaan verwijderen
     409
     410{{{#!python
     411#!/bin/jython
     412
     413'''
     414RepairTurns.py  - Remove extra ways resulting from Potlatch way split operations under turn restriction relations
     415
     416This code is released under the GNU General
     417Public License v2 or later.
     418
     419The GPL v3 is accessible here:
     420http://www.gnu.org/licenses/gpl.html
     421
     422The GPL v2 is accessible here:
     423http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     424
     425It comes with no warranty whatsoever.
     426
     427This code Loops through selected turn restriction relations, trying to remove ways split from originally the same way (with to / from roles) under turn restriction relations which should no longer remain as members of these relations, as a result of a Potlatch issue: https://trac.openstreetmap.org/ticket/3254
     428
     429Only work for turn restrictions with one via node
     430
     431e.g. Original      : from: Way1, via: Node, to:Way2
     432     Split         : from: Way1a, from: Way1b, via: Node, to: Way2
     433     After running : from: Way1b, via: Node, to: Way2
     434
     435This code illustrates how to use Jython to:
     436* process selected items
     437* download missing primitives in the same thread (blocking)
     438* process, validate and remove members from relations
     439
     440'''
     441from javax.swing import JOptionPane
     442from org.openstreetmap.josm import Main
     443import org.openstreetmap.josm.data.osm.Node as Node
     444import org.openstreetmap.josm.data.osm.Way as Way
     445import org.openstreetmap.josm.data.osm.Relation as Relation
     446import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     447import org.openstreetmap.josm.data.osm.DataSet as DataSet
     448import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
     449import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask
     450import org.openstreetmap.josm.io.MultiFetchServerObjectReader as MultiFetchServerObjectReader
     451import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor as PleaseWaitProgressMonitor
     452import org.openstreetmap.josm.command as Command
     453
     454class RestrictionError(Exception):
     455    pass
     456
     457def getMapView():
     458    if Main.main and Main.main.map:
     459        return Main.main.map.mapView
     460    else:
     461        return None
     462
     463def getMembers (restriction):
     464    memberlist = dict()
     465    for member in restriction.getMembers():
     466        memberRole = member.getRole()
     467        if memberRole == "via":
     468            if member.isNode() and not "via" in memberlist:
     469                memberlist[memberRole] = [member]
     470            else:
     471                raise RestrictionError, "More than one via role or via not a node"
     472        elif memberRole in ("from", "to"):
     473            if member.isWay():
     474                try:
     475                    memberlist[memberRole].append (member)
     476                except KeyError:
     477                    memberlist[memberRole] = [member]
     478            else:
     479                raise RestrictionError, "From or to role not a way"
     480        else:
     481            raise RestrictionError, "Unknown role " + memberRole
     482
     483    if len(memberlist.keys())<3:
     484        raise RestrictionError, "Some roles missing: Only " + ",".join (memberlist.keys()) + " found"
     485    return memberlist
     486
     487def downloadPrimitives (primitives, editlayer):
     488    """
     489        Download a list of primitives from server, and merge into editlayer. Blocking.
     490    """
     491    monitor = PleaseWaitProgressMonitor()
     492    monitor.showForegroundDialog()   
     493
     494    print "Downloading"
     495    try:
     496        objectReader = MultiFetchServerObjectReader().append (primitives)
     497        dataSet = objectReader.parseOsm (monitor)
     498        editlayer.mergeFrom (dataSet)
     499        editlayer.onPostDownloadFromServer()
     500        if (not objectReader.getMissingPrimitives().isEmpty()) :
     501            raise RestrictionError, "Unable to download missing primitives"
     502        print "Download completed"   
     503    finally:
     504        monitor.close()
     505
     506def checkIfConnected (node, way, reverse):
     507    """
     508        Return (connected, next node to compare (i.e. other end of the node) if true)
     509    """
     510    if (way.isOneway() != 0 and reverse):
     511        return node == way.lastNode(True), way.firstNode(True) # True: auto process case whan isOneway == -1
     512    if (way.isOneway() != 0):     # not reverse
     513        return node == way.firstNode(True), way.lastNode(True)
     514    if node == way.firstNode():
     515        return True, way.lastNode()
     516    if node == way.lastNode():
     517        return True, way.firstNode()
     518    return False, node   
     519
     520
     521def repairrestriction (relation, memberlist, editLayer):
     522    """
     523        Download missing members if needed, get list of members to remove, and remove them if no error raised during checking
     524    """
     525    incompleteMembers = relation.getIncompleteMembers()
     526    if incompleteMembers:
     527          downloadPrimitives (incompleteMembers, editLayer);       
     528
     529    fromRemovalList = []; toRemovalList = []
     530   
     531    if len (memberlist["from"]) >= 1:
     532        currnode = memberlist["via"][0].getNode()
     533        firstMember = True
     534        failed = False;
     535        # trace "from" members to confirm if split from one way
     536        for member in reversed(memberlist['from']):
     537            connected, currnode = checkIfConnected (currnode, member.getWay(), True)
     538            if not connected:
     539                if not firstMember:
     540                    raise RestrictionError, "from ways not continuous from via node"
     541                failed = True
     542                break
     543            if not firstMember:
     544                fromRemovalList.append (member)
     545            else:
     546                firstMember = False
     547
     548        if failed: # Second attempt in case sequence reversed when split
     549            currnode = memberlist["via"][0].getNode()
     550            for member in memberlist['from']:
     551                connected, currnode = checkIfConnected (currnode, member.getWay(), True)
     552                if not connected:
     553                    raise RestrictionError, "from ways not continuous from via node"
     554                if not firstMember:
     555                    fromRemovalList.append (member)
     556                else:
     557                    firstMember = False
     558                                                                       
     559    if len (memberlist["to"]) >= 1:
     560        currnode = memberlist["via"][0].getNode()
     561        firstMember = True
     562        failed = False
     563        # trace "to" members to confirm if split from one way
     564        for member in memberlist['to']:
     565            connected, currnode = checkIfConnected (currnode, member.getWay(), False)
     566            if not connected:
     567                if not firstMember:
     568                    raise RestrictionError, "to ways not continuous from via node"
     569                failed = True
     570                break
     571            if not firstMember:
     572                toRemovalList.append (member)
     573            else:
     574                firstMember = False
     575
     576        if failed: # Second attempt in case sequence reversed when split
     577            currnode = memberlist["via"][0].getNode()
     578            for member in reversed(memberlist['to']):
     579                connected, currnode = checkIfConnected (currnode, member.getWay(), False)
     580                if not connected:
     581                    raise RestrictionError, "to ways not continuous from via node"
     582                if not firstMember:
     583                    toRemovalList.append (member)
     584                else:
     585                    firstMember = False         
     586                         
     587    # to remove ways in fromRemovalList, toRemovalList         
     588    newRelation = Relation(relation)
     589    waysToRemove = set()
     590    for removalList in [fromRemovalList, toRemovalList]:
     591        waysToRemove |= set ([m.getWay() for m in removalList])
     592    newRelation.removeMembersFor (waysToRemove)
     593    print "Remove way(s) id:" + ",".join ([str(w.getId()) for w in waysToRemove])
     594    return Command.ChangeCommand (relation, newRelation)   
     595   
     596   
     597validrestrictiontypes = ('only_straight_on', 'only_right_turn', 'only_left_turn', 'no_right_turn', 'no_left_turn', 'no_straight_on', 'no_u_turn')
     598mv = getMapView()
     599if mv and mv.editLayer and mv.editLayer.data:
     600    selectedRelations = mv.editLayer.data.getSelectedRelations()
     601   
     602    if not(selectedRelations):
     603        JOptionPane.showMessageDialog(Main.parent, "Please select one or more relations")
     604    else:
     605        commandsList = []
     606        for relation in selectedRelations:
     607            if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes:
     608                try:
     609                    memberlist = getMembers (relation)     
     610                    #print "".join(v * len(memberlist[v]) for v in memberlist.keys())           
     611                    if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 :
     612                        # Repair attempt
     613                        print "Attempt repair",
     614                        print "relation id: " + str(relation.getId())
     615                        command = repairrestriction (relation, memberlist, mv.editLayer)
     616                        print "Success"                         
     617                        commandsList.append (command)
     618                except RestrictionError, e:
     619                    print str(e), "; relation id: "+ str(relation.getId())
     620               
     621       
     622        Main.main.undoRedo.add(Command.SequenceCommand("Repair turn restrictions", commandsList))
     623        commandsList=[]
     624}}}