wiki:Nb:Help/Plugin/Scripting/Python

Andre språk:

Plugin -> Skripting -> Python =

Formål

Noen flere eksempler i Python:

Konverter en vei som kobler til en usplittet rundkjøring til en forgrening

Konverter en vei som kobler til en rundkjøring til en forgrening som består av 2 envegsveier. Deler veien på sin siste node og fest den til de 2 nodene ved siden av fellesnoden til rundkjøringsveien. Denne versjonen fungerer bare på usplittede rundkjøringer. Se neste eksempel for en oppdatert versjon.

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(),
                                         "Vennligst velg en enkelt vei som kobler til en rundkjøring")
    else:
        for way in selected_ways:
            if way.get('oneway') in ['yes', '-1']:
                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Denne veien har envegsmerke")
            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:
                                    # fant felles node mellom valgt vei og
                                    # rundkjøringsvei i forrige iterasjon
                                    node_after = n
                                    # vi er ferdige her
                                    break
                                if n.getId() == fln.getId():
                                    # dette er noden rundkjøringen har felles med valgt vei
                                    common_node = n
                                    if not(node_before):
                                        # normalt møter vi en node på rundkjøringsveien
                                        # før denne, men hvis fellesnoden er den første noden
                                        # i en usplittet rundkjøring, må vi ta den siste
                                        # noden i rundkjøringen i stedet
                                        node_before = parentway.getNodes()[-2]
                                        node_after = parentway.getNodes()[1]
                                        break
                                    # hvis ikke går vi gjennom løkken en gang til for å sette neste
                                    # node i node_after
                                    continue
                                node_before = n
                        if common_node:
                            # hvis common_node allerede er definert på dette tidspunktet, betyr det at den var
                            # den første noden i den valgte veien,
                            # så den må erstattes med node_before i den valgte veien
                            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(),
                                               "Vennligst velg en vei som kobler til en rundkjøring")
                else:
                    print common_node.get('name')
                    print node_before.get('name')
                    print node_after.get('name')

                    commandsList = []
                    if len(way.getNodes())>2:
                        # del siste segment før rundkjøring hvis nødvendig
                        commandsList.append(Command.SplitWayCommand.split(
                                    way, [adjacent_node_to_split_on], []))
                        MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Del valgt vei", commandsList))
                        commandsList = []
                    # Etter deling finn segmentet som kobler til rundkjøringen igjen
                    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()
                    # tid til å faktisk gjøre noe
                    # lag en kopi av veien
                    modified_way = Way(waypartconnectedtoroundabout)
                    # erstatt nodene slik at den blir en forgrening
                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
                    # legg til envegsmerke
                    modified_way.put('oneway', 'yes')
                    # bruk endringene
                    commandsList.append(Command.ChangeCommand(
                                    waypartconnectedtoroundabout, modified_way))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Legg til envegsmerke og lag forgreningsvei", commandsList))
                    commandsList = []
                    # del denne veien der den forgrener seg
                    commandsList.append(Command.SplitWayCommand.split(
                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Del forgrening i 2 veier", commandsList))
                    commandsList = []

Konverter en vei som kobler til en splittet rundkjøring til en forgrening

Dette skriptet gjør det samme som det forrige, men det fungerer også på rundkjøringer der veiene er splittet. Det tar ikke hensyn til relasjoner.

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 '==== Ny kjøring ===='
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(), "Vennligst velg en enkelt vei som kobler til en rundkjøring")
    else:
        for way in selected_ways:
            if way.get('oneway') in ['yes', '-1']:
                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Denne veien har envegsmerke")
            elif way.get('junction') in ['roundabout']:
                JOptionPane.showMessageDialog(MainApplication.getMainFrame(), "Denne veien er en del av en rundkjøring")
            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():
                                # usplittet rundkjøring
                                for n in parentway.getNodes():
                                    if common_node:
                                        # fant felles node mellom valgt vei
                                        # og rundkjøringsvei i forrige iterasjon
                                        node_after = n
                                        print node_before.get('name')
                                        print node_after.get('name')
                                        # vi er ferdige her
                                        break
                                    if n.getId() == fln.getId():
                                        # dette er noden rundkjøringen har felles med valgt vei
                                        common_node = n
                                        print common_node.get('name')
                                        if not(node_before):
                                            # normalt møter vi en node på rundkjøringsveien
                                            # før denne, men hvis fellesnoden er den første noden
                                            # i en usplittet rundkjøring, må vi ta den siste
                                            # noden i rundkjøringen i stedet
                                            node_before = parentway.getNodes()[-2]
                                            node_after = parentway.getNodes()[1]
                                            print node_before.get('name')
                                            print node_after.get('name')
                                            break
                                        # hvis ikke går vi gjennom løkken en gang til for å sette neste
                                        # node i node_after
                                        continue
                                    node_before = n
                            else:
                                # dette er en splittet rundkjøring
                                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:
                                # hvis common_node allerede er definert på dette tidspunktet, betyr det at den var
                                # den første noden i den valgte veien,
                                # så den må erstattes med node_before i den valgte veien
                                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(), "Vennligst velg en vei som kobler til en rundkjøring")
                else:
                    commandsList = []
                    if len(way.getNodes())>2:
                        # del siste segment før rundkjøring hvis nødvendig
                        commandsList.append(Command.SplitWayCommand.split(
                                    way, [adjacent_node_to_split_on], []))
                        MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Del valgt vei", commandsList))
                        commandsList = []
                    # Etter deling finn segmentet som kobler til rundkjøringen igjen
                    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()
                    # tid til å faktisk gjøre noe
                    # lag en kopi av veien
                    modified_way = Way(waypartconnectedtoroundabout)
                    # erstatt nodene slik at den blir en forgrening
                    modified_way.setNodes([node_before, adjacent_node_to_split_on, node_after])
                    # legg til envegsmerke
                    modified_way.put('oneway', 'yes')
                    # bruk endringene
                    commandsList.append(Command.ChangeCommand(
                                    waypartconnectedtoroundabout, modified_way))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Legg til envegsmerke og lag forgreningsvei", commandsList))
                    commandsList = []
                    # del denne veien der den forgrener seg
                    commandsList.append(Command.SplitWayCommand.split(
                                    waypartconnectedtoroundabout, [adjacent_node_to_split_on], []))
                    MainApplication.undoRedo.add(Command.SequenceCommand(
                                    "Del forgrening i 2 veier", 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(
#                                        "Legg til vei på rundkjøring der forgrening kobler til", commandsList))
                        commandsList.append(Command.SplitWayCommand.split(
                                        roundabout_way_before, [node_before], []))
                        MainApplication.undoRedo.add(Command.SequenceCommand(
                                        "Del rundkjøringsvei", commandsList))
                        commandsList = []

Eksporter en samling av ruter til Garmin GPX-fil

Eksporter en samling av ruter til Garmin GPX-fil (ikke et supereksempel, da jeg ikke tror vi gjør samlingsrelasjoner lenger):

#!/bin/jython
'''
RWN2Garmin.py  - Nummererte nettverk til Garmin GPX-fil konverter
Denne koden er utgitt under GNU General Public License v2 eller senere.

GPL v3 er tilgjengelig her:
https://www.gnu.org/licenses/gpl.html

Den kommer uten noen form for garanti.
'''
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, "Mer enn én via-rolle eller via er ikke en node"
        elif memberRole in ("from", "to"):
            if member.isWay():
                try:
                    memberlist[memberRole].append (member)
                except KeyError:
                    memberlist[memberRole] = [member]
            else:
                raise RestrictionError, "From eller to-rolle er ikke en vei"
        else: 
            raise RestrictionError, "Ukjent rolle " + memberRole

    if len(memberlist.keys())<3:
        raise RestrictionError, "Noen roller mangler: Bare " + ",".join (memberlist.keys()) + " funnet"
    return memberlist

def downloadPrimitives (primitives, editlayer):
    """
        Last ned en liste av primitiver fra serveren, og flett inn i redigeringslaget. Blokkerende.
    """
    monitor = PleaseWaitProgressMonitor()
    monitor.showForegroundDialog()   

    print "Laster ned"
    try:
        objectReader = MultiFetchServerObjectReader().append (primitives)
        dataSet = objectReader.parseOsm (monitor)
        editlayer.mergeFrom (dataSet)
        editlayer.onPostDownloadFromServer()
        if (not objectReader.getMissingPrimitives().isEmpty()) :
            raise RestrictionError, "Kan ikke laste ned manglende primitiver"
        print "Nedlasting fullført"    
    finally:
        monitor.close()

def checkIfConnected (node, way, reverse):
    """
        Returner (koblet, neste node å sammenligne (dvs. andre enden av noden) hvis sant)
    """
    if (way.isOneway() != 0 and reverse):
        return node == way.lastNode(True), way.firstNode(True) # Sant: automatisk prosesser tilfellet når isOneway == -1
    if (way.isOneway() != 0):     # ikke 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):
    """
        Last ned manglende medlemmer hvis nødvendig, få liste over medlemmer å fjerne, og fjern dem hvis ingen feil oppstår under kontroll
    """
    incompleteMembers = relation.getIncompleteMembers()
    if incompleteMembers:
          downloadPrimitives (incompleteMembers, editLayer);        

    fromRemovalList = []; toRemovalList = []
    
    if len (memberlist["from"]) >= 1:
        currnode = memberlist["via"][0].getNode()
        firstMember = True
        failed = False;
        # spore "from"-medlemmer for å bekrefte om de er delt fra én vei
        for member in reversed(memberlist['from']):
            connected, currnode = checkIfConnected (currnode, member.getWay(), True)
            if not connected:
                if not firstMember:
                    raise RestrictionError, "from-veier er ikke kontinuerlige fra via-node" 
                failed = True
                break
            if not firstMember:
                fromRemovalList.append (member)
            else:
                firstMember = False

        if failed: # Andre forsøk i tilfelle sekvensen er reversert ved deling
            currnode = memberlist["via"][0].getNode()
            for member in memberlist['from']:
                connected, currnode = checkIfConnected (currnode, member.getWay(), True)
                if not connected:
                    raise RestrictionError, "from-veier er ikke kontinuerlige fra via-node"
                if not firstMember:
                    fromRemovalList.append (member)
                else:
                    firstMember = False
                                                                        
    if len (memberlist["to"]) >= 1:
        currnode = memberlist["via"][0].getNode()
        firstMember = True
        failed = False
        # spore "to"-medlemmer for å bekrefte om de er delt fra én vei
        for member in memberlist['to']:
            connected, currnode = checkIfConnected (currnode, member.getWay(), False)
            if not connected:
                if not firstMember:
                    raise RestrictionError, "to-veier er ikke kontinuerlige fra via-node" 
                failed = True
                break
            if not firstMember:
                toRemovalList.append (member)
            else:
                firstMember = False

        if failed: # Andre forsøk i tilfelle sekvensen er reversert ved deling
            currnode = memberlist["via"][0].getNode()
            for member in reversed(memberlist['to']):
                connected, currnode = checkIfConnected (currnode, member.getWay(), False)
                if not connected:
                    raise RestrictionError, "to-veier er ikke kontinuerlige fra via-node"
                if not firstMember:
                    toRemovalList.append (member)
                else:
                    firstMember = False          
                         
    # for å fjerne veier i fromRemovalList, toRemovalList          
    newRelation = Relation(relation)
    waysToRemove = set()
    for removalList in [fromRemovalList, toRemovalList]:
        waysToRemove |= set ([m.getWay() for m in removalList])
    newRelation.removeMembersFor (waysToRemove)
    print "Fjern vei(er) 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, "Vennligst velg en eller flere relasjoner")
    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 :
                        # Reparasjonsforsøk
                        print "Prøver å reparere",
                        print "relasjon id: " + str(relation.getId())
                        command = repairrestriction (relation, memberlist, mv.editLayer)
                        print "Suksess"                         
                        commandsList.append (command)
                except RestrictionError, e:
                    print str(e), "; relasjon id: "+ str(relation.getId())
                
        
        Main.main.undoRedo.add(Command.SequenceCommand("Reparer svingrestriksjoner", commandsList))
        commandsList=[]

Tilbake til Plugin Skripting
Tilbake til Plugin Hjelp
Tilbake til Hovedhjelp

Last modified 5 days ago Last modified on 2025-03-08T20:14:37+01:00
Note: See TracWiki for help on using the wiki.