wiki:Eo:Help/Plugin/Scripting/Python

Kromaĵo -> Skriptado -> Python

Celo

Kelkaj pliaj ekzemploj en Python:

Konverti vojon kiu konektiĝas al nerompita ĉirkaŭvojo al forko

Konverti 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.

from javax.swing import JOptionPane
from org.openstreetmap.josm.gui import MainApplication

import org.openstreetmap.josm.command as Command
import org.openstreetmap.josm.data.osm.Way as Way

editLayer = MainApplication.getLayerManager().getEditLayer()
if editLayer and editLayer.data:
    selected_ways = editLayer.data.getSelectedWays()
    print selected_ways

    if not(selected_ways) or len(selected_ways)>1:
        JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
                                         "Bonvolu elekti unu vojon kiu konektiĝas al ĉirkaŭvojo")
    else:
        for way in selected_ways:
            if way.get('oneway') in ['yes', '-1']:
                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ĉi tiu vojo havas unudirektan etikedon")
            else:
                node_before = None
                node_after = None
                common_node = None
                common_node_becomes_node_before=None
                #print dir(way)
                for fln in [way.firstNode(),  way.lastNode()]:
                    print 'fln',  fln
                    for parentway in fln.getParentWays():
                        if parentway.get("junction")=='roundabout':
                            for n in parentway.getNodes():
                                if common_node:
                                    # trovita komuna nodo inter elektita vojo kaj
                                    # ĉirkaŭvojo en antaŭa iteracio
                                    node_after = n
                                    # ni estas pretaj ĉi tie
                                    break
                                if n.getId() == fln.getId():
                                    # ĉi tiu estas la nodo kiun la ĉirkaŭvojo havas komunan kun la elektita vojo
                                    common_node = n
                                    if not(node_before):
                                        # normale ni renkontis nodon sur la ĉirkaŭvojo
                                        # antaŭ ĉi tiu, sed se la komuna nodo estas la unua nodo
                                        # de nerompita ĉirkaŭvojo, ni devos preni la lastan
                                        # nodon de la ĉirkaŭvojo anstataŭe
                                        node_before = parentway.getNodes()[-2]
                                        node_after = parentway.getNodes()[1]
                                        break
                                    # se ne, ni iras tra la buklo unu fojon pli por meti la sekvan
                                    # nodon en node_after
                                    continue
                                node_before = n
                        if common_node:
                            # se common_node jam estas difinita ĉe ĉi tiu punkto, ĝi signifas ke ĝi estis
                            # la unua nodo de la elektita vojo,
                            # do ĝi devos esti anstataŭigita per node_before en la elektita vojo
                            common_node_becomes_node_before = True
                            adjacent_node_to_split_on = way.getNodes()[1]
                            break
                        else:
                            common_node_becomes_node_before = False
                            adjacent_node_to_split_on = way.getNodes()[-1]
                if not(common_node) or common_node_becomes_node_before==None:
                    JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
                                               "Bonvolu elekti vojon kiu konektiĝas al ĉirkaŭvojo")
                else:
                    print common_node.get('name')
                    print node_before.get('name')
                    print node_after.get('name')

                    commandsList = []
                    if len(way.getNodes())>2:
                        # dividi lastan segmenton antaŭ ĉirkaŭvojo se necese
                        commandsList.append(Command.SplitWayCommand.split(
                                    way, [adjacent_node_to_split_on], []))
                        MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Dividi elektitan vojon", commandsList))
                        commandsList = []
                    # Post dividado trovi la segmenton kiu konektiĝas al la ĉirkaŭvojo denove
                    for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays():
                        if common_node in waypartconnectedtoroundabout.getNodes():
                            break
                    if len(way.getNodes())==2:
                        if common_node == waypartconnectedtoroundabout.firstNode():
                            adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode()
                        else:
                            adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode()
                    # tempo por efektive fari ion
                    # krei kopion de la vojo
                    modified_way = Way(waypartconnectedtoroundabout)
                    # anstataŭigi ĝiajn nodojn, por ke ĝi iĝu forko
                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
                    # aldoni unudirektan etikedon
                    modified_way.put('oneway', 'yes')
                    # apliki la ŝanĝojn
                    commandsList.append(Command.ChangeCommand(
                                    waypartconnectedtoroundabout, modified_way))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Aldoni unudirektan etikedon kaj krei forkan vojon", commandsList))
                    commandsList = []
                    # dividi ĉi tiun vojon kie ĝi forkas
                    commandsList.append(Command.SplitWayCommand.split(
                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Dividi forkon en 2 vojojn", commandsList))
                    commandsList = []

Konverti vojon kiu konektiĝas al rompita ĉirkaŭvojo al forko

Ĉ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.

from javax.swing import JOptionPane
from org.openstreetmap.josm.gui import MainApplication

import org.openstreetmap.josm.command as Command
import org.openstreetmap.josm.data.osm.Way as Way

editLayer = MainApplication.getLayerManager().getEditLayer()
print '==== Freŝa rulo ===='
if editLayer and editLayer.data:
    selected_ways = editLayer.data.getSelectedWays()
    print selected_ways

    if not(selected_ways) or len(selected_ways)>1:
        JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Bonvolu elekti unu vojon kiu konektiĝas al ĉirkaŭvojo")
    else:
        for way in selected_ways:
            if way.get('oneway') in ['yes', '-1']:
                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ĉi tiu vojo havas unudirektan etikedon")
            elif way.get('junction') in ['roundabout']:
                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Ĉi tiu vojo estas parto de ĉirkaŭvojo")
            else:
                node_before = None
                node_after = None
                common_node = None
                common_node_becomes_node_before=None
                roundabout_way_before = None
                roundabout_way_after = None
                for fln in [way.firstNode(),  way.lastNode()]:
                    print 'fln',  fln
                    for parentway in fln.getParentWays():
                        if parentway.get("junction")=='roundabout':
                            print parentway.get('name')
                            if parentway.isClosed():
                                # nerompita ĉirkaŭvojo
                                for n in parentway.getNodes():
                                    if common_node:
                                        # trovita komuna nodo inter elektita vojo
                                        # kaj ĉirkaŭvojo en antaŭa iteracio
                                        node_after = n
                                        print node_before.get('name')
                                        print node_after.get('name')
                                        # ni estas pretaj ĉi tie
                                        break
                                    if n.getId() == fln.getId():
                                        # ĉi tiu estas la nodo kiun la ĉirkaŭvojo havas komunan kun la elektita vojo
                                        common_node = n
                                        print common_node.get('name')
                                        if not(node_before):
                                            # normale ni renkontis nodon sur la ĉirkaŭvojo
                                            # antaŭ ĉi tiu, sed se la komuna nodo estas la unua nodo
                                            # de nerompita ĉirkaŭvojo, ni devos preni la lastan
                                            # nodon de la ĉirkaŭvojo anstataŭe
                                            node_before = parentway.getNodes()[-2]
                                            node_after = parentway.getNodes()[1]
                                            print node_before.get('name')
                                            print node_after.get('name')
                                            break
                                        # se ne, ni iras tra la buklo unu fojon pli por meti la sekvan
                                        # nodon en node_after
                                        continue
                                    node_before = n
                            else:
                                # ĉi tiu estas rompita ĉirkaŭvojo
                                if parentway.firstNode().getId() == fln.getId():
                                    node_after = parentway.getNodes()[1]
                                    roundabout_way_after = parentway
                                    print 'node after', node_after.get('name')
                                else:
                                    node_before = parentway.getNodes()[-2]
                                    roundabout_way_before = parentway
                                if node_before and node_after:
                                    common_node = fln
                                    break

                            if common_node:
                                # se common_node jam estas difinita ĉe ĉi tiu punkto, ĝi signifas ke ĝi estis
                                # la unua nodo de la elektita vojo,
                                # do ĝi devos esti anstataŭigita per node_before en la elektita vojo
                                common_node_becomes_node_before = True
                                break
                            else:
                                common_node_becomes_node_before = False
                        
                if common_node.getId() == way.firstNode().getId():
                    adjacent_node_to_split_on = way.getNodes()[1]
                else:
                    adjacent_node_to_split_on = way.getNodes()[-1]

                if not(common_node) or ((parentway.isClosed() and common_node_becomes_node_before==None)):
                    JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Bonvolu elekti vojon kiu konektiĝas al ĉirkaŭvojo")
                else:
                    commandsList = []
                    if len(way.getNodes())>2:
                        # dividi lastan segmenton antaŭ ĉirkaŭvojo se necese
                        commandsList.append(Command.SplitWayCommand.split(
                                    way, [adjacent_node_to_split_on], []))
                        MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Dividi elektitan vojon", commandsList))
                        commandsList = []
                    # Post dividado trovi la segmenton kiu konektiĝas al la ĉirkaŭvojo denove
                    for waypartconnectedtoroundabout in adjacent_node_to_split_on.getParentWays():
                        if waypartconnectedtoroundabout.get('junction') == 'roundabout':
                            continue
                        if common_node in waypartconnectedtoroundabout.getNodes():
                            break
                    if len(way.getNodes())==2:
                        if common_node == waypartconnectedtoroundabout.firstNode():
                            adjacent_node_to_split_on = waypartconnectedtoroundabout.lastNode()
                        else:
                            adjacent_node_to_split_on = waypartconnectedtoroundabout.firstNode()
                    # tempo por efektive fari ion
                    # krei kopion de la vojo
                    modified_way = Way(waypartconnectedtoroundabout)
                    # anstataŭigi ĝiajn nodojn, por ke ĝi iĝu forko
                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
                    # aldoni unudirektan etikedon
                    modified_way.put('oneway', 'yes')
                    # apliki la ŝanĝojn
                    commandsList.append(Command.ChangeCommand(
                                    waypartconnectedtoroundabout, modified_way))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Aldoni unudirektan etikedon kaj krei forkan vojon", commandsList))
                    commandsList = []
                    # dividi ĉi tiun vojon kie ĝi forkas
                    commandsList.append(Command.SplitWayCommand.split(
                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Dividi forkon en 2 vojojn", commandsList))
                    commandsList = []
                    
                    if roundabout_way_before and roundabout_way_after:
                        origway = roundabout_way_before
                        roundabout_way_before.addNode(node_after)
                        commandsList.append(Command.ChangeCommand(
                                        origway,  roundabout_way_before))
                        origway = roundabout_way_after
                        roundabout_way_after.removeNode(common_node)
                        commandsList.append(Command.ChangeCommand(
                                        origway,roundabout_way_after))
#                        middleway = Way(roundabout_way_after).setNodes(
#                                        [node_before, common_node, node_after])
#                        commandsList.append(Command.AddCommand(editLayer.data, middleway))
#                        MainApplication.undoRedo.add(Command.SequenceCommand(
#                                        "Aldoni vojon sur ĉirkaŭvojo kie forko konektiĝas", commandsList))
                        commandsList.append(Command.SplitWayCommand.split(
                                        roundabout_way_before, [node_before], []))
                        MainApplication.undoRedo.add(Command.SequenceCommand(
                                        "Dividi ĉirkaŭvojon", commandsList))
                        commandsList = []

Eksporti kolekton de itineroj al Garmin GPX-dosiero

Eksporti kolekton de itineroj al Garmin GPX-dosiero (ne ekzemplo, ĉar mi ne pensas ke ni plu faras kolektajn rilatojn):

#!/bin/jython
'''
RWN2Garmin.py  - Numeritaj retoj al Garmin GPX-dosiera konvertilo
Ĉi tiu kodo estas liberigita sub la GNU General Public License v2 aŭ poste.

La GPL v3 estas alirebla ĉi tie:
https://www.gnu.org/licenses/gpl.html

Ĝi venas sen ia ajn garantio.
'''
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 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 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, "Pli ol unu via rolo aŭ via ne estas nodo"
        elif memberRole in ("from", "to"):
            if member.isWay():
                try:
                    memberlist[memberRole].append (member)
                except KeyError:
                    memberlist[memberRole] = [member]
            else:
                raise RestrictionError, "From aŭ to rolo ne estas vojo"
        else: 
            raise RestrictionError, "Nekonata rolo " + memberRole

    if len(memberlist.keys())<3:
        raise RestrictionError, "Iuj roloj mankas: Nur " + ",".join (memberlist.keys()) + " trovita"
    return memberlist

def downloadPrimitives (primitives, editlayer):
    """
        Elŝuti liston de primitivoj de servilo, kaj kunfandi en redaktotavolon. Blokanta.
    """
    monitor = PleaseWaitProgressMonitor()
    monitor.showForegroundDialog()   

    print "Elŝutante"
    try:
        objectReader = MultiFetchServerObjectReader().append (primitives)
        dataSet = objectReader.parseOsm (monitor)
        editlayer.mergeFrom (dataSet)
        editlayer.onPostDownloadFromServer()
        if (not objectReader.getMissingPrimitives().isEmpty()) :
            raise RestrictionError, "Ne eblas elŝuti mankantajn primitivojn"
        print "Elŝuto kompletigita"    
    finally:
        monitor.close()

def checkIfConnected (node, way, reverse):
    """
        Redoni (konektita, sekva nodo por kompari (t.e. alia fino de la nodo) se vera)
    """
    if (way.isOneway() != 0 and reverse):
        return node == way.lastNode(True), way.firstNode(True) # Vera: aŭtomate prilabori kazon kiam isOneway == -1
    if (way.isOneway() != 0):     # ne 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):
    """
        Elŝuti mankantajn membrojn se necese, akiri liston de membroj por forigi, kaj forigi ilin se neniu eraro leviĝas dum kontrolado
    """
    incompleteMembers = relation.getIncompleteMembers()
    if incompleteMembers:
          downloadPrimitives (incompleteMembers, editLayer);        

    fromRemovalList = []; toRemovalList = []
    
    if len (memberlist["from"]) >= 1:
        currnode = memberlist["via"][0].getNode()
        firstMember = True
        failed = False;
        # spuri "from" membrojn por konfirmi ĉu dividitaj de unu vojo
        for member in reversed(memberlist['from']):
            connected, currnode = checkIfConnected (currnode, member.getWay(), True)
            if not connected:
                if not firstMember:
                    raise RestrictionError, "from vojoj ne kontinuaj de via nodo" 
                failed = True
                break
            if not firstMember:
                fromRemovalList.append (member)
            else:
                firstMember = False

        if failed: # Dua provo en kazo sekvenco inversigita kiam dividita
            currnode = memberlist["via"][0].getNode()
            for member in memberlist['from']:
                connected, currnode = checkIfConnected (currnode, member.getWay(), True)
                if not connected:
                    raise RestrictionError, "from vojoj ne kontinuaj de via nodo"
                if not firstMember:
                    fromRemovalList.append (member)
                else:
                    firstMember = False
                                                                        
    if len (memberlist["to"]) >= 1:
        currnode = memberlist["via"][0].getNode()
        firstMember = True
        failed = False
        # spuri "to" membrojn por konfirmi ĉu dividitaj de unu vojo
        for member in memberlist['to']:
            connected, currnode = checkIfConnected (currnode, member.getWay(), False)
            if not connected:
                if not firstMember:
                    raise RestrictionError, "to vojoj ne kontinuaj de via nodo" 
                failed = True
                break
            if not firstMember:
                toRemovalList.append (member)
            else:
                firstMember = False

        if failed: # Dua provo en kazo sekvenco inversigita kiam dividita
            currnode = memberlist["via"][0].getNode()
            for member in reversed(memberlist['to']):
                connected, currnode = checkIfConnected (currnode, member.getWay(), False)
                if not connected:
                    raise RestrictionError, "to vojoj ne kontinuaj de via nodo"
                if not firstMember:
                    toRemovalList.append (member)
                else:
                    firstMember = False          
                         
    # por forigi vojojn en fromRemovalList, toRemovalList          
    newRelation = Relation(relation)
    waysToRemove = set()
    for removalList in [fromRemovalList, toRemovalList]:
        waysToRemove |= set ([m.getWay() for m in removalList])
    newRelation.removeMembersFor (waysToRemove)
    print "Forigi vojon(jn) 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')
editLayer = Main.getLayerManager().getEditLayer()
if editLayer and editLayer.data:
    selectedRelations = editLayer.data.getSelectedRelations()
   
    if not(selectedRelations):
        JOptionPane.showMessageDialog(Main.parent, "Bonvolu elekti unu aŭ plurajn rilatojn")
    else:
        commandsList = []
        for relation in selectedRelations:
            if relation.get('type') == "restriction" and relation.get('restriction') in validrestrictiontypes:
                try:
                    memberlist = getMembers (relation)
                    if (len (memberlist["from"])) > 1 or (len (memberlist["to"])) > 1 :
                        # Ripara provo
                        print "Provu ripari",
                        print "rilato id: " + str(relation.getId())
                        command = repairrestriction (relation, memberlist, mv.editLayer)
                        print "Sukceso"                         
                        commandsList.append (command)
                except RestrictionError, e:
                    print str(e), "; rilato id: "+ str(relation.getId())
                
        
        Main.main.undoRedo.add(Command.SequenceCommand("Ripari turnrestriktojn", commandsList))
        commandsList=[]

Reen al Kromaĵa Skriptado
Reen al Kromaĵa Helpo
Reen al Ĉefa Helpo

Last modified 4 months ago Last modified on 2025-03-08T20:11:50+01:00
Note: See TracWiki for help on using the wiki.