Changes between Initial Version and Version 1 of Eo:Help/Plugin/Scripting/Python


Ignore:
Timestamp:
2025-03-08T20:11:50+01:00 (5 months ago)
Author:
paleid
Comment:

Eo added

Legend:

Unmodified
Added
Removed
Modified
  • TabularUnified Eo:Help/Plugin/Scripting/Python

    v1 v1  
     1[[TranslatedPages(revision=18)]]
     2
     3= Kromaĵo -> Skriptado -> Python =
     4== Celo ==
     5Kelkaj pliaj ekzemploj en Python:
     6
     7[[PageOutline(2,Enhavotabelo)]]
     8
     9== Konverti vojon kiu konektiĝas al nerompita ĉirkaŭvojo al forko ==
     10Konverti vojon kiu konektiĝas al ĉirkaŭvojo al forko konsistanta el 2 unudirektaj vojoj. Dividi la vojon sur ĝia lasta nodo kaj konekti al la 2 nodoj apudaj al la komuna nodo de la ĉirkaŭvojo. Ĉi tiu versio nur funkcias sur nerompitaj ĉirkaŭvojoj. Vidu la sekvan ekzemplon por ĝisdatigita versio.
     11
     12{{{#!python
     13from javax.swing import JOptionPane
     14from org.openstreetmap.josm.gui import MainApplication
     15
     16import org.openstreetmap.josm.command as Command
     17import org.openstreetmap.josm.data.osm.Way as Way
     18
     19editLayer = MainApplication.getLayerManager().getEditLayer()
     20if editLayer and editLayer.data:
     21    selected_ways = editLayer.data.getSelectedWays()
     22    print selected_ways
     23
     24    if not(selected_ways) or len(selected_ways)>1:
     25        JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
     26                                         "Bonvolu elekti unu vojon kiu konektiĝas al ĉirkaŭvojo")
     27    else:
     28        for way in selected_ways:
     29            if way.get('oneway') in ['yes', '-1']:
     30                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ĉi tiu vojo havas unudirektan etikedon")
     31            else:
     32                node_before = None
     33                node_after = None
     34                common_node = None
     35                common_node_becomes_node_before=None
     36                #print dir(way)
     37                for fln in [way.firstNode(),  way.lastNode()]:
     38                    print 'fln',  fln
     39                    for parentway in fln.getParentWays():
     40                        if parentway.get("junction")=='roundabout':
     41                            for n in parentway.getNodes():
     42                                if common_node:
     43                                    # trovita komuna nodo inter elektita vojo kaj
     44                                    # ĉirkaŭvojo en antaŭa iteracio
     45                                    node_after = n
     46                                    # ni estas pretaj ĉi tie
     47                                    break
     48                                if n.getId() == fln.getId():
     49                                    # ĉi tiu estas la nodo kiun la ĉirkaŭvojo havas komunan kun la elektita vojo
     50                                    common_node = n
     51                                    if not(node_before):
     52                                        # normale ni renkontis nodon sur la ĉirkaŭvojo
     53                                        # antaŭ ĉi tiu, sed se la komuna nodo estas la unua nodo
     54                                        # de nerompita ĉirkaŭvojo, ni devos preni la lastan
     55                                        # nodon de la ĉirkaŭvojo anstataŭe
     56                                        node_before = parentway.getNodes()[-2]
     57                                        node_after = parentway.getNodes()[1]
     58                                        break
     59                                    # se ne, ni iras tra la buklo unu fojon pli por meti la sekvan
     60                                    # nodon en node_after
     61                                    continue
     62                                node_before = n
     63                        if common_node:
     64                            # se common_node jam estas difinita ĉe ĉi tiu punkto, ĝi signifas ke ĝi estis
     65                            # la unua nodo de la elektita vojo,
     66                            # do ĝi devos esti anstataŭigita per node_before en la elektita vojo
     67                            common_node_becomes_node_before = True
     68                            adjacent_node_to_split_on = way.getNodes()[1]
     69                            break
     70                        else:
     71                            common_node_becomes_node_before = False
     72                            adjacent_node_to_split_on = way.getNodes()[-1]
     73                if not(common_node) or common_node_becomes_node_before==None:
     74                    JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
     75                                               "Bonvolu elekti vojon kiu konektiĝas al ĉirkaŭvojo")
     76                else:
     77                    print common_node.get('name')
     78                    print node_before.get('name')
     79                    print node_after.get('name')
     80
     81                    commandsList = []
     82                    if len(way.getNodes())>2:
     83                        # dividi lastan segmenton antaŭ ĉirkaŭvojo se necese
     84                        commandsList.append(Command.SplitWayCommand.split(
     85                                    way, [adjacent_node_to_split_on], []))
     86                        MainApplication.undoRedo.add(Command.SequenceCommand(
     87                                    "Dividi elektitan vojon", commandsList))
     88                        commandsList = []
     89                    # Post dividado trovi la segmenton kiu konektiĝas al la ĉirkaŭvojo denove
     90                    for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays():
     91                        if common_node in waypartconnectedtoroundabout.getNodes():
     92                            break
     93                    if len(way.getNodes())==2:
     94                        if common_node == waypartconnectedtoroundabout.firstNode():
     95                            adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode()
     96                        else:
     97                            adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode()
     98                    # tempo por efektive fari ion
     99                    # krei kopion de la vojo
     100                    modified_way = Way(waypartconnectedtoroundabout)
     101                    # anstataŭigi ĝiajn nodojn, por ke ĝi iĝu forko
     102                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
     103                    # aldoni unudirektan etikedon
     104                    modified_way.put('oneway', 'yes')
     105                    # apliki la ŝanĝojn
     106                    commandsList.append(Command.ChangeCommand(
     107                                    waypartconnectedtoroundabout, modified_way))
     108                    MainApplication.undoRedo.add(Command.SequenceCommand(
     109                                    "Aldoni unudirektan etikedon kaj krei forkan vojon", commandsList))
     110                    commandsList = []
     111                    # dividi ĉi tiun vojon kie ĝi forkas
     112                    commandsList.append(Command.SplitWayCommand.split(
     113                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
     114                    MainApplication.undoRedo.add(Command.SequenceCommand(
     115                                    "Dividi forkon en 2 vojojn", commandsList))
     116                    commandsList = []
     117
     118}}}
     119
     120
     121== Konverti vojon kiu konektiĝas al rompita ĉirkaŭvojo al forko ==
     122Ĉi tiu skripto faras la samon kiel la antaŭa, sed ĝi ankaŭ funkcias sur ĉirkaŭvojoj kie la vojoj estas rompitaj. Ĝi ne zorgas pri la rilatoj.
     123
     124{{{#!python
     125from javax.swing import JOptionPane
     126from org.openstreetmap.josm.gui import MainApplication
     127
     128import org.openstreetmap.josm.command as Command
     129import org.openstreetmap.josm.data.osm.Way as Way
     130
     131editLayer = MainApplication.getLayerManager().getEditLayer()
     132print '==== Freŝa rulo ===='
     133if editLayer and editLayer.data:
     134    selected_ways = editLayer.data.getSelectedWays()
     135    print selected_ways
     136
     137    if not(selected_ways) or len(selected_ways)>1:
     138        JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Bonvolu elekti unu vojon kiu konektiĝas al ĉirkaŭvojo")
     139    else:
     140        for way in selected_ways:
     141            if way.get('oneway') in ['yes', '-1']:
     142                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ĉi tiu vojo havas unudirektan etikedon")
     143            elif way.get('junction') in ['roundabout']:
     144                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ĉi tiu vojo estas parto de ĉirkaŭvojo")
     145            else:
     146                node_before = None
     147                node_after = None
     148                common_node = None
     149                common_node_becomes_node_before=None
     150                roundabout_way_before = None
     151                roundabout_way_after = None
     152                for fln in [way.firstNode(),  way.lastNode()]:
     153                    print 'fln',  fln
     154                    for parentway in fln.getParentWays():
     155                        if parentway.get("junction")=='roundabout':
     156                            print parentway.get('name')
     157                            if parentway.isClosed():
     158                                # nerompita ĉirkaŭvojo
     159                                for n in parentway.getNodes():
     160                                    if common_node:
     161                                        # trovita komuna nodo inter elektita vojo
     162                                        # kaj ĉirkaŭvojo en antaŭa iteracio
     163                                        node_after = n
     164                                        print node_before.get('name')
     165                                        print node_after.get('name')
     166                                        # ni estas pretaj ĉi tie
     167                                        break
     168                                    if n.getId() == fln.getId():
     169                                        # ĉi tiu estas la nodo kiun la ĉirkaŭvojo havas komunan kun la elektita vojo
     170                                        common_node = n
     171                                        print common_node.get('name')
     172                                        if not(node_before):
     173                                            # normale ni renkontis nodon sur la ĉirkaŭvojo
     174                                            # antaŭ ĉi tiu, sed se la komuna nodo estas la unua nodo
     175                                            # de nerompita ĉirkaŭvojo, ni devos preni la lastan
     176                                            # nodon de la ĉirkaŭvojo anstataŭe
     177                                            node_before = parentway.getNodes()[-2]
     178                                            node_after = parentway.getNodes()[1]
     179                                            print node_before.get('name')
     180                                            print node_after.get('name')
     181                                            break
     182                                        # se ne, ni iras tra la buklo unu fojon pli por meti la sekvan
     183                                        # nodon en node_after
     184                                        continue
     185                                    node_before = n
     186                            else:
     187                                # ĉi tiu estas rompita ĉirkaŭvojo
     188                                if parentway.firstNode().getId() == fln.getId():
     189                                    node_after = parentway.getNodes()[1]
     190                                    roundabout_way_after = parentway
     191                                    print 'node after', node_after.get('name')
     192                                else:
     193                                    node_before = parentway.getNodes()[-2]
     194                                    roundabout_way_before = parentway
     195                                if node_before and node_after:
     196                                    common_node = fln
     197                                    break
     198
     199                            if common_node:
     200                                # se common_node jam estas difinita ĉe ĉi tiu punkto, ĝi signifas ke ĝi estis
     201                                # la unua nodo de la elektita vojo,
     202                                # do ĝi devos esti anstataŭigita per node_before en la elektita vojo
     203                                common_node_becomes_node_before = True
     204                                break
     205                            else:
     206                                common_node_becomes_node_before = False
     207                       
     208                if common_node.getId() == way.firstNode().getId():
     209                    adjacent_node_to_split_on = way.getNodes()[1]
     210                else:
     211                    adjacent_node_to_split_on = way.getNodes()[-1]
     212
     213                if not(common_node) or ((parentway.isClosed() and common_node_becomes_node_before==None)):
     214                    JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Bonvolu elekti vojon kiu konektiĝas al ĉirkaŭvojo")
     215                else:
     216                    commandsList = []
     217                    if len(way.getNodes())>2:
     218                        # dividi lastan segmenton antaŭ ĉirkaŭvojo se necese
     219                        commandsList.append(Command.SplitWayCommand.split(
     220                                    way, [adjacent_node_to_split_on], []))
     221                        MainApplication.undoRedo.add(Command.SequenceCommand(
     222                                    "Dividi elektitan vojon", commandsList))
     223                        commandsList = []
     224                    # Post dividado trovi la segmenton kiu konektiĝas al la ĉirkaŭvojo denove
     225                    for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays():
     226                        if waypartconnectedtoroundabout.get('junction') == 'roundabout':
     227                            continue
     228                        if common_node in waypartconnectedtoroundabout.getNodes():
     229                            break
     230                    if len(way.getNodes())==2:
     231                        if common_node == waypartconnectedtoroundabout.firstNode():
     232                            adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode()
     233                        else:
     234                            adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode()
     235                    # tempo por efektive fari ion
     236                    # krei kopion de la vojo
     237                    modified_way = Way(waypartconnectedtoroundabout)
     238                    # anstataŭigi ĝiajn nodojn, por ke ĝi iĝu forko
     239                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
     240                    # aldoni unudirektan etikedon
     241                    modified_way.put('oneway', 'yes')
     242                    # apliki la ŝanĝojn
     243                    commandsList.append(Command.ChangeCommand(
     244                                    waypartconnectedtoroundabout, modified_way))
     245                    MainApplication.undoRedo.add(Command.SequenceCommand(
     246                                    "Aldoni unudirektan etikedon kaj krei forkan vojon", commandsList))
     247                    commandsList = []
     248                    # dividi ĉi tiun vojon kie ĝi forkas
     249                    commandsList.append(Command.SplitWayCommand.split(
     250                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
     251                    MainApplication.undoRedo.add(Command.SequenceCommand(
     252                                    "Dividi forkon en 2 vojojn", commandsList))
     253                    commandsList = []
     254                   
     255                    if roundabout_way_before and roundabout_way_after:
     256                        origway = roundabout_way_before
     257                        roundabout_way_before.addNode(node_after)
     258                        commandsList.append(Command.ChangeCommand(
     259                                        origway,  roundabout_way_before))
     260                        origway = roundabout_way_after
     261                        roundabout_way_after.removeNode(common_node)
     262                        commandsList.append(Command.ChangeCommand(
     263                                        origway,roundabout_way_after))
     264#                        middleway = Way(roundabout_way_after).setNodes(
     265#                                        [node_before, common_node, node_after])
     266#                        commandsList.append(Command.AddCommand(editLayer.data, middleway))
     267#                        MainApplication.undoRedo.add(Command.SequenceCommand(
     268#                                        "Aldoni vojon sur ĉirkaŭvojo kie forko konektiĝas", commandsList))
     269                        commandsList.append(Command.SplitWayCommand.split(
     270                                        roundabout_way_before, [node_before], []))
     271                        MainApplication.undoRedo.add(Command.SequenceCommand(
     272                                        "Dividi ĉirkaŭvojon", commandsList))
     273                        commandsList = []
     274
     275}}}
     276
     277
     278== Eksporti kolekton de itineroj al Garmin GPX-dosiero ==
     279Eksporti kolekton de itineroj al Garmin GPX-dosiero (ne ekzemplo, ĉar mi ne pensas ke ni plu faras kolektajn rilatojn):
     280
     281{{{#!python
     282#!/bin/jython
     283'''
     284RWN2Garmin.py  - Numeritaj retoj al Garmin GPX-dosiera konvertilo
     285Ĉi tiu kodo estas liberigita sub la GNU General Public License v2 aŭ poste.
     286
     287La GPL v3 estas alirebla ĉi tie:
     288https://www.gnu.org/licenses/gpl.html
     289
     290Ĝi venas sen ia ajn garantio.
     291'''
     292from javax.swing import JOptionPane, JDialog
     293from java.awt.event import ActionListener, ActionEvent
     294from org.openstreetmap.josm import Main
     295import org.openstreetmap.josm.command as Command
     296import org.openstreetmap.josm.data.osm.Node as Node
     297import org.openstreetmap.josm.data.osm.Way as Way
     298import org.openstreetmap.josm.data.osm.TagCollection as TagCollection
     299import org.openstreetmap.josm.data.osm.DataSet as DataSet
     300import org.openstreetmap.josm.data.osm.RelationMember as RelationMember
     301import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask as DownloadRelationMemberTask
     302import org.openstreetmap.josm.io.MultiFetchServerObjectReader as MultiFetchServerObjectReader
     303import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor as PleaseWaitProgressMonitor
     304import org.openstreetmap.josm.command as Command
     305
     306class RestrictionError(Exception):
     307    pass
     308
     309def getMembers (restriction):
     310    memberlist = dict()
     311    for member in restriction.getMembers():
     312        memberRole = member.getRole()
     313        if memberRole == "via":
     314            if member.isNode() and not "via" in memberlist:
     315                memberlist[memberRole] = [member]
     316            else:
     317                raise RestrictionError, "Pli ol unu via rolo aŭ via ne estas nodo"
     318        elif memberRole in ("from", "to"):
     319            if member.isWay():
     320                try:
     321                    memberlist[memberRole].append (member)
     322                except KeyError:
     323                    memberlist[memberRole] = [member]
     324            else:
     325                raise RestrictionError, "From aŭ to rolo ne estas vojo"
     326        else:
     327            raise RestrictionError, "Nekonata rolo " + memberRole
     328
     329    if len(memberlist.keys())<3:
     330        raise RestrictionError, "Iuj roloj mankas: Nur " + ",".join (memberlist.keys()) + " trovita"
     331    return memberlist
     332
     333def downloadPrimitives (primitives, editlayer):
     334    """
     335        Elŝuti liston de primitivoj de servilo, kaj kunfandi en redaktotavolon. Blokanta.
     336    """
     337    monitor = PleaseWaitProgressMonitor()
     338    monitor.showForegroundDialog()   
     339
     340    print "Elŝutante"
     341    try:
     342        objectReader = MultiFetchServerObjectReader().append (primitives)
     343        dataSet = objectReader.parseOsm (monitor)
     344        editlayer.mergeFrom (dataSet)
     345        editlayer.onPostDownloadFromServer()
     346        if (not objectReader.getMissingPrimitives().isEmpty()) :
     347            raise RestrictionError, "Ne eblas elŝuti mankantajn primitivojn"
     348        print "Elŝuto kompletigita"   
     349    finally:
     350        monitor.close()
     351
     352def checkIfConnected (node, way, reverse):
     353    """
     354        Redoni (konektita, sekva nodo por kompari (t.e. alia fino de la nodo) se vera)
     355    """
     356    if (way.isOneway() != 0 and reverse):
     357        return node == way.lastNode(True), way.firstNode(True) # Vera: aŭtomate prilabori kazon kiam isOneway == -1
     358    if (way.isOneway() != 0):     # ne reverse
     359        return node == way.firstNode(True), way.lastNode(True)
     360    if node == way.firstNode():
     361        return True, way.lastNode()
     362    if node == way.lastNode():
     363        return True, way.firstNode()
     364    return False, node   
     365
     366
     367def repairrestriction (relation, memberlist, editLayer):
     368    """
     369        Elŝuti mankantajn membrojn se necese, akiri liston de membroj por forigi, kaj forigi ilin se neniu eraro leviĝas dum kontrolado
     370    """
     371    incompleteMembers = relation.getIncompleteMembers()
     372    if incompleteMembers:
     373          downloadPrimitives (incompleteMembers, editLayer);       
     374
     375    fromRemovalList = []; toRemovalList = []
     376   
     377    if len (memberlist["from"]) >= 1:
     378        currnode = memberlist["via"][0].getNode()
     379        firstMember = True
     380        failed = False;
     381        # spuri "from" membrojn por konfirmi ĉu dividitaj de unu vojo
     382        for member in reversed(memberlist['from']):
     383            connected, currnode = checkIfConnected (currnode, member.getWay(), True)
     384            if not connected:
     385                if not firstMember:
     386                    raise RestrictionError, "from vojoj ne kontinuaj de via nodo"
     387                failed = True
     388                break
     389            if not firstMember:
     390                fromRemovalList.append (member)
     391            else:
     392                firstMember = False
     393
     394        if failed: # Dua provo en kazo sekvenco inversigita kiam dividita
     395            currnode = memberlist["via"][0].getNode()
     396            for member in memberlist['from']:
     397                connected, currnode = checkIfConnected (currnode, member.getWay(), True)
     398                if not connected:
     399                    raise RestrictionError, "from vojoj ne kontinuaj de via nodo"
     400                if not firstMember:
     401                    fromRemovalList.append (member)
     402                else:
     403                    firstMember = False
     404                                                                       
     405    if len (memberlist["to"]) >= 1:
     406        currnode = memberlist["via"][0].getNode()
     407        firstMember = True
     408        failed = False
     409        # spuri "to" membrojn por konfirmi ĉu dividitaj de unu vojo
     410        for member in memberlist['to']:
     411            connected, currnode = checkIfConnected (currnode, member.getWay(), False)
     412            if not connected:
     413                if not firstMember:
     414                    raise RestrictionError, "to vojoj ne kontinuaj de via nodo"
     415                failed = True
     416                break
     417            if not firstMember:
     418                toRemovalList.append (member)
     419            else:
     420                firstMember = False
     421
     422        if failed: # Dua provo en kazo sekvenco inversigita kiam dividita
     423            currnode = memberlist["via"][0].getNode()
     424            for member in reversed(memberlist['to']):
     425                connected, currnode = checkIfConnected (currnode, member.getWay(), False)
     426                if not connected:
     427                    raise RestrictionError, "to vojoj ne kontinuaj de via nodo"
     428                if not firstMember:
     429                    toRemovalList.append (member)
     430                else:
     431                    firstMember = False         
     432                         
     433    # por forigi vojojn en fromRemovalList, toRemovalList         
     434    newRelation = Relation(relation)
     435    waysToRemove = set()
     436    for removalList in [fromRemovalList, toRemovalList]:
     437        waysToRemove |= set ([m.getWay() for m in removalList])
     438    newRelation.removeMembersFor (waysToRemove)
     439    print "Forigi vojon(jn) id:" + ",".join ([str(w.getId()) for w in waysToRemove])
     440    return Command.ChangeCommand (relation, newRelation)   
     441   
     442   
     443validrestrictiontypes = ('only_straight_on', 'only_right_turn', 'only_left_turn', 'no_right_turn', 'no_left_turn', 'no_straight_on', 'no_u_turn')
     444editLayer = Main.getLayerManager().getEditLayer()
     445if editLayer and editLayer.data:
     446    selectedRelations = editLayer.data.getSelectedRelations()
     447   
     448    if not(selectedRelations):
     449        JOptionPane.showMessageDialog(Main.parent, "Bonvolu elekti unu aŭ plurajn rilatojn")
     450    else:
     451        commandsList = []
     452        for relation in selectedRelations:
     453            if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes:
     454                try:
     455                    memberlist = getMembers (relation)
     456                    if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 :
     457                        # Ripara provo
     458                        print "Provu ripari",
     459                        print "rilato id: " + str(relation.getId())
     460                        command = repairrestriction (relation, memberlist, mv.editLayer)
     461                        print "Sukceso"                         
     462                        commandsList.append (command)
     463                except RestrictionError, e:
     464                    print str(e), "; rilato id: "+ str(relation.getId())
     465               
     466       
     467        Main.main.undoRedo.add(Command.SequenceCommand("Ripari turnrestriktojn", commandsList))
     468        commandsList=[]
     469}}}
     470
     471
     472----
     473Reen al [wikitr:/Help/Plugin/Scripting Kromaĵa Skriptado] \\
     474Reen al [wikitr:/Plugins Kromaĵa Helpo] \\
     475Reen al [wikitr:/Help Ĉefa Helpo]