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


Ignore:
Timestamp:
2011-10-04T17:04:42+02:00 (14 years ago)
Author:
Polyglot
Comment:

The script is starting to become presentable

Legend:

Unmodified
Added
Removed
Modified
  • Help/Plugin/Scripting/Python/RCN_Route_Validator

    v1 v1  
     1
     2{{{
     3#!/bin/jython
     4'''
     5CheckRouteOrNetworkOrCollectionOfRoutes.jy
     6- Validation of a rcn route, network or collection of networks relation
     7- Depending on what is selected in JOSM when invoked
     8
     9This code is released under the GNU General
     10Public License v2 or later.
     11
     12The GPL v3 is accessible here:
     13http://www.gnu.org/licenses/gpl.html
     14
     15The GPL v2 is accessible here:
     16http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     17
     18It comes with no warranty whatsoever.
     19
     20This code illustrates how to use Jython (Python in the scripting plugin of JOSM) to:
     21* loop over all members of a route relation
     22* find out whether the member is a node, a way or a relation
     23* add/change properties of a relation
     24* remove properties of a relation
     25* add members to a relation
     26* remove members from a relation
     27* sort all members backwards
     28
     29* How to set an element selected
     30
     31'''
     32from javax.swing import JOptionPane
     33from org.openstreetmap.josm import Main
     34import org.openstreetmap.josm.command as Command
     35import org.openstreetmap.josm.data.osm.Node as Node
     36import org.openstreetmap.josm.data.osm.Way as Way
     37import org.openstreetmap.josm.data.osm.Relation as Relation
     38import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     39import org.openstreetmap.josm.data.osm.DataSet as DataSet
     40import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
     41import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask
     42import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction
     43import org.openstreetmap.josm.actions.AutoScaleAction as AutoScaleAction
     44import re, time
     45
     46# comment to disable side effect
     47sideEffects = {
     48    'addRouteToNetwork': None,
     49    'removeNameRefKey_xx-yyAndcreated_by': None,
     50    'modifyNoteTo_xx-yy': None,
     51    'flipOrderOfMembers': None, # such that ways go from lower rcn_ref to higher rcn_ref
     52    'sortRouteRelations': None,
     53    'selectObjects': None,
     54    'zoomToSelection': None,
     55    #'downloadReferrersForNodes': None, # This will download all ways and relations for nodes with an rcn_ref
     56    #'downloadReferrersForWays': None, # This will download all relations for ways that have an endnode with an rcn_ref
     57    'downloadIncompleteMembers': None,
     58    'createWikiReport': None,
     59    'createGarminGPX': None,
     60    #'checkOneWays = False, # not implemented yet
     61    }
     62
     63logVerbosity = 10
     64'''
     6510: only report problems that need fixing
     6620: report on collection
     6730: report on network nodes
     6840: report on which routes are being checked
     6950: report everything
     70'''
     71def getMapView():
     72    if Main.main and Main.main.map:
     73        return Main.main.map.mapView
     74    else:
     75        return None
     76
     77def sortRouteRelation(route, nodesDict, beginAndEndnodes):
     78    # TODO This can still be improved a lot. Now it aborts at the first sign of probable failure.
     79    # TODO It sorts the simple cases though (i.e. the ones with no forward/backward roles which actually are continuous)
     80    nextNode = None
     81    routeToReturn = Relation(route)
     82    ##print dir (routeToReturn)
     83    #routeToReturn.clearOsmId()
     84    lowestNodeInt = 10000; lowPos = 0
     85    for nodeTuple in beginAndEndnodes:
     86        if nodeTuple[0] < lowestNodeInt:
     87            lowestNodeInt, nextNode = nodeTuple
     88    if not(nextNode):
     89        return route
     90    members=nodesDict[nextNode]
     91    processedMembers = {}
     92    #print len(nodesDict)
     93    #print dir(route)
     94    while lowPos<route.getMembersCount():
     95        #print 'in loop', routeToReturn
     96        if len(members) == 1:
     97            member = members[0]
     98        else:
     99            member = members[1]
     100            if member in processedMembers: member = members[0]
     101        processedMembers[member] = True
     102        way = member.getWay()
     103        routeToReturn.removeMembersFor(way)
     104        routeToReturn.addMember(lowPos,member)
     105        #routeToReturn.setModified(True)
     106        currentNode = nextNode
     107        nextNode = way.getNode(way.nodesCount-1).getUniqueId()
     108        if currentNode == nextNode:
     109            nextNode = way.getNode(0).getUniqueId()           
     110        if nextNode in nodesDict:
     111            members=nodesDict[nextNode]
     112        else:
     113            break
     114        del nodesDict[nextNode]
     115        #print len(nodesDict)
     116        if len(nodesDict)<3: break
     117        lowPos += 1
     118    #print 'before return', routeToReturn
     119    return routeToReturn
     120
     121def checkForContinuity(membersList):
     122    listIsContinuous = True; prev_endnodes = []
     123    for member in membersList:
     124        if member.isWay():
     125            way = member.getWay()
     126            if logVerbosity > 50: print dir(way)
     127            if logVerbosity > 49:
     128                print way.getKeys()
     129                print way.get('name')
     130                print way.nodesCount-1, way
     131            if way.get('junction') == 'roundabout':
     132                endnodes = way.getNodes()
     133            else:
     134                if way.nodesCount:
     135                    endnodes = [way.getNode(0), way.getNode(way.nodesCount-1)]
     136                else:
     137                    endnodes = []
     138            foundTheNode = False
     139            for endnode in endnodes:
     140                if logVerbosity > 49: print endnode, prev_endnodes
     141                if endnode in prev_endnodes:
     142                    foundTheNode = True
     143            if prev_endnodes and not(foundTheNode):
     144                listIsContinuous = False
     145                if logVerbosity > 49:
     146                    print way
     147                    print endnodes
     148                    print prev_endnodes
     149                break
     150            prev_endnodes = endnodes
     151    return listIsContinuous
     152
     153def checkRCNroute(route):
     154    if 'removeNameRefKey_xx-yyAndcreated_by' in sideEffects:
     155        commandsList = []
     156        reNumberDashNumber = re.compile(r'\d+-\d+')
     157        newRelation = Relation(route)
     158        relationChanged = False
     159        created_by = route.get('created_by')
     160        if created_by:
     161            print 'removing created_by'
     162            newRelation.remove('created_by')
     163            relationChanged = True
     164        name = route.get('name')
     165        if name:
     166            if reNumberDashNumber.match(name):
     167                print 'removing name when it is of the form ##-##'
     168                newRelation.remove('name')
     169                relationChanged = True
     170        else:
     171            name = ''
     172        ref = route.get('ref')
     173        if ref:
     174            if reNumberDashNumber.match(ref):
     175                print 'removing ref when it is of the form ##-##'
     176                newRelation.remove('ref')
     177                relationChanged = True
     178        else:
     179            ref = ''
     180        if relationChanged:
     181            commandsList.append(Command.ChangeCommand(route, newRelation))
     182           
     183            Main.main.undoRedo.add(Command.SequenceCommand("Removing name and/or ref and/or created_by" + name + '/' + ref, commandsList))
     184            commandsList = []
     185
     186    fixme = route.get('fixme') == 'incomplete'
     187    rcn_refs = []; route_relation_names = []; memberslist = []; roleInNetwork = ''
     188    sameNodeNumberRepeated = False
     189    allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = []; branch = None
     190    newRelation = Relation(route); commandslist = []; i=0; roundabout = []
     191
     192    if 'sortRouteRelations' in sideEffects: nodesForSorting = {}; beginAndEndNodes = []
     193    routeMembers = route.getMembers()
     194    for member in routeMembers:
     195        if member.isWay():
     196            role = member.getRole()
     197            memberslist.append(member)
     198            way = member.getWay()
     199            # print way.get('name')
     200            wayNodes = way.getNodes()
     201
     202            notfoundyet = True
     203            for endnode in wayNodes:
     204                if 'sortRouteRelations' in sideEffects:
     205                    endnodeId = endnode.getUniqueId()
     206                    if not(endnodeId in nodesForSorting):
     207                        nodesForSorting[endnodeId] = []
     208                    nodesForSorting[endnodeId].append(member)
     209
     210                rcn_ref = endnode.get('rcn_ref')
     211                if rcn_ref:
     212                    rcn_refAsInt = int(rcn_ref)
     213                    if 'sortRouteRelations' in sideEffects: beginAndEndNodes.append([rcn_refAsInt, endnodeId])
     214                    if not(rcn_refAsInt in rcn_refs):
     215                        rcn_refs.append(rcn_refAsInt)
     216                    else:
     217                        sameNodeNumberRepeated = True
     218                    referrersForNode = endnode.getReferrers(); networkNotFoundForNode = True
     219                    for referrer in referrersForNode:
     220                        if referrer.getType() is dummy_relation.getType():
     221                            if referrer.get('type') in ['network'] and referrer.get('network') in ['rcn']:
     222                                networkNotFoundForNode = False
     223                                break
     224                    if networkNotFoundForNode:
     225                        # node is not assigned to a network yet
     226                        Main.main.getCurrentDataSet().setSelected(endnode)
     227                        AutoScaleAction.zoomToSelection()
     228                        selectedNode = mv.editLayer.data.getSelected()
     229                        if 'downloadReferrersForNodes' in sideEffects:
     230                            print "Downloading referrers for ", endnode.get('rcn_ref'), ' ', wayNodes
     231                            DownloadReferrersAction.downloadReferrers(mv.editLayer, wayNodes)
     232                        else:
     233                            print "Would download referrers for ", endnode.get('rcn_ref'), ' ', wayNodes
     234                        referrersForNode = endnode.getReferrers()
     235                    for referrer in referrersForNode:
     236                        if referrer.getType() is dummy_relation.getType():
     237                            networkOrRouteType = referrer.get('type') in ['network'] #, 'route']
     238                            if referrer.get('network')=='rcn' and networkOrRouteType:
     239                                relname=referrer.get('name')
     240                                if relname:
     241                                    route_relation_names.append(relname)
     242                            elif not(referrer.get('type') in ['route']):
     243                                route_relation_names.append('Node not assigned to network yet')
     244                                # FIXME This is still buggy
     245            # build 2 structures to help check for continuity on ways
     246            if i==0:
     247                lastNodesBeforeSplit = [wayNodes]
     248            if role and role in ['forward', 'backward']:
     249                if not(branch):
     250                    print 'wayNodes', wayNodes
     251                   
     252                    if wayNodes:
     253                        if role in ['forward']:
     254                            lastNodesBeforeSplit = [wayNodes[0]]
     255                        else:
     256                            lastNodesBeforeSplit = [wayNodes[-1]]
     257                    else:
     258                        return '', True, '|align="right" | way has no nodes||align="right" | {{BrowseRoute|' + str(route.getId()) + '}}||align="right" needs to be downloaded first\n'
     259                if logVerbosity > 29:
     260                    print 'lastNodesBeforeSplit', lastNodesBeforeSplit
     261                    print way.getNodesCount(), 'startnode', wayNodes[0], 'endnode', wayNodes[-1]
     262                    print 'roundabout', roundabout
     263                    print wayNodes[-1].get('rcn_ref'),not(member.getUniqueId() == routeMembers[-1].getUniqueId())
     264                if role in ['forward'] and (wayNodes[-1] in lastNodesBeforeSplit or wayNodes[-1] in roundabout):
     265                    branch = 'HigherToLower'
     266                elif role in ['backward'] and wayNodes[0] in lastNodesBeforeSplit:
     267                    branch = 'HigherToLower'
     268                   
     269                elif not(allWaysgoingFromHigherToLower) and wayNodes[-1].get('rcn_ref') and not(member.getUniqueId() == routeMembers[-1].getUniqueId()):
     270                    # This is for when the route starts forked from a different rcn node (split node situation), we don't want it to kick in for the last member of the route
     271                    branch = 'HigherToLower'
     272                elif not(branch == 'HigherToLower'):
     273                    branch = 'LowerToHigher'
     274                print branch
     275                if branch == 'LowerToHigher':
     276                    allWaysgoingFromLowerToHigher.append(member)
     277                elif branch == 'HigherToLower':
     278                    allWaysgoingFromHigherToLower.append(member)
     279            else:
     280                branch = None; roundabout = []
     281                allWaysgoingFromLowerToHigher.append(member)
     282                allWaysgoingFromHigherToLower.append(member)
     283            if way.get('junction') == 'roundabout':
     284                roundabout = way.getNodes()
     285        i+=1
     286    #if modified:
     287        #commandsList.append(Command.ChangeCommand(route, newRelation))
     288        #Main.main.undoRedo.add(Command.SequenceCommand("Removing way which has no nodes", commandsList))
     289        #commandsList = []
     290
     291    continuous_forward = True; continuous_backward = True
     292    if len(allWaysgoingFromLowerToHigher) > 1:
     293        continuous_forward = checkForContinuity(allWaysgoingFromLowerToHigher)
     294        if not(continuous_forward) and not(fixme) and 'sortRouteRelations' in sideEffects:
     295            sortedRelation = sortRouteRelation(route, nodesForSorting, beginAndEndNodes)
     296
     297            if logVerbosity>49:
     298                print route
     299                print sortedRelation
     300            commandsList.append(Command.ChangeCommand(route, sortedRelation))
     301            Main.main.undoRedo.add(Command.SequenceCommand("Sorted route relation", commandsList))           
     302            allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = []
     303
     304            routeMembers = route.getMembers(); i=0
     305            for member in routeMembers:
     306                if member.isWay():
     307                    role = member.getRole()
     308                    if i==0:
     309                        lastNodesBeforeSplit = [wayNodes]
     310                    if role and role in ['forward', 'backward']:
     311                        if not(branch):
     312                            if role in ['forward']:
     313                                lastNodesBeforeSplit = [wayNodes[0]]
     314                            else:
     315                                lastNodesBeforeSplit = [wayNodes[-1]]
     316                        if logVerbosity > 29:
     317                            print 'wayNodes', wayNodes
     318                            print 'lastNodesBeforeSplit', lastNodesBeforeSplit
     319                            print way.getNodesCount(), 'startnode', wayNodes[0], 'endnode', wayNodes[-1]
     320                            print 'roundabout', roundabout
     321
     322                        if role in ['forward'] and (wayNodes[-1] in lastNodesBeforeSplit or wayNodes[-1] in roundabout):
     323                            branch = 'HigherToLower'
     324                        elif role in ['backward'] and wayNodes[0] in lastNodesBeforeSplit:
     325                            branch = 'HigherToLower'
     326                        elif wayNodes[-1].get('rcn_ref') and not(member.getUniqueId() == routeMembers[-1].getUniqueId()): # not(allWaysgoingFromHigherToLower) and ## this last part is probably not necessary anymore
     327                            # This is for when the route starts forked from a different rcn node (split node situation), we don't want it to kick in for the last member of the route
     328                            branch = 'HigherToLower'
     329                        elif not(branch == 'HigherToLower'):
     330                            branch = 'LowerToHigher'
     331                        print branch
     332                        if branch == 'LowerToHigher':
     333                            allWaysgoingFromLowerToHigher.append(member)
     334                        elif branch == 'HigherToLower':
     335                            allWaysgoingFromHigherToLower.append(member)
     336                    else:
     337                        branch = None; roundabout = []
     338                        allWaysgoingFromLowerToHigher.append(member)
     339                        allWaysgoingFromHigherToLower.append(member)
     340                    if way.get('junction') == 'roundabout':
     341                        roundabout = way.getNodes()
     342                i+=1
     343            continuous_forward = checkForContinuity(allWaysgoingFromLowerToHigher)
     344        #else:
     345    else:
     346        # a route relation with only one way member
     347        continuous_forward = True
     348    if len(allWaysgoingFromHigherToLower) > 1:
     349        continuous_backward = checkForContinuity(reversed(allWaysgoingFromHigherToLower))
     350    else:
     351        # a route relation with only one way member
     352        continuous_backward = True
     353
     354    # Drawing conclusions about rcn_refs
     355    if logVerbosity > 39: print rcn_refs
     356    if sameNodeNumberRepeated:
     357        rcn_refs.append(rcn_refs[0])
     358    newNote = note = repr(rcn_refs)
     359    sortedRelation = route
     360    if len(rcn_refs) > 1:
     361        #newRelation = Relation(route)
     362        relationChanged = False
     363
     364        if rcn_refs[0] > rcn_refs[1]:
     365            rcn_refs.sort()
     366            if len(memberslist)>1 and 'flipOrderOfMembers' in sideEffects:
     367                for member in reversed(memberslist):
     368                    sortedRelation.addMember( sortedRelation.getMembersCount(), member)
     369                    sortedRelation.removeMember (0)
     370                commandsList.append(Command.ChangeCommand(route, sortedRelation))
     371                Main.main.undoRedo.add(Command.SequenceCommand("Flipping order of members", commandsList))
     372                commandsList = []
     373        note = route.get('note')
     374        newNote = str(rcn_refs[0]).zfill(2) + '-' + str(rcn_refs[1]).zfill(2)
     375        #print note, newNote
     376        if 'modifyNoteTo_xx-yy' in sideEffects:
     377            if not(note) or note != newNote:
     378                if not(note): note = 'nothing'
     379                newRelation.put('note', newNote)
     380                relationChanged = True
     381                commandsList.append(Command.ChangeCommand(route, newRelation))
     382           
     383                Main.main.undoRedo.add(Command.SequenceCommand("Changing note from " + note + ' to ' + newNote, commandsList))
     384                if logVerbosity > 9: print 'Flipping members order for ', note
     385                commandsList = []
     386
     387        if len(route_relation_names) > 1 and route_relation_names[0] != route_relation_names[1]:
     388            # print 'This is probably a CONNECTION to another network'
     389            if logVerbosity > 9: print route_relation_names
     390            roleInNetwork = 'connection'
     391    else:
     392        print 'less than 2 end nodes with rcn_ref found'
     393    if fixme and not(continuous_forward or continuous_backward):
     394        if logVerbosity > 1: print 'FIXME flag is INCOMPLETE'
     395    if continuous_forward:
     396        wikiCF = 'align="right" | continuous'
     397        if logVerbosity > 29: print 'route is continous in the forward direction'
     398    else:
     399        wikiCF = 'align="right" style="color:red" | NOT continuous'
     400        if logVerbosity > 9: print 'route ',newNote,' is NOT CONTINUOUS in the forward direction'
     401        if logVerbosity > 49: print allWaysgoingFromLowerToHigher
     402    if continuous_backward:
     403        wikiCB = 'align="right" | continuous'
     404        if logVerbosity > 29: print 'route is continous in the backward direction'
     405    else:
     406        wikiCB = 'align="right" style="color:red" | NOT continuous'
     407        if logVerbosity > 9: print 'route ',newNote,' is NOT CONTINUOUS in the backward direction'
     408        if logVerbosity > 49: print allWaysgoingFromHigherToLower
     409    print
     410    if fixme:
     411        wikiFM = 'style="color:red" | fixme'
     412    else:
     413        wikiFM = ' | '
     414    if fixme or not(continuous_forward) or not(continuous_backward):
     415        problem = True
     416    else:
     417        problem = False
     418    return roleInNetwork, problem, '|align="right" | ' + note + '||align="right" | {{BrowseRoute|' + str(route.getId()) + '}}||align="right" ' + wikiFM + ' ||' + wikiCF + ' ||' + wikiCB + '\n'
     419
     420def checkNetwork(network):
     421    name = network.get('name')
     422    if logVerbosity>19:
     423        print '********************************************'
     424        print name
     425        print '********************************************'
     426    if 'createWikiReport' in sideEffects:
     427        wikiReportOnNodes = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name +
     428                             '\n|-\n!style="width:2.5em" | Node\n!Link\n! # Roads\n! # Relations\n|-\n')
     429        wikiReportOnRelations = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name +
     430                                 '\n|-\n!style="width:2.5em" | note\n!link\n!fixme\n! forward\n! backward\n|-\n')
     431    i=1
     432    for networkMember in network.getMembers():
     433        if networkMember.isRelation():
     434            routeRelation = networkMember.getRelation()
     435            if routeRelation.hasIncompleteMembers():
     436                if 'downloadIncompleteMembers' in sideEffects:
     437                    print 'Downloading incomplete members for', routeRelation.get('note')
     438                    DownloadRelationMemberTask.run(DownloadRelationMemberTask(routeRelation, routeRelation.getIncompleteMembers(), mv.editLayer ))
     439                    continue
     440                else:
     441                    JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the route relations first')
     442                    break
     443            roleFromRouteCheck, problemReported, wikiReport = checkRCNroute(routeRelation)
     444            if problemReported and 'createWikiReport' in sideEffects:
     445                wikiReportOnRelations += wikiReport + '\n|-\n'
     446            role = networkMember.getRole()
     447            if logVerbosity > 29 and role != roleFromRouteCheck:
     448                print
     449                print 'Role in network is ', role
     450                print 'Maybe this should be: ', roleFromRouteCheck
     451        if networkMember.isNode():
     452            node = networkMember.getNode()
     453            rcn_ref = node.get('rcn_ref')
     454            expected_rcn_route_relations = node.get('expected_rcn_route_relations')
     455            if expected_rcn_route_relations:
     456                expected_rcn_route_relations = int(expected_rcn_route_relations)
     457            else:
     458                expected_rcn_route_relations = 3
     459            if rcn_ref:
     460                if logVerbosity > 39: print rcn_ref
     461                referrersForNode = node.getReferrers()
     462                networkNotFoundForNode = True
     463                for referrer in referrersForNode:
     464                    if referrer.getType() is dummy_relation.getType():
     465                        if referrer.get('type') in ['network'] and referrer.get('network') in ['rcn']:
     466                            networkNotFoundForNode = False
     467                            break
     468                if networkNotFoundForNode and 'downloadReferrersNodes' in sideEffects:
     469                    Main.main.getCurrentDataSet().setSelected(node)
     470                    AutoScaleAction.zoomToSelection()
     471                    selectedNode = mv.editLayer.data.getSelected()
     472                    print 'Downloading referrers for ', selectedNode.get('rcn_ref')
     473                    DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedNode)
     474                    referrersForNode = node.getReferrers()
     475
     476                rcnNetworkCountForNode = roads = 0
     477                for referrer in referrersForNode:
     478                    if referrer.getType() is dummy_way.getType():
     479                        if referrer.get('highway'): roads += 1
     480                        referrersForWay = referrer.getReferrers()
     481                        if len(referrersForWay) < 1 and 'downloadReferrersForWays' in sideEffects:
     482                            Main.main.getCurrentDataSet().setSelected(referrer)
     483                            AutoScaleAction.zoomToSelection()
     484                            selectedWay = mv.editLayer.data.getSelected()
     485                            print 'Downloading referrers for ', referrer.get('name') , ' ', rcn_ref
     486                            DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedWay)
     487                            referrersForWay = referrer.getReferrers()
     488                        for wayReferrer in referrersForWay:
     489                            if wayReferrer.getType() is dummy_relation.getType():
     490                                aRelation = wayReferrer
     491                                if aRelation.get('type') == 'route' and aRelation.get('network') == 'rcn':
     492                                    rcnNetworkCountForNode+=1
     493                                networkMembersList = []
     494                                for subMember in network.getMembers():
     495                                    if subMember.isRelation():
     496                                        routeRelation = subMember.getRelation()
     497                                        networkMembersList.append(routeRelation.getUniqueId())
     498                                routeId = aRelation.getUniqueId()
     499                                if not(routeId in networkMembersList):
     500                                    if aRelation.get('network') == 'rcn':
     501                                        roleFromRouteCheck, problemReported, wikiReport = checkRCNroute(aRelation)
     502                                        if problemReported and 'createWikiReport' in sideEffects:
     503                                            wikiReportOnRelations += wikiReport + '\n|-\n'
     504                                        if 'addRouteToNetwork' in sideEffects:
     505                                            newRelation = Relation(network)
     506                                            newmember = RelationMember(roleFromRouteCheck, aRelation)
     507                                            if logVerbosity > 9: print newRelation.getMembersCount(), ' ',i, ' ', newmember
     508                                            newRelation.addMember( i, newmember)
     509                                            commandsList = []
     510                                            commandsList.append(Command.ChangeCommand(network, newRelation))
     511                                            note = aRelation.get('note')
     512                                            if not(note):
     513                                                note = ''
     514                                            Main.main.undoRedo.add(Command.SequenceCommand("Adding " + note + " to network", commandsList))
     515                                            commandsList = []
     516                                            if logVerbosity > 9: print 'Added newly found RCN route relation to network: ', note
     517                                            i+=1
     518                if rcnNetworkCountForNode < expected_rcn_route_relations:
     519                    if logVerbosity > 9: print 'Node ', rcn_ref, ' only has ', rcnNetworkCountForNode, ' rcn routes connected to it'
     520                    if 'createWikiReport' in sideEffects: wikiReportOnNodes += '|align="right" | ' + rcn_ref + '||align="right" | {{Node|' + str(node.getId()) + '}}||align="right" |' + str(roads) + ' ||align="right" style="color:red" | ' + str(rcnNetworkCountForNode) + '\n|-\n'
     521
     522        i+=1
     523    if logVerbosity > 19: print
     524    if 'createWikiReport' in sideEffects:
     525        wikiReportOnNodes += ('|-\n|}\n')
     526        wikiReportOnRelations += ('|-\n|}\n<br style="clear:left;" />\n')
     527        fh = open('C:/wikiReport.txt', 'a')
     528        fh.write(wikiReportOnNodes)
     529        fh.write(wikiReportOnRelations)
     530        fh.close()
     531
     532
     533dummy_way = Way()
     534dummy_relation = Relation()
     535
     536mv = getMapView()
     537if mv and mv.editLayer and mv.editLayer.data:
     538    if 'createWikiReport' in sideEffects:
     539        fh = open('C:/wikiReport.txt', 'w')
     540        fh.close()
     541    selectedRelations = mv.editLayer.data.getSelectedRelations()
     542
     543    if not(selectedRelations):
     544        JOptionPane.showMessageDialog(Main.parent, "Please select a route, network or collection relation")
     545    else:
     546        for relation in selectedRelations:
     547            if logVerbosity> 49: print relation
     548            if relation.hasIncompleteMembers():
     549                if 'downloadIncompleteMembers' in sideEffects:
     550                    print 'Downloading referrers for ', str(relation.get('name')), ' ', str(relation.get('note'))
     551                    DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer ))
     552                    continue
     553                else:
     554                    JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the relations first')
     555                    break
     556            if relation.get('network') == 'rcn':
     557                relationType = relation.get('type')
     558                if relationType == 'route':
     559                    checkRCNroute(relation)
     560                elif relationType == 'network':
     561                    checkNetwork(relation)
     562                elif relationType == 'collection':
     563                    for collectionMember in relation.getMembers():
     564                        if collectionMember.isRelation():
     565                            networkRelation = collectionMember.getRelation()
     566                            if networkRelation.hasIncompleteMembers():
     567                                if 'downloadIncompleteMembers' in sideEffects:
     568                                    print 'Downloading referrers for ', relation.get('name')
     569                                    DownloadRelationMemberTask.run(DownloadRelationMemberTask(networkRelation, networkRelation.getIncompleteMembers(), mv.editLayer ))
     570                                    continue
     571                                else:
     572                                    JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the network relations first')
     573                                    break
     574                            checkNetwork(networkRelation)
     575
     576}}}