Version 6 (modified by 10 years ago) ( diff ) | ,
---|
#!/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<route.getMembersCount(): #print 'in loop', routeToReturn if len(members) == 1: member = members[0] else: member = members[1] if member in processedMembers: member = members[0] processedMembers[member] = True way = member.getWay() routeToReturn.removeMembersFor(way) routeToReturn.addMember(lowPos,member) #routeToReturn.setModified(True) currentNode = nextNode nextNode = way.getNode(way.nodesCount-1).getId() if currentNode == nextNode: nextNode = way.getNode(0).getId() if nextNode in nodesDict: members=nodesDict[nextNode] else: break del nodesDict[nextNode] #print len(nodesDict) if len(nodesDict)<3: break lowPos += 1 #print 'before return', routeToReturn return routeToReturn def checkForContinuity(membersList): listIsContinuous = True; prev_endnodes = [] for member in membersList: if member.isWay(): way = member.getWay() #print dir(way) #print way.getKeys() #print way.get('name') #print way.nodesCount-1, way if way.get('junction') == 'roundabout': endnodes = way.getNodes() else: if way.nodesCount: endnodes = [way.getNode(0), way.getNode(way.nodesCount-1)] else: endnodes = [] foundTheNode = False for endnode in endnodes: #print endnode, prev_endnodes if endnode in prev_endnodes: foundTheNode = True if prev_endnodes and not(foundTheNode): listIsContinuous = False #print way #print endnodes #print prev_endnodes break prev_endnodes = endnodes #print listIsContinuous return listIsContinuous def checkRCNroute(route): commandsList = [] reNumberDashNumber = re.compile(r'\d+-\d+') newRelation = Relation(route) relationChanged = False created_by = route.get('created_by') if created_by: print 'removing created_by' newRelation.remove('created_by') relationChanged = True name = route.get('name') if name: if reNumberDashNumber.match(name): print 'removing name when it is of the form ##-##' newRelation.remove('name') relationChanged = True else: name = '' ref = route.get('ref') if ref: if reNumberDashNumber.match(ref): print 'removing ref when it is of the form ##-##' newRelation.remove('ref') relationChanged = True else: ref = '' if relationChanged: commandsList.append(Command.ChangeCommand(route, newRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Removing name and/or ref and/or created_by" + name + '/' + ref, commandsList)) commandsList = [] fixme = route.get('fixme') == 'incomplete' rcn_refs = []; route_relation_names = []; memberslist = []; roleInNetwork = '' sameNodeNumberRepeated = False continuous_forward = True; continuous_backward = True allWaysgoingFromLowerToHigher = []; allWaysgoingFromHigherToLower = []; branch = None nodesForSorting = {}; beginAndEndNodes = [] newRelation = Relation(route); commandslist = []; modified = False; i=0; roundabout = [] for member in route.getMembers(): if member.isWay(): role = member.getRole() memberslist.append(member) way = member.getWay() #JOptionPane.showMessageDialog(Main.parent, 'way is selected') wayNodes = way.getNodes() #if len(wayNodes): #if way.get('junction') != 'roundabout': #wayNodes = [way.getNode(0), way.getNode(way.nodesCount-1)] #else: #newRelation.removeMember(i) #modified = True notfoundyet = True for endnode in wayNodes: endnodeId = endnode.getId() if not(endnodeId in nodesForSorting): nodesForSorting[endnodeId] = [] nodesForSorting[endnodeId].append(member) rcn_ref = endnode.get('rcn_ref') if rcn_ref: rcn_refAsInt = int(rcn_ref) beginAndEndNodes.append([rcn_refAsInt, endnodeId]) if not(rcn_refAsInt in rcn_refs): rcn_refs.append(rcn_refAsInt) else: sameNodeNumberRepeated = True referrersForNode = endnode.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(endnode) AutoScaleAction.zoomToSelection() #selectedNode = mv.editLayer.data.getSelected() print "Would download referrers for ", endnode.get('rcn_ref'), ' ', wayNodes # DownloadReferrersAction.downloadReferrers(mv.editLayer, wayNodes) referrersForNode = endnode.getReferrers() for referrer in referrersForNode: if referrer.getType() is dummy_relation.getType(): networkOrRouteType = referrer.get('type') in ['network'] #, 'route'] if referrer.get('network')=='rcn' and networkOrRouteType: relname=referrer.get('name') if relname: route_relation_names.append(relname) elif not(referrer.get('type') in ['route']): route_relation_names.append('Node not assigned to network yet') # build 2 structures to help check for continuity on ways if i==0: lastNodesBeforeSplit = [wayNodes] if role and role in ['forward', 'backward']: if not(branch): if role in ['forward']: lastNodesBeforeSplit = [wayNodes[0]] else: lastNodesBeforeSplit = [wayNodes[-1]] print 'wayNodes', wayNodes print 'lastNodesBeforeSplit', lastNodesBeforeSplit print way.getNodesCount(), 'startnode', wayNodes[0], 'endnode', wayNodes[-1] print 'roundabout', roundabout if role in ['forward'] and (wayNodes[-1] in lastNodesBeforeSplit or wayNodes[-1] in roundabout): branch = 'HigherToLower' elif role in ['backward'] and wayNodes[0] in lastNodesBeforeSplit: branch = 'HigherToLower' elif not(allWaysgoingFromHigherToLower) and wayNodes[-1].get('rcn_ref'): branch = 'HigherToLower' elif not(branch == 'HigherToLower'): branch = 'LowerToHigher' print branch if branch == 'LowerToHigher': allWaysgoingFromLowerToHigher.append(member) elif branch == 'HigherToLower': allWaysgoingFromHigherToLower.append(member) else: branch = None; roundabout = [] allWaysgoingFromLowerToHigher.append(member) allWaysgoingFromHigherToLower.append(member) if way.get('junction') == 'roundabout': roundabout = way.getNodes() i+=1 if modified: commandsList.append(Command.ChangeCommand(route, newRelation)) Main.main.undoRedo.add(Command.SequenceCommand("Removing way which has no nodes", commandsList)) commandsList = [] #print allWaysgoingFromLowerToHigher if len(allWaysgoingFromLowerToHigher) > 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<br style="clear:left;" />\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)
Note:
See TracWiki
for help on using the wiki.