Changes between Version 11 and Version 18 of Help/Plugin/Scripting/Python


Ignore:
Timestamp:
(multiple changes)
Author:
(multiple changes)
Comment:
(multiple changes)

Legend:

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

    v11 v18  
    11[[TranslatedPages]]
    22
     3= Plugin -> Scripting -> Python =
     4== Purpose ==
    35Some more examples in Python:
    46
    5 Export a collection of routes to Garmin GPX file:
    6 
     7[[PageOutline(2,Table of Contents)]]
     8
     9
     10== Convert a way that connects to an unsplit roundabout to a fork ==
     11Convert a way that connects to a roundabout to a fork consisting of 2 oneway ways. Splitting the way on its last node and attaching to the 2 nodes adjacent to the common node of the roundabout way. This version only works on unsplit roundabouts. See the next example for an updated version.
     12
     13{{{#!python
     14from javax.swing import JOptionPane
     15from org.openstreetmap.josm.gui import MainApplication
     16
     17import org.openstreetmap.josm.command as Command
     18import org.openstreetmap.josm.data.osm.Way as Way
     19
     20editLayer = MainApplication.getLayerManager().getEditLayer()
     21if editLayer and editLayer.data:
     22    selected_ways = editLayer.data.getSelectedWays()
     23    print selected_ways
     24
     25    if not(selected_ways) or len(selected_ways)>1:
     26        JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
     27                                         "Please select a single way that connects to a roundabout")
     28    else:
     29        for way in selected_ways:
     30            if way.get('oneway') in ['yes', '-1']:
     31                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "This way has oneway tag set")
     32            else:
     33                node_before = None
     34                node_after = None
     35                common_node = None
     36                common_node_becomes_node_before=None
     37                #print dir(way)
     38                for fln in [way.firstNode(),  way.lastNode()]:
     39                    print 'fln',  fln
     40                    for parentway in fln.getParentWays():
     41                        if parentway.get("junction")=='roundabout':
     42                            for n in parentway.getNodes():
     43                                if common_node:
     44                                    # found common node between selected way and
     45                                    # roundabout way in previous iteration
     46                                    node_after = n
     47                                    # we are done here
     48                                    break
     49                                if n.getId() == fln.getId():
     50                                    # this is the node the roundabout has in common with selected way
     51                                    common_node = n
     52                                    if not(node_before):
     53                                        # normally we encountered a node on the roundabout way
     54                                        # before this one, but if the common node is the first node
     55                                        # of an unsplit roundabout, we will need to take the last
     56                                        # node of the roundabout instead
     57                                        node_before = parentway.getNodes()[-2]
     58                                        node_after = parentway.getNodes()[1]
     59                                        break
     60                                    # if not we go through the loop one more time to put the next
     61                                    # node in node_after
     62                                    continue
     63                                node_before = n
     64                        if common_node:
     65                            # if common_node is already defined at this point, it means it was
     66                            # the first node of the selected way,
     67                            # so it will have to be replaced with node_before in the selected way
     68                            common_node_becomes_node_before = True
     69                            adjacent_node_to_split_on = way.getNodes()[1]
     70                            break
     71                        else:
     72                            common_node_becomes_node_before = False
     73                            adjacent_node_to_split_on = way.getNodes()[-1]
     74                if not(common_node) or common_node_becomes_node_before==None:
     75                    JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
     76                                               "Please select a way that connects to a roundabout")
     77                else:
     78                    print common_node.get('name')
     79                    print node_before.get('name')
     80                    print node_after.get('name')
     81
     82                    commandsList = []
     83                    if len(way.getNodes())>2:
     84                        # split off last segment before roundabout if needed
     85                        commandsList.append(Command.SplitWayCommand.split(
     86                                    way, [adjacent_node_to_split_on], []))
     87                        MainApplication.undoRedo.add(Command.SequenceCommand(
     88                                    "Split selected way", commandsList))
     89                        commandsList = []
     90                    # After splitting find the segment that connects to the roundabout again
     91                    for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays():
     92                        if common_node in waypartconnectedtoroundabout.getNodes():
     93                            break
     94                    if len(way.getNodes())==2:
     95                        if common_node == waypartconnectedtoroundabout.firstNode():
     96                            adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode()
     97                        else:
     98                            adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode()
     99                    # time to actually do something
     100                    # make a copy of the way
     101                    modified_way = Way(waypartconnectedtoroundabout)
     102                    # replace its nodes, so it becomes a fork
     103                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
     104                    # add oneway tag
     105                    modified_way.put('oneway', 'yes')
     106                    # apply the changes
     107                    commandsList.append(Command.ChangeCommand(
     108                                    waypartconnectedtoroundabout, modified_way))
     109                    MainApplication.undoRedo.add(Command.SequenceCommand(
     110                                    "Add oneway tag and create forked way", commandsList))
     111                    commandsList = []
     112                    # split this way where it forks
     113                    commandsList.append(Command.SplitWayCommand.split(
     114                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
     115                    MainApplication.undoRedo.add(Command.SequenceCommand(
     116                                    "Split fork into 2 ways", commandsList))
     117                    commandsList = []
     118
     119}}}
     120
     121
     122== Convert a way that connects to a split roundabout to a fork ==
     123This script does the same as the previous one, but it also works on roundabouts where the ways are split. It's not taking care of the relations.
     124
     125{{{#!python
     126from javax.swing import JOptionPane
     127from org.openstreetmap.josm.gui import MainApplication
     128
     129import org.openstreetmap.josm.command as Command
     130import org.openstreetmap.josm.data.osm.Way as Way
     131
     132editLayer = MainApplication.getLayerManager().getEditLayer()
     133print '==== Fresh run ===='
     134if editLayer and editLayer.data:
     135    selected_ways = editLayer.data.getSelectedWays()
     136    print selected_ways
     137
     138    if not(selected_ways) or len(selected_ways)>1:
     139        JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Please select a single way that connects to a roundabout")
     140    else:
     141        for way in selected_ways:
     142            if way.get('oneway') in ['yes', '-1']:
     143                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "This way has oneway tag set")
     144            elif way.get('junction') in ['roundabout']:
     145                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "This way is part of a roundabout")
     146            else:
     147                node_before = None
     148                node_after = None
     149                common_node = None
     150                common_node_becomes_node_before=None
     151                roundabout_way_before = None
     152                roundabout_way_after = None
     153                for fln in [way.firstNode(),  way.lastNode()]:
     154                    print 'fln',  fln
     155                    for parentway in fln.getParentWays():
     156                        if parentway.get("junction")=='roundabout':
     157                            print parentway.get('name')
     158                            if parentway.isClosed():
     159                                # unsplit roundabout
     160                                for n in parentway.getNodes():
     161                                    if common_node:
     162                                        # found common node between selected way
     163                                        # and roundabout way in previous iteration
     164                                        node_after = n
     165                                        print node_before.get('name')
     166                                        print node_after.get('name')
     167                                        # we are done here
     168                                        break
     169                                    if n.getId() == fln.getId():
     170                                        # this is the node the roundabout has in common with selected way
     171                                        common_node = n
     172                                        print common_node.get('name')
     173                                        if not(node_before):
     174                                            # normally we encountered a node on the roundabout way
     175                                            # before this one, but if the common node is the first node
     176                                            # of an unsplit roundabout, we will need to take the last
     177                                            # node of the roundabout instead
     178                                            node_before = parentway.getNodes()[-2]
     179                                            node_after = parentway.getNodes()[1]
     180                                            print node_before.get('name')
     181                                            print node_after.get('name')
     182                                            break
     183                                        # if not we go through the loop one more time to put the next
     184                                        # node in node_after
     185                                        continue
     186                                    node_before = n
     187                            else:
     188                                # this is a split roundabout
     189                                if parentway.firstNode().getId() == fln.getId():
     190                                    node_after = parentway.getNodes()[1]
     191                                    roundabout_way_after = parentway
     192                                    print 'node after', node_after.get('name')
     193                                else:
     194                                    node_before = parentway.getNodes()[-2]
     195                                    roundabout_way_before = parentway
     196                                if node_before and node_after:
     197                                    common_node = fln
     198                                    break
     199
     200                            if common_node:
     201                                # if common_node is already defined at this point, it means it was
     202                                # the first node of the selected way,
     203                                # so it will have to be replaced with node_before in the selected way
     204                                common_node_becomes_node_before = True
     205                                break
     206                            else:
     207                                common_node_becomes_node_before = False
     208                       
     209                if common_node.getId() == way.firstNode().getId():
     210                    adjacent_node_to_split_on = way.getNodes()[1]
     211                else:
     212                    adjacent_node_to_split_on = way.getNodes()[-1]
     213
     214                if not(common_node) or ((parentway.isClosed() and common_node_becomes_node_before==None)):
     215                    JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Please select a way that connects to a roundabout")
     216                else:
     217                    commandsList = []
     218                    if len(way.getNodes())>2:
     219                        # split off last segment before roundabout if needed
     220                        commandsList.append(Command.SplitWayCommand.split(
     221                                    way, [adjacent_node_to_split_on], []))
     222                        MainApplication.undoRedo.add(Command.SequenceCommand(
     223                                    "Split selected way", commandsList))
     224                        commandsList = []
     225                    # After splitting find the segment that connects to the roundabout again
     226                    for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays():
     227                        if waypartconnectedtoroundabout.get('junction') == 'roundabout':
     228                            continue
     229                        if common_node in waypartconnectedtoroundabout.getNodes():
     230                            break
     231                    if len(way.getNodes())==2:
     232                        if common_node == waypartconnectedtoroundabout.firstNode():
     233                            adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode()
     234                        else:
     235                            adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode()
     236                    # time to actually do something
     237                    # make a copy of the way
     238                    modified_way = Way(waypartconnectedtoroundabout)
     239                    # replace its nodes, so it becomes a fork
     240                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
     241                    # add oneway tag
     242                    modified_way.put('oneway', 'yes')
     243                    # apply the changes
     244                    commandsList.append(Command.ChangeCommand(
     245                                    waypartconnectedtoroundabout, modified_way))
     246                    MainApplication.undoRedo.add(Command.SequenceCommand(
     247                                    "Add oneway tag and create forked way", commandsList))
     248                    commandsList = []
     249                    # split this way where it forks
     250                    commandsList.append(Command.SplitWayCommand.split(
     251                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
     252                    MainApplication.undoRedo.add(Command.SequenceCommand(
     253                                    "Split fork into 2 ways", commandsList))
     254                    commandsList = []
     255                   
     256                    if roundabout_way_before and roundabout_way_after:
     257                        origway = roundabout_way_before
     258                        roundabout_way_before.addNode(node_after)
     259                        commandsList.append(Command.ChangeCommand(
     260                                        origway,  roundabout_way_before))
     261                        origway = roundabout_way_after
     262                        roundabout_way_after.removeNode(common_node)
     263                        commandsList.append(Command.ChangeCommand(
     264                                        origway,roundabout_way_after))
     265#                        middleway = Way(roundabout_way_after).setNodes(
     266#                                        [node_before, common_node, node_after])
     267#                        commandsList.append(Command.AddCommand(editLayer.data, middleway))
     268#                        MainApplication.undoRedo.add(Command.SequenceCommand(
     269#                                        "Add way on roundabout where fork attaches", commandsList))
     270                        commandsList.append(Command.SplitWayCommand.split(
     271                                        roundabout_way_before, [node_before], []))
     272                        MainApplication.undoRedo.add(Command.SequenceCommand(
     273                                        "Split roundabout way", commandsList))
     274                        commandsList = []
     275
     276}}}
     277
     278
     279== Export a collection of routes to Garmin GPX file ==
     280Export a collection of routes to Garmin GPX file (not a super example, as I don't think we do collection relations anymore):
    7281
    8282{{{#!python
     
    10284'''
    11285RWN2Garmin.py  - Numbered networks to Garmin GPX file converter
    12 This code is released under the GNU General
    13 Public License v2 or later.
     286This code is released under the GNU General Public License v2 or later.
    14287
    15288The GPL v3 is accessible here:
    16 http://www.gnu.org/licenses/gpl.html
    17 
    18 The GPL v2 is accessible here:
    19 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     289https://www.gnu.org/licenses/gpl.html
    20290
    21291It comes with no warranty whatsoever.
    22 
    23 This code illustrates how to use Jython to:
    24 * work with selected items or how to process all the primitives of a certain kind (node, way, relation)
    25 
    26292'''
    27293from javax.swing import JOptionPane, JDialog
     
    35301import time
    36302
    37 def getMapView():
    38     if Main.main and Main.main.map:
    39         return Main.main.map.mapView
    40     else:
    41         return None
    42 
    43 mv = getMapView()
    44303f = open('C:/export.gpx', 'w')
    45304f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n')
    46 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')
    47 f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (http://creativecommons.org/licenses/by-sa/2.0/). -->\n')
    48 if mv and mv.editLayer and mv.editLayer.data:
    49     #selectedNodes = mv.editLayer.data.getSelectedNodes()
    50     #selectedWays = mv.editLayer.data.getSelectedWays()
     305f.write('<gpx xmlns="https://www.topografix.com/GPX/1/1" creator="OSM Route Manager" version="1.1" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.topografix.com/GPX/1/1 https://www.topografix.com/GPX/1/1/gpx.xsd">\n')
     306f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (https://creativecommons.org/licenses/by-sa/2.0/). -->\n')
     307
     308editLayer = Main.getLayerManager().getEditLayer()
     309if editLayer and editLayer.data:
    51310    selectedRelations = mv.editLayer.data.getSelectedRelations()
    52311
     
    54313        JOptionPane.showMessageDialog(Main.parent, "Please select a collection relation")
    55314    else:
    56         # nodetype = Node().getType()
    57315        print
    58316        for collection in selectedRelations:
     
    101359
    102360
    103 Download missing parent elements for the selected element:
    104 
     361== Download missing parent elements for the selected element ==
    105362
    106363{{{#!python
     
    112369
    113370The GPL v3 is accessible here:
    114 http://www.gnu.org/licenses/gpl.html
     371https://www.gnu.org/licenses/gpl.html
    115372
    116373The GPL v2 is accessible here:
    117 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     374https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    118375
    119376It comes with no warranty whatsoever.
    120377
    121378This code illustrates how to use Jython to:
    122 * Download all referrer for an element
     379* Download all referrers for an element
    123380
    124381'''
    125382from javax.swing import JOptionPane
    126383from org.openstreetmap.josm import Main
    127 import org.openstreetmap.josm.data.osm.Node as Node
    128 import org.openstreetmap.josm.data.osm.Way as Way
    129 import org.openstreetmap.josm.data.osm.Relation as Relation
    130 import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
    131 import org.openstreetmap.josm.data.osm.DataSet as DataSet
    132 import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
    133384import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction
    134 #import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask as DownloadReferrersTask;
    135 
    136 def getMapView():
    137     if Main.main and Main.main.map:
    138         return Main.main.map.mapView
    139     else:
    140         return None
    141 
    142 mv = getMapView()
    143 if mv and mv.editLayer and mv.editLayer.data:
    144     selectedElements = mv.editLayer.data.getSelected()
     385
     386editLayer = Main.getLayerManager().getEditLayer()
     387if editLayer and editLayer.data:
     388    selectedElements = editLayer.data.getSelected()
    145389   
    146390    if not(selectedElements):
    147391        JOptionPane.showMessageDialog(Main.parent, "Please select an element")
    148392    else:
    149         DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedElements)
     393        DownloadReferrersAction.downloadReferrers(editLayer, selectedElements)
    150394}}}
    151395
    152396
    153 Download missing relation members:
    154 
     397== Download missing relation members ==
    155398
    156399{{{
     
    162405
    163406The GPL v3 is accessible here:
    164 http://www.gnu.org/licenses/gpl.html
     407https://www.gnu.org/licenses/gpl.html
    165408
    166409The GPL v2 is accessible here:
    167 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     410https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    168411
    169412It comes with no warranty whatsoever.
     
    183426import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask
    184427
    185 def getMapView():
    186     if Main.main and Main.main.map:
    187         return Main.main.map.mapView
    188     else:
    189         return None
    190 
    191 mv = getMapView()
    192 if mv and mv.editLayer and mv.editLayer.data:
    193     selectedRelations = mv.editLayer.data.getSelectedRelations()
     428editLayer = Main.getLayerManager().getEditLayer()
     429if editLayer:
     430    selectedRelations = editLayer.data.getSelectedRelations()
    194431   
    195432    if not(selectedRelations):
    196         JOptionPane.showMessageDialog(Main.parent, "Please select a node")
     433        JOptionPane.showMessageDialog(Main.parent, "Please select a relation")
    197434    else:
    198435        for relation in selectedRelations:
     
    200437                #print dir(relation)
    201438                print dir(DownloadRelationMemberTask)
    202                 DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer ))
    203 
     439                DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), editLayer ))
    204440}}}
    205441
    206442
    207 Validate an rcn route relation:
    208 
     443== Validate an rcn route relation ==
    209444
    210445{{{
     
    217452
    218453The GPL v3 is accessible here:
    219 http://www.gnu.org/licenses/gpl.html
     454https://www.gnu.org/licenses/gpl.html
    220455
    221456The GPL v2 is accessible here:
    222 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     457https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    223458
    224459It comes with no warranty whatsoever.
     
    405640}}}
    406641
    407 [wiki:Python/RCN_Route_Validator]
    408 
     642[wiki:/Help/Plugin/Scripting/Python/RCN_Route_Validator]
     643
     644
     645== Remove extra ways resulting from Potlatch operations ==
    409646Remove extra ways resulting from Potlatch way split operations under turn restriction relations
    410647
    411648{{{#!python
    412 
    413649#!/bin/jython
    414650
     
    420656
    421657The GPL v3 is accessible here:
    422 http://www.gnu.org/licenses/gpl.html
    423 
    424 The GPL v2 is accessible here:
    425 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     658https://www.gnu.org/licenses/gpl.html
    426659
    427660It comes with no warranty whatsoever.
     
    429662This 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
    430663
    431 Only work for turn restrictions with one via node
     664Only works for turn restrictions with one via node
    432665
    433666e.g. Original      : from: Way1, via: Node, to:Way2
     
    457690    pass
    458691
    459 def getMapView():
    460     if Main.main and Main.main.map:
    461         return Main.main.map.mapView
    462     else:
    463         return None
    464 
    465692def getMembers (restriction):
    466693    memberlist = dict()
     
    511738    """
    512739    if (way.isOneway() != 0 and reverse):
    513         return node == way.lastNode(True), way.firstNode(True) # True: auto process case whan isOneway == -1
     740        return node == way.lastNode(True), way.firstNode(True) # True: auto process case when isOneway == -1
    514741    if (way.isOneway() != 0):     # not reverse
    515742        return node == way.firstNode(True), way.lastNode(True)
     
    598825   
    599826validrestrictiontypes = ('only_straight_on', 'only_right_turn', 'only_left_turn', 'no_right_turn', 'no_left_turn', 'no_straight_on', 'no_u_turn')
    600 mv = getMapView()
    601 if mv and mv.editLayer and mv.editLayer.data:
    602     selectedRelations = mv.editLayer.data.getSelectedRelations()
     827editLayer = Main.getLayerManager().getEditLayer()
     828if editLayer and editLayer.data:
     829    selectedRelations = editLayer.data.getSelectedRelations()
    603830   
    604831    if not(selectedRelations):
     
    609836            if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes:
    610837                try:
    611                     memberlist = getMembers (relation)     
    612                     #print "".join(v * len(memberlist[v]) for v in memberlist.keys())           
     838                    memberlist = getMembers (relation)
    613839                    if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 :
    614840                        # Repair attempt
     
    625851        commandsList=[]
    626852}}}
     853
     854
     855----
     856Back to [wikitr:/Help/Plugin/Scripting Plugin Scripting] \\
     857Back to [wikitr:/Plugins Plugin Help] \\
     858Back to [wikitr:/Help Main Help]