| | 1 | |
| | 2 | {{{ |
| | 3 | #!/bin/jython |
| | 4 | ''' |
| | 5 | CheckRouteOrNetworkOrCollectionOfRoutes.jy |
| | 6 | - Validation of a rcn route, network or collection of networks relation |
| | 7 | - Depending on what is selected in JOSM when invoked |
| | 8 | |
| | 9 | This code is released under the GNU General |
| | 10 | Public License v2 or later. |
| | 11 | |
| | 12 | The GPL v3 is accessible here: |
| | 13 | http://www.gnu.org/licenses/gpl.html |
| | 14 | |
| | 15 | The GPL v2 is accessible here: |
| | 16 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| | 17 | |
| | 18 | It comes with no warranty whatsoever. |
| | 19 | |
| | 20 | This 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 | ''' |
| | 32 | from javax.swing import JOptionPane |
| | 33 | from org.openstreetmap.josm import Main |
| | 34 | import org.openstreetmap.josm.command as Command |
| | 35 | import org.openstreetmap.josm.data.osm.Node as Node |
| | 36 | import org.openstreetmap.josm.data.osm.Way as Way |
| | 37 | import org.openstreetmap.josm.data.osm.Relation as Relation |
| | 38 | import org.openstreetmap.josm.data.osm.TagCollection as TagCollection |
| | 39 | import org.openstreetmap.josm.data.osm.DataSet as DataSet |
| | 40 | import org.openstreetmap.josm.data.osm.RelationMember as RelationMember |
| | 41 | import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask |
| | 42 | import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction |
| | 43 | import org.openstreetmap.josm.actions.AutoScaleAction as AutoScaleAction |
| | 44 | import re, time |
| | 45 | |
| | 46 | # comment to disable side effect |
| | 47 | sideEffects = { |
| | 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 | |
| | 63 | logVerbosity = 10 |
| | 64 | ''' |
| | 65 | 10: only report problems that need fixing |
| | 66 | 20: report on collection |
| | 67 | 30: report on network nodes |
| | 68 | 40: report on which routes are being checked |
| | 69 | 50: report everything |
| | 70 | ''' |
| | 71 | def getMapView(): |
| | 72 | if Main.main and Main.main.map: |
| | 73 | return Main.main.map.mapView |
| | 74 | else: |
| | 75 | return None |
| | 76 | |
| | 77 | def 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 | |
| | 121 | def 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 | |
| | 153 | def 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 | |
| | 420 | def 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 | |
| | 533 | dummy_way = Way() |
| | 534 | dummy_relation = Relation() |
| | 535 | |
| | 536 | mv = getMapView() |
| | 537 | if 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 | }}} |