{{{ #!python #!/bin/jython ''' CheckRouteOrNetworkOrCollectionOfRoutes.jy - Validation of a rcn route relation This code is released under the GNU General Public License v2 or later. The GPL v3 is accessible here: http://www.gnu.org/licenses/gpl.html The GPL v2 is accessible here: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html It comes with no warranty whatsoever. This code illustrates how to use Jython (Python in the scripting plugin of JOSM) to: * loop over all members of a route relation * find out whether the member is a node, a way or a relation * add/change properties of a relation * remove properties of a relation * add members to a relation * remove members from a relation * sort all members backwards * How to set an element selected ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main import org.openstreetmap.josm.command as Command import org.openstreetmap.josm.data.osm.Node as Node import org.openstreetmap.josm.data.osm.Way as Way import org.openstreetmap.josm.data.osm.Relation as Relation import org.openstreetmap.josm.data.osm.TagCollection as TagCollection import org.openstreetmap.josm.data.osm.DataSet as DataSet import org.openstreetmap.josm.data.osm.RelationMember as RelationMember import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction import org.openstreetmap.josm.actions.AutoScaleAction as AutoScaleAction import re, time def getMapView(): if Main.main and Main.main.map: return Main.main.map.mapView else: return None def sortRouteRelation(route, nodesDict, beginAndEndnodes): nextNode = None routeToReturn = Relation(route) ##print dir (routeToReturn) #routeToReturn.clearOsmId() lowestNodeInt = 10000; lowPos = 0 for nodeTuple in beginAndEndnodes: if nodeTuple[0] < lowestNodeInt: lowestNodeInt, nextNode = nodeTuple if not(nextNode): return route members=nodesDict[nextNode] processedMembers = {} #print len(nodesDict) #print dir(route) while lowPos 1: continuous_forward = checkForContinuity(allWaysgoingFromLowerToHigher) #if not(continuous_forward) and not(fixme): #sortedRelation = sortRouteRelation(route, nodesForSorting, beginAndEndNodes) #print route #print sortedRelation #commandsList.append(Command.ChangeCommand(route, sortedRelation)) #Main.main.undoRedo.add(Command.SequenceCommand("Sorted route relation", commandsList)) #allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = [] #for member in route.getMembers(): #if member.isWay(): #role = member.getRole() #way = member.getWay() #if role=='forward': #allWaysgoingFromLowerToHigher.append(member) #elif role=='backward': #allWaysgoingFromHigherToLower.append(member) #else: #allWaysgoingFromLowerToHigher.append(member) #allWaysgoingFromHigherToLower.append(member) #print allWaysgoingFromLowerToHigher #continuous_forward = checkForContinuity(allWaysgoingFromLowerToHigher) #else: else: continuous_forward = True if len(allWaysgoingFromHigherToLower) > 1: continuous_backward = checkForContinuity(reversed(allWaysgoingFromHigherToLower)) else: continuous_backward = True # Drawing conclusions about rcn_refs print rcn_refs if sameNodeNumberRepeated: rcn_refs.append(rcn_refs[0]) newNote = note = repr(rcn_refs) sortedRelation = route if len(rcn_refs) > 1: #newRelation = Relation(route) relationChanged = False if rcn_refs[0] > rcn_refs[1]: rcn_refs.sort() if len(memberslist)>1: print 'Flipping members order' for member in reversed(memberslist): sortedRelation.addMember( sortedRelation.getMembersCount(), member) sortedRelation.removeMember (0) commandsList.append(Command.ChangeCommand(route, sortedRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Flipping order of members", commandsList)) commandsList = [] note = route.get('note') newNote = str(rcn_refs[0]).zfill(2) + '-' + str(rcn_refs[1]).zfill(2) #print note, newNote if not(note) or note != newNote: if not(note): note = 'nothing' newRelation.put('note', newNote) relationChanged = True commandsList.append(Command.ChangeCommand(route, newRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Changing note from " + note + ' to ' + newNote, commandsList)) commandsList = [] if len(route_relation_names) > 1 and route_relation_names[0] != route_relation_names[1]: # print 'This is probably a CONNECTION to another network' print route_relation_names roleInNetwork = 'connection' else: print 'less than 2 end nodes with rcn_ref found' if fixme and not(continuous_forward or continuous_backward): print 'FIXME flag is INCOMPLETE' if continuous_forward: wikiCF = 'align="right" | continuous' #print 'route is continous in the forward direction' else: wikiCF = 'align="right" style="color:red" | NOT continuous' print 'route ',newNote,' is NOT CONTINUOUS in the forward direction' #print allWaysgoingFromLowerToHigher if continuous_backward: wikiCB = 'align="right" | continuous' #print 'route is continous in the backward direction' else: wikiCB = 'align="right" style="color:red" | NOT continuous' print 'route ',newNote,' is NOT CONTINUOUS in the backward direction' #print allWaysgoingFromHigherToLower print if fixme: wikiFM = 'style="color:red" | fixme' else: wikiFM = ' | ' if fixme or not(continuous_forward) or not(continuous_backward): problem = True else: problem = False return roleInNetwork, problem, '|align="right" | ' + note + '||align="right" | {{BrowseRoute|' + str(route.getId()) + '}}||align="right" ' + wikiFM + ' ||' + wikiCF + ' ||' + wikiCB + '\n' def checkNetwork(network): name = network.get('name') print '********************************************' print name print '********************************************' #'===' + name + '===\n' + wikiReportOnNodes = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name + '\n|-\n!style="width:2.5em" | Node\n!Link\n! # Roads\n! # Relations\n|-\n') wikiReportOnRelations = ('{| class="wikitable" align="left" style="margin:0 0 2em 2em;"\n|-\n|+' + name + '\n|-\n!style="width:2.5em" | note\n!link\n!fixme\n! forward\n! backward\n|-\n') i=1 for networkmember in network.getMembers(): if networkmember.isRelation(): subrelation = networkmember.getRelation() if subrelation.hasIncompleteMembers(): #JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the route relations first') DownloadRelationMemberTask.run(DownloadRelationMemberTask(subrelation, subrelation.getIncompleteMembers(), mv.editLayer )) break roleFromRouteCheck, problemReported, wikiReport = checkRCNroute(subrelation) if problemReported: wikiReportOnRelations += wikiReport + '\n|-\n' #if roleFromRouteCheck: role = networkmember.getRole() if role != roleFromRouteCheck: print print 'Role in network is ', role print 'Maybe this should be: ', roleFromRouteCheck if networkmember.isNode(): node = networkmember.getNode() rcn_ref = node.get('rcn_ref') expected_rcn_route_relations = node.get('expected_rcn_route_relations') if expected_rcn_route_relations: expected_rcn_route_relations = int(expected_rcn_route_relations) else: expected_rcn_route_relations = 3 if rcn_ref: #print rcn_ref referrersForNode = node.getReferrers() networkNotFoundForNode = True for referrer in referrersForNode: if referrer.getType() is dummy_relation.getType(): if referrer.get('type') in ['network'] and referrer.get('network') in ['rcn']: networkNotFoundForNode = False break if networkNotFoundForNode: #Main.main.getCurrentDataSet().setSelected(node) #AutoScaleAction.zoomToSelection() #selectedNode = mv.editLayer.data.getSelected() #DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedNode) referrersForNode = node.getReferrers() rcnNetworkCountForNode = roads = 0 for referrer in referrersForNode: if referrer.getType() is dummy_way.getType(): if referrer.get('highway'): roads += 1 referrersForWay = referrer.getReferrers() if len(referrersForWay) < 1: Main.main.getCurrentDataSet().setSelected(referrer) AutoScaleAction.zoomToSelection() ##selectedWay = mv.editLayer.data.getSelected() #DownloadReferrersAction.downloadReferrers(mv.editLayer, referrersForNode) referrersForWay = referrer.getReferrers() for wayreferrer in referrersForWay: if wayreferrer.getType() is dummy_relation.getType(): memberslist = [] if wayreferrer.get('type') == 'route' and wayreferrer.get('network') == 'rcn': rcnNetworkCountForNode+=1 for submember in network.getMembers(): if submember.isRelation(): subrelation = submember.getRelation() memberslist.append(subrelation.getId()) if not(wayreferrer.getId()): print dir(wayreferrer) break routeId = wayreferrer.getId() if not(routeId) or not(routeId in memberslist): if wayreferrer.get('network') == 'rcn': roleFromRouteCheck, problemReported, wikiReport = checkRCNroute(wayreferrer) print wikiReport if problemReported: wikiReportOnRelations += wikiReport + '\n|-\n' newRelation = Relation(network) newmember = RelationMember(roleFromRouteCheck, wayreferrer) print newRelation.getMembersCount(), ' ',i, ' ', newmember ##if i>newRelation.getMembersCount() newRelation.addMember( i, newmember) commandsList = [] commandsList.append(Command.ChangeCommand(network, newRelation)) note = wayreferrer.get('note') if not(note): note = '' Main.main.undoRedo.add(Command.SequenceCommand("Adding " + note + " to network", commandsList)) commandsList = [] print 'Added newly found RCN route relation to network: ', note i+=1 if rcnNetworkCountForNode < expected_rcn_route_relations: print 'Node ', rcn_ref, ' only has ', rcnNetworkCountForNode, ' rcn routes connected to it' wikiReportOnNodes += '|align="right" | ' + rcn_ref + '||align="right" | {{Node|' + str(node.getId()) + '}}||align="right" |' + str(roads) + ' ||align="right" style="color:red" | ' + str(rcnNetworkCountForNode) + '\n|-\n' i+=1 print wikiReportOnNodes += ('|-\n|}\n') wikiReportOnRelations += ('|-\n|}\n
\n') fh = open('C:/wikiReport.txt', 'a') fh.write(wikiReportOnNodes) fh.write(wikiReportOnRelations) fh.close() dummy_way = Way() dummy_relation = Relation() mv = getMapView() if mv and mv.editLayer and mv.editLayer.data: fh = open('C:/wikiReport.txt', 'w') fh.close() dummy_relation = Relation() selectedRelations = mv.editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Please select a route, network or collection relation") else: for relation in selectedRelations: #print relation #print relation.hasIncompleteMembers() if relation.hasIncompleteMembers(): #JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the relations first') DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer )) break if relation.get('type') == 'route' and relation.get('network') == 'rcn': checkRCNroute(relation) if relation.get('type') == 'network' and relation.get('network') == 'rcn': checkNetwork(relation) if relation.get('type') == 'collection' and relation.get('network') == 'rcn': for networkmember in relation.getMembers(): if networkmember.isRelation(): subrelation = networkmember.getRelation() if subrelation.hasIncompleteMembers(): #JOptionPane.showMessageDialog(Main.parent, 'Please download all incomplete member of the network relations first') DownloadRelationMemberTask.run(DownloadRelationMemberTask(subrelation, subrelation.getIncompleteMembers(), mv.editLayer )) #break checkNetwork(subrelation) }}}