Changes between Version 10 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

    v10 v18  
     1[[TranslatedPages]]
     2
     3= Plugin -> Scripting -> Python =
     4== Purpose ==
    15Some more examples in Python:
    26
    3 Export a collection of routes to Garmin GPX file:
    4 
     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):
    5281
    6282{{{#!python
     
    8284'''
    9285RWN2Garmin.py  - Numbered networks to Garmin GPX file converter
    10 This code is released under the GNU General
    11 Public License v2 or later.
     286This code is released under the GNU General Public License v2 or later.
    12287
    13288The GPL v3 is accessible here:
    14 http://www.gnu.org/licenses/gpl.html
    15 
    16 The GPL v2 is accessible here:
    17 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     289https://www.gnu.org/licenses/gpl.html
    18290
    19291It comes with no warranty whatsoever.
    20 
    21 This code illustrates how to use Jython to:
    22 * work with selected items or how to process all the primitives of a certain kind (node, way, relation)
    23 
    24292'''
    25293from javax.swing import JOptionPane, JDialog
     
    33301import time
    34302
    35 def getMapView():
    36     if Main.main and Main.main.map:
    37         return Main.main.map.mapView
    38     else:
    39         return None
    40 
    41 mv = getMapView()
    42303f = open('C:/export.gpx', 'w')
    43304f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n')
    44 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')
    45 f.write('<!-- All data by OpenStreetMap, licensed under cc-by-sa-2.0 (http://creativecommons.org/licenses/by-sa/2.0/). -->\n')
    46 if mv and mv.editLayer and mv.editLayer.data:
    47     #selectedNodes = mv.editLayer.data.getSelectedNodes()
    48     #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:
    49310    selectedRelations = mv.editLayer.data.getSelectedRelations()
    50311
     
    52313        JOptionPane.showMessageDialog(Main.parent, "Please select a collection relation")
    53314    else:
    54         # nodetype = Node().getType()
    55315        print
    56316        for collection in selectedRelations:
     
    99359
    100360
    101 Download missing parent elements for the selected element:
    102 
     361== Download missing parent elements for the selected element ==
    103362
    104363{{{#!python
     
    110369
    111370The GPL v3 is accessible here:
    112 http://www.gnu.org/licenses/gpl.html
     371https://www.gnu.org/licenses/gpl.html
    113372
    114373The GPL v2 is accessible here:
    115 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     374https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    116375
    117376It comes with no warranty whatsoever.
    118377
    119378This code illustrates how to use Jython to:
    120 * Download all referrer for an element
     379* Download all referrers for an element
    121380
    122381'''
    123382from javax.swing import JOptionPane
    124383from org.openstreetmap.josm import Main
    125 import org.openstreetmap.josm.data.osm.Node as Node
    126 import org.openstreetmap.josm.data.osm.Way as Way
    127 import org.openstreetmap.josm.data.osm.Relation as Relation
    128 import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
    129 import org.openstreetmap.josm.data.osm.DataSet as DataSet
    130 import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
    131384import org.openstreetmap.josm.actions.DownloadReferrersAction as DownloadReferrersAction
    132 #import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask as DownloadReferrersTask;
    133 
    134 def getMapView():
    135     if Main.main and Main.main.map:
    136         return Main.main.map.mapView
    137     else:
    138         return None
    139 
    140 mv = getMapView()
    141 if mv and mv.editLayer and mv.editLayer.data:
    142     selectedElements = mv.editLayer.data.getSelected()
     385
     386editLayer = Main.getLayerManager().getEditLayer()
     387if editLayer and editLayer.data:
     388    selectedElements = editLayer.data.getSelected()
    143389   
    144390    if not(selectedElements):
    145391        JOptionPane.showMessageDialog(Main.parent, "Please select an element")
    146392    else:
    147         DownloadReferrersAction.downloadReferrers(mv.editLayer, selectedElements)
     393        DownloadReferrersAction.downloadReferrers(editLayer, selectedElements)
    148394}}}
    149395
    150396
    151 Download missing relation members:
    152 
     397== Download missing relation members ==
    153398
    154399{{{
     
    160405
    161406The GPL v3 is accessible here:
    162 http://www.gnu.org/licenses/gpl.html
     407https://www.gnu.org/licenses/gpl.html
    163408
    164409The GPL v2 is accessible here:
    165 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     410https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    166411
    167412It comes with no warranty whatsoever.
     
    181426import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask
    182427
    183 def getMapView():
    184     if Main.main and Main.main.map:
    185         return Main.main.map.mapView
    186     else:
    187         return None
    188 
    189 mv = getMapView()
    190 if mv and mv.editLayer and mv.editLayer.data:
    191     selectedRelations = mv.editLayer.data.getSelectedRelations()
     428editLayer = Main.getLayerManager().getEditLayer()
     429if editLayer:
     430    selectedRelations = editLayer.data.getSelectedRelations()
    192431   
    193432    if not(selectedRelations):
    194         JOptionPane.showMessageDialog(Main.parent, "Please select a node")
     433        JOptionPane.showMessageDialog(Main.parent, "Please select a relation")
    195434    else:
    196435        for relation in selectedRelations:
     
    198437                #print dir(relation)
    199438                print dir(DownloadRelationMemberTask)
    200                 DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), mv.editLayer ))
    201 
     439                DownloadRelationMemberTask.run(DownloadRelationMemberTask(relation, relation.getIncompleteMembers(), editLayer ))
    202440}}}
    203441
    204442
    205 Validate an rcn route relation:
    206 
     443== Validate an rcn route relation ==
    207444
    208445{{{
     
    215452
    216453The GPL v3 is accessible here:
    217 http://www.gnu.org/licenses/gpl.html
     454https://www.gnu.org/licenses/gpl.html
    218455
    219456The GPL v2 is accessible here:
    220 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     457https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    221458
    222459It comes with no warranty whatsoever.
     
    403640}}}
    404641
    405 [wiki:Python/RCN_Route_Validator]
    406 
     642[wiki:/Help/Plugin/Scripting/Python/RCN_Route_Validator]
     643
     644
     645== Remove extra ways resulting from Potlatch operations ==
    407646Remove extra ways resulting from Potlatch way split operations under turn restriction relations
    408647
    409648{{{#!python
    410 
    411649#!/bin/jython
    412650
     
    418656
    419657The GPL v3 is accessible here:
    420 http://www.gnu.org/licenses/gpl.html
    421 
    422 The GPL v2 is accessible here:
    423 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
     658https://www.gnu.org/licenses/gpl.html
    424659
    425660It comes with no warranty whatsoever.
     
    427662This 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
    428663
    429 Only work for turn restrictions with one via node
     664Only works for turn restrictions with one via node
    430665
    431666e.g. Original      : from: Way1, via: Node, to:Way2
     
    455690    pass
    456691
    457 def getMapView():
    458     if Main.main and Main.main.map:
    459         return Main.main.map.mapView
    460     else:
    461         return None
    462 
    463692def getMembers (restriction):
    464693    memberlist = dict()
     
    509738    """
    510739    if (way.isOneway() != 0 and reverse):
    511         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
    512741    if (way.isOneway() != 0):     # not reverse
    513742        return node == way.firstNode(True), way.lastNode(True)
     
    596825   
    597826validrestrictiontypes = ('only_straight_on', 'only_right_turn', 'only_left_turn', 'no_right_turn', 'no_left_turn', 'no_straight_on', 'no_u_turn')
    598 mv = getMapView()
    599 if mv and mv.editLayer and mv.editLayer.data:
    600     selectedRelations = mv.editLayer.data.getSelectedRelations()
     827editLayer = Main.getLayerManager().getEditLayer()
     828if editLayer and editLayer.data:
     829    selectedRelations = editLayer.data.getSelectedRelations()
    601830   
    602831    if not(selectedRelations):
     
    607836            if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes:
    608837                try:
    609                     memberlist = getMembers (relation)     
    610                     #print "".join(v * len(memberlist[v]) for v in memberlist.keys())           
     838                    memberlist = getMembers (relation)
    611839                    if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 :
    612840                        # Repair attempt
     
    623851        commandsList=[]
    624852}}}
     853
     854
     855----
     856Back to [wikitr:/Help/Plugin/Scripting Plugin Scripting] \\
     857Back to [wikitr:/Plugins Plugin Help] \\
     858Back to [wikitr:/Help Main Help]