| Version 10 (modified by , 14 years ago) ( diff ) |
|---|
Some more examples in Python:
Export a collection of routes to Garmin GPX file:
#!/bin/jython ''' RWN2Garmin.py - Numbered networks to Garmin GPX file converter 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 to: * work with selected items or how to process all the primitives of a certain kind (node, way, relation) ''' from javax.swing import JOptionPane, JDialog from java.awt.event import ActionListener, ActionEvent 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.TagCollection as TagCollection import org.openstreetmap.josm.data.osm.DataSet as DataSet import time def getMapView(): if Main.main and Main.main.map: return Main.main.map.mapView else: return None mv = getMapView() f = open('C:/export.gpx', 'w') f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n') f.write('<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="OSM Route Manager" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">\n') f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (http://creativecommons.org/licenses/by-sa/2.0/). -->\n') if mv and mv.editLayer and mv.editLayer.data: #selectedNodes = mv.editLayer.data.getSelectedNodes() #selectedWays = mv.editLayer.data.getSelectedWays() selectedRelations = mv.editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Please select a collection relation") else: # nodetype = Node().getType() print for collection in selectedRelations: print 'COLLECTION:', collection for member in collection.getMembers(): print 'MEMBER:',member if member.isNode(): node = member.getNode() coords = node.getCoor() lon = coords.getX() lat = coords.getY() rwn_ref = node.get('rwn_ref') f.write('\t<wpt lat="' + str(lat) + '" lon="' + str(lon) + '">\n') if rwn_ref: f.write('\t\t<name>' + rwn_ref + '</name>\n') f.write('\t</wpt>\n') for member in collection.getMembers(): if member.isRelation(): routerelation = member.getRelation() f.write('\t<trk>\n') networkname = routerelation.get('network:name') if not(networkname): networkname = '' else: networkname += ' ' note = routerelation.get('note') if not(note): note = '' f.write('\t\t<name>' + networkname + note + '</name>\n') f.write('\t\t<src>OpenStreetMap.org</src>\n') f.write('\t\t<type>foot</type>\n') for routerelmember in routerelation.getMembers(): if routerelmember.isWay(): f.write('\t\t<trkseg>\n') way=routerelmember.getWay() for waynode in way.getNodes(): coords = waynode.getCoor() lon = coords.getX() lat = coords.getY() f.write('\t\t\t<trkpt lat="' + str(lat) + '" lon="' + str(lon) + '"> </trkpt>\n') f.write('\t\t</trkseg>\n') f.write('\t</trk>\n') f.write('</gpx>\n') f.close()
Download missing parent elements for the selected element:
#!/bin/jython ''' 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 to: * Download all referrer for an element ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main 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.actions.DownloadReferrersAction as DownloadReferrersAction #import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask as DownloadReferrersTask; def getMapView(): if Main.main and Main.main.map: return Main.main.map.mapView else: return None mv = getMapView() if mv and mv.editLayer and mv.editLayer.data: selectedElements = mv.editLayer.data.getSelected() if not(selectedElements): JOptionPane.showMessageDialog(Main.parent, "Please select an element") else: DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedElements)
Download missing relation members:
#!/bin/jython
'''
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 to:
* Download all missing members of a relation
'''
from javax.swing import JOptionPane
from org.openstreetmap.josm import Main
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
def getMapView():
if Main.main and Main.main.map:
return Main.main.map.mapView
else:
return None
mv = getMapView()
if mv and mv.editLayer and mv.editLayer.data:
selectedRelations = mv.editLayer.data.getSelectedRelations()
if not(selectedRelations):
JOptionPane.showMessageDialog(Main.parent, "Please select a node")
else:
for relation in selectedRelations:
if relation.hasIncompleteMembers():
#print dir(relation)
print dir(DownloadRelationMemberTask)
DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer ))
Validate an rcn route relation:
#!/bin/jython
'''
- 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 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 re
commandsList = []
reNumberDashNumber = re.compile(r'\d+-\d+')
def getMapView():
if Main.main and Main.main.map:
return Main.main.map.mapView
else:
return None
mv = getMapView()
if mv and mv.editLayer and mv.editLayer.data:
dummy_relation = Relation()
selectedRelations = mv.editLayer.data.getSelectedRelations()
if not(selectedRelations):
JOptionPane.showMessageDialog(Main.parent, "Please select a route relation")
else:
print
for route in selectedRelations:
newRelation = Relation(route)
relationChanged = False
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 " + name + '/' + ref, commandsList))
commandsList = []
rcn_refs = []; route_relation_names = []; memberslist = []
endnodes = []; prev_endnodes = []
continuous_forward = True; continuous_backward = True
prev_role = None; prev_endnodes_before_forward = None; last_endnodes_before_backward = None
for member in route.getMembers():
if member.isWay():
role = member.getRole()
memberslist.append(member)
way = member.getWay()
#JOptionPane.showMessageDialog(Main.parent, 'way is selected')
endnodes = [way.getNode(0), way.getNode(way.nodesCount-1)]
notfoundyet = True
for endnode in endnodes:
# inventorizing of rcn_ref on end nodes
rcn_ref = endnode.get('rcn_ref')
if rcn_ref:
rcn_refs.append(int(rcn_ref))
for referrer in endnode.getReferrers():
if referrer.getType() is dummy_relation.getType():
if referrer.get('type')=='network' and referrer.get('network')=='rcn':
relname=referrer.get('name')
if relname:
route_relation_names.append(relname)
elif referrer.get('type')=='collection':
route_relation_names.append('Node not assigned to network yet')
# checking for continuity on ways
if notfoundyet:
if role:
if prev_role:
if role=='forward' and prev_role=='forward' and endnode in prev_endnodes:
notfoundyet = False
elif role=='forward' and prev_role=='backward' and endnode in last_endnodes_before_backward:
notfoundyet = False
elif role=='backward' and prev_role=='forward' and endnode in prev_endnodes:
notfoundyet = False
elif role=='backward' and prev_role=='backward' and endnode in prev_endnodes:
notfoundyet = False
else:
if role=='forward' and endnode in prev_endnodes:
notfoundyet = False
elif role=='backward' and endnode in prev_endnodes:
notfoundyet = False
else:
if prev_role:
if prev_role=='forward' and endnode in prev_endnodes:
notfoundyet = False
elif prev_role=='backward' and endnode in last_endnodes_before_backward:
notfoundyet = False
else:
if endnode in prev_endnodes:
notfoundyet = False
# Analysis of continuity of ways
if prev_endnodes and notfoundyet:
if role:
if role == 'forward':
continuous_forward = False
elif role == 'backward':
continuous_backward = False
else:
continuous_forward = False
continuous_backward = False
if role=='forward':
if not(prev_endnodes_before_forward):
prev_endnodes_before_forward = prev_endnodes
elif prev_role=='forward' and role=='backward':
if not(last_endnodes_before_backward):
last_endnodes_before_backward = prev_endnodes
elif not(role) and prev_role=='backward':
prev_endnodes_before_forward = None
prev_role = role
prev_endnodes = endnodes
# Drawing conclusions about continuity of ways
if continuous_forward:
print 'route is continous in the forward direction'
else:
print 'route is NOT CONTINUOUS in the forward direction'
if continuous_backward:
print 'route is continous in the backward direction'
else:
print 'route is NOT CONTINUOUS in the backward direction'
# Drawing conclusions about rcn_refs
print rcn_refs
if len(rcn_refs) > 1:
newRelation = Relation(route)
relationChanged = False
if rcn_refs[0] > rcn_refs[1]:
rcn_refs.sort()
print 'Flipping members order'
for member in reversed(memberslist):
newRelation.addMember( newRelation.getMembersCount(), member)
newRelation.removeMember (0)
commandsList.append(Command.ChangeCommand(route, newRelation))
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)
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
print 'This is probably a CONNECTION to another network'
print route_relation_names
else:
print 'less than 2 end nodes with rcn_ref found'
Remove extra ways resulting from Potlatch way split operations under turn restriction relations
#!/bin/jython ''' RepairTurns.py - Remove extra ways resulting from Potlatch way split operations under turn restriction relations 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 Loops through selected turn restriction relations, trying to remove ways split from originally the same way (with to / from roles) under turn restriction relations which should no longer remain as members of these relations, as a result of a Potlatch issue: https://trac.openstreetmap.org/ticket/3254 Only work for turn restrictions with one via node e.g. Original : from: Way1, via: Node, to:Way2 Split : from: Way1a, from: Way1b, via: Node, to: Way2 After running : from: Way1b, via: Node, to: Way2 This code illustrates how to use Jython to: * process selected items * download missing primitives in the same thread (blocking) * process, validate and remove members from relations ''' from javax.swing import JOptionPane from org.openstreetmap.josm import Main 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.io.MultiFetchServerObjectReader as MultiFetchServerObjectReader import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor as PleaseWaitProgressMonitor import org.openstreetmap.josm.command as Command class RestrictionError(Exception): pass def getMapView(): if Main.main and Main.main.map: return Main.main.map.mapView else: return None def getMembers (restriction): memberlist = dict() for member in restriction.getMembers(): memberRole = member.getRole() if memberRole == "via": if member.isNode() and not "via" in memberlist: memberlist[memberRole] = [member] else: raise RestrictionError, "More than one via role or via not a node" elif memberRole in ("from", "to"): if member.isWay(): try: memberlist[memberRole].append (member) except KeyError: memberlist[memberRole] = [member] else: raise RestrictionError, "From or to role not a way" else: raise RestrictionError, "Unknown role " + memberRole if len(memberlist.keys())<3: raise RestrictionError, "Some roles missing: Only " + ",".join (memberlist.keys()) + " found" return memberlist def downloadPrimitives (primitives, editlayer): """ Download a list of primitives from server, and merge into editlayer. Blocking. """ monitor = PleaseWaitProgressMonitor() monitor.showForegroundDialog() print "Downloading" try: objectReader = MultiFetchServerObjectReader().append (primitives) dataSet = objectReader.parseOsm (monitor) editlayer.mergeFrom (dataSet) editlayer.onPostDownloadFromServer() if (not objectReader.getMissingPrimitives().isEmpty()) : raise RestrictionError, "Unable to download missing primitives" print "Download completed" finally: monitor.close() def checkIfConnected (node, way, reverse): """ Return (connected, next node to compare (i.e. other end of the node) if true) """ if (way.isOneway() != 0 and reverse): return node == way.lastNode(True), way.firstNode(True) # True: auto process case whan isOneway == -1 if (way.isOneway() != 0): # not reverse return node == way.firstNode(True), way.lastNode(True) if node == way.firstNode(): return True, way.lastNode() if node == way.lastNode(): return True, way.firstNode() return False, node def repairrestriction (relation, memberlist, editLayer): """ Download missing members if needed, get list of members to remove, and remove them if no error raised during checking """ incompleteMembers = relation.getIncompleteMembers() if incompleteMembers: downloadPrimitives (incompleteMembers, editLayer); fromRemovalList = []; toRemovalList = [] if len (memberlist["from"]) >= 1: currnode = memberlist["via"][0].getNode() firstMember = True failed = False; # trace "from" members to confirm if split from one way for member in reversed(memberlist['from']): connected, currnode = checkIfConnected (currnode, member.getWay(), True) if not connected: if not firstMember: raise RestrictionError, "from ways not continuous from via node" failed = True break if not firstMember: fromRemovalList.append (member) else: firstMember = False if failed: # Second attempt in case sequence reversed when split currnode = memberlist["via"][0].getNode() for member in memberlist['from']: connected, currnode = checkIfConnected (currnode, member.getWay(), True) if not connected: raise RestrictionError, "from ways not continuous from via node" if not firstMember: fromRemovalList.append (member) else: firstMember = False if len (memberlist["to"]) >= 1: currnode = memberlist["via"][0].getNode() firstMember = True failed = False # trace "to" members to confirm if split from one way for member in memberlist['to']: connected, currnode = checkIfConnected (currnode, member.getWay(), False) if not connected: if not firstMember: raise RestrictionError, "to ways not continuous from via node" failed = True break if not firstMember: toRemovalList.append (member) else: firstMember = False if failed: # Second attempt in case sequence reversed when split currnode = memberlist["via"][0].getNode() for member in reversed(memberlist['to']): connected, currnode = checkIfConnected (currnode, member.getWay(), False) if not connected: raise RestrictionError, "to ways not continuous from via node" if not firstMember: toRemovalList.append (member) else: firstMember = False # to remove ways in fromRemovalList, toRemovalList newRelation = Relation(relation) waysToRemove = set() for removalList in [fromRemovalList, toRemovalList]: waysToRemove |= set ([m.getWay() for m in removalList]) newRelation.removeMembersFor (waysToRemove) print "Remove way(s) id:" + ",".join ([str(w.getId()) for w in waysToRemove]) return Command.ChangeCommand (relation, newRelation) validrestrictiontypes = ('only_straight_on', 'only_right_turn', 'only_left_turn', 'no_right_turn', 'no_left_turn', 'no_straight_on', 'no_u_turn') mv = getMapView() if mv and mv.editLayer and mv.editLayer.data: selectedRelations = mv.editLayer.data.getSelectedRelations() if not(selectedRelations): JOptionPane.showMessageDialog(Main.parent, "Please select one or more relations") else: commandsList = [] for relation in selectedRelations: if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes: try: memberlist = getMembers (relation) #print "".join(v * len(memberlist[v]) for v in memberlist.keys()) if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 : # Repair attempt print "Attempt repair", print "relation id: " + str(relation.getId()) command = repairrestriction (relation, memberlist, mv.editLayer) print "Success" commandsList.append (command) except RestrictionError, e: print str(e), "; relation id: "+ str(relation.getId()) Main.main.undoRedo.add(Command.SequenceCommand("Repair turn restrictions", commandsList)) commandsList=[]
Note:
See TracWiki
for help on using the wiki.


