Changes between Version 3 and Version 4 of Help/Plugin/Scripting/Python/RCN_Route_Validator


Ignore:
Timestamp:
2012-10-20T22:23:47+02:00 (13 years ago)
Author:
Polyglot
Comment:

Latest version with a few less bugs and some extra functionality

Legend:

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

    v3 v4  
    55'''
    66CheckRouteOrNetworkOrCollectionOfRoutes.jy
    7 - Validation of a rcn route relation
     7- Validation of a rXn route relation
    88
    99This code is released under the GNU General
     
    4343import org.openstreetmap.josm.actions.AutoScaleAction as AutoScaleAction
    4444import re, time
    45 
     45import codecs
     46
     47
     48# the file name where the report for the wiki goes, needs to be configurable
     49wikiReportFN = 'C:/wikiReport.txt'
    4650# comment to disable side effect
    4751sideEffects = {
    4852    '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
     53    #'removeNameRefKey_xx-yyAndcreated_by': None,
     54    #'modifyNoteTo_xx-yy': None,
     55    #'flipOrderOfMembers': None, # such that ways go from lower rXn_ref to higher rXn_ref
     56    #'sortRouteRelations': None,
     57    #'sortNetworkRelations': None, # not implemented yet
     58    #'removeNodesFromRoutes': None,
     59    #'addNodes2Routes': None,
     60    #'selectObjects': None,
     61    #'zoomToSelection': None,
     62    #'downloadReferrersForNodes': None, # This will download all ways and relations for nodes with an rXn_ref
     63    #'downloadReferrersForWays': None, # This will download all relations for ways that have an endnode with an rXn_ref
    5764    #'downloadIncompleteMembers': None,
    5865    'createWikiReport': None,
     66        'reportWhenWaysAreUsedInAnotherRelationToo': None,
     67    #'addFixmeTODOtags': None, # This will add todo tags to the data containing problems,
     68                              # the intention is that these tags are removed before uploading,
     69                              # once the reported problems are resolved
    5970    #'createGarminGPX': None, # not implemented yet
    6071    #'checkOneWays = False, # not implemented yet
    6172    }
    6273
    63 logVerbosity = 10
     74logVerbosity = 20
    6475'''
    657610: only report problems that require attention
     
    8192    nextNode = None
    8293    routeToReturn = Relation(route)
    83     # Which node has the lower rcn_ref?
     94    # Which node has the lower rXn_ref?
    8495    lowestNodeInt = 10000; lowPos = 0
    8596    for nodeTuple in beginAndEndnodes:
     
    100111    node10: way10, way11
    101112    w1,w2,w3,w5,w6,w7,w4,w8,w9,w10'''
    102     # At this point nextNode contains the unique ID of the node with the lower rcn_ref
     113    # At this point nextNode contains the unique ID of the node with the lower rXn_ref
    103114    members=nodesDict[nextNode]
    104115    processedMembers = {}; inBranch = False
     
    144155                                                                                        bo in ['yes', '1', 'true'] or
    145156                                                                                        co in ['yes', '1', 'true'])
    146                         if oneway == '-1': pass # TODO this needs to be taken in consideration
     157                        if oneway == '-1': pass # TODO this also needs to be taken in consideration
    147158                    if way.getNode(0).getUniqueId() == nextNode:
    148159                        break
     
    168179        if len(nodesDict)<3: break
    169180        lowPos += 1
    170     #print 'before return', routeToReturn
     181    print 'before return', routeToReturn
    171182    return routeToReturn
    172183
     
    176187        if member.isWay():
    177188            way = member.getWay()
     189            #print dir(way)
    178190            if logVerbosity > 49:
    179191                print way.getKeys()
     
    202214    return listIsContinuous
    203215
    204 def checkRCNroute(route, aDownloadWasNeeded):
     216def checkRxNroute(route, networklevel, aDownloadWasNeeded):
    205217    if aDownloadWasNeeded:
    206218        return None, False, ''
     
    217229        name = route.get('name')
    218230        if name:
    219             if reNumberDashNumber.match(name):
    220                 print 'removing name when it is of the form ##-##'
    221                 newRelation.remove('name')
    222                 relationChanged = True
     231            #if reNumberDashNumber.match(name):
     232            print 'removing name'
     233            newRelation.remove('name')
     234            relationChanged = True
    223235        else:
    224236            name = ''
     
    238250
    239251    fixme = route.get('fixme')
    240     rcn_refs = []; route_relation_names = []; memberslist = []; roleInNetwork = ''
     252    rXn_refs = []; actual_rXn_refs = []; route_relation_names = []
     253    memberslist = []; waymembersinlist = 0; roleInNetwork = ''
    241254    sameNodeNumberRepeated = False
    242255    allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = []; branch = None
    243256    allWaysgoingFromLowerToHigherBeyondEndOfRoute = []; allWaysgoingFromHigherToLowerBeyondEndOfRoute = []
    244     nodesWithrcn_ref = {}; likelyCandidateNodesForActualStartOfRoute = {}
    245     tentacle = 0; tentacles = {}; routeHasStarted = False; high_rcn_refEncountered = 0
    246     rcn_refAsInt = None
     257    nodesWithrXn_ref = {}; likelyCandidateNodesForActualStartOfRoute = {}
     258    tentacle = 0; tentacles = {}; routeHasStarted = False; high_rXn_refEncountered = 0
     259    rXn_refAsInt = None
    247260    # tentacles is a nested list of all the segments of ways wich are present before the actual start of the route
    248     # sequence, UID of node with rcn_ref, list with ways, reference to next tentacle sequence
    249     # 1st level: rcn_refs
    250     # 2nd level: rcn_ref, tentacle sequence, ways, next tentacle
     261    # sequence, UID of node with rXn_ref, list with ways, reference to next tentacle sequence
     262    # 1st level: rXn_refs
     263    # 2nd level: rXn_ref, tentacle sequence, ways, next tentacle
    251264    # {40: [[1, [5n], 2],
    252265    #       [2, [3n], 3],
     
    262275    if 'sortRouteRelations' in sideEffects: nodesForSorting = {}; beginAndEndNodes = []
    263276    routeMembers = route.getMembers()
     277    modified = False
     278
    264279    for member in routeMembers:
     280        memberslist.append(member)
    265281        if member.isWay():
    266             if high_rcn_refEncountered: high_rcn_refEncountered += 1
     282            waymembersinlist += 1
     283            if high_rXn_refEncountered: high_rXn_refEncountered += 1
    267284            role = member.getRole()
    268285            # make a Python list out of the members, in case we want to simply flip all of them
    269             # this would happen if we encounter the high rcn_ref before the low rcn_ref
    270             memberslist.append(member)
     286            # this would happen if we encounter the high rXn_ref before the low rXn_ref
    271287            way = member.getWay()
    272288            if logVerbosity > 49: print way.get('name')
     
    292308                    nodesForSorting[endnodeId].append(member)
    293309
    294                 rcn_ref = endnode.get('rcn_ref')
    295                 if rcn_ref:
    296                     rcn_refAsInt = int(rcn_ref.replace("(","").replace(")",""))
    297                     if 'sortRouteRelations' in sideEffects: beginAndEndNodes.append([rcn_refAsInt, endnodeId])
    298                     # keep track of distinct rcn_ref numbers in a list
    299                     if not(rcn_refAsInt in rcn_refs):
    300                         if len(rcn_refs): high_rcn_refEncountered += 1; tentacle = 0
    301                         rcn_refs.append(rcn_refAsInt)
     310                rXn_ref = endnode.get(networklevel + '_ref')
     311                if rXn_ref:
     312                    rXn_ref_digits = ''
     313                    for character in rXn_ref:
     314                        try:
     315                            int(character)
     316                            rXn_ref_digits += character
     317                        except: pass
     318                    if rXn_ref_digits and rXn_ref_digits==rXn_ref:
     319                        rXn_refAsInt = int(rXn_ref_digits)
     320                    else:
     321                        rXn_refAsInt = -1
     322
     323                        print rXn_ref
     324                    if 'sortRouteRelations' in sideEffects: beginAndEndNodes.append([rXn_refAsInt, endnodeId])
     325                    # keep track of distinct rXn_ref numbers in a list
     326                    if not(rXn_refAsInt in rXn_refs):
     327                        if len(rXn_refs): high_rXn_refEncountered += 1; tentacle = 0
     328                        rXn_refs.append(rXn_refAsInt)
     329                        if rXn_refAsInt == -1:
     330                            actual_rXn_refs.append(rXn_ref)
     331                        else:
     332                            actual_rXn_refs.append(str(rXn_refAsInt).zfill(2))
    302333                    else:
    303334                        sameNodeNumberRepeated = True
    304                     # keep track of node IDs with an rcn_ref on them
    305                     if not(rcn_refAsInt in nodesWithrcn_ref):
    306                         nodesWithrcn_ref[rcn_refAsInt] = []
    307                     nodesWithrcn_ref[rcn_refAsInt].append(endnodeId)
     335                    # keep track of node IDs with an rXn_ref on them
     336                    if not(rXn_refAsInt in nodesWithrXn_ref):
     337                        nodesWithrXn_ref[rXn_refAsInt] = []
     338                    nodesWithrXn_ref[rXn_refAsInt].append(endnode)
    308339                    referrersForNode = endnode.getReferrers(); networkNotFoundForNode = True
    309340                    for referrer in referrersForNode:
    310341                        if referrer.getType() is dummy_relation.getType():
    311342                            # This node belongs to a relation
    312                             if referrer.get('type') in ['network'] and referrer.get('network') in ['rcn']:
     343                            if referrer.get('type') in ['network'] and referrer.get('network') in [networklevel]:
    313344                                # and we have a winner
    314345                                networkNotFoundForNode = False
     
    323354                        if 'downloadReferrersForNodes' in sideEffects:
    324355                            aDownloadWasNeeded = True
    325                             print "Downloading referrers for ", endnode.get('rcn_ref'), ' ', wayNodes
     356                            print "Downloading referrers for ", endnode.get(networklevel + '_ref'), ' ', wayNodes
    326357                            DownloadReferrersAction.downloadReferrers(mv.editLayer, wayNodes)
    327358                            return None, False, ''
    328359                        else:
    329                             print "Would download referrers for ", endnode.get('rcn_ref'), ' ', wayNodes
     360                            print "Would download referrers for ", endnode.get(networklevel + '_ref'), ' ', wayNodes
    330361                           
    331362            # *** Now let's process the ways ***
     
    353384                        if firstNodeUid in likelyCandidateNodesForActualStartOfRoute and likelyCandidateNodesForActualStartOfRoute[firstNodeUid]>1:
    354385                            routeHasStarted = True
    355                         if firstNode.get('rcn_ref'):
    356                             if logVerbosity > 49: print 'rcn_ref', firstNode.get('rcn_ref'), 'found in ', firstNode.getUniqueId()
    357                             # This is not the first member anymore and the first node has an rcn_ref and the member has a role,
     386                        if firstNode.get(networklevel + '_ref'):
     387                            if logVerbosity > 49: print 'rXn_ref', firstNode.get(networklevel + '_ref'), 'found in ', firstNode.getUniqueId()
     388                            # This is not the first member anymore and the first node has an rXn_ref and the member has a role,
    358389                            # so we have to assign what we thought was the start of the route to one of our tentacles
    359390                            tentacle +=1; reference = 0; interestingNodeId = None; tentacledescription = []
     
    380411                            allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = []; branch = None
    381412                            if tentacledescription:
    382                                 if rcn_refAsInt and not(rcn_refAsInt in tentacles):
    383                                     tentacles[rcn_refAsInt] = []
    384                                 tentacles[rcn_refAsInt].append(tentacledescription)
     413                                if rXn_refAsInt and not(rXn_refAsInt in tentacles):
     414                                    tentacles[rXn_refAsInt] = []
     415                                tentacles[rXn_refAsInt].append(tentacledescription)
    385416                    else:
    386417                        # no role on way means this is the actual start of our route
     
    395426                            # it should have gone to both 'branches', so we create a shallow copy
    396427                            allWaysgoingFromLowerToHigher = allWaysgoingFromHigherToLower[:]; branch = None
    397                             if not(rcn_refAsInt in tentacles):
    398                                 tentacles[rcn_refAsInt] = []
    399                             tentacles[rcn_refAsInt].append(tentacledescription)
    400                 if high_rcn_refEncountered > 1:
    401                     # We're past the first high rcn_ref
     428                            if not(rXn_refAsInt in tentacles):
     429                                tentacles[rXn_refAsInt] = []
     430                            tentacles[rXn_refAsInt].append(tentacledescription)
     431                if high_rXn_refEncountered > 1:
     432                    # We're past the first high rXn_ref, time to disover more tentacles
    402433                    if role:
    403434                        if role in ['forward']:
     
    405436                        else:
    406437                            lastNode=wayNodes[0]
    407                         if lastNode.get('rcn_ref'):
    408                             print 'rcn_ref', lastNode.get('rcn_ref'), 'found in ', lastNode.getUniqueId()
     438                        if lastNode.get(networklevel + '_ref'):
     439                            print 'rXn_ref', lastNode.get(networklevel + '_ref'), 'found in ', lastNode.getUniqueId()
    409440                            tentacle +=1; reference = 0; interestingNodeId = None; tentacledescription = []
    410441                            if interestingNodeId and lastNode.getUniqueId() == interestingNodeId:
     
    416447                            allWaysgoingFromLowerToHigherBeyondEndOfRoute = []; allWaysgoingFromHigherToLowerBeyondEndOfRoute = []; branch = None
    417448                            if tentacledescription:
    418                                 if rcn_refAsInt and not(rcn_refAsInt in tentacles):
    419                                     tentacles[rcn_refAsInt] = []
    420                                 tentacles[rcn_refAsInt].append(tentacledescription)
     449                                if rXn_refAsInt and not(rXn_refAsInt in tentacles):
     450                                    tentacles[rXn_refAsInt] = []
     451                                tentacles[rXn_refAsInt].append(tentacledescription)
    421452            if logVerbosity > 49: print tentacle, repr(tentacles)
    422453                           
    423454            if role and role in ['forward', 'backward']:
    424                 # if there is a role, it might be part of the route proper when it branches
    425                 # this is what we suppose, if we encounter another node with a low rcn_ref, we add what we already had
     455                # if there is a role, it might be part of the route proper when it starts or ends in a fork
     456                # this is what we suppose, if we encounter another node with a low rXn_ref, we add what we already had
    426457                # to the tentacles structure and clear fromLowToHigh
    427458                if not(branch):                   
     
    438469                    print way.getNodesCount(), 'startnode', wayNodes[0], 'endnode', wayNodes[-1]
    439470                    print 'roundabout', roundabout
    440                     print wayNodes[-1].get('rcn_ref'),not(member.getUniqueId() == routeMembers[-1].getUniqueId())
     471                    print wayNodes[-1].get(networklevel + '_ref'),not(member.getUniqueId() == routeMembers[-1].getUniqueId())
    441472                if role in ['forward'] and (wayNodes[-1] in lastNodesBeforeSplit or wayNodes[-1] in roundabout):
    442473                    branch = 'HigherToLower'
     
    444475                    branch = 'HigherToLower'
    445476                   
    446                 elif branch == 'LowerToHigher' and not(allWaysgoingFromHigherToLower) and wayNodes[-1].get('rcn_ref') and not(member.getUniqueId() == routeMembers[-1].getUniqueId()):
    447                     # 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
     477                elif branch == 'LowerToHigher' and not(allWaysgoingFromHigherToLower) and wayNodes[-1].get(networklevel + '_ref') and not(member.getUniqueId() == routeMembers[-1].getUniqueId()):
     478                    # This is for when the route starts forked from a different rXn node (split node situation), we don't want it to kick in for the last member of the route
    448479                    branch = 'HigherToLower'
    449480                elif not(branch == 'HigherToLower'):
    450481                    branch = 'LowerToHigher'
    451482                print branch
    452                 if high_rcn_refEncountered < 2:
     483                if high_rXn_refEncountered < 2:
    453484                    if branch == 'LowerToHigher':
    454485                        allWaysgoingFromLowerToHigher.append(member)
     
    463494                branch = None; roundabout = []
    464495                routeHasStarted = True
    465                 if high_rcn_refEncountered < 2:
     496                if high_rXn_refEncountered < 2:
    466497                    allWaysgoingFromLowerToHigher.append(member)
    467498                    allWaysgoingFromHigherToLower.append(member)
     
    471502            if way.get('junction') == 'roundabout':
    472503                roundabout = way.getNodes()
    473         elif member.isNode():
    474             node = member.getNode()
    475             #commandsList.append(Command.ChangeCommand(route, sortedRelation))
    476             #Main.main.undoRedo.add(Command.SequenceCommand("Sorted route relation", commandsList))           
    477504        i+=1
    478     #if modified:
    479         #commandsList.append(Command.ChangeCommand(route, newRelation))
    480         #Main.main.undoRedo.add(Command.SequenceCommand("Removing way which has no nodes", commandsList))
    481         #commandsList = []
     505    modified = False
     506    if 'removeNodesFromRoutes' in sideEffects:
     507        newRelation = Relation(route)
     508        for member in routeMembers:
     509            if member.isNode():
     510                node = member.getNode()
     511                newRelation.removeMembersFor(node)
     512                modified = True
     513    if modified:
     514        commandsList.append(Command.ChangeCommand(route, newRelation))
     515        Main.main.undoRedo.add(Command.SequenceCommand("Removing nodes with rXn_ref", commandsList))
     516        commandsList = []
     517    modified = False
     518    if 'addNodes2Routes' in sideEffects:
     519        newRelation = Relation(route)
     520        # (re)add nodes to route
     521        lowrXn_ref2BDone = True; lowPos = 0
     522        for nodeNumber in sorted(nodesWithrXn_ref.keys()):
     523            for node in nodesWithrXn_ref[nodeNumber]:
     524               newRelation.removeMembersFor(node)
     525               newMember = RelationMember("",node)
     526               if lowrXn_ref2BDone:
     527                   newRelation.addMember(lowPos, newMember)
     528                   lowPos += 1
     529               else:
     530                   newRelation.addMember(newRelation.getMembersCount(), newMember)
     531            lowrXn_ref2BDone = False; modified = True
     532
     533    if modified:
     534        commandsList.append(Command.ChangeCommand(route, newRelation))
     535        Main.main.undoRedo.add(Command.SequenceCommand("Adding nodes with rXn_ref", commandsList))
     536        commandsList = []
    482537
    483538    continuous_forward = True; continuous_backward = True
     
    490545                print route
    491546                print sortedRelation
    492             commandsList.append(Command.ChangeCommand(route, sortedRelation))
    493             Main.main.undoRedo.add(Command.SequenceCommand("Sorted route relation", commandsList))           
     547
    494548            allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = []
    495 
    496             routeMembers = route.getMembers(); i=0
     549            routeMembers = sortedRelation.getMembers(); i=0
    497550            for member in routeMembers:
    498551                if member.isWay():
    499552                    role = member.getRole()
    500553                    if i==0:
    501                         lastNodesBeforeSplit = [wayNodes]
     554                        lastNodesBeforeSplit = [wayNodes] # why nodes in plural? situations occur where the branch starts on a roundabout
    502555                    if role and role in ['forward', 'backward']:
    503556                        if not(branch):
     
    516569                        elif role in ['backward'] and wayNodes[0] in lastNodesBeforeSplit:
    517570                            branch = 'HigherToLower'
    518                         elif wayNodes[-1].get('rcn_ref') and not(member.getUniqueId() == routeMembers[-1].getUniqueId()): # not(allWaysgoingFromHigherToLower) and ## this last part is probably not necessary anymore
    519                             # 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
     571                        elif wayNodes[-1].get(networklevel + '_ref') and not(member.getUniqueId() == routeMembers[-1].getUniqueId()): # not(allWaysgoingFromHigherToLower) and ## this last part is probably not necessary anymore
     572                            # This is for when the route starts forked from a different rXn node (split node situation), we don't want it to kick in for the last member of the route
    520573                            branch = 'HigherToLower'
    521574                        elif not(branch == 'HigherToLower'):
     
    534587                i+=1
    535588            continuous_forward = checkForContinuity(allWaysgoingFromLowerToHigher)
    536         #else:
     589            if continuous_forward:
     590                # we only want to store the sorted relation, when sorting actually succeeded in getting it continuous
     591                commandsList.append(Command.ChangeCommand(route, sortedRelation))
     592                Main.main.undoRedo.add(Command.SequenceCommand("Sorted route relation", commandsList))           
    537593    else:
    538594        # a route relation with only one way member
     
    545601    print continuous_forward, continuous_backward
    546602
    547     for rcn_nodeTentacles in tentacles:
    548         for seq, tentacleMember, next in tentacles[rcn_nodeTentacles]:
    549             print rcn_nodeTentacles, ' ', seq, ' ', next, ' ', checkForContinuity(tentacleMember)
    550     # Drawing conclusions about rcn_refs
    551     if logVerbosity > 39: print rcn_refs
     603    for rXn_nodeTentacles in tentacles:
     604        for seq, tentacleMember, next in tentacles[rXn_nodeTentacles]:
     605            print rXn_nodeTentacles, ' ', seq, ' ', next, ' ', checkForContinuity(tentacleMember)
     606           
     607    # Drawing conclusions about rXn_refs
     608    fixmetodo = ''
     609    if logVerbosity > 39: print rXn_refs
    552610    if sameNodeNumberRepeated:
    553         rcn_refs.append(rcn_refs[0])
    554     newNote = note = repr(rcn_refs)
     611        rXn_refs.append(rXn_refs[0])
     612    newNote = note = repr(rXn_refs)
    555613    sortedRelation = route
    556     if len(rcn_refs) > 1:
    557         #newRelation = Relation(route)
     614    if len(rXn_refs) > 1:
    558615        relationChanged = False
    559616
    560         if rcn_refs[0] > rcn_refs[1]:
    561             rcn_refs.sort()
    562             if len(memberslist)>1 and 'flipOrderOfMembers' in sideEffects:
     617        if rXn_refs[0] > rXn_refs[1]:
     618            rXn_refs.sort()
     619            if waymembersinlist>1 and 'flipOrderOfMembers' in sideEffects:
    563620                for member in reversed(memberslist):
    564621                    sortedRelation.addMember( sortedRelation.getMembersCount(), member)
     
    568625                commandsList = []
    569626        note = route.get('note')
    570         newNote = str(rcn_refs[0]).zfill(2) + '-' + str(rcn_refs[1]).zfill(2)
     627        if not(-1 in rXn_refs):
     628            rXn_refs.sort()
     629            newNote = str(rXn_refs[0]).zfill(2) + '-' + str(rXn_refs[-1]).zfill(2)
     630        else:
     631            newNote = ''
     632            for ref in actual_rXn_refs:
     633               newNote+=ref + '-'
     634            newNote = newNote[:-1]
    571635        if logVerbosity > 49: print note, newNote
    572636        if 'modifyNoteTo_xx-yy' in sideEffects:
    573             if not(note) or note != newNote:
     637            if (not(note) or note != newNote) and rXn_refs[0] != rXn_refs[-1]:
     638                newRelation = Relation(route)
     639                #print newRelation.getUniqueId()
     640                #print route.getUniqueId()
    574641                if not(note): note = 'nothing'
    575642                newRelation.put('note', newNote)
     
    578645           
    579646                Main.main.undoRedo.add(Command.SequenceCommand("Changing note from " + note + ' to ' + newNote, commandsList))
    580                 if logVerbosity > 9: print 'Flipping members order for ', note
    581647                commandsList = []
    582648
     
    587653        wikiEN = ''
    588654    else:
    589         if logVerbosity > 9: print 'less than 2 end nodes with rcn_ref found for route', newNote
    590         wikiEN = 'style="color:red" | ' + repr(rcn_refs) + ' - ?'
     655        if logVerbosity > 9: print 'less than 2 end nodes with '+networklevel+'_ref found for route', newNote
     656        wikiEN = 'style="color:red" | ' + repr(rXn_refs) + ' - ?'
     657        if 'addFixmeTODOtags' in sideEffects and not(route.get(networklevel+':external_connection')) and not(route.get('roundtrip')):
     658            newRelation = Relation(route)
     659            #print newRelation.getUniqueId()
     660            #print route.getUniqueId()
     661            fixmetodo = 'less than 2 end nodes with '+networklevel+'_ref found for route' + newNote + ' ' + repr(rXn_refs) + ' ' + note
     662            newRelation.put('fixmetodo', fixmetodo)
     663            relationChanged = True
     664            commandsList.append(Command.ChangeCommand(route, newRelation))
     665       
     666            Main.main.undoRedo.add(Command.SequenceCommand("report that only one '+networklevel+'_ref was found " + note + ' to ' + newNote, commandsList))
     667            commandsList = []
    591668    if fixme and not(continuous_forward or continuous_backward):
    592669        if logVerbosity > 9: print 'FIXME flag is INCOMPLETE for route', newNote
     
    596673    else:
    597674        wikiCF = 'align="right" style="color:red" | NOT continuous'
    598         if logVerbosity > 9: print 'route ',newNote,' is NOT CONTINUOUS in the forward direction'
     675        if logVerbosity > 9: print 'route ',newNote,' is NOT CONTINUOUS going from xx to yy; xx<yy'
    599676        if logVerbosity > 49: print 'L2H:', allWaysgoingFromLowerToHigher
     677        if not(fixme) and 'addFixmeTODOtags' in sideEffects:
     678            newRelation = Relation(route)
     679            #print newRelation.getUniqueId()
     680            #print route.getUniqueId()
     681            fixmetodo += ' ' + newNote + 'is not continuous going from xx to yy; xx<yy'
     682            newRelation.put('fixmetodo', fixmetodo)
     683            relationChanged = True
     684            commandsList.append(Command.ChangeCommand(route, newRelation))
     685            Main.main.undoRedo.add(Command.SequenceCommand("report that  " + note + ' is not continuous going from xx to yy; xx<yy' , commandsList))
     686            commandsList = []
    600687    if continuous_backward:
    601688        wikiCB = 'align="right" | continuous'
     
    603690    else:
    604691        wikiCB = 'align="right" style="color:red" | NOT continuous'
    605         if logVerbosity > 9: print 'route ',newNote,' is NOT CONTINUOUS in the backward direction'
     692        if logVerbosity > 9: print 'route ',newNote,' is NOT CONTINUOUS coming back from yy to xx; xx<yy'
    606693        if logVerbosity > 49: print 'H2L: ', allWaysgoingFromHigherToLower
     694        if not(fixme) and 'addFixmeTODOtags' in sideEffects:
     695            newRelation = Relation(route)
     696            #print newRelation.getUniqueId()
     697            #print route.getUniqueId()
     698            fixmetodo += ' ' + newNote + 'is not continuous coming back from yy to xx; xx<yy'
     699            newRelation.put('fixmetodo', fixmetodo)
     700            relationChanged = True
     701            commandsList.append(Command.ChangeCommand(route, newRelation))
     702       
     703            Main.main.undoRedo.add(Command.SequenceCommand("report that  " + note + ' is not continuous coming back from yy to xx; xx<yy' , commandsList))
     704            commandsList = []
    607705    print
    608706    if fixme:
     
    610708    else:
    611709        wikiFM = ' | '
    612     if fixme or not(continuous_forward) or not(continuous_backward) or (len(rcn_refs)<2 and not(route.get('rcn:external_connection'))):
    613         problem = True
     710    if fixme or not(continuous_forward) or not(continuous_backward) or (len(rXn_refs)<2 and not(route.get(networklevel+':external_connection'))):
     711        problem = 'yes'
    614712    else:
    615         problem = False
    616 
    617     return roleInNetwork, problem, '|align="right" | ' + note + '||align="right" | {{BrowseRoute|' + str(route.getId()) + '}}||align="right" ' + wikiFM + ' ||' + wikiCF + ' ||' + wikiCB  + ' ||' + wikiEN + '\n'
    618 
    619 def checkNetwork(network, aDownloadWasNeeded):
     713        problem = ''
     714
     715    print 'PROBLEM:', problem
     716    return str(roleInNetwork), problem, '|align="right" | ' + str(note) + '||align="right" | {{BrowseRoute|' + str(route.getId()) + '}}||align="right" ' + str(wikiFM) + ' ||' + str(wikiCF) + ' ||' + str(wikiCB)  + ' ||' + str(wikiEN) + '\n'
     717
     718def sortNetwork(network):
     719    # While making a list of all the nodes in the relation with an rXn_ref, find the node with the lowest rXn_ref in the network, not necessarily 01 and bring it to the first position
     720    # Look at the ways connecting to this node and their parent route relations with network=rXn
     721    # For all these relations, make a list of all the rXn_ref numbers, they lead to and remember the UIDs of these nodes and keep a ref to the relations
     722    # Split this list in two, one for internal routes, another for route relations connecting to a foreign network (so the ones with a connection role)
     723    # Sort both lists and bring the relations in positions following the first node
     724    # Do the same for all the relations in the second list
     725    # Then add the lowest rXn_ref number and remove it from the general todo list of rXn_ref nodes that were encountered in internal route relations
    620726    name = network.get('name')
    621727    if logVerbosity>19:
     
    623729        print name
    624730        print '********************************************'
    625     if 'createWikiReport' in sideEffects:
    626         wikiReportOnNodes = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name +
    627                              '\n|-\n!style="width:2.5em" | Node\n!Link\n! # Roads\n! # Relations\n|-\n')
    628         wikiReportOnRelations = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name +
    629                                  '\n|-\n!style="width:2.5em" | note\n!link\n!fixme\n! forward\n! backward\n! end nodes\n|-\n')
    630     i=1
     731    lowestrXn_refInNetwork=9999; listOfNodeMembersSeen = []
     732    dictionaryWithAllNodesBelongingToThisNetwork = {}; dictionaryWithAllNodesBelongingToNeighbouringNetworks = {}
     733    ListOfInternalRoutesSeen = []; ListOfExternalRoutesSeen = []; dictionaryLinkingRoutesToNotes = {}
     734    members = network.getMembers()
     735    # Find a member node with the lowestrXn_refInNetwork and bring it to the front if such node is not there yet
     736    firstMember = members[0]
     737    if firstMember.isRelation() or firstMember.isNode() and int(firstMember.getNode().get(networklevel + '_ref')) != lowestrXn_refInNetwork:
     738        memberNode = None
     739        for networkMember in members:
     740            if networkMember.isNode():
     741                memberNode = networkMember.getNode()
     742                if int(memberNode.get(networklevel + '_ref')) == 1: break
     743        if memberNode:
     744            network.removeMembersFor(memberNode)
     745            network.addMember(0, networkMember)
     746   
    631747    for networkMember in network.getMembers():
    632         if networkMember.isRelation():
    633             routeRelation = networkMember.getRelation()
    634             if routeRelation.get('network') == 'rcn':
    635                 if routeRelation.hasIncompleteMembers():
    636                     name = aRelation.get('name')
    637                     if not(name): name = ''
    638                     note = aRelation.get('note')
    639                     if not(note): note = ''
    640                     network = aRelation.get('network')
    641                     if not(network): network = ''
    642                     if 'downloadIncompleteMembers' in sideEffects:
    643                         aDownloadWasNeeded = True
    644                         print 'Downloading incomplete members for', note
    645                         DownloadRelationMemberTask.run(DownloadRelationMemberTask(routeRelation, routeRelation.getIncompleteMembers(), mv.editLayer ))
    646                         time.sleep(1)
    647                         continue
    648                     else:
    649                         JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete members of the route relations first: ' + network + ' ' + note + ' ' + name)
    650                         break
    651                 roleFromRouteCheck, problemReported, wikiReport = checkRCNroute(routeRelation, aDownloadWasNeeded)
    652                 if problemReported and 'createWikiReport' in sideEffects:
    653                     wikiReportOnRelations += wikiReport + '\n|-\n'
    654                 role = networkMember.getRole()
    655                 if logVerbosity > 29 and role != roleFromRouteCheck:
    656                     print
    657                     print 'Role in network is ', role
    658                     print 'Maybe this should be: ', roleFromRouteCheck
    659748        if networkMember.isNode():
    660749            node = networkMember.getNode()
    661             rcn_ref = node.get('rcn_ref')
    662             expected_rcn_route_relations = node.get('expected_rcn_route_relations')
    663             if expected_rcn_route_relations:
    664                 expected_rcn_route_relations = int(expected_rcn_route_relations)
    665             else:
    666                 expected_rcn_route_relations = 3
    667             if rcn_ref:
    668                 if logVerbosity > 39: print rcn_ref
     750            rXn_ref = node.get(networklevel + '_ref')
     751            if int(rXn_ref) == 1:
    669752                referrersForNode = node.getReferrers()
    670                 networkNotFoundForNode = True
    671                 for referrer in referrersForNode:
    672                     if referrer.getType() is dummy_relation.getType():
    673                         if referrer.get('type') in ['network'] and referrer.get('network') in ['rcn']:
    674                             networkNotFoundForNode = False
    675                             break
    676                 if networkNotFoundForNode and 'downloadReferrersNodes' in sideEffects:
    677                     aDownloadWasNeeded = True
    678                     if 'selectObjects' in sideEffects: Main.main.getCurrentDataSet().setSelected(node)
    679                     if 'zoomToSelection' in sideEffects: AutoScaleAction.zoomToSelection()
    680                     #selectedNode = mv.editLayer.data.getSelected()
    681                     print 'Downloading referrers for ', node.get('rcn_ref')
    682                     DownloadReferrersAction.downloadReferrers(mv.editLayer, node)
    683 
    684                 rcnNetworkCountForNode = roads = 0
    685753                for referrer in referrersForNode:
    686754                    if referrer.getType() is dummy_way.getType():
    687                         if referrer.get('highway'): roads += 1
    688755                        referrersForWay = referrer.getReferrers()
    689                         if len(referrersForWay) < 1 and 'downloadReferrersForWays' in sideEffects:
    690                             aDownloadWasNeeded = True
    691                             if 'selectObjects' in sideEffects: Main.main.getCurrentDataSet().setSelected(referrer)
    692                             if 'zoomToSelection' in sideEffects: AutoScaleAction.zoomToSelection()
    693                             print 'Downloading referrers for ', referrer.get('name') , ' ', rcn_ref
    694                             DownloadReferrersAction.downloadReferrers(mv.editLayer, referrer)
    695 
    696756                        for wayReferrer in referrersForWay:
    697757                            if wayReferrer.getType() is dummy_relation.getType():
    698758                                aRelation = wayReferrer
    699                                 rcnRelationWeWantToProcess = False # We need this again further on, when deciding whether or not to add this relation to the network
    700                                 if aRelation.get('type') == 'route' and aRelation.get('network') == 'rcn' and not(aRelation.get('ref') in ['RUR','NRR','NRW','2LR','3LR','KAI','EHR','DFR','WBR','Nk']):
    701                                     # The check on the ref is for Germany, where many rcn networks run crisscross through another.
    702                                     # We wouldn't want to get entangled in that mess.
    703                                     # The list is continuously getting longer, of course. But it's the best we can do here
    704                                     rcnRelationWeWantToProcess = True
    705                                     rcnNetworkCountForNode+=1
     759                                if aRelation.get('type') == 'route' and aRelation.get('network') ==networklevel and not(aRelation.get('ref')):
     760                                    rXnNetworkCountForNode+=1
    706761                                    if aRelation.hasIncompleteMembers():
    707762                                        name = aRelation.get('name')
     
    726781                                        networkMembersList.append(routeRelation.getUniqueId())
    727782                                routeId = aRelation.getUniqueId()
    728                                 if rcnRelationWeWantToProcess and not(routeId in networkMembersList):
     783                                if rXnRelationWeWantToProcess and not(routeId in networkMembersList):
    729784                                    roleFromRouteCheck, problemReported, wikiReport = checkRCNroute(aRelation, aDownloadWasNeeded)
    730785                                    if problemReported and 'createWikiReport' in sideEffects:
     
    744799                                        if logVerbosity > 9: print 'Added newly found RCN route relation to network: ', note
    745800                                        i+=1
    746                 if rcnNetworkCountForNode < expected_rcn_route_relations:
    747                     if logVerbosity > 9: print 'Node ', rcn_ref, ' only has ', rcnNetworkCountForNode, ' rcn routes connected to it'
    748                     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'
     801 
     802
     803def checkNetwork(network, networklevel, aDownloadWasNeeded):
     804    name = network.get('name')
     805    if logVerbosity>19:
     806        print '********************************************'
     807        print name
     808        print '********************************************'
     809    if 'createWikiReport' in sideEffects:
     810        wikiReportOnNodes = ('\n==' + name + '==\n{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name +
     811                             '\n|-\n!style="width:2.5em" | Node\n!Link\n! # Roads\n! # Relations\n|-\n')
     812        wikiReportOnRelations = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name +
     813                                 '\n|-\n!style="width:2.5em" | note\n!link\n!fixme\n! forward\n! backward\n! end nodes\n|-\n')
     814    i=1
     815    for networkMember in network.getMembers():
     816        if networkMember.isRelation():
     817            routeRelation = networkMember.getRelation()
     818            if routeRelation.get('network') ==networklevel:
     819                if routeRelation.hasIncompleteMembers():
     820                    name = routeRelation.get('name')
     821                    if not(name): name = ''
     822                    note = routeRelation.get('note')
     823                    if not(note): note = ''
     824                    kindOfNetwork = routeRelation.get('network')
     825                    if not(kindOfNetwork): kindOfNetwork = ''
     826                    if 'downloadIncompleteMembers' in sideEffects:
     827                        aDownloadWasNeeded = True
     828                        print 'Downloading incomplete members for', note
     829                        DownloadRelationMemberTask.run(DownloadRelationMemberTask(routeRelation, routeRelation.getIncompleteMembers(), mv.editLayer ))
     830                        time.sleep(1)
     831                        continue
     832                    else:
     833                        JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete members of the route relations first: ' + kindOfNetwork + ' ' + note + ' ' + name)
     834                        break
     835                roleFromRouteCheck, problemReported, wikiReport = checkRxNroute(routeRelation, networklevel, aDownloadWasNeeded)
     836                if problemReported and 'createWikiReport' in sideEffects:
     837                    wikiReportOnRelations += wikiReport + '\n|-\n'
     838                role = networkMember.getRole()
     839                if logVerbosity > 29 and role != roleFromRouteCheck:
     840                    print
     841                    print 'Role in network is ', role
     842                    print 'Maybe this should be: ', roleFromRouteCheck
     843        if networkMember.isNode():
     844            node = networkMember.getNode()
     845            rXn_ref = node.get(networklevel + '_ref')
     846            expected_rXn_route_relations = node.get('expected_' + networklevel + '_route_relations')
     847            if expected_rXn_route_relations:
     848                expected_rXn_route_relations = int(expected_rXn_route_relations)
     849            else:
     850                expected_rXn_route_relations = 3
     851            if rXn_ref:
     852                if logVerbosity > 39: print rXn_ref
     853                referrersForNode = node.getReferrers()
     854                networkNotFoundForNode = True
     855                for referrer in referrersForNode:
     856                    if referrer.getType() is dummy_relation.getType():
     857                        if referrer.get('type') in ['network'] and referrer.get('network') in ['rcn','rwn','rhn']:
     858                            networkNotFoundForNode = False
     859                            break
     860                if networkNotFoundForNode and 'downloadReferrersNodes' in sideEffects:
     861                    aDownloadWasNeeded = True
     862                    if 'selectObjects' in sideEffects: Main.main.getCurrentDataSet().setSelected(node)
     863                    if 'zoomToSelection' in sideEffects: AutoScaleAction.zoomToSelection()
     864                    #selectedNode = mv.editLayer.data.getSelected()
     865                    print 'Downloading referrers for ', node.get(networklevel + '_ref')
     866                    DownloadReferrersAction.downloadReferrers(mv.editLayer, node)
     867
     868                rXnNetworkCountForNode = roads = 0
     869                for referrer in referrersForNode:
     870                    if referrer.getType() is dummy_way.getType():
     871                        if referrer.get('highway'): roads += 1
     872                        referrersForWay = referrer.getReferrers()
     873                        if len(referrersForWay) < 1 and 'downloadReferrersForWays' in sideEffects:
     874                            aDownloadWasNeeded = True
     875                            if 'selectObjects' in sideEffects: Main.main.getCurrentDataSet().setSelected(referrer)
     876                            if 'zoomToSelection' in sideEffects: AutoScaleAction.zoomToSelection()
     877                            print 'Downloading referrers for ', referrer.get('name') , ' ', rXn_ref
     878                            DownloadReferrersAction.downloadReferrers(mv.editLayer, referrer)
     879
     880                        for wayReferrer in referrersForWay:
     881                            if wayReferrer.getType() is dummy_relation.getType():
     882                                aRelation = wayReferrer
     883                                rXnRelationWeWantToProcess = False # We need this again further on, when deciding whether or not to add this relation to the network
     884                                if aRelation.get('type') == 'route' and aRelation.get('network') ==networklevel and not(aRelation.get('ref')): # in ['RUR','NRR','NRW','2LR','3LR','KAI','EHR','DFR','WBR','Nk']):
     885                                    # The check on the ref is for Germany, where many rXn networks run crisscross through another.
     886                                    # We wouldn't want to get entangled in that mess.
     887                                    # The list is continuously getting longer, of course. But it's the best we can do here
     888                                    rXnRelationWeWantToProcess = True
     889                                    rXnNetworkCountForNode+=1
     890                                    if aRelation.hasIncompleteMembers():
     891                                        name = aRelation.get('name')
     892                                        if not(name): name = ''
     893                                        note = aRelation.get('note')
     894                                        if not(note): note = ''
     895                                        kindOfNetwork = aRelation.get('network')
     896                                        if not(kindOfNetwork): kindOfNetwork = ''
     897                                        if 'downloadIncompleteMembers' in sideEffects:
     898                                            aDownloadWasNeeded = True
     899                                            print 'Downloading incomplete members for', note
     900                                            DownloadRelationMemberTask.run(DownloadRelationMemberTask(aRelation, aRelation.getIncompleteMembers(), mv.editLayer ))
     901                                            time.sleep(1)
     902                                            continue
     903                                        else:
     904                                            JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete members of the route relations first: ' + kindOfNetwork + ' ' + note + ' ' + name)
     905                                            break
     906                                networkMembersList = []
     907                                # print network
     908                                for subMember in network.getMembers():
     909                                    if subMember.isRelation():
     910                                        routeRelation = subMember.getRelation()
     911                                        networkMembersList.append(routeRelation.getUniqueId())
     912                                routeId = aRelation.getUniqueId()
     913                                if rXnRelationWeWantToProcess and not(routeId in networkMembersList):
     914                                    roleFromRouteCheck, problemReported, wikiReport = checkRxNroute(aRelation, networklevel, aDownloadWasNeeded)
     915                                    if problemReported and 'createWikiReport' in sideEffects:
     916                                        wikiReportOnRelations += wikiReport + '\n|-\n'
     917                                    if 'addRouteToNetwork' in sideEffects and not(aDownloadWasNeeded):
     918                                        newRelation = Relation(network)
     919                                        newmember = RelationMember(roleFromRouteCheck, aRelation)
     920                                        if logVerbosity > 9: print newRelation.getMembersCount(), ' ',i, ' ', newmember
     921                                        newRelation.addMember( i, newmember)
     922                                        commandsList = []
     923                                        commandsList.append(Command.ChangeCommand(network, newRelation))
     924                                        note = aRelation.get('note')
     925                                        if not(note):
     926                                            note = ''
     927                                        Main.main.undoRedo.add(Command.SequenceCommand("Adding " + note + " to network", commandsList))
     928                                        commandsList = []
     929                                        if logVerbosity > 9: print 'Added newly found RCN route relation to network: ', note
     930                                        i+=1
     931                if rXnNetworkCountForNode < expected_rXn_route_relations:
     932                    if logVerbosity > 9: print 'Node ', rXn_ref, ' only has ', rXnNetworkCountForNode, ' rXn routes connected to it'
     933                    if 'createWikiReport' in sideEffects: wikiReportOnNodes += '|align="right" | ' + rXn_ref + '||align="right" | {{Node|' + str(node.getId()) + '}}||align="right" |' + str(roads) + ' ||align="right" style="color:red" | ' + str(rXnNetworkCountForNode) + '\n|-\n'
    749934
    750935        i+=1
    751936    if logVerbosity > 19: print
    752937    if 'createWikiReport' in sideEffects:
     938        fh = codecs.open(wikiReportFN, 'a', encoding="UTF-8")
    753939        wikiReportOnNodes += ('|-\n|}\n')
    754940        wikiReportOnRelations += ('|-\n|}\n<br style="clear:left;" />\n')
    755         fh = open('C:/wikiReport.txt', 'a')
    756941        fh.write(wikiReportOnNodes)
    757942        fh.write(wikiReportOnRelations)
     
    781966    else:
    782967        if 'createWikiReport' in sideEffects:
    783             fh = open('C:/wikiReport.txt', 'w')
     968            fh = codecs.open(wikiReportFN, 'w', encoding="UTF-8")
    784969            fh.close()
    785970        for relation in selectedRelations:
     
    794979                    JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the relations first')
    795980                    exit()
    796             if relation.get('network') == 'rcn':
     981            networklevel=relation.get('network')
     982            if networklevel in ('rcn','rwn','rhn'):
    797983                relationType = relation.get('type')
    798984                if relationType == 'route':
    799                     checkRCNroute(relation, aDownloadWasNeeded)
     985                    checkRxNroute(relation, networklevel, aDownloadWasNeeded)
    800986                elif relationType == 'network':
    801                     checkNetwork(relation, aDownloadWasNeeded)
     987                    checkNetwork(relation, networklevel, aDownloadWasNeeded)
    802988                elif relationType == 'collection':
    803989                    for collectionMember in relation.getMembers():
     
    8171003                                    JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete members of the network relations first:' + networkname + ' ' + name)
    8181004                                    break
    819                             checkNetwork(networkRelation, aDownloadWasNeeded)
     1005                            checkNetwork(networkRelation, networklevel, aDownloadWasNeeded)
    8201006        if aDownloadWasNeeded:
    8211007            JOptionPane.showMessageDialog(Main.parent, 'There was incomplete data and downloading mode was initiated,\nNo further quality checks were performed.\nPlease run the script again when all downloads have completed')
    8221008
     1009
    8231010}}}